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.

1126 lines
40 KiB

  1. //
  2. // DEVNODE.C
  3. //
  4. #include "sigverif.h"
  5. #include <initguid.h>
  6. #include <devguid.h>
  7. //
  8. // Given the full path to a driver, add it to the file list.
  9. //
  10. LPFILENODE
  11. AddDriverFileToList(
  12. LPTSTR lpDirName,
  13. LPTSTR lpFullPathName
  14. )
  15. {
  16. DWORD Err = ERROR_SUCCESS;
  17. LPFILENODE lpFileNode = NULL;
  18. TCHAR szDirName[MAX_PATH];
  19. TCHAR szFileName[MAX_PATH];
  20. LPTSTR lpFilePart;
  21. *szDirName = 0;
  22. *szFileName = 0;
  23. //
  24. // If no directory is passed in, try to get the full path
  25. //
  26. if (!lpDirName || !*lpDirName) {
  27. if (GetFullPathName(lpFullPathName, cA(szDirName), szDirName, &lpFilePart)) {
  28. if (lpFilePart && *lpFilePart) {
  29. if (SUCCEEDED(StringCchCopy(szFileName, cA(szFileName), lpFilePart))) {
  30. *lpFilePart = 0;
  31. if (lstrlen(szDirName) > 3) {
  32. *(lpFilePart - 1) = 0;
  33. }
  34. } else {
  35. *szFileName = 0;
  36. }
  37. }
  38. } else {
  39. *szDirName = 0;
  40. }
  41. } else {
  42. //
  43. // Use the directory and filename that was passed in to us
  44. // Expand out lpDirName in case there are any ".." entries
  45. //
  46. if (!GetFullPathName(lpDirName, cA(szDirName), szDirName, NULL)) {
  47. //
  48. // If we can't get the full path, then just use the one
  49. // that was passed in. This could happen if the directory
  50. // is missing for instance.
  51. //
  52. if (FAILED(StringCchCopy(szDirName, cA(szDirName), lpDirName))) {
  53. //
  54. // If we can't fit the directory name into our buffer then
  55. // clear szDirName so this node won't be added to the list.
  56. //
  57. *szDirName = 0;
  58. }
  59. }
  60. if (FAILED(StringCchCopy(szFileName, cA(szFileName), lpFullPathName))) {
  61. //
  62. // If we can't fit the file name into our buffer then
  63. // clear szFileName so this node won't be added to the list.
  64. //
  65. *szFileName = 0;
  66. }
  67. }
  68. if (*szDirName && *szFileName && !IsFileAlreadyInList(szDirName, szFileName)) {
  69. //
  70. // Create a filenode, based on the directory and filename
  71. //
  72. lpFileNode = CreateFileNode(szDirName, szFileName);
  73. if (lpFileNode) {
  74. InsertFileNodeIntoList(lpFileNode);
  75. //
  76. // Increment the total number of files we've found that meet the
  77. // search criteria.
  78. //
  79. g_App.dwFiles++;
  80. } else {
  81. Err = GetLastError();
  82. }
  83. }
  84. SetLastError(Err);
  85. return lpFileNode;
  86. }
  87. BOOL
  88. GetFullPathFromImagePath(
  89. LPCTSTR ImagePath,
  90. LPTSTR FullPath,
  91. UINT FullPathLength
  92. )
  93. {
  94. TCHAR OriginalCurrentDirectory[MAX_PATH];
  95. LPTSTR pRelativeString;
  96. LPTSTR lpFilePart;
  97. if (!ImagePath || (ImagePath[0] == TEXT('\0'))) {
  98. return FALSE;
  99. }
  100. //
  101. // First check if the ImagePath happens to be a valid full path.
  102. //
  103. if (GetFileAttributes(ImagePath) != 0xFFFFFFFF) {
  104. GetFullPathName(ImagePath, FullPathLength, FullPath, &lpFilePart);
  105. return TRUE;
  106. }
  107. pRelativeString = (LPTSTR)ImagePath;
  108. //
  109. // If the ImagePath starts with "\SystemRoot" or "%SystemRoot%" then
  110. // remove those values.
  111. //
  112. if (StrCmpNI(ImagePath, TEXT("\\SystemRoot\\"), lstrlen(TEXT("\\SystemRoot\\"))) == 0) {
  113. pRelativeString += lstrlen(TEXT("\\SystemRoot\\"));
  114. } else if (StrCmpNI(ImagePath, TEXT("%SystemRoot%\\"), lstrlen(TEXT("%SystemRoot%\\"))) == 0) {
  115. pRelativeString += lstrlen(TEXT("%SystemRoot%\\"));
  116. }
  117. //
  118. // At this point pRelativeString should point to the image path relative to
  119. // the windows directory.
  120. //
  121. if (!GetSystemWindowsDirectory(FullPath, FullPathLength)) {
  122. return FALSE;
  123. }
  124. if (!GetCurrentDirectory(cA(OriginalCurrentDirectory), OriginalCurrentDirectory)) {
  125. OriginalCurrentDirectory[0] = TEXT('\0');
  126. }
  127. if (!SetCurrentDirectory(FullPath)) {
  128. return FALSE;
  129. }
  130. GetFullPathName(pRelativeString, FullPathLength, FullPath, &lpFilePart);
  131. if (OriginalCurrentDirectory[0] != TEXT('\0')) {
  132. SetCurrentDirectory(OriginalCurrentDirectory);
  133. }
  134. return TRUE;
  135. }
  136. DWORD
  137. CreateFromService(
  138. SC_HANDLE hscManager,
  139. PCTSTR ServiceName
  140. )
  141. {
  142. DWORD Err = ERROR_SUCCESS;
  143. SC_HANDLE hscService = NULL;
  144. DWORD BytesRequired, Size;
  145. TCHAR FullPath[MAX_PATH];
  146. LPQUERY_SERVICE_CONFIG pqsc;
  147. PBYTE BufferPtr = NULL;
  148. if (hscManager == NULL) {
  149. //
  150. // This should never happen.
  151. //
  152. goto clean0;
  153. }
  154. if (!ServiceName ||
  155. (ServiceName[0] == TEXT('\0'))) {
  156. //
  157. // This should also never happen.
  158. //
  159. goto clean0;
  160. }
  161. hscService = OpenService(hscManager, ServiceName, GENERIC_READ);
  162. if (NULL == hscService) {
  163. //
  164. // This service does not exist. We won't return an error in this case
  165. // since if the service doesn't exist then the driver won't get
  166. // loaded.
  167. //
  168. goto clean0;
  169. }
  170. //
  171. // First, probe for buffer size
  172. //
  173. if (!QueryServiceConfig(hscService, NULL, 0, &BytesRequired) &&
  174. ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
  175. BufferPtr = MALLOC(BytesRequired);
  176. if (!BufferPtr) {
  177. Err = ERROR_NOT_ENOUGH_MEMORY;
  178. goto clean0;
  179. }
  180. pqsc = (LPQUERY_SERVICE_CONFIG)(PBYTE)BufferPtr;
  181. if (QueryServiceConfig(hscService, pqsc, BytesRequired, &Size) &&
  182. pqsc->lpBinaryPathName &&
  183. (TEXT('\0') != pqsc->lpBinaryPathName[0])) {
  184. //
  185. // Make sure we have a valid full path.
  186. //
  187. if (GetFullPathFromImagePath(pqsc->lpBinaryPathName,
  188. FullPath,
  189. cA(FullPath))) {
  190. AddDriverFileToList(NULL, FullPath);
  191. }
  192. }
  193. FREE(BufferPtr);
  194. }
  195. clean0:
  196. if (hscService) {
  197. CloseServiceHandle(hscService);
  198. hscService = NULL;
  199. }
  200. if (BufferPtr) {
  201. FREE(BufferPtr);
  202. }
  203. return Err;
  204. }
  205. UINT
  206. ScanQueueCallback(
  207. PVOID Context,
  208. UINT Notification,
  209. UINT_PTR Param1,
  210. UINT_PTR Param2
  211. )
  212. {
  213. LPFILENODE lpFileNode;
  214. TCHAR szBuffer[MAX_PATH];
  215. LPTSTR lpFilePart;
  216. ULONG BufCbSize;
  217. HRESULT hr;
  218. UNREFERENCED_PARAMETER(Param2);
  219. if ((Notification == SPFILENOTIFY_QUEUESCAN_SIGNERINFO) &&
  220. Param1) {
  221. //
  222. // Special case for printers:
  223. // After setupapi copies files from the file queue into their destination
  224. // location, the printer class installer moves some of these files into
  225. // other 'special' locations. This can lead to the callback Win32Error
  226. // returning ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND since the file
  227. // is not present in the location where setupapi put it. So, we will
  228. // catch this case for printers and not add the file to our list of
  229. // files to scan. These 'special' printer files will get added later
  230. // when we call the spooler APIs.
  231. // Also note that we can't just skip getting the list of files for printers
  232. // altogether since the printer class installer only moves some of the
  233. // files that setupapi copies and not all of them.
  234. //
  235. if (Context &&
  236. (IsEqualGUID((LPGUID)Context, &GUID_DEVCLASS_PRINTER)) &&
  237. ((((PFILEPATHS_SIGNERINFO)Param1)->Win32Error == ERROR_FILE_NOT_FOUND) ||
  238. (((PFILEPATHS_SIGNERINFO)Param1)->Win32Error == ERROR_PATH_NOT_FOUND))) {
  239. //
  240. // Assume this was a file moved by the printer class installer. Don't
  241. // add it to the list of files to be scanned at this time.
  242. //
  243. return NO_ERROR;
  244. }
  245. lpFileNode = AddDriverFileToList(NULL,
  246. (LPTSTR)((PFILEPATHS_SIGNERINFO)Param1)->Target);
  247. //
  248. // Fill in some information into the FILENODE structure since we already
  249. // scanned the file.
  250. //
  251. if (lpFileNode) {
  252. lpFileNode->bScanned = TRUE;
  253. lpFileNode->bSigned = (((PFILEPATHS_SIGNERINFO)Param1)->Win32Error == NO_ERROR);
  254. if (lpFileNode->bSigned) {
  255. if (((PFILEPATHS_SIGNERINFO)Param1)->CatalogFile) {
  256. GetFullPathName(((PFILEPATHS_SIGNERINFO)Param1)->CatalogFile, cA(szBuffer), szBuffer, &lpFilePart);
  257. BufCbSize = (lstrlen(lpFilePart) + 1) * sizeof(TCHAR);
  258. lpFileNode->lpCatalog = MALLOC(BufCbSize);
  259. if (lpFileNode->lpCatalog) {
  260. hr = StringCbCopy(lpFileNode->lpCatalog, BufCbSize, lpFilePart);
  261. if (FAILED(hr) && (hr != STRSAFE_E_INSUFFICIENT_BUFFER)) {
  262. //
  263. // If we fail for some reason other than insufficient
  264. // buffer, then free the string and set the pointer
  265. // to NULL, since the string is undefined.
  266. //
  267. FREE(lpFileNode->lpCatalog);
  268. lpFileNode->lpCatalog = NULL;
  269. }
  270. }
  271. }
  272. if (((PFILEPATHS_SIGNERINFO)Param1)->DigitalSigner) {
  273. BufCbSize = (lstrlen(((PFILEPATHS_SIGNERINFO)Param1)->DigitalSigner) + 1) * sizeof(TCHAR);
  274. lpFileNode->lpSignedBy = MALLOC(BufCbSize);
  275. if (lpFileNode->lpSignedBy) {
  276. hr = StringCbCopy(lpFileNode->lpSignedBy, BufCbSize, ((PFILEPATHS_SIGNERINFO)Param1)->DigitalSigner);
  277. if (FAILED(hr) && (hr != STRSAFE_E_INSUFFICIENT_BUFFER)) {
  278. //
  279. // If we fail for some reason other than insufficient
  280. // buffer, then free the string and set the pointer
  281. // to NULL, since the string is undefined.
  282. //
  283. FREE(lpFileNode->lpSignedBy);
  284. lpFileNode->lpSignedBy = NULL;
  285. }
  286. }
  287. }
  288. if (((PFILEPATHS_SIGNERINFO)Param1)->Version) {
  289. BufCbSize = (lstrlen(((PFILEPATHS_SIGNERINFO)Param1)->Version) + 1) * sizeof(TCHAR);
  290. lpFileNode->lpVersion = MALLOC(BufCbSize);
  291. if (lpFileNode->lpVersion) {
  292. hr = StringCbCopy(lpFileNode->lpVersion, BufCbSize, ((PFILEPATHS_SIGNERINFO)Param1)->Version);
  293. if (FAILED(hr) && (hr != STRSAFE_E_INSUFFICIENT_BUFFER)) {
  294. //
  295. // If we fail for some reason other than insufficient
  296. // buffer, then free the string and set the pointer
  297. // to NULL, since the string is undefined.
  298. //
  299. FREE(lpFileNode->lpVersion);
  300. lpFileNode->lpVersion = NULL;
  301. }
  302. }
  303. }
  304. } else {
  305. //
  306. // Get the icon (if the file isn't signed) so we can display it in the listview faster.
  307. //
  308. MyGetFileInfo(lpFileNode);
  309. }
  310. }
  311. }
  312. return NO_ERROR;
  313. }
  314. void
  315. AddClassInstallerToList(
  316. LPCTSTR ClassInstallerString
  317. )
  318. {
  319. DWORD BufferSize;
  320. TCHAR ModulePath[MAX_PATH];
  321. TCHAR TempBuffer[MAX_PATH];
  322. PTSTR StringPtr;
  323. if ((ClassInstallerString == NULL) ||
  324. (ClassInstallerString[0] == TEXT('\0'))) {
  325. return;
  326. }
  327. if (FAILED(StringCchCopy(TempBuffer, cA(TempBuffer), ClassInstallerString))) {
  328. return;
  329. }
  330. //
  331. // Class/Co-installers are always based under the %windir%\system32
  332. // directory.
  333. //
  334. if (GetSystemDirectory(ModulePath, cA(ModulePath)) == 0) {
  335. return;
  336. }
  337. //
  338. // Find the beginning of the entry point name, if present.
  339. //
  340. BufferSize = (lstrlen(TempBuffer) + 1) * sizeof(TCHAR);
  341. for(StringPtr = TempBuffer + ((BufferSize / sizeof(TCHAR)) - 2);
  342. StringPtr >= TempBuffer;
  343. StringPtr--) {
  344. if(*StringPtr == TEXT(',')) {
  345. *(StringPtr++) = TEXT('\0');
  346. break;
  347. }
  348. //
  349. // If we hit a double-quote mark, then set the character pointer
  350. // to the beginning of the string so we'll terminate the search.
  351. //
  352. if(*StringPtr == TEXT('\"')) {
  353. StringPtr = TempBuffer;
  354. }
  355. }
  356. if (pSetupConcatenatePaths(ModulePath, TempBuffer, MAX_PATH, NULL)) {
  357. AddDriverFileToList(NULL, ModulePath);
  358. }
  359. }
  360. DWORD
  361. BuildDriverFileList(
  362. void
  363. )
  364. {
  365. DWORD Err = ERROR_SUCCESS;
  366. HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
  367. SP_DEVINFO_DATA DeviceInfoData;
  368. SP_DRVINFO_DATA DriverInfoData;
  369. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  370. DWORD DeviceMemberIndex;
  371. HSPFILEQ hFileQueue;
  372. DWORD ScanResult;
  373. DWORD Status, Problem;
  374. SC_HANDLE hscManager = NULL;
  375. TCHAR Buffer[MAX_PATH];
  376. ULONG BufferSize;
  377. DWORD dwType;
  378. HKEY hKey = INVALID_HANDLE_VALUE, hKeyClassCoInstallers = INVALID_HANDLE_VALUE;
  379. PTSTR pItemList = NULL, pSingleItem;
  380. LPGUID ClassGuidList = NULL;
  381. DWORD i, NumberClassGuids, CurrentClassGuid;
  382. TCHAR GuidString[MAX_GUID_STRING_LEN];
  383. //
  384. // Build up a list of all the devices in the system.
  385. //
  386. hDeviceInfo = SetupDiGetClassDevs(NULL,
  387. NULL,
  388. NULL,
  389. DIGCF_ALLCLASSES
  390. );
  391. if (hDeviceInfo == INVALID_HANDLE_VALUE) {
  392. Err = GetLastError();
  393. goto clean0;
  394. }
  395. DeviceInfoData.cbSize = sizeof(DeviceInfoData);
  396. DeviceMemberIndex = 0;
  397. //
  398. // Enumerate through the list of devices and get a list of all
  399. // the files they copy, if they are signed or not, and which catalog
  400. // signed them.
  401. //
  402. while (SetupDiEnumDeviceInfo(hDeviceInfo,
  403. DeviceMemberIndex++,
  404. &DeviceInfoData
  405. ) &&
  406. !g_App.bStopScan) {
  407. //
  408. // We will only build up a driver list for swenum phantoms. All other
  409. // phantoms will be skipped.
  410. //
  411. if (CM_Get_DevNode_Status(&Status,
  412. &Problem,
  413. DeviceInfoData.DevInst,
  414. 0) == CR_NO_SUCH_DEVINST) {
  415. //
  416. // This device is a phantom, if it is not a swenum device, then
  417. // skip it.
  418. //
  419. if (!SetupDiGetDeviceRegistryProperty(hDeviceInfo,
  420. &DeviceInfoData,
  421. SPDRP_ENUMERATOR_NAME,
  422. NULL,
  423. (PBYTE)Buffer,
  424. sizeof(Buffer),
  425. NULL) ||
  426. (_wcsicmp(Buffer, TEXT("SW")) != 0)) {
  427. //
  428. // Either we couldn't get the enumerator name, or it is not
  429. // SW.
  430. //
  431. continue;
  432. }
  433. }
  434. DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
  435. //
  436. // Before we call SetupDiBuildDriverInfoList to build up a list of drivers
  437. // for this device we first need to set the DI_FLAGSEX_INSTALLEDDRIVER flag
  438. // (which tells the API to only include the currently installed driver in
  439. // the list) and the DI_FLAGSEX_ALLOWEXCLUDEDRVS (allow ExcludeFromSelect
  440. // devices in the list).
  441. //
  442. if (SetupDiGetDeviceInstallParams(hDeviceInfo,
  443. &DeviceInfoData,
  444. &DeviceInstallParams
  445. )) {
  446. DeviceInstallParams.FlagsEx = (DI_FLAGSEX_INSTALLEDDRIVER |
  447. DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
  448. if (SetupDiSetDeviceInstallParams(hDeviceInfo,
  449. &DeviceInfoData,
  450. &DeviceInstallParams
  451. ) &&
  452. SetupDiBuildDriverInfoList(hDeviceInfo,
  453. &DeviceInfoData,
  454. SPDIT_CLASSDRIVER
  455. )) {
  456. //
  457. // Now we will get the one driver node that is in the list that
  458. // was just built and make it the selected driver node.
  459. //
  460. DriverInfoData.cbSize = sizeof(DriverInfoData);
  461. if (SetupDiEnumDriverInfo(hDeviceInfo,
  462. &DeviceInfoData,
  463. SPDIT_CLASSDRIVER,
  464. 0,
  465. &DriverInfoData
  466. ) &&
  467. SetupDiSetSelectedDriver(hDeviceInfo,
  468. &DeviceInfoData,
  469. &DriverInfoData
  470. )) {
  471. hFileQueue = SetupOpenFileQueue();
  472. if (hFileQueue != INVALID_HANDLE_VALUE) {
  473. //
  474. // Set the FileQueue parameter to the file queue we just
  475. // created and set the DI_NOVCP flag.
  476. //
  477. // The call SetupDiCallClassInstaller with DIF_INSTALLDEVICEFILES
  478. // to build up a queue of all the files that are copied for
  479. // this driver node.
  480. //
  481. DeviceInstallParams.FileQueue = hFileQueue;
  482. DeviceInstallParams.Flags |= DI_NOVCP;
  483. if (SetupDiSetDeviceInstallParams(hDeviceInfo,
  484. &DeviceInfoData,
  485. &DeviceInstallParams
  486. ) &&
  487. SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES,
  488. hDeviceInfo,
  489. &DeviceInfoData
  490. )) {
  491. //
  492. // Scan the file queue and have it call our callback
  493. // function for each file in the queue.
  494. //
  495. SetupScanFileQueue(hFileQueue,
  496. SPQ_SCAN_USE_CALLBACK_SIGNERINFO,
  497. NULL,
  498. ScanQueueCallback,
  499. (PVOID)&(DeviceInfoData.ClassGuid),
  500. &ScanResult
  501. );
  502. //
  503. // Dereference the file queue so we can close it.
  504. //
  505. DeviceInstallParams.FileQueue = NULL;
  506. DeviceInstallParams.Flags &= ~DI_NOVCP;
  507. SetupDiSetDeviceInstallParams(hDeviceInfo,
  508. &DeviceInfoData,
  509. &DeviceInstallParams
  510. );
  511. }
  512. SetupCloseFileQueue(hFileQueue);
  513. }
  514. }
  515. SetupDiDestroyDriverInfoList(hDeviceInfo,
  516. &DeviceInfoData,
  517. SPDIT_CLASSDRIVER
  518. );
  519. }
  520. }
  521. }
  522. //
  523. // Enumerate through the list of devices and add any function, device
  524. // upper/lower filters, and class upper/lower filter drivers to the list
  525. // that aren't already in the list.
  526. // We are doing this after we get all the files copied by the INF, because
  527. // these files can only be validated globally, where the INF copied files
  528. // can be validated using the catalog associated with their package.
  529. //
  530. hscManager = OpenSCManager(NULL, NULL, GENERIC_READ);
  531. if (hscManager) {
  532. DeviceInfoData.cbSize = sizeof(DeviceInfoData);
  533. DeviceMemberIndex = 0;
  534. while (SetupDiEnumDeviceInfo(hDeviceInfo,
  535. DeviceMemberIndex++,
  536. &DeviceInfoData
  537. ) &&
  538. !g_App.bStopScan) {
  539. //
  540. // Only look at SWENUM phantoms
  541. //
  542. if (CM_Get_DevNode_Status(&Status,
  543. &Problem,
  544. DeviceInfoData.DevInst,
  545. 0) == CR_NO_SUCH_DEVINST) {
  546. //
  547. // This device is a phantom, if it is not a swenum device, then
  548. // skip it.
  549. //
  550. if (!SetupDiGetDeviceRegistryProperty(hDeviceInfo,
  551. &DeviceInfoData,
  552. SPDRP_ENUMERATOR_NAME,
  553. NULL,
  554. (PBYTE)Buffer,
  555. sizeof(Buffer),
  556. NULL) ||
  557. (_wcsicmp(Buffer, TEXT("SW")) != 0)) {
  558. //
  559. // Either we couldn't get the enumerator name, or it is not
  560. // SW.
  561. //
  562. continue;
  563. }
  564. }
  565. if (g_App.bStopScan) {
  566. continue;
  567. }
  568. //
  569. // Function driver.
  570. //
  571. if (SetupDiGetDeviceRegistryProperty(hDeviceInfo,
  572. &DeviceInfoData,
  573. SPDRP_SERVICE,
  574. NULL,
  575. (PBYTE)Buffer,
  576. sizeof(Buffer),
  577. NULL)) {
  578. CreateFromService(hscManager, Buffer);
  579. }
  580. if (g_App.bStopScan) {
  581. continue;
  582. }
  583. //
  584. // Upper and Lower device filters
  585. //
  586. for (i=0; i<2; i++) {
  587. BufferSize = 0;
  588. SetupDiGetDeviceRegistryProperty(hDeviceInfo,
  589. &DeviceInfoData,
  590. i ? SPDRP_LOWERFILTERS : SPDRP_UPPERFILTERS,
  591. NULL,
  592. NULL,
  593. BufferSize,
  594. &BufferSize);
  595. if (BufferSize > 0) {
  596. pItemList = MALLOC(BufferSize + (2 * sizeof(TCHAR)));
  597. if (!pItemList) {
  598. Err = ERROR_NOT_ENOUGH_MEMORY;
  599. goto clean0;
  600. }
  601. if (SetupDiGetDeviceRegistryProperty(hDeviceInfo,
  602. &DeviceInfoData,
  603. i ? SPDRP_LOWERFILTERS : SPDRP_UPPERFILTERS,
  604. NULL,
  605. (PBYTE)pItemList,
  606. BufferSize,
  607. &BufferSize)) {
  608. for (pSingleItem=pItemList;
  609. *pSingleItem;
  610. pSingleItem += (lstrlen(pSingleItem) + 1)) {
  611. CreateFromService(hscManager, pSingleItem);
  612. }
  613. }
  614. FREE(pItemList);
  615. }
  616. }
  617. if (g_App.bStopScan) {
  618. continue;
  619. }
  620. //
  621. // Device co-installers.
  622. //
  623. hKey = SetupDiOpenDevRegKey(hDeviceInfo,
  624. &DeviceInfoData,
  625. DICS_FLAG_GLOBAL,
  626. 0,
  627. DIREG_DRV,
  628. KEY_READ);
  629. if (hKey != INVALID_HANDLE_VALUE) {
  630. BufferSize = 0;
  631. RegQueryValueEx(hKey,
  632. REGSTR_VAL_COINSTALLERS_32,
  633. NULL,
  634. &dwType,
  635. NULL,
  636. &BufferSize);
  637. if (BufferSize > 0) {
  638. pItemList = MALLOC(BufferSize + (2 * sizeof(TCHAR)));
  639. if (!pItemList) {
  640. Err = ERROR_NOT_ENOUGH_MEMORY;
  641. goto clean0;
  642. }
  643. dwType = REG_MULTI_SZ;
  644. if (RegQueryValueEx(hKey,
  645. REGSTR_VAL_COINSTALLERS_32,
  646. NULL,
  647. &dwType,
  648. (PBYTE)pItemList,
  649. &BufferSize) == ERROR_SUCCESS) {
  650. for (pSingleItem=pItemList;
  651. *pSingleItem;
  652. pSingleItem += (lstrlen(pSingleItem) + 1)) {
  653. AddClassInstallerToList(pSingleItem);
  654. }
  655. }
  656. FREE(pItemList);
  657. }
  658. RegCloseKey(hKey);
  659. hKey = INVALID_HANDLE_VALUE;
  660. }
  661. }
  662. //
  663. // Enumerate through the classes so we can get the class upper and
  664. // lower filters and the class installers.
  665. //
  666. NumberClassGuids = 0;
  667. SetupDiBuildClassInfoList(0, NULL, 0, &NumberClassGuids);
  668. if (NumberClassGuids > 0) {
  669. ClassGuidList = MALLOC(NumberClassGuids * sizeof(GUID));
  670. if (!ClassGuidList) {
  671. Err = ERROR_NOT_ENOUGH_MEMORY;
  672. goto clean0;
  673. }
  674. if (SetupDiBuildClassInfoList(0, ClassGuidList, NumberClassGuids, &NumberClassGuids)) {
  675. //
  676. // Open the class co-installer key since we will go through that
  677. // list while we have the class guids handy.
  678. //
  679. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  680. REGSTR_PATH_CODEVICEINSTALLERS,
  681. 0,
  682. KEY_READ,
  683. &hKeyClassCoInstallers) != ERROR_SUCCESS) {
  684. hKeyClassCoInstallers = INVALID_HANDLE_VALUE;
  685. }
  686. for (CurrentClassGuid=0; CurrentClassGuid<NumberClassGuids; CurrentClassGuid++) {
  687. //
  688. // Open the class key.
  689. //
  690. hKey = SetupDiOpenClassRegKey(&(ClassGuidList[CurrentClassGuid]),
  691. KEY_READ);
  692. if (hKey != INVALID_HANDLE_VALUE) {
  693. //
  694. // Upper and Lower class filters
  695. //
  696. for (i=0; i<2; i++) {
  697. BufferSize = 0;
  698. RegQueryValueEx(hKey,
  699. i ? REGSTR_VAL_LOWERFILTERS : REGSTR_VAL_UPPERFILTERS,
  700. NULL,
  701. &dwType,
  702. NULL,
  703. &BufferSize);
  704. if (BufferSize > 0) {
  705. pItemList = MALLOC(BufferSize + (2 * sizeof(TCHAR)));
  706. if (!pItemList) {
  707. Err = ERROR_NOT_ENOUGH_MEMORY;
  708. goto clean0;
  709. }
  710. dwType = REG_MULTI_SZ;
  711. if (RegQueryValueEx(hKey,
  712. i ? REGSTR_VAL_LOWERFILTERS : REGSTR_VAL_UPPERFILTERS,
  713. NULL,
  714. &dwType,
  715. (PBYTE)pItemList,
  716. &BufferSize) == ERROR_SUCCESS) {
  717. for (pSingleItem=pItemList;
  718. *pSingleItem;
  719. pSingleItem += (lstrlen(pSingleItem) + 1)) {
  720. CreateFromService(hscManager, pSingleItem);
  721. }
  722. }
  723. FREE(pItemList);
  724. }
  725. }
  726. //
  727. // Class installer
  728. //
  729. dwType = REG_SZ;
  730. BufferSize = sizeof(Buffer);
  731. if (RegQueryValueEx(hKey,
  732. REGSTR_VAL_INSTALLER_32,
  733. NULL,
  734. &dwType,
  735. (PBYTE)Buffer,
  736. &BufferSize) == ERROR_SUCCESS) {
  737. AddClassInstallerToList(Buffer);
  738. }
  739. RegCloseKey(hKey);
  740. hKey = INVALID_HANDLE_VALUE;
  741. }
  742. //
  743. // Class co-installers.
  744. //
  745. if (hKeyClassCoInstallers != INVALID_HANDLE_VALUE) {
  746. if (pSetupStringFromGuid(&(ClassGuidList[CurrentClassGuid]),
  747. GuidString,
  748. cA(GuidString)) == ERROR_SUCCESS) {
  749. BufferSize = 0;
  750. RegQueryValueEx(hKeyClassCoInstallers,
  751. GuidString,
  752. NULL,
  753. &dwType,
  754. NULL,
  755. &BufferSize);
  756. if (BufferSize > 0) {
  757. pItemList = MALLOC(BufferSize + (2 * sizeof(TCHAR)));
  758. if (!pItemList) {
  759. Err = ERROR_NOT_ENOUGH_MEMORY;
  760. goto clean0;
  761. }
  762. dwType = REG_MULTI_SZ;
  763. if (RegQueryValueEx(hKeyClassCoInstallers,
  764. GuidString,
  765. NULL,
  766. &dwType,
  767. (PBYTE)pItemList,
  768. &BufferSize) == ERROR_SUCCESS) {
  769. for (pSingleItem=pItemList;
  770. *pSingleItem;
  771. pSingleItem += (lstrlen(pSingleItem) + 1)) {
  772. AddClassInstallerToList(pSingleItem);
  773. }
  774. }
  775. FREE(pItemList);
  776. }
  777. }
  778. }
  779. }
  780. }
  781. if (hKeyClassCoInstallers != INVALID_HANDLE_VALUE) {
  782. RegCloseKey(hKeyClassCoInstallers);
  783. hKeyClassCoInstallers = INVALID_HANDLE_VALUE;
  784. }
  785. FREE(ClassGuidList);
  786. }
  787. CloseServiceHandle(hscManager);
  788. }
  789. clean0:
  790. if (hscManager) {
  791. CloseServiceHandle(hscManager);
  792. }
  793. if (pItemList) {
  794. FREE(pItemList);
  795. }
  796. if (ClassGuidList) {
  797. FREE(ClassGuidList);
  798. }
  799. if (hDeviceInfo != INVALID_HANDLE_VALUE) {
  800. SetupDiDestroyDeviceInfoList(hDeviceInfo);
  801. }
  802. if (hKeyClassCoInstallers != INVALID_HANDLE_VALUE) {
  803. RegCloseKey(hKeyClassCoInstallers);
  804. hKeyClassCoInstallers = INVALID_HANDLE_VALUE;
  805. }
  806. if (hKey != INVALID_HANDLE_VALUE) {
  807. RegCloseKey(hKey);
  808. hKey = INVALID_HANDLE_VALUE;
  809. }
  810. return Err;
  811. }
  812. DWORD
  813. BuildPrinterFileList(
  814. void
  815. )
  816. {
  817. DWORD Err = ERROR_SUCCESS;
  818. BOOL bRet;
  819. DWORD dwBytesNeeded = 0;
  820. DWORD dwDrivers = 0;
  821. LPBYTE lpBuffer = NULL, lpTemp = NULL;
  822. LPTSTR lpFileName;
  823. DRIVER_INFO_3 DriverInfo;
  824. PDRIVER_INFO_3 lpDriverInfo;
  825. TCHAR szBuffer[MAX_PATH];
  826. LPFILENODE lpFileNode = NULL;
  827. ZeroMemory(&DriverInfo, sizeof(DRIVER_INFO_3));
  828. bRet = EnumPrinterDrivers( NULL,
  829. SIGVERIF_PRINTER_ENV,
  830. 3,
  831. (LPBYTE) &DriverInfo,
  832. sizeof(DRIVER_INFO_3),
  833. &dwBytesNeeded,
  834. &dwDrivers);
  835. if (!bRet && dwBytesNeeded > 0) {
  836. lpBuffer = MALLOC(dwBytesNeeded);
  837. //
  838. // If we can't get any memory then just bail out of this function
  839. //
  840. if (!lpBuffer) {
  841. Err = ERROR_NOT_ENOUGH_MEMORY;
  842. goto clean0;
  843. }
  844. bRet = EnumPrinterDrivers( NULL,
  845. SIGVERIF_PRINTER_ENV,
  846. 3,
  847. (LPBYTE) lpBuffer,
  848. dwBytesNeeded,
  849. &dwBytesNeeded,
  850. &dwDrivers);
  851. }
  852. if (dwDrivers > 0) {
  853. //
  854. // By default, go into the System directory, since Win9x doesn't give full paths to drivers.
  855. //
  856. GetSystemDirectory(szBuffer, cA(szBuffer));
  857. SetCurrentDirectory(szBuffer);
  858. for (lpTemp = lpBuffer; dwDrivers > 0; dwDrivers--) {
  859. lpDriverInfo = (PDRIVER_INFO_3) lpTemp;
  860. if (lpDriverInfo->pName) {
  861. if (lpDriverInfo->pDriverPath && *lpDriverInfo->pDriverPath) {
  862. lpFileNode = AddDriverFileToList(NULL, lpDriverInfo->pDriverPath);
  863. if (lpFileNode) {
  864. lpFileNode->bValidateAgainstAnyOs = TRUE;
  865. }
  866. }
  867. if (lpDriverInfo->pDataFile && *lpDriverInfo->pDataFile) {
  868. lpFileNode = AddDriverFileToList(NULL, lpDriverInfo->pDataFile);
  869. if (lpFileNode) {
  870. lpFileNode->bValidateAgainstAnyOs = TRUE;
  871. }
  872. }
  873. if (lpDriverInfo->pConfigFile && *lpDriverInfo->pConfigFile) {
  874. lpFileNode = AddDriverFileToList(NULL, lpDriverInfo->pConfigFile);
  875. if (lpFileNode) {
  876. lpFileNode->bValidateAgainstAnyOs = TRUE;
  877. }
  878. }
  879. if (lpDriverInfo->pHelpFile && *lpDriverInfo->pHelpFile) {
  880. lpFileNode = AddDriverFileToList(NULL, lpDriverInfo->pHelpFile);
  881. if (lpFileNode) {
  882. lpFileNode->bValidateAgainstAnyOs = TRUE;
  883. }
  884. }
  885. lpFileName = lpDriverInfo->pDependentFiles;
  886. while (lpFileName && *lpFileName) {
  887. lpFileNode = AddDriverFileToList(NULL, lpFileName);
  888. if (lpFileNode) {
  889. lpFileNode->bValidateAgainstAnyOs = TRUE;
  890. }
  891. for (;*lpFileName;lpFileName++);
  892. lpFileName++;
  893. }
  894. }
  895. lpTemp += sizeof(DRIVER_INFO_3);
  896. }
  897. }
  898. clean0:
  899. if (lpBuffer) {
  900. FREE(lpBuffer);
  901. }
  902. return Err;
  903. }
  904. DWORD
  905. BuildCoreFileList(
  906. void
  907. )
  908. {
  909. DWORD Err = ERROR_SUCCESS;
  910. PROTECTED_FILE_DATA pfd;
  911. pfd.FileNumber = 0;
  912. while (SfcGetNextProtectedFile(NULL, &pfd)) {
  913. if (g_App.bStopScan) {
  914. Err = ERROR_CANCELLED;
  915. break;
  916. }
  917. AddDriverFileToList(NULL, pfd.FileName);
  918. }
  919. //
  920. // See if SfcGetNextProtectedFile failed from some reason other than
  921. // ERROR_NO_MORE_FILES.
  922. //
  923. if ((Err == ERROR_SUCCESS) &&
  924. (GetLastError() != ERROR_NO_MORE_FILES)) {
  925. //
  926. // SfcGetNextProtectedFile failed before we reached then end of the
  927. // list of protected file list. This means we won't scan all the
  928. // protected files, so we should fail up front!
  929. //
  930. Err = GetLastError();
  931. }
  932. return Err;
  933. }