Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

437 lines
17 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net.c
  5. Abstract:
  6. Process NetCards section of WINBOM.INI
  7. Author:
  8. Donald McNamara (donaldm) 5/11/2000
  9. Revision History:
  10. --*/
  11. #include "factoryp.h"
  12. // UpdateDriverForPlugAndPlayDevices constants
  13. #include <newdev.h>
  14. // NetBT registry refresh IOCTL
  15. #include <nbtioctl.h>
  16. // for run-time loading of newdev.dll
  17. typedef BOOL (WINAPI *ExternalUpdateDriverForPlugAndPlayDevicesW)
  18. (
  19. HWND hwndParent,
  20. LPCWSTR HardwareId,
  21. LPCWSTR FullInfPath,
  22. DWORD InstallFlags,
  23. PBOOL bRebootRequired OPTIONAL
  24. );
  25. extern CONFIGRET CMP_WaitServicesAvailable(IN HMACHINE hMachine);
  26. //
  27. // function prototypes
  28. //
  29. BOOL
  30. SetupRegistryForRemoteBoot(
  31. VOID
  32. );
  33. BOOL
  34. InstallNetworkCard(
  35. LPTSTR lpszWinBOMPath,
  36. BOOL bForceIDScan
  37. )
  38. /*++
  39. Routine Description:
  40. This function installs all network card found in the system.
  41. Arguments:
  42. Return Value:
  43. Returns TRUE if there are no fatal errors.
  44. --*/
  45. {
  46. BOOL bRet = FALSE;
  47. HINSTANCE hInstNewDev;
  48. ExternalUpdateDriverForPlugAndPlayDevicesW pUpdateDriverForPlugAndPlayDevicesW = NULL;
  49. // We need the "UpdateDriverForPlugAndPlayDevices" function from newdev.dll.
  50. //
  51. if ( NULL == (hInstNewDev = LoadLibrary(L"newdev.dll")) )
  52. {
  53. FacLogFileStr(3 | LOG_ERR, L"Failed to load newdev.dll. Error = %d", GetLastError());
  54. return bRet;
  55. }
  56. pUpdateDriverForPlugAndPlayDevicesW =
  57. (ExternalUpdateDriverForPlugAndPlayDevicesW) GetProcAddress(hInstNewDev, "UpdateDriverForPlugAndPlayDevicesW");
  58. if ( NULL == pUpdateDriverForPlugAndPlayDevicesW )
  59. {
  60. FacLogFileStr(3 | LOG_ERR, L"Failed to get UpdateDriverForPlugAndPlayDevicesW. Error = %d", GetLastError());
  61. }
  62. else
  63. {
  64. BOOL bRebootFlag = FALSE;
  65. // Need to ensure that pnp services are available.
  66. //
  67. CMP_WaitServicesAvailable(NULL);
  68. //
  69. // If remote boot then do the necessary registry processing
  70. // so that upper level protocol drivers can bind & work
  71. // correctly with already created device objects
  72. //
  73. if ( !IsRemoteBoot() ||
  74. SetupRegistryForRemoteBoot() )
  75. {
  76. if ( !bForceIDScan )
  77. {
  78. LPTSTR lpszHardwareId;
  79. // Now check to see if there are any PNP ids in the [NetCards] section of the winbom.
  80. //
  81. LPTSTR lpszNetCards = IniGetString(lpszWinBOMPath, WBOM_NETCARD_SECTION, NULL, NULLSTR);
  82. // Check to make sure that we have a valid string
  83. //
  84. if ( lpszNetCards )
  85. {
  86. for ( lpszHardwareId = lpszNetCards; *lpszHardwareId; lpszHardwareId += (lstrlen(lpszHardwareId) + 1) )
  87. {
  88. // Get the INF name
  89. //
  90. LPTSTR lpszInfFileName = IniGetExpand(lpszWinBOMPath, WBOM_NETCARD_SECTION, lpszHardwareId, NULLSTR);
  91. // At this point lpHardwareId is the PNP id for a network card that we want to install and
  92. // lpszInfFileName is the name of the Inf to use to install this card.
  93. //
  94. if ( lpszInfFileName && *lpszInfFileName && *lpszHardwareId )
  95. {
  96. if ( pUpdateDriverForPlugAndPlayDevicesW(NULL,
  97. lpszHardwareId,
  98. lpszInfFileName,
  99. INSTALLFLAG_READONLY,
  100. &bRebootFlag) )
  101. {
  102. bRet = TRUE;
  103. }
  104. else
  105. {
  106. FacLogFileStr(3 | LOG_ERR, L"Failed to install network driver listed in the NetCards section. Hardware ID: %s, InfName: %s, Error = %d.", lpszHardwareId, lpszInfFileName, GetLastError());
  107. //
  108. // Not setting bRet to FALSE here since it is FALSE by default, and
  109. // if we succesfully install at least one network card we want to return TRUE.
  110. //
  111. }
  112. }
  113. FREE(lpszInfFileName);
  114. }
  115. }
  116. FREE(lpszNetCards);
  117. }
  118. else // if ( bForceIDScan )
  119. {
  120. HDEVINFO DeviceInfoSet = NULL;
  121. // Get the list of all present devices.
  122. //
  123. DeviceInfoSet = SetupDiGetClassDevs(NULL,
  124. NULL,
  125. NULL,
  126. DIGCF_ALLCLASSES);
  127. if ( INVALID_HANDLE_VALUE == DeviceInfoSet )
  128. {
  129. FacLogFileStr(3 | LOG_ERR, L"Failed SetupDiGetClassDevsEx(). Error = %d", GetLastError());
  130. }
  131. else
  132. {
  133. DWORD dwDevice;
  134. SP_DEVINFO_DATA DeviceInfoData;
  135. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  136. // Loop through all the devices.
  137. //
  138. for ( dwDevice = 0; SetupDiEnumDeviceInfo(DeviceInfoSet, dwDevice, &DeviceInfoData); dwDevice++ )
  139. {
  140. SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
  141. SP_DRVINFO_DATA DriverInfoData = {0};
  142. ULONG ulStatus = 0,
  143. ulProblemNumber = 0;
  144. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  145. DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  146. // If we can get the dev node status and the devnode does have a problem, then
  147. // build a list of possible drivers for this device and select the best one.
  148. // Otherwise just skip this this device.
  149. //
  150. if ( ( CR_SUCCESS == CM_Get_DevNode_Status(&ulStatus, &ulProblemNumber, DeviceInfoData.DevInst, 0) ) &&
  151. ( ( IsRemoteBoot() &&
  152. IsEqualGUID(&DeviceInfoData.ClassGuid, (LPGUID)&GUID_DEVCLASS_NET) ) ||
  153. ( ulStatus & (DN_HAS_PROBLEM | DN_PRIVATE_PROBLEM) ) ) &&
  154. SetupDiBuildDriverInfoList(DeviceInfoSet, &DeviceInfoData, SPDIT_COMPATDRIVER) )
  155. {
  156. if ( ( SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV, DeviceInfoSet, &DeviceInfoData) ) &&
  157. ( SetupDiGetSelectedDriver(DeviceInfoSet, &DeviceInfoData, &DriverInfoData) ) )
  158. {
  159. //
  160. // DriverInfoData contains details about the best driver, we can now see if this is a NET driver
  161. // as at this point the class will have been modified to NET if best driver is a NET driver.
  162. // Compare DeviceInfoData.ClassGuid against NET class GUID. If no match, skip.
  163. // Otherwise get DRVINFO_DETAIL_DATA into a resizable buffer to get HardwareID.
  164. // Use The HardwareID and InfFileName entries in DRVINFO_DETAIL_DATA
  165. // to pass into UpdateDriverForPlugAndPlayDevices.
  166. // DO NOT pass FORCE flag into UpdateDriverForPlugAndPlayDevices.
  167. //
  168. if ( IsEqualGUID(&DeviceInfoData.ClassGuid, (LPGUID)&GUID_DEVCLASS_NET) )
  169. {
  170. DWORD cbBytesNeeded = 0;
  171. PSP_DRVINFO_DETAIL_DATA pDriverInfoDetailData = NULL;
  172. if ( ( ( SetupDiGetDriverInfoDetail(DeviceInfoSet,
  173. &DeviceInfoData,
  174. &DriverInfoData,
  175. NULL,
  176. 0,
  177. &cbBytesNeeded) ) ||
  178. ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) ) &&
  179. ( cbBytesNeeded ) &&
  180. ( pDriverInfoDetailData = MALLOC( cbBytesNeeded) ) &&
  181. ( 0 != (pDriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA)) ) &&
  182. ( SetupDiGetDriverInfoDetail(DeviceInfoSet,
  183. &DeviceInfoData,
  184. &DriverInfoData,
  185. pDriverInfoDetailData,
  186. cbBytesNeeded,
  187. NULL) ) )
  188. {
  189. if ( pUpdateDriverForPlugAndPlayDevicesW(NULL,
  190. pDriverInfoDetailData->HardwareID,
  191. pDriverInfoDetailData->InfFileName,
  192. INSTALLFLAG_READONLY,
  193. &bRebootFlag) )
  194. {
  195. bRet = TRUE;
  196. }
  197. else
  198. {
  199. FacLogFileStr(3 | LOG_ERR, L"Failed to install network driver. Error = %d", GetLastError());
  200. //
  201. // Not setting bRet to FALSE here since it is FALSE by default, and
  202. // if we succesfully install at least one network card we want to return TRUE.
  203. //
  204. }
  205. }
  206. // Free this if allocated. Macro checks for NULL.
  207. //
  208. FREE ( pDriverInfoDetailData );
  209. }
  210. }
  211. SetupDiDestroyDriverInfoList(DeviceInfoSet, &DeviceInfoData, SPDIT_COMPATDRIVER);
  212. }
  213. }
  214. // Make sure we clean up the list.
  215. //
  216. SetupDiDestroyDeviceInfoList(DeviceInfoSet);
  217. }
  218. }
  219. }
  220. }
  221. FreeLibrary(hInstNewDev);
  222. return bRet;
  223. }
  224. BOOL SetupNetwork(LPSTATEDATA lpStateData)
  225. {
  226. LPTSTR lpszWinBOMPath = lpStateData->lpszWinBOMPath;
  227. BOOL bRet = TRUE;
  228. TCHAR szScratch[MAX_PATH] = NULLSTR;
  229. if ( GetPrivateProfileString(WBOM_FACTORY_SECTION, WBOM_FACTORY_FORCEIDSCAN, NULLSTR, szScratch, AS(szScratch), lpszWinBOMPath) )
  230. {
  231. if ( LSTRCMPI(szScratch, _T("NO")) == 0 )
  232. FacLogFile(1, IDS_LOG_NONET);
  233. else
  234. {
  235. // Attempt to install the Net card using the [NetCards] section of the WINBOM
  236. //
  237. if ( !InstallNetworkCard(lpszWinBOMPath, FALSE) )
  238. {
  239. FacLogFile(1, IDS_LOG_FORCEDNETSCAN);
  240. // Attempt a forced scan of all network capable devices
  241. //
  242. if ( !InstallNetworkCard(lpszWinBOMPath, TRUE) )
  243. {
  244. FacLogFile(0 | LOG_ERR, IDS_ERR_FAILEDNETDRIVER);
  245. bRet = FALSE;
  246. }
  247. }
  248. }
  249. }
  250. return bRet;
  251. }
  252. //
  253. // constant strings for remote boot
  254. //
  255. #define NETCFG_INSTANCEID_VALUE_NAME TEXT("NetCfgInstanceId")
  256. #define NETBOOTCARD_ROOT_DEVICE_GUID TEXT("{54C7D140-09EF-11D1-B25A-F5FE627ED95E}")
  257. #define NETBT_TCPIP_DEVICE_PATH TEXT("\\Device\\NetBt_Tcpip_") NETBOOTCARD_ROOT_DEVICE_GUID
  258. #define NET_CLASS_DEVICE_INSTANCE_PATH TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000")
  259. NTSTATUS
  260. ForceNetbtRegistryRead(
  261. VOID
  262. )
  263. /*++
  264. Routine description:
  265. Issue IOCTL to NETBT to re-read its registry setting.
  266. Arguements :
  267. Return Value :
  268. --*/
  269. {
  270. NTSTATUS status;
  271. UNICODE_STRING nameString;
  272. IO_STATUS_BLOCK ioStatusBlock;
  273. OBJECT_ATTRIBUTES objectAttributes;
  274. HANDLE hNetbtDevice = NULL;
  275. //
  276. // Step I:
  277. //
  278. // Open NETBT driver
  279. //
  280. RtlInitUnicodeString( &nameString,
  281. NETBT_TCPIP_DEVICE_PATH );
  282. InitializeObjectAttributes( &objectAttributes,
  283. &nameString,
  284. OBJ_CASE_INSENSITIVE,
  285. NULL,
  286. NULL );
  287. status = NtCreateFile( &hNetbtDevice,
  288. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  289. &objectAttributes,
  290. &ioStatusBlock,
  291. NULL,
  292. FILE_ATTRIBUTE_NORMAL,
  293. FILE_SHARE_READ | FILE_SHARE_WRITE,
  294. FILE_OPEN_IF,
  295. 0,
  296. NULL,
  297. 0 );
  298. if ( NT_SUCCESS(status) )
  299. {
  300. //
  301. // Issue IOCTL to purge the cache...
  302. //
  303. status = NtDeviceIoControlFile( hNetbtDevice,
  304. NULL,
  305. NULL,
  306. NULL,
  307. &ioStatusBlock,
  308. IOCTL_NETBT_REREAD_REGISTRY,
  309. NULL,
  310. 0,
  311. NULL,
  312. 0 );
  313. //
  314. // Close NETBT driver
  315. //
  316. NtClose( hNetbtDevice );
  317. }
  318. return status;
  319. }
  320. BOOL
  321. SetupRegistryForRemoteBoot(
  322. VOID
  323. )
  324. /*++
  325. Routine Description:
  326. Munges the registry and sets up the required entries for
  327. upper layer protocol drivers to see that a valid NIC is
  328. installed.
  329. Arguments:
  330. None.
  331. Return value:
  332. TRUE if successful, otherwise FALSE.
  333. --*/
  334. {
  335. BOOL Result = FALSE;
  336. HKEY InstanceKey;
  337. // Open the remote boot network card instance
  338. //
  339. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  340. NET_CLASS_DEVICE_INSTANCE_PATH,
  341. 0,
  342. KEY_ALL_ACCESS,
  343. &InstanceKey) )
  344. {
  345. // Set the hard-coded instance id
  346. //
  347. if ( ERROR_SUCCESS == RegSetValueEx( InstanceKey,
  348. NETCFG_INSTANCEID_VALUE_NAME,
  349. 0,
  350. REG_SZ,
  351. (LPBYTE)NETBOOTCARD_ROOT_DEVICE_GUID,
  352. (lstrlen(NETBOOTCARD_ROOT_DEVICE_GUID) + 1) * sizeof(TCHAR)) )
  353. {
  354. // Set the return value to TRUE...
  355. //
  356. Result = TRUE;
  357. }
  358. // Close the key...
  359. //
  360. RegCloseKey( InstanceKey );
  361. }
  362. return Result;
  363. }