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("[IbInstaller]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("[IbInstaller]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("[IbInstaller]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("[IbInstaller]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
138 OutputDebugString( L"SelectDriver" );
\r
140 // Get a list of drivers.
\r
142 SetupDiBuildDriverInfoList( hDevList, pDevInfo, SPDIT_CLASSDRIVER );
\r
145 swprintf( debug_buf,L"[IbInstaller] SetupDiBuildDriverInfoList failed Error %d\n",GetLastError());
\r
146 OutputDebugString( debug_buf );
\r
147 return GetLastError();
\r
150 // Set the size of the structure properly.
\r
151 pDrvInfo->cbSize = sizeof(SP_DRVINFO_DATA);
\r
153 // Enumerate all drivers, looking for the correct description.
\r
158 bSuccess = SetupDiEnumDriverInfo( hDevList, pDevInfo,
\r
159 SPDIT_CLASSDRIVER, i++, pDrvInfo );
\r
162 swprintf( debug_buf,L"[IbInstaller] SetupDiEnumDriverInfo failed Error %d\n",GetLastError());
\r
163 OutputDebugString( debug_buf );
\r
168 swprintf( debug_buf,TEXT("[IbInstaller] pDrvInfo->Description %s\n"),pDrvInfo->Description);
\r
169 OutputDebugString( debug_buf );
\r
171 if( _tcscmp( pDrvInfo->Description, DEVICE_DESC ) )
\r
175 OutputDebugString( TEXT("[IbInstaller]Found our driver!\n") );
\r
176 return ERROR_SUCCESS;
\r
178 } while( bSuccess );
\r
180 return ERROR_NOT_FOUND;
\r
186 IN PTSTR driverPath )
\r
190 SP_DEVINFO_DATA devInfo;
\r
191 SP_DRVINFO_DATA drvInfo;
\r
193 SP_DEVINSTALL_PARAMS installParams;
\r
197 memset( &devInfo, 0, sizeof(SP_DEVINFO_DATA) );
\r
198 devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
\r
200 OutputDebugString( TEXT("[IbInstaller]Creating IB Fabric Root device.\n") );
\r
202 // Create a list for devices of the system class.
\r
203 hDevList = SetupDiCreateDeviceInfoList( &GUID_CLASS_SYSTEM, NULL );
\r
204 if( hDevList == INVALID_HANDLE_VALUE )
\r
206 gle = GetLastError();
\r
207 OutputDebugString( TEXT("[IbInstaller]Failed to create dev info list.\n") );
\r
211 // Create the device.
\r
212 bSuccess = SetupDiCreateDeviceInfo( hDevList, TEXT("SYSTEM"),
\r
213 &GUID_CLASS_SYSTEM, DEVICE_DESC,
\r
214 NULL, DICD_GENERATE_ID, &devInfo );
\r
217 gle = GetLastError();
\r
218 OutputDebugString( TEXT("[IbInstaller]SetupDiCreateDeviceInfo failed.\n") );
\r
219 SetupDiDestroyDeviceInfoList( hDevList );
\r
223 // Setup the HW ID for the device.
\r
224 bSuccess = SetupDiSetDeviceRegistryProperty( hDevList, &devInfo,
\r
225 SPDRP_HARDWAREID, (BYTE*)GUID_IB_BUS_HW_ID, sizeof(GUID_IB_BUS_HW_ID) );
\r
228 gle = GetLastError();
\r
230 TEXT("[IbInstaller]SetupDiSetDeviceRegistryProperty failed.\n") );
\r
231 SetupDiDestroyDeviceInfoList( hDevList );
\r
235 // Setup the install path.
\r
236 ZeroMemory( &installParams, sizeof(installParams) );
\r
237 installParams.cbSize = sizeof(installParams);
\r
240 OSVERSIONINFO osvi;
\r
241 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
\r
242 bSuccess = GetVersionEx (&osvi);
\r
245 gle = GetLastError();
\r
247 TEXT("[IbInstaller]GetVersionEx failed.\n") );
\r
248 SetupDiDestroyDeviceInfoList( hDevList );
\r
252 // for LH we want to find the correct path
\r
253 if (osvi.dwMajorVersion > 5)
\r
255 WIN32_FIND_DATA FindFileData;
\r
258 // Strip the file name from the path.
\r
259 nEnd = _tcslen( driverPath );
\r
260 while( driverPath[nEnd] != '\\' ) {
\r
263 driverPath[nEnd] = _T('\0');
\r
264 _tcsncat(driverPath,TEXT("\\ib_bus.inf_*"), MAX_PATH);
\r
266 hFind = FindFirstFile(driverPath, &FindFileData);
\r
267 if (hFind == INVALID_HANDLE_VALUE)
\r
269 printf ("Invalid File Handle. GetLastError reports %d\n", GetLastError ());
\r
270 return ERROR_FILE_NOT_FOUND;
\r
274 printf ("The first file found is %s\n", FindFileData.cFileName);
\r
276 // Strip the file name from the path.
\r
277 nEnd = _tcslen( driverPath );
\r
278 while( driverPath[nEnd] != '\\' ) {
\r
281 driverPath[nEnd+1] = _T('\0');
\r
283 _tcsncpy( installParams.DriverPath, driverPath, MAX_PATH );
\r
284 _tcsncat(installParams.DriverPath, FindFileData.cFileName, MAX_PATH);
\r
289 _tcsncpy( installParams.DriverPath, driverPath, MAX_PATH );
\r
294 SetupDiSetDeviceInstallParams( hDevList, &devInfo, &installParams );
\r
297 gle = GetLastError();
\r
298 OutputDebugString( TEXT("[IbInstaller]SetupDiSetDeviceInstallParams failed.\n") );
\r
299 SetupDiDestroyDeviceInfoList( hDevList );
\r
303 status = SelectDriver( hDevList, &devInfo, &drvInfo );
\r
304 if( status != ERROR_SUCCESS )
\r
306 OutputDebugString( TEXT("[IbInstaller]Could not find driver.\n") );
\r
307 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
308 SetupDiDestroyDeviceInfoList( hDevList );
\r
312 // Select the device.
\r
313 bSuccess = SetupDiSetSelectedDevice( hDevList, &devInfo );
\r
316 gle = GetLastError();
\r
317 OutputDebugString( TEXT("[IbInstaller]SetupDiSetSelectedDevice failed.\n") );
\r
318 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
319 SetupDiDestroyDeviceInfoList( hDevList );
\r
323 // Select the driver.
\r
324 bSuccess = SetupDiSetSelectedDriver( hDevList, &devInfo, &drvInfo );
\r
327 gle = GetLastError();
\r
328 OutputDebugString( TEXT("[IbInstaller]SetupDiSetSelectedDriver failed.\n") );
\r
329 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
330 SetupDiDestroyDeviceInfoList( hDevList );
\r
334 // Register the device (since it is non-PnP).
\r
335 bSuccess = SetupDiRegisterDeviceInfo( hDevList, &devInfo, SPRDI_FIND_DUPS,
\r
336 NULL, NULL, NULL );
\r
339 gle = GetLastError();
\r
340 OutputDebugString( TEXT("[IbInstaller]SetupDiRegisterDeviceInfo failed.\n") );
\r
341 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
342 SetupDiDestroyDeviceInfoList( hDevList );
\r
346 // Install the device (copies the files and starts it).
\r
347 bSuccess = SetupDiInstallDevice( hDevList, &devInfo );
\r
350 gle = GetLastError();
\r
351 OutputDebugString( TEXT("[IbInstaller]SetupDiInstallDevice failed.\n") );
\r
352 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
353 SetupDiDestroyDeviceInfoList( hDevList );
\r
357 return ERROR_SUCCESS;
\r
364 IN UINT Notification,
\r
365 IN UINT_PTR Param1,
\r
366 IN UINT_PTR Param2 )
\r
369 FILEPATHS *pFileInfo;
\r
371 OutputDebugString( L"IbFileCallback" );
\r
373 UNREFERENCED_PARAMETER( Param2 );
\r
375 if( Notification != SPFILENOTIFY_QUEUESCAN_EX )
\r
378 pPath = (TCHAR*)Context;
\r
379 pFileInfo = (FILEPATHS*)Param1;
\r
381 // Copy the source path of the file to the path.
\r
382 if( pFileInfo->Source )
\r
383 _tcsncpy( pPath, pFileInfo->Source, MAX_PATH );
\r
394 IN DI_FUNCTION InstallFunction,
\r
395 IN HDEVINFO DeviceInfoSet,
\r
396 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
\r
397 IN OUT PCOINSTALLER_CONTEXT_DATA Context )
\r
399 SP_DEVINSTALL_PARAMS InstallParams;
\r
402 TCHAR path[MAX_PATH];
\r
405 UNREFERENCED_PARAMETER( Context );
\r
407 swprintf( debug_buf ,L"IbCoInstaller called DI_FUNCTION =%d\n", InstallFunction);
\r
408 OutputDebugString( debug_buf );
\r
410 // The file queue is valid on the DIF_INSTALLDEVICE, so trap that
\r
411 // code and extract the install path.
\r
412 if( InstallFunction != DIF_INSTALLDEVICE )
\r
415 // First find out if we need to install the transport.
\r
416 result = NeedInstall();
\r
417 if( result != ERROR_SUCCESS )
\r
419 if( result == ERROR_ALREADY_EXISTS )
\r
425 // Extract the file path from the file queue.
\r
426 // First get the file queue (it's in the install parameters).
\r
427 memset( &InstallParams, 0, sizeof(InstallParams) );
\r
428 InstallParams.cbSize = sizeof(InstallParams);
\r
430 // Get the installation parameters.
\r
431 b = SetupDiGetDeviceInstallParams( DeviceInfoSet, DeviceInfoData,
\r
434 return GetLastError();
\r
436 // If there isn't a file queue, abort the installation.
\r
437 if( !InstallParams.FileQueue )
\r
438 return ERROR_DI_DONT_INSTALL;
\r
440 // Scan the file queue. The callback will copy the file name to our path.
\r
441 SetupScanFileQueue( InstallParams.FileQueue, SPQ_SCAN_USE_CALLBACKEX, NULL,
\r
442 IbFileCallback, &path, &result );
\r
446 // Strip the file name from the path.
\r
447 nEnd = _tcslen( path );
\r
448 while( path[nEnd] != '\\' )
\r
451 NOTE: no need to strip the platform directoty it was removed for WHQL
\r
454 // Strip the platform subdir name from the path.
\r
455 while( path[nEnd] != '\\' )
\r
458 path[nEnd] = _T('\0');
\r
460 swprintf( debug_buf ,L"[IbInstaller] path %s\n",path);
\r
461 OutputDebugString( debug_buf );
\r
464 // Create the bus root.
\r
465 result = CreateIbBusRoot( path );
\r
466 if( result != ERROR_SUCCESS )
\r