2 * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.
\r
4 * This software is available to you under the OpenIB.org BSD license
\r
7 * Redistribution and use in source and binary forms, with or
\r
8 * without modification, are permitted provided that the following
\r
9 * conditions are met:
\r
11 * - Redistributions of source code must retain the above
\r
12 * copyright notice, this list of conditions and the following
\r
15 * - Redistributions in binary form must reproduce the above
\r
16 * copyright notice, this list of conditions and the following
\r
17 * disclaimer in the documentation and/or other materials
\r
18 * provided with the distribution.
\r
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
33 // IBInstaller.cpp : Defines the entry point for the DLL application.
\r
38 wchar_t debug_buf[256];
\r
40 // IB Fabric device HW ID
\r
41 #define GUID_IB_BUS_HW_ID TEXT("{94f41ced-78eb-407c-b5df-958040af0fd8}")
\r
43 #define DEVICE_DESC TEXT("InfiniBand Fabric")
\r
45 // System Class GUID (from wdmguid.h)
\r
46 //{4D36E97D-E325-11CE-BFC1-08002BE10318}
\r
47 static const GUID GUID_CLASS_SYSTEM =
\r
48 { 0x4D36E97D, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
\r
51 BOOL APIENTRY DllMain(
\r
53 DWORD ul_reason_for_call,
\r
56 UNREFERENCED_PARAMETER( hModule );
\r
57 UNREFERENCED_PARAMETER( ul_reason_for_call );
\r
58 UNREFERENCED_PARAMETER( lpReserved );
\r
64 // Checks the installed devices, looking for an instance of the bus root.
\r
70 SP_DEVINFO_DATA devInfo;
\r
74 memset( &devInfo, 0, sizeof(SP_DEVINFO_DATA) );
\r
75 devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
\r
78 TEXT("Checking for existance of IB Fabric Root device.\n") );
\r
80 // Get all devices of the system class.
\r
81 hDevList = SetupDiGetClassDevs( &GUID_CLASS_SYSTEM, 0, NULL, 0 );
\r
82 if( hDevList == INVALID_HANDLE_VALUE )
\r
84 swprintf( debug_buf,L"[IbInstaller] Failed to get system class dev info list Error %d\n",GetLastError());
\r
85 OutputDebugString( debug_buf );
\r
86 return GetLastError();
\r
89 // Enumerate until we find our device. If the device exists, we
\r
94 // Get the next device.
\r
95 bSuccess = SetupDiEnumDeviceInfo( hDevList, i++, &devInfo );
\r
98 OutputDebugString( TEXT("SetupDiEnumDeviceInfo failed.\n") );
\r
102 // Get the device's description.
\r
103 bSuccess = SetupDiGetDeviceRegistryProperty( hDevList, &devInfo,
\r
104 SPDRP_HARDWAREID, NULL, (BYTE*)buf, sizeof(buf), NULL );
\r
107 // Device has no HW ID.
\r
109 TEXT("SetupDiGetDeviceRegistryProperty failed.\n") );
\r
110 // Skip to the next.
\r
115 // Compare to our device description.
\r
116 if( _tcscmp( buf, GUID_IB_BUS_HW_ID ) )
\r
119 // The device is already installed.
\r
120 SetupDiDestroyDeviceInfoList( hDevList );
\r
121 OutputDebugString( TEXT("IB Fabric Root device already exists.\n") );
\r
122 return ERROR_ALREADY_EXISTS;
\r
124 } while( bSuccess );
\r
126 return ERROR_SUCCESS;
\r
130 DWORD SelectDriver(
\r
131 IN HDEVINFO hDevList,
\r
132 IN SP_DEVINFO_DATA *pDevInfo,
\r
133 OUT SP_DRVINFO_DATA *pDrvInfo )
\r
139 // Get a list of drivers.
\r
141 SetupDiBuildDriverInfoList( hDevList, pDevInfo, SPDIT_CLASSDRIVER );
\r
144 swprintf( debug_buf,L"[IbInstaller] SetupDiBuildDriverInfoList failed Error %d\n",GetLastError());
\r
145 OutputDebugString( debug_buf );
\r
146 return GetLastError();
\r
149 // Set the size of the structure properly.
\r
150 pDrvInfo->cbSize = sizeof(SP_DRVINFO_DATA);
\r
152 // Enumerate all drivers, looking for the correct description.
\r
157 bSuccess = SetupDiEnumDriverInfo( hDevList, pDevInfo,
\r
158 SPDIT_CLASSDRIVER, i++, pDrvInfo );
\r
161 swprintf( debug_buf,L"[IbInstaller] SetupDiEnumDriverInfo failed Error %d\n",GetLastError());
\r
162 OutputDebugString( debug_buf );
\r
167 swprintf( debug_buf,TEXT("[IbInstaller] pDrvInfo->Description %s\n"),pDrvInfo->Description);
\r
168 OutputDebugString( debug_buf );
\r
170 if( _tcscmp( pDrvInfo->Description, DEVICE_DESC ) )
\r
174 OutputDebugString( TEXT("Found our driver!\n") );
\r
175 return ERROR_SUCCESS;
\r
177 } while( bSuccess );
\r
179 return ERROR_NOT_FOUND;
\r
185 IN PCTSTR driverPath )
\r
189 SP_DEVINFO_DATA devInfo;
\r
190 SP_DRVINFO_DATA drvInfo;
\r
192 SP_DEVINSTALL_PARAMS installParams;
\r
195 memset( &devInfo, 0, sizeof(SP_DEVINFO_DATA) );
\r
196 devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
\r
198 OutputDebugString( TEXT("Creating IB Fabric Root device.\n") );
\r
200 // Create a list for devices of the system class.
\r
201 hDevList = SetupDiCreateDeviceInfoList( &GUID_CLASS_SYSTEM, NULL );
\r
202 if( hDevList == INVALID_HANDLE_VALUE )
\r
204 OutputDebugString( TEXT("Failed to create dev info list.\n") );
\r
205 return GetLastError();
\r
208 // Create the device.
\r
209 bSuccess = SetupDiCreateDeviceInfo( hDevList, TEXT("SYSTEM"),
\r
210 &GUID_CLASS_SYSTEM, DEVICE_DESC,
\r
211 NULL, DICD_GENERATE_ID, &devInfo );
\r
214 OutputDebugString( TEXT("SetupDiCreateDeviceInfo failed.\n") );
\r
215 SetupDiDestroyDeviceInfoList( hDevList );
\r
216 return GetLastError();
\r
219 // Setup the HW ID for the device.
\r
220 bSuccess = SetupDiSetDeviceRegistryProperty( hDevList, &devInfo,
\r
221 SPDRP_HARDWAREID, (BYTE*)GUID_IB_BUS_HW_ID, sizeof(GUID_IB_BUS_HW_ID) );
\r
225 TEXT("SetupDiSetDeviceRegistryProperty failed.\n") );
\r
226 SetupDiDestroyDeviceInfoList( hDevList );
\r
227 return GetLastError();
\r
230 // Setup the install path.
\r
231 ZeroMemory( &installParams, sizeof(installParams) );
\r
232 installParams.cbSize = sizeof(installParams);
\r
233 _tcsncpy( installParams.DriverPath, driverPath, MAX_PATH );
\r
236 SetupDiSetDeviceInstallParams( hDevList, &devInfo, &installParams );
\r
239 OutputDebugString( TEXT("SetupDiSetDeviceInstallParams failed.\n") );
\r
240 SetupDiDestroyDeviceInfoList( hDevList );
\r
241 return GetLastError();
\r
244 status = SelectDriver( hDevList, &devInfo, &drvInfo );
\r
245 if( status != ERROR_SUCCESS )
\r
247 OutputDebugString( TEXT("Could not find driver.\n") );
\r
248 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
249 SetupDiDestroyDeviceInfoList( hDevList );
\r
253 // Select the device.
\r
254 bSuccess = SetupDiSetSelectedDevice( hDevList, &devInfo );
\r
257 OutputDebugString( TEXT("SetupDiSetSelectedDevice failed.\n") );
\r
258 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
259 SetupDiDestroyDeviceInfoList( hDevList );
\r
260 return GetLastError();
\r
263 // Select the driver.
\r
264 bSuccess = SetupDiSetSelectedDriver( hDevList, &devInfo, &drvInfo );
\r
267 OutputDebugString( TEXT("SetupDiSetSelectedDriver failed.\n") );
\r
268 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
269 SetupDiDestroyDeviceInfoList( hDevList );
\r
270 return GetLastError();
\r
273 // Register the device (since it is non-PnP).
\r
274 bSuccess = SetupDiRegisterDeviceInfo( hDevList, &devInfo, SPRDI_FIND_DUPS,
\r
275 NULL, NULL, NULL );
\r
278 OutputDebugString( TEXT("SetupDiRegisterDeviceInfo failed.\n") );
\r
279 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
280 SetupDiDestroyDeviceInfoList( hDevList );
\r
281 return GetLastError();
\r
284 // Install the device (copies the files and starts it).
\r
285 bSuccess = SetupDiInstallDevice( hDevList, &devInfo );
\r
288 OutputDebugString( TEXT("SetupDiInstallDevice failed.\n") );
\r
289 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
290 SetupDiDestroyDeviceInfoList( hDevList );
\r
291 return GetLastError();
\r
294 return ERROR_SUCCESS;
\r
301 IN UINT Notification,
\r
302 IN UINT_PTR Param1,
\r
303 IN UINT_PTR Param2 )
\r
306 FILEPATHS *pFileInfo;
\r
308 UNREFERENCED_PARAMETER( Param2 );
\r
310 if( Notification != SPFILENOTIFY_QUEUESCAN_EX )
\r
313 pPath = (TCHAR*)Context;
\r
314 pFileInfo = (FILEPATHS*)Param1;
\r
316 // Copy the source path of the file to the path.
\r
317 if( pFileInfo->Source )
\r
318 _tcsncpy( pPath, pFileInfo->Source, MAX_PATH );
\r
329 IN DI_FUNCTION InstallFunction,
\r
330 IN HDEVINFO DeviceInfoSet,
\r
331 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
\r
332 IN OUT PCOINSTALLER_CONTEXT_DATA Context )
\r
334 SP_DEVINSTALL_PARAMS InstallParams;
\r
337 TCHAR path[MAX_PATH];
\r
340 UNREFERENCED_PARAMETER( Context );
\r
342 // The file queue is valid on the DIF_INSTALLDEVICE, so trap that
\r
343 // code and extract the install path.
\r
344 if( InstallFunction != DIF_INSTALLDEVICE )
\r
347 // First find out if we need to install the transport.
\r
348 result = NeedInstall();
\r
349 if( result != ERROR_SUCCESS )
\r
351 if( result == ERROR_ALREADY_EXISTS )
\r
357 // Extract the file path from the file queue.
\r
358 // First get the file queue (it's in the install parameters).
\r
359 memset( &InstallParams, 0, sizeof(InstallParams) );
\r
360 InstallParams.cbSize = sizeof(InstallParams);
\r
362 // Get the installation parameters.
\r
363 b = SetupDiGetDeviceInstallParams( DeviceInfoSet, DeviceInfoData,
\r
366 return GetLastError();
\r
368 // If there isn't a file queue, abort the installation.
\r
369 if( !InstallParams.FileQueue )
\r
370 return ERROR_DI_DONT_INSTALL;
\r
372 // Scan the file queue. The callback will copy the file name to our path.
\r
373 SetupScanFileQueue( InstallParams.FileQueue, SPQ_SCAN_USE_CALLBACKEX, NULL,
\r
374 IbFileCallback, &path, &result );
\r
378 // Strip the file name from the path.
\r
379 nEnd = _tcslen( path );
\r
380 while( path[nEnd] != '\\' )
\r
383 NOTE: no need to strip the platform directoty it was removed for WHQL
\r
386 // Strip the platform subdir name from the path.
\r
387 while( path[nEnd] != '\\' )
\r
390 path[nEnd] = _T('\0');
\r
392 swprintf( debug_buf ,L"[IbInstaller] path %s\n",path);
\r
393 OutputDebugString( debug_buf );
\r
396 // Create the bus root.
\r
397 result = CreateIbBusRoot( path );
\r
398 if( result != ERROR_SUCCESS )
\r