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.

766 lines
26 KiB

  1. //
  2. // DEVNODE.C
  3. //
  4. #include "sigverif.h"
  5. //
  6. // Given the full path to a driver, add it to the file list.
  7. //
  8. void AddDriverFileToList(LPTSTR lpDirName, LPTSTR lpFullPathName)
  9. {
  10. LPFILENODE lpFileNode = NULL;
  11. TCHAR szFullPath[MAX_PATH];
  12. TCHAR szDirName[MAX_PATH];
  13. TCHAR szFileName[MAX_PATH];
  14. LPTSTR lpFilePart;
  15. BOOL bRet;
  16. *szFullPath = 0;
  17. *szDirName = 0;
  18. *szFileName = 0;
  19. // If no directory is passed in, try to get the full path
  20. if (!lpDirName || !*lpDirName) {
  21. bRet = GetFullPathName(lpFullPathName, MAX_PATH, szDirName, &lpFilePart);
  22. if (bRet) {
  23. lstrcpy(szFullPath, szDirName);
  24. if (lpFilePart && *lpFilePart) {
  25. lstrcpy(szFileName, lpFilePart);
  26. *lpFilePart = 0;
  27. if (lstrlen(szDirName) > 3)
  28. *(lpFilePart - 1) = 0;
  29. }
  30. }
  31. } else { // Use the directory and filename that was passed in to us
  32. // Expand out lpDirName in case there are any ".." entries
  33. if (!GetFullPathName(lpDirName, MAX_PATH, szDirName, NULL))
  34. lstrcpy(szDirName, lpDirName);
  35. lstrcpy(szFileName, lpFullPathName);
  36. }
  37. if (*szDirName && *szFileName && !IsFileAlreadyInList(szDirName, szFileName)) {
  38. // Create a filenode, based on the directory and filename
  39. lpFileNode = CreateFileNode(szDirName, szFileName);
  40. if (lpFileNode) {
  41. InsertFileNodeIntoList(lpFileNode);
  42. // Increment the total number of files we've found that meet the search criteria.
  43. g_App.dwFiles++;
  44. }
  45. }
  46. }
  47. //
  48. // Some Services have "\\SystemRoot" in their ImagePath entry, so I have to
  49. // handle that as if it were the MyGetWindowsDirectory string instead.
  50. //
  51. BOOL CheckPathForSystemRoot(LPTSTR lpPathName)
  52. {
  53. TCHAR szSystemRoot[MAX_PATH];
  54. TCHAR szTempBuffer[MAX_PATH];
  55. //
  56. // Check for "\\SystemRoot" and convert to MyGetWindowsDirectory path
  57. //
  58. szSystemRoot[0] = 0;
  59. MyLoadString(szSystemRoot, IDS_SYSTEMROOT);
  60. if (!_tcsnicmp(lpPathName, szSystemRoot, lstrlen(szSystemRoot))) {
  61. MyGetWindowsDirectory(szTempBuffer, MAX_PATH);
  62. lstrcat(szTempBuffer, lpPathName + lstrlen(szSystemRoot));
  63. lstrcpy(lpPathName, szTempBuffer);
  64. return TRUE;
  65. }
  66. return FALSE;
  67. }
  68. void GetFilesFromInfSection(HINF hInf, LPTSTR lpFileName, LPTSTR lpSectionName)
  69. {
  70. TCHAR szTarget[MAX_PATH];
  71. TCHAR szBuffer[MAX_PATH];
  72. LPTSTR lpBuffer;
  73. LPTSTR lpString, lpSeparator;
  74. BOOL bRet;
  75. DWORD dwRequiredSize;
  76. INFCONTEXT iContext;
  77. ZeroMemory(szTarget, sizeof(szTarget));
  78. SetupGetTargetPath(hInf, NULL, lpSectionName, szTarget, sizeof(szTarget), NULL);
  79. // HYDRA HACK!!!
  80. //
  81. // Check to see if the target is %WINDIR% and if %WINDIR% has been redirected, change it back!!
  82. // We have the real %WINDIR% stored in g_App.szWinDir, so we can stuff that into szTarget.
  83. // We just have to remember to put back whatever was at the end of szTarget.
  84. //
  85. GetWindowsDirectory(szBuffer, MAX_PATH);
  86. if (!_tcsnicmp(szBuffer, szTarget, lstrlen(szBuffer)) && _tcsicmp(g_App.szWinDir, szBuffer)) {
  87. lstrcpy(szBuffer, szTarget + lstrlen(szBuffer));
  88. lstrcpy(szTarget, g_App.szWinDir);
  89. lstrcat(szTarget, szBuffer);
  90. }
  91. ZeroMemory(&iContext, sizeof(INFCONTEXT));
  92. bRet = SetupFindFirstLine(hInf, lpSectionName, NULL, &iContext);
  93. while (bRet && !g_App.bStopScan) {
  94. dwRequiredSize = 0;
  95. bRet = SetupGetLineText(&iContext, NULL, NULL, NULL, NULL, 0, &dwRequiredSize);
  96. if (dwRequiredSize) {
  97. lpBuffer = MALLOC((dwRequiredSize + 1) * sizeof(TCHAR));
  98. if (lpBuffer) {
  99. bRet = SetupGetLineText(&iContext, NULL, NULL, NULL, lpBuffer, dwRequiredSize, NULL);
  100. if (bRet) {
  101. lpString = lpBuffer;
  102. if (lpString && *lpString) {
  103. // If there's a comma, then terminate the string at the comma
  104. lpSeparator = _tcschr(lpString, TEXT(','));
  105. if (lpSeparator) {
  106. // Null terminate at the comma, so the first entry is a null-terminated string
  107. *lpSeparator = 0;
  108. }
  109. // Make sure we didn't just terminate ourselves.
  110. if (*lpString) {
  111. AddDriverFileToList(szTarget, lpString);
  112. }
  113. }
  114. }
  115. FREE(lpBuffer);
  116. }
  117. }
  118. bRet = SetupFindNextLine(&iContext, &iContext);
  119. }
  120. }
  121. void GetStuffFromInfSection(LPTSTR lpFileName, LPTSTR lpSectionName)
  122. {
  123. TCHAR szFullPath[MAX_PATH];
  124. TCHAR szTarget[MAX_PATH];
  125. TCHAR szKeyName[MAX_PATH];
  126. LPTSTR lpString = NULL;
  127. LPTSTR lpSeparator = NULL;
  128. LPTSTR lpBuffer = NULL;
  129. DWORD dwRequiredSize;
  130. HINF hInf;
  131. BOOL bRet;
  132. UINT uError;
  133. szFullPath[0] = 0;
  134. GetFullPathName(lpFileName, MAX_PATH, szFullPath, NULL);
  135. //
  136. // Try opening the INF in the usual INF directory
  137. //
  138. hInf = SetupOpenInfFile(szFullPath, NULL, INF_STYLE_WIN4, &uError);
  139. if (hInf == INVALID_HANDLE_VALUE) {
  140. //
  141. // We didn't find it in the INF directory, so try the INF\OTHER directory.
  142. //
  143. MyLoadString(szKeyName, IDS_OTHER);
  144. lstrcat(szKeyName, lpFileName);
  145. GetFullPathName(szKeyName, MAX_PATH, szFullPath, NULL);
  146. hInf = SetupOpenInfFile(szFullPath, NULL, INF_STYLE_WIN4, &uError);
  147. if (hInf == INVALID_HANDLE_VALUE) {
  148. // Add the INF to the file list so it shows up as unscanned.
  149. AddDriverFileToList(NULL, lpFileName);
  150. return;
  151. }
  152. // The INF must exist, so add it to the file list for verification!
  153. AddDriverFileToList(NULL, szFullPath);
  154. } else {
  155. // The INF must exist, so add it to the file list for verification!
  156. AddDriverFileToList(NULL, szFullPath);
  157. }
  158. MyLoadString(szKeyName, IDS_COPYFILES);
  159. dwRequiredSize = 0;
  160. bRet = SetupGetLineText(NULL, hInf, lpSectionName, szKeyName, NULL, 0, &dwRequiredSize);
  161. if (dwRequiredSize) {
  162. lpBuffer = MALLOC((dwRequiredSize + 1) * sizeof(TCHAR));
  163. if (lpBuffer) {
  164. bRet = SetupGetLineText(NULL, hInf, lpSectionName, szKeyName, lpBuffer, dwRequiredSize, NULL);
  165. if (!bRet) {
  166. //MyMessageBox(TEXT("SetupGetLineText Failed!"));
  167. FREE(lpBuffer);
  168. return;
  169. }
  170. }
  171. lpString = lpBuffer;
  172. }
  173. ZeroMemory(szTarget, sizeof(szTarget));
  174. SetupGetTargetPath(hInf, NULL, lpSectionName, szTarget, sizeof(szTarget), NULL);
  175. while (lpString && *lpString && !g_App.bStopScan) {
  176. // If there's a comma, then bump lpSeparator to after the comma
  177. lpSeparator = _tcschr(lpString, TEXT(','));
  178. if (lpSeparator) {
  179. // Null terminate at the comma, so the first entry is a null-terminated string
  180. *lpSeparator = 0;
  181. lpSeparator++;
  182. }
  183. //
  184. // If the section has an '@' symbol, then it is directly referencing a filename
  185. // Otherwise, it's a section and we need to process that via GetFilesFromInfSection()
  186. //
  187. if (*lpString == TEXT('@')) {
  188. lpString++;
  189. if (*lpString) {
  190. AddDriverFileToList(szTarget, lpString);
  191. }
  192. } else GetFilesFromInfSection(hInf, lpFileName, lpString);
  193. lpString = lpSeparator;
  194. }
  195. if (lpBuffer) {
  196. FREE(lpBuffer);
  197. }
  198. SetupCloseInfFile(hInf);
  199. }
  200. void FillDeviceStatus(PDEVICETREE DeviceTree, PDEVTREENODE DeviceTreeNode)
  201. {
  202. DEVINST DeviceInstance = DeviceTreeNode->DevInst;
  203. TCHAR LineBuffer[MAX_PATH*2];
  204. TCHAR szBuffer[MAX_PATH];
  205. TCHAR szBuffer2[MAX_PATH];
  206. TCHAR szRegBuffer[MAX_PATH];
  207. HKEY hServiceKey;
  208. DWORD dwType, dwSize;
  209. LONG lRet;
  210. CONFIGRET ConfigRet;
  211. ZeroMemory(szBuffer, sizeof(szBuffer));
  212. dwSize = sizeof(szBuffer);
  213. ConfigRet = CM_Get_DevNode_Registry_Property_Ex(DeviceInstance,
  214. CM_DRP_CLASS,
  215. NULL,
  216. (PVOID)szBuffer,
  217. &dwSize,
  218. 0,
  219. NULL);
  220. //
  221. // We don't want to pick up PNP printers, since we get their drivers from
  222. // EnumPrinterDrivers (and NTPRINT.INF has a DestinationID of 66000)
  223. //
  224. if (!lstrcmp(szBuffer, TEXT("Printer")))
  225. return;
  226. ZeroMemory(szBuffer, sizeof(szBuffer));
  227. dwSize = sizeof(DeviceTreeNode->Driver);
  228. ConfigRet = CM_Get_DevNode_Registry_Property_Ex(DeviceInstance,
  229. CM_DRP_DRIVER,
  230. NULL,
  231. (PVOID)DeviceTreeNode->Driver,
  232. &dwSize,
  233. 0,
  234. NULL);
  235. if (ConfigRet != CR_SUCCESS) {
  236. MyLoadString(szBuffer, IDS_QUESTIONMARK);
  237. }
  238. //wsprintf(LineBuffer, TEXT("Driver: %s"), DeviceTreeNode->Driver);
  239. //MyMessageBox(LineBuffer);
  240. if (DeviceTreeNode->Driver && *DeviceTreeNode->Driver) {
  241. MyLoadString(szRegBuffer, IDS_REG_CLASS);
  242. lstrcat(szRegBuffer, DeviceTreeNode->Driver);
  243. lRet = RegOpenKey(HKEY_LOCAL_MACHINE, szRegBuffer, &hServiceKey);
  244. if (lRet != ERROR_SUCCESS) {
  245. // If the NT5 registry path doesn't work, try the Win9x path.
  246. MyLoadString(szRegBuffer, IDS_REG_CLASS2);
  247. lstrcat(szRegBuffer, DeviceTreeNode->Driver);
  248. lRet = RegOpenKey(HKEY_LOCAL_MACHINE, szRegBuffer, &hServiceKey);
  249. }
  250. if (lRet == ERROR_SUCCESS) {
  251. //
  252. // Get the INF file and section to determine what files get copied for this driver
  253. //
  254. dwSize = sizeof(szBuffer);
  255. MyLoadString(szRegBuffer, IDS_REG_INFPATH);
  256. lRet = RegQueryValueEx(hServiceKey, szRegBuffer, NULL, &dwType, (PVOID)szBuffer, &dwSize);
  257. if (lRet == ERROR_SUCCESS) {
  258. lstrcpy(LineBuffer, szBuffer);
  259. dwSize = sizeof(szBuffer);
  260. MyLoadString(szRegBuffer, IDS_REG_INFSECTION);
  261. lRet = RegQueryValueEx(hServiceKey, szRegBuffer, NULL, &dwType, (PVOID)szBuffer, &dwSize);
  262. if (lRet == ERROR_SUCCESS) {
  263. //
  264. // Now look for an "InfSectionExt" value, which we need to stick on the end of InfSection.
  265. //
  266. dwSize = sizeof(szBuffer2);
  267. MyLoadString(szRegBuffer, IDS_REG_INFSECTIONEXT);
  268. lRet = RegQueryValueEx(hServiceKey, szRegBuffer, NULL, &dwType, (PVOID)szBuffer2, &dwSize);
  269. if (lRet == ERROR_SUCCESS) {
  270. lstrcat(szBuffer, szBuffer2);
  271. }
  272. GetStuffFromInfSection(LineBuffer, szBuffer);
  273. }
  274. }
  275. // Make sure the reg key gets closed!!
  276. RegCloseKey(hServiceKey);
  277. }
  278. }
  279. dwSize = sizeof(szBuffer);
  280. ConfigRet = CM_Get_DevNode_Registry_Property_Ex(DeviceInstance,
  281. CM_DRP_SERVICE,
  282. NULL,
  283. (PVOID)szBuffer,
  284. &dwSize,
  285. 0,
  286. NULL);
  287. if (ConfigRet != CR_SUCCESS) {
  288. MyLoadString(szBuffer, IDS_QUESTIONMARK);
  289. }
  290. //wsprintf(LineBuffer, TEXT("Service:\t\t%s"), szBuffer);
  291. //MyMessageBox(LineBuffer);
  292. if (*szBuffer) {
  293. MyLoadString(szRegBuffer, IDS_REG_SERVICES);
  294. lstrcat(szRegBuffer, szBuffer);
  295. lRet = RegOpenKey(HKEY_LOCAL_MACHINE, szRegBuffer, &hServiceKey);
  296. if (lRet == ERROR_SUCCESS) {
  297. dwSize = sizeof(szBuffer);
  298. MyLoadString(szRegBuffer, IDS_REG_IMAGEPATH);
  299. lRet = RegQueryValueEx(hServiceKey, szRegBuffer, NULL, &dwType, (PVOID)szBuffer, &dwSize);
  300. if (lRet == ERROR_SUCCESS) {
  301. if (!CheckPathForSystemRoot(szBuffer)) {
  302. MyGetWindowsDirectory(LineBuffer, MAX_PATH);
  303. if (*szBuffer != TEXT('\\'))
  304. lstrcat(LineBuffer, TEXT("\\"));
  305. lstrcat(LineBuffer, szBuffer);
  306. } else lstrcpy(LineBuffer, szBuffer);
  307. // Add this file to the master lpFileList!!
  308. AddDriverFileToList(NULL, LineBuffer);
  309. }
  310. // Make sure the reg key is closed!!
  311. RegCloseKey(hServiceKey);
  312. }
  313. }
  314. }
  315. BOOL AddChildDevices(PDEVICETREE DeviceTree, PDEVTREENODE ParentNode)
  316. {
  317. CONFIGRET ConfigRet;
  318. DEVINST DeviceInstance;
  319. PDEVTREENODE pDeviceTreeNode;
  320. DEVTREENODE DeviceTreeNode;
  321. DWORD dwSize;
  322. TCHAR szBuffer[MAX_PATH];
  323. ConfigRet = CM_Get_Child_Ex(&DeviceInstance,
  324. ParentNode->DevInst,
  325. 0,
  326. NULL
  327. );
  328. while (ConfigRet == CR_SUCCESS) {
  329. pDeviceTreeNode = NULL;
  330. ZeroMemory(&DeviceTreeNode, sizeof(DEVTREENODE));
  331. DeviceTreeNode.DevInst = DeviceInstance;
  332. //
  333. // Fetch the class, if it doesn't exist, skip it.
  334. //
  335. dwSize = sizeof(szBuffer);
  336. ConfigRet = CM_Get_DevNode_Registry_Property_Ex(DeviceInstance,
  337. CM_DRP_CLASSGUID,
  338. NULL,
  339. &szBuffer,
  340. &dwSize,
  341. 0,
  342. NULL);
  343. pDeviceTreeNode = MALLOC(sizeof(DEVTREENODE));
  344. if (pDeviceTreeNode) {
  345. *pDeviceTreeNode = DeviceTreeNode;
  346. pDeviceTreeNode->Sibling = ParentNode->Child;
  347. ParentNode->Child = pDeviceTreeNode;
  348. dwSize = sizeof(szBuffer);
  349. ConfigRet = CM_Get_DevNode_Registry_Property_Ex(DeviceInstance,
  350. CM_DRP_DEVICEDESC,
  351. NULL,
  352. (PVOID)szBuffer,
  353. &dwSize,
  354. 0,
  355. NULL);
  356. if (ConfigRet != CR_SUCCESS) {
  357. MyLoadString(szBuffer, IDS_UNKNOWN);
  358. }
  359. }
  360. //
  361. // Do Child DevNodes
  362. //
  363. if (pDeviceTreeNode) {
  364. FillDeviceStatus(DeviceTree, pDeviceTreeNode);
  365. AddChildDevices(DeviceTree, pDeviceTreeNode);
  366. }
  367. //
  368. // We're done this branch, now get the next sibling ...
  369. //
  370. ConfigRet = CM_Get_Sibling_Ex(&DeviceInstance,
  371. DeviceInstance,
  372. 0,
  373. NULL);
  374. }
  375. return TRUE;
  376. }
  377. void DestroyDeviceTree(PDEVTREENODE pDevTreeNode, PDEVTREENODE pRootNode)
  378. {
  379. PDEVTREENODE pTreeNode;
  380. while (pDevTreeNode) {
  381. if (pDevTreeNode->Child)
  382. DestroyDeviceTree(pDevTreeNode->Child, pRootNode);
  383. pTreeNode = pDevTreeNode->Sibling;
  384. if (pDevTreeNode != pRootNode)
  385. FREE(pDevTreeNode);
  386. pDevTreeNode = pTreeNode;
  387. }
  388. }
  389. void BuildDriverFileList(void)
  390. {
  391. CONFIGRET ConfigRet;
  392. DEVICETREE DeviceTree;
  393. TCHAR szBuffer[MAX_PATH];
  394. //
  395. // Get the root devnode.
  396. //
  397. ZeroMemory(&DeviceTree, sizeof(DEVICETREE));
  398. ConfigRet = CM_Locate_DevNode_Ex(&DeviceTree.RootNode.DevInst,
  399. NULL,
  400. CM_LOCATE_DEVNODE_NORMAL,
  401. NULL
  402. );
  403. if (ConfigRet != CR_SUCCESS) {
  404. //MyErrorBoxId(IDS_ROOTDEVNODE);
  405. return;
  406. }
  407. //
  408. // Make sure we are in the %WINDIR%\INF directory so the driver INFs get populated properly
  409. // First we switch into the %WINDIR% directory
  410. //
  411. if (MyGetWindowsDirectory(szBuffer, MAX_PATH)) {
  412. if (SetCurrentDirectory(szBuffer)) {
  413. // Now go into the INF directory
  414. MyLoadString(szBuffer, IDS_INFPATH);
  415. SetCurrentDirectory(szBuffer);
  416. }
  417. }
  418. AddChildDevices(&DeviceTree, &DeviceTree.RootNode);
  419. DestroyDeviceTree(&DeviceTree.RootNode, &DeviceTree.RootNode);
  420. }
  421. void BuildPrinterFileList(void)
  422. {
  423. BOOL bRet;
  424. DWORD dwBytesNeeded = 0;
  425. DWORD dwDrivers = 0;
  426. LPBYTE lpBuffer = NULL, lpTemp = NULL;
  427. LPTSTR lpFileName;
  428. DRIVER_INFO_3 DriverInfo;
  429. PDRIVER_INFO_3 lpDriverInfo;
  430. TCHAR szBuffer[MAX_PATH];
  431. ZeroMemory(&DriverInfo, sizeof(DRIVER_INFO_3));
  432. bRet = EnumPrinterDrivers( NULL,
  433. SIGVERIF_PRINTER_ENV,
  434. 3,
  435. (LPBYTE) &DriverInfo,
  436. sizeof(DRIVER_INFO_3),
  437. &dwBytesNeeded,
  438. &dwDrivers);
  439. if (!bRet && dwBytesNeeded > 0) {
  440. lpBuffer = MALLOC(dwBytesNeeded);
  441. //
  442. // If we can't get any memory then just bail out of this function
  443. //
  444. if (!lpBuffer) {
  445. return;
  446. }
  447. bRet = EnumPrinterDrivers( NULL,
  448. SIGVERIF_PRINTER_ENV,
  449. 3,
  450. (LPBYTE) lpBuffer,
  451. dwBytesNeeded,
  452. &dwBytesNeeded,
  453. &dwDrivers);
  454. }
  455. //wsprintf(szBuffer, TEXT("dwBytesNeeded: %d, dwDrivers: %d"), dwBytesNeeded, dwDrivers);
  456. //MyMessageBox(szBuffer);
  457. if (dwDrivers > 0) {
  458. // By default, go into the System directory, since Win9x doesn't give full paths to drivers.
  459. GetSystemDirectory(szBuffer, MAX_PATH);
  460. SetCurrentDirectory(szBuffer);
  461. for (lpTemp = lpBuffer; dwDrivers > 0; dwDrivers--) {
  462. lpDriverInfo = (PDRIVER_INFO_3) lpTemp;
  463. if (lpDriverInfo->pName) {
  464. if (lpDriverInfo->pDriverPath && *lpDriverInfo->pDriverPath) {
  465. AddDriverFileToList(NULL, lpDriverInfo->pDriverPath);
  466. }
  467. if (lpDriverInfo->pDataFile && *lpDriverInfo->pDataFile) {
  468. AddDriverFileToList(NULL, lpDriverInfo->pDataFile);
  469. }
  470. if (lpDriverInfo->pConfigFile && *lpDriverInfo->pConfigFile) {
  471. AddDriverFileToList(NULL, lpDriverInfo->pConfigFile);
  472. }
  473. if (lpDriverInfo->pHelpFile && *lpDriverInfo->pHelpFile) {
  474. AddDriverFileToList(NULL, lpDriverInfo->pHelpFile);
  475. }
  476. //MyMessageBox(lpDriverInfo->pName);
  477. lpFileName = lpDriverInfo->pDependentFiles;
  478. while (lpFileName && *lpFileName) {
  479. AddDriverFileToList(NULL, lpFileName);
  480. for (;*lpFileName;lpFileName++);
  481. lpFileName++;
  482. }
  483. }
  484. lpTemp += sizeof(DRIVER_INFO_3);
  485. }
  486. }
  487. if (lpBuffer) {
  488. FREE(lpBuffer);
  489. }
  490. }
  491. BOOL GetBVTFileList(LPTSTR lpDirName, LPTSTR lpFileName)
  492. {
  493. TCHAR szBuffer[MAX_PATH];
  494. LPTSTR lpString, lpFilePart;
  495. //
  496. // If the user specified the "/BVT:" switch, we want to grab the string after it
  497. //
  498. MyLoadString(szBuffer, IDS_BVT);
  499. lpString = MyStrStr(GetCommandLine(), szBuffer);
  500. if (lpString && *lpString) {
  501. // Switch back into the original startup directory
  502. SetCurrentDirectory(g_App.szAppDir);
  503. lpString += lstrlen(szBuffer);
  504. if (!EXIST(lpString)) {
  505. //MyMessageBox(lpString);
  506. return FALSE;
  507. }
  508. GetFullPathName(lpString, MAX_PATH, lpDirName, &lpFilePart);
  509. lstrcpy(lpFileName, lpDirName);
  510. *lpFilePart = 0;
  511. SetCurrentDirectory(lpDirName);
  512. return TRUE;
  513. }
  514. return FALSE;
  515. }
  516. BOOL IsNTServer(void)
  517. {
  518. BOOL bRet = FALSE;
  519. HKEY hKey;
  520. LONG lRet;
  521. DWORD dwSize, dwType;
  522. TCHAR szBuffer[MAX_PATH];
  523. TCHAR szRegBuffer[MAX_PATH];
  524. // Open HKLM\System\CurrentControlSet\Control\ProductOptions
  525. MyLoadString(szRegBuffer, IDS_REG_PRODUCTOPTIONS);
  526. lRet = RegOpenKey(HKEY_LOCAL_MACHINE, szRegBuffer, &hKey);
  527. if (lRet == ERROR_SUCCESS) {
  528. // Now we need to query the ProductType value
  529. ZeroMemory(szBuffer, sizeof(szBuffer));
  530. dwSize = sizeof(szBuffer);
  531. MyLoadString(szRegBuffer, IDS_REG_PRODUCTTYPE);
  532. lRet = RegQueryValueEx(hKey, szRegBuffer, NULL, &dwType, (PVOID)szBuffer, &dwSize);
  533. if (lRet == ERROR_SUCCESS) {
  534. // Check to see if ProductType contained "ServerNT"
  535. MyLoadString(szRegBuffer, IDS_PRODUCT_SERVER);
  536. if (!_tcsnicmp(szRegBuffer, szBuffer, lstrlen(szRegBuffer))) {
  537. // If so, then we want to return TRUE!
  538. bRet = TRUE;
  539. }
  540. }
  541. RegCloseKey(hKey);
  542. }
  543. return bRet;
  544. }
  545. BOOL IsProcessorAlpha(void)
  546. {
  547. OSVERSIONINFO osinfo;
  548. SYSTEM_INFO sysinfo;
  549. ZeroMemory(&osinfo, sizeof(OSVERSIONINFO));
  550. osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  551. GetVersionEx(&osinfo);
  552. if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  553. ZeroMemory(&sysinfo, sizeof(SYSTEM_INFO));
  554. GetSystemInfo(&sysinfo);
  555. if (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA) {
  556. return TRUE;
  557. }
  558. }
  559. return FALSE;
  560. }
  561. void BuildCoreFileList(void)
  562. {
  563. LPFILENODE lpFileNode;
  564. TCHAR szInfName[MAX_PATH];
  565. TCHAR szSectionName[MAX_PATH];
  566. TCHAR szBuffer[MAX_PATH];
  567. BOOL bRet = TRUE;
  568. // Check to see if the "/BVT:" switch was specified for a custom file list
  569. // If so, then don't verify that the file is digitally signed.
  570. if (GetBVTFileList(szBuffer, szInfName)) {
  571. GetCurrentDirectory(MAX_PATH, szBuffer);
  572. MyLoadString(szSectionName, IDS_MASTERFILELIST);
  573. GetStuffFromInfSection(szInfName, szSectionName);
  574. if (IsNTServer()) {
  575. SetCurrentDirectory(szBuffer);
  576. MyLoadString(szSectionName, IDS_SERVERFILELIST);
  577. GetStuffFromInfSection(szInfName, szSectionName);
  578. }
  579. if (!IsProcessorAlpha()) {
  580. SetCurrentDirectory(szBuffer);
  581. MyLoadString(szSectionName, IDS_X86FILELIST);
  582. GetStuffFromInfSection(szInfName, szSectionName);
  583. }
  584. } else {
  585. // The user didn't use "/BVT:", so grab the corelist filename from our resources
  586. // Make sure we are in the %WINDIR%\INF directory so lpFileNode gets created properly
  587. // First switch into the %WINDIR% directory
  588. bRet = MyGetWindowsDirectory(szBuffer, MAX_PATH);
  589. if (bRet) {
  590. bRet = SetCurrentDirectory(szBuffer);
  591. if (bRet) {
  592. // Now go into the %WINDIR%\INF directory.
  593. MyLoadString(szBuffer, IDS_INFPATH);
  594. bRet = SetCurrentDirectory(szBuffer);
  595. }
  596. }
  597. // If we actually get into %WINDIR%\INF, then we verify the core list and party on it!
  598. if (bRet) {
  599. // Get the name of the INF containing the core file list
  600. MyLoadString(szInfName, IDS_COREFILELIST);
  601. //
  602. // Verify that the core file list is digitally signed before using it.
  603. //
  604. lpFileNode = CreateFileNode(NULL, szInfName);
  605. if (lpFileNode) {
  606. // If we don't already have an g_App.hCatAdmin handle, acquire one.
  607. if (g_App.hCatAdmin || CryptCATAdminAcquireContext(&g_App.hCatAdmin, NULL, 0)) {
  608. bRet = VerifyFileNode(lpFileNode);
  609. if (bRet) {
  610. GetCurrentDirectory(MAX_PATH, szBuffer);
  611. MyLoadString(szSectionName, IDS_MASTERFILELIST);
  612. GetStuffFromInfSection(szInfName, szSectionName);
  613. if (IsNTServer()) {
  614. SetCurrentDirectory(szBuffer);
  615. MyLoadString(szSectionName, IDS_SERVERFILELIST);
  616. GetStuffFromInfSection(szInfName, szSectionName);
  617. }
  618. if (!IsProcessorAlpha()) {
  619. SetCurrentDirectory(szBuffer);
  620. MyLoadString(szSectionName, IDS_X86FILELIST);
  621. GetStuffFromInfSection(szInfName, szSectionName);
  622. }
  623. }
  624. // If we had an g_App.hCatAdmin, free it and set it to zero so we can acquire a new one in the future.
  625. if (g_App.hCatAdmin) {
  626. CryptCATAdminReleaseContext(g_App.hCatAdmin,0);
  627. g_App.hCatAdmin = (HCATADMIN) NULL;
  628. }
  629. } else bRet = FALSE;
  630. // Free the memory for this file node
  631. DestroyFileNode(lpFileNode);
  632. } else {
  633. bRet = FALSE;
  634. }
  635. }
  636. }
  637. if (!bRet) {
  638. MyErrorBoxId(IDS_COREFILELIST_NOTSIGNED);
  639. }
  640. }