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
39 // IB Fabric device HW ID
\r
40 #define GUID_IB_BUS_HW_ID TEXT("{94f41ced-78eb-407c-b5df-958040af0fd8}")
\r
42 #define DEVICE_DESC TEXT("InfiniBand Fabric")
\r
44 // System Class GUID (from wdmguid.h)
\r
45 //{4D36E97D-E325-11CE-BFC1-08002BE10318}
\r
46 static const GUID GUID_CLASS_SYSTEM =
\r
47 { 0x4D36E97D, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
\r
50 BOOL APIENTRY DllMain(
\r
52 DWORD ul_reason_for_call,
\r
55 UNREFERENCED_PARAMETER( hModule );
\r
56 UNREFERENCED_PARAMETER( ul_reason_for_call );
\r
57 UNREFERENCED_PARAMETER( lpReserved );
\r
63 // Checks the installed devices, looking for an instance of the bus root.
\r
69 SP_DEVINFO_DATA devInfo;
\r
73 memset( &devInfo, 0, sizeof(SP_DEVINFO_DATA) );
\r
74 devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
\r
77 TEXT("Checking for existance of IB Fabric Root device.\n") );
\r
79 // Get all devices of the system class.
\r
80 hDevList = SetupDiGetClassDevs( &GUID_CLASS_SYSTEM, 0, NULL, 0 );
\r
81 if( hDevList == INVALID_HANDLE_VALUE )
\r
84 TEXT("Failed to get system class dev info list.\n") );
\r
85 return GetLastError();
\r
88 // Enumerate until we find our device. If the device exists, we
\r
93 // Get the next device.
\r
94 bSuccess = SetupDiEnumDeviceInfo( hDevList, i++, &devInfo );
\r
97 OutputDebugString( TEXT("SetupDiEnumDeviceInfo failed.\n") );
\r
101 // Get the device's description.
\r
102 bSuccess = SetupDiGetDeviceRegistryProperty( hDevList, &devInfo,
\r
103 SPDRP_HARDWAREID, NULL, (BYTE*)buf, sizeof(buf), NULL );
\r
106 // Device has no HW ID.
\r
108 TEXT("SetupDiGetDeviceRegistryProperty failed.\n") );
\r
109 // Skip to the next.
\r
114 // Compare to our device description.
\r
115 if( _tcscmp( buf, GUID_IB_BUS_HW_ID ) )
\r
118 // The device is already installed.
\r
119 SetupDiDestroyDeviceInfoList( hDevList );
\r
120 OutputDebugString( TEXT("IB Fabric Root device already exists.\n") );
\r
121 return ERROR_ALREADY_EXISTS;
\r
123 } while( bSuccess );
\r
125 return ERROR_SUCCESS;
\r
129 DWORD SelectDriver(
\r
130 IN HDEVINFO hDevList,
\r
131 IN SP_DEVINFO_DATA *pDevInfo,
\r
132 OUT SP_DRVINFO_DATA *pDrvInfo )
\r
137 // Get a list of drivers.
\r
139 SetupDiBuildDriverInfoList( hDevList, pDevInfo, SPDIT_CLASSDRIVER );
\r
142 OutputDebugString( TEXT("SetupDiBuildDriverInfoList failed.\n") );
\r
143 return GetLastError();
\r
146 // Set the size of the structure properly.
\r
147 pDrvInfo->cbSize = sizeof(SP_DRVINFO_DATA);
\r
149 // Enumerate all drivers, looking for the correct description.
\r
153 bSuccess = SetupDiEnumDriverInfo( hDevList, pDevInfo,
\r
154 SPDIT_CLASSDRIVER, i++, pDrvInfo );
\r
157 OutputDebugString( TEXT("SetupDiEnumDriverInfo failed.\n") );
\r
161 if( _tcscmp( pDrvInfo->Description, DEVICE_DESC ) )
\r
165 OutputDebugString( TEXT("Found our driver!\n") );
\r
166 return ERROR_SUCCESS;
\r
168 } while( bSuccess );
\r
170 return ERROR_NOT_FOUND;
\r
176 IN PCTSTR driverPath )
\r
180 SP_DEVINFO_DATA devInfo;
\r
181 SP_DRVINFO_DATA drvInfo;
\r
183 SP_DEVINSTALL_PARAMS installParams;
\r
185 memset( &devInfo, 0, sizeof(SP_DEVINFO_DATA) );
\r
186 devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
\r
188 OutputDebugString( TEXT("Creating IB Fabric Root device.\n") );
\r
190 // Create a list for devices of the system class.
\r
191 hDevList = SetupDiCreateDeviceInfoList( &GUID_CLASS_SYSTEM, NULL );
\r
192 if( hDevList == INVALID_HANDLE_VALUE )
\r
194 OutputDebugString( TEXT("Failed to create dev info list.\n") );
\r
195 return GetLastError();
\r
198 // Create the device.
\r
199 bSuccess = SetupDiCreateDeviceInfo( hDevList, TEXT("SYSTEM"),
\r
200 &GUID_CLASS_SYSTEM, DEVICE_DESC,
\r
201 NULL, DICD_GENERATE_ID, &devInfo );
\r
204 OutputDebugString( TEXT("SetupDiCreateDeviceInfo failed.\n") );
\r
205 SetupDiDestroyDeviceInfoList( hDevList );
\r
206 return GetLastError();
\r
209 // Setup the HW ID for the device.
\r
210 bSuccess = SetupDiSetDeviceRegistryProperty( hDevList, &devInfo,
\r
211 SPDRP_HARDWAREID, (BYTE*)GUID_IB_BUS_HW_ID, sizeof(GUID_IB_BUS_HW_ID) );
\r
215 TEXT("SetupDiSetDeviceRegistryProperty failed.\n") );
\r
216 SetupDiDestroyDeviceInfoList( hDevList );
\r
217 return GetLastError();
\r
220 // Setup the install path.
\r
221 ZeroMemory( &installParams, sizeof(installParams) );
\r
222 installParams.cbSize = sizeof(installParams);
\r
223 _tcsncpy( installParams.DriverPath, driverPath, MAX_PATH );
\r
226 SetupDiSetDeviceInstallParams( hDevList, &devInfo, &installParams );
\r
229 OutputDebugString( TEXT("SetupDiSetDeviceInstallParams failed.\n") );
\r
230 SetupDiDestroyDeviceInfoList( hDevList );
\r
231 return GetLastError();
\r
234 status = SelectDriver( hDevList, &devInfo, &drvInfo );
\r
235 if( status != ERROR_SUCCESS )
\r
237 OutputDebugString( TEXT("Could not find driver.\n") );
\r
238 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
239 SetupDiDestroyDeviceInfoList( hDevList );
\r
243 // Select the device.
\r
244 bSuccess = SetupDiSetSelectedDevice( hDevList, &devInfo );
\r
247 OutputDebugString( TEXT("SetupDiSetSelectedDevice failed.\n") );
\r
248 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
249 SetupDiDestroyDeviceInfoList( hDevList );
\r
250 return GetLastError();
\r
253 // Select the driver.
\r
254 bSuccess = SetupDiSetSelectedDriver( hDevList, &devInfo, &drvInfo );
\r
257 OutputDebugString( TEXT("SetupDiSetSelectedDriver failed.\n") );
\r
258 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
259 SetupDiDestroyDeviceInfoList( hDevList );
\r
260 return GetLastError();
\r
263 // Register the device (since it is non-PnP).
\r
264 bSuccess = SetupDiRegisterDeviceInfo( hDevList, &devInfo, SPRDI_FIND_DUPS,
\r
265 NULL, NULL, NULL );
\r
268 OutputDebugString( TEXT("SetupDiRegisterDeviceInfo failed.\n") );
\r
269 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
270 SetupDiDestroyDeviceInfoList( hDevList );
\r
271 return GetLastError();
\r
274 // Install the device (copies the files and starts it).
\r
275 bSuccess = SetupDiInstallDevice( hDevList, &devInfo );
\r
278 OutputDebugString( TEXT("SetupDiInstallDevice failed.\n") );
\r
279 SetupDiDestroyDriverInfoList( hDevList, &devInfo, SPDIT_CLASSDRIVER );
\r
280 SetupDiDestroyDeviceInfoList( hDevList );
\r
281 return GetLastError();
\r
284 return ERROR_SUCCESS;
\r
291 IN UINT Notification,
\r
292 IN UINT_PTR Param1,
\r
293 IN UINT_PTR Param2 )
\r
296 FILEPATHS *pFileInfo;
\r
298 UNREFERENCED_PARAMETER( Param2 );
\r
300 if( Notification != SPFILENOTIFY_QUEUESCAN_EX )
\r
303 pPath = (TCHAR*)Context;
\r
304 pFileInfo = (FILEPATHS*)Param1;
\r
306 // Copy the source path of the file to the path.
\r
307 if( pFileInfo->Source )
\r
308 _tcsncpy( pPath, pFileInfo->Source, MAX_PATH );
\r
319 IN DI_FUNCTION InstallFunction,
\r
320 IN HDEVINFO DeviceInfoSet,
\r
321 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
\r
322 IN OUT PCOINSTALLER_CONTEXT_DATA Context )
\r
324 SP_DEVINSTALL_PARAMS InstallParams;
\r
327 TCHAR path[MAX_PATH];
\r
330 UNREFERENCED_PARAMETER( Context );
\r
332 // The file queue is valid on the DIF_INSTALLDEVICE, so trap that
\r
333 // code and extract the install path.
\r
334 if( InstallFunction != DIF_INSTALLDEVICE )
\r
337 // First find out if we need to install the transport.
\r
338 result = NeedInstall();
\r
339 if( result != ERROR_SUCCESS )
\r
341 if( result == ERROR_ALREADY_EXISTS )
\r
347 // Extract the file path from the file queue.
\r
348 // First get the file queue (it's in the install parameters).
\r
349 memset( &InstallParams, 0, sizeof(InstallParams) );
\r
350 InstallParams.cbSize = sizeof(InstallParams);
\r
352 // Get the installation parameters.
\r
353 b = SetupDiGetDeviceInstallParams( DeviceInfoSet, DeviceInfoData,
\r
356 return GetLastError();
\r
358 // If there isn't a file queue, abort the installation.
\r
359 if( !InstallParams.FileQueue )
\r
360 return ERROR_DI_DONT_INSTALL;
\r
362 // Scan the file queue. The callback will copy the file name to our path.
\r
363 SetupScanFileQueue( InstallParams.FileQueue, SPQ_SCAN_USE_CALLBACKEX, NULL,
\r
364 IbFileCallback, &path, &result );
\r
368 // Strip the file name from the path.
\r
369 nEnd = _tcslen( path );
\r
370 while( path[nEnd] != '\\' )
\r
374 // Strip the platform subdir name from the path.
\r
375 while( path[nEnd] != '\\' )
\r
378 path[nEnd] = _T('\0');
\r
380 // Create the bus root.
\r
381 result = CreateIbBusRoot( path );
\r
382 if( result != ERROR_SUCCESS )
\r