Source code of Windows XP (NT5)
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.

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