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.

1205 lines
32 KiB

  1. #include "stdafx.h"
  2. #include <chkdev.h>
  3. BOOL testCatAPIs(LPWSTR lpwzCatName, HCATADMIN hCatAdmin, HCATINFO hCatInfo);
  4. HCATADMIN hCatAdmin = 0;
  5. extern Classes_Provided eClasses;
  6. #define NumberTestCerts 7
  7. BYTE TestCertHashes[NumberTestCerts][20] =
  8. {
  9. {0xBB, 0x11, 0x81, 0xF2, 0xB0, 0xC5, 0xE3, 0x2F, 0x7F, 0x2D, 0x62, 0x3B, 0x9C, 0x87, 0xE8, 0x55, 0x26, 0xF9, 0xCF, 0x2F},
  10. {0xBA, 0x9E, 0x3C, 0x32, 0x56, 0x2A, 0x67, 0x12, 0x8C, 0xAA, 0xBD, 0x4A, 0xB0, 0xC5, 0x00, 0xBE, 0xE1, 0xD0, 0xC2, 0x56},
  11. {0xA4, 0x34, 0x89, 0x15, 0x9A, 0x52, 0x0F, 0x0D, 0x93, 0xD0, 0x32, 0xCC, 0xAF, 0x37, 0xE7, 0xFE, 0x20, 0xA8, 0xB4, 0x19},
  12. {0x73, 0xA9, 0x01, 0x93, 0x83, 0x4C, 0x5B, 0x16, 0xB4, 0x3F, 0x0C, 0xE0, 0x5E, 0xB4, 0xA3, 0xEF, 0x6F, 0x2C, 0x08, 0x2F},
  13. {0xD2, 0xC3, 0x78, 0xCE, 0x42, 0xBC, 0x93, 0xA0, 0x3D, 0xD5, 0xA4, 0x2E, 0x8E, 0x08, 0xB1, 0x71, 0xB6, 0x27, 0x90, 0x1D},
  14. {0xFC, 0x94, 0x4A, 0x1F, 0xA0, 0xDC, 0x8A, 0xC7, 0x78, 0x4A, 0xAC, 0x36, 0x9D, 0x14, 0x46, 0x02, 0x24, 0x08, 0xFF, 0x5D},
  15. {0x92, 0x6A, 0xF1, 0x27, 0x25, 0x37, 0xE0, 0x73, 0x32, 0x6F, 0x12, 0xF7, 0xA7, 0x11, 0xE7, 0x55, 0xE6, 0x4E, 0x78, 0x4C}
  16. };
  17. CheckDevice::CheckDevice()
  18. {
  19. m_FileList = NULL;
  20. lpszServiceName = NULL;
  21. lpszServiceImage = NULL;
  22. m_hDevInfo = SetupDiCreateDeviceInfoListEx(NULL, NULL, NULL, NULL);
  23. }
  24. CheckDevice::~CheckDevice(void)
  25. {
  26. if ( m_FileList )
  27. {
  28. delete m_FileList;
  29. }
  30. if ( lpszServiceName )
  31. {
  32. delete lpszServiceName;
  33. lpszServiceName = NULL;
  34. }
  35. if ( lpszServiceImage )
  36. {
  37. delete lpszServiceImage;
  38. lpszServiceImage = NULL;
  39. }
  40. m_FileList = NULL;
  41. SetupDiDestroyDeviceInfoList(m_hDevInfo);
  42. }
  43. CheckDevice::CheckDevice(DEVNODE hDevice, DEVNODE hParent) : InfnodeClass (hDevice, hParent)
  44. {
  45. m_FileList = NULL;
  46. lpszServiceName = NULL;
  47. lpszServiceImage = NULL;
  48. m_hDevInfo = SetupDiCreateDeviceInfoListEx(NULL, NULL, NULL, NULL);
  49. if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile)
  50. CreateFileNode();
  51. }
  52. BOOL CheckDevice::AddFileNode(TCHAR *szFileName , UINT uiWin32Error /*= 0 */, LPCTSTR szSigner /*= NULL*/)
  53. {
  54. FileNode *pThisFile;
  55. if ( !szFileName || !strlen(szFileName) )
  56. {
  57. return(FALSE);
  58. }
  59. _strlwr(szFileName);
  60. // need to check that this file exists, if it doesn't, need to munge it so that it does
  61. HANDLE hFile;
  62. TCHAR cMungedName[_MAX_PATH];
  63. TCHAR *pStrPos;
  64. hFile = CreateFile(szFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  65. if (BADHANDLE(hFile))
  66. {
  67. // file does not exist, need to search for it
  68. if (pStrPos = strstr(szFileName, _T("\\system\\")))
  69. {
  70. // this may have been placed in the system32 dir instead
  71. *pStrPos = '\0';
  72. pStrPos++;
  73. pStrPos = strchr(pStrPos, '\\');
  74. sprintf(cMungedName, _T("%s\\system32%s"), szFileName, pStrPos);
  75. szFileName = cMungedName;
  76. hFile = CreateFile(szFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  77. if (BADHANDLE(hFile))
  78. {
  79. return FALSE;
  80. }
  81. }
  82. else if (pStrPos = strstr(szFileName, _T(".inf")))
  83. {
  84. // might be that an inf got caught in the other directory
  85. pStrPos = _tcsrchr(szFileName, '\\');
  86. //a-kjaw. to fix prefix bug# 259380.
  87. if(NULL == pStrPos)
  88. return FALSE;
  89. *pStrPos = '\0';
  90. pStrPos++;
  91. sprintf(cMungedName, _T("%s\\other\\%s"),szFileName, pStrPos);
  92. szFileName = cMungedName;
  93. hFile = CreateFile(szFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  94. if (BADHANDLE(hFile))
  95. {
  96. return FALSE;
  97. }
  98. }
  99. else
  100. return FALSE;
  101. }
  102. CloseHandle(hFile);
  103. // first scan the file list for duplicates
  104. pThisFile = m_FileList;
  105. while ( pThisFile )
  106. {
  107. if ( !strcmp(pThisFile->FilePath(), szFileName) )
  108. {
  109. return(TRUE); // no copy, no add
  110. }
  111. pThisFile = pThisFile->pNext;
  112. }
  113. pThisFile = NULL;
  114. pThisFile = new FileNode;
  115. if ( !pThisFile )
  116. {
  117. return(FALSE);
  118. }
  119. pThisFile->pDevnode = this;
  120. pThisFile->lpszFilePath = new TCHAR[strlen(szFileName) + 1];
  121. if ( !pThisFile->lpszFilePath )
  122. {
  123. delete pThisFile;
  124. return(FALSE);
  125. }
  126. strcpy(pThisFile->lpszFilePath, szFileName);
  127. // copyed the data
  128. pThisFile->lpszFileName = _tcsrchr(pThisFile->lpszFilePath, '\\');
  129. pThisFile->lpszFileName++;
  130. pThisFile->lpszFileExt = _tcsrchr(pThisFile->lpszFilePath, '.');
  131. pThisFile->lpszFileExt++;
  132. // get the version information
  133. //pThisFile->GetFileInformation();
  134. if(uiWin32Error == NO_ERROR)
  135. pThisFile->bSigned = TRUE;
  136. else
  137. pThisFile->bSigned = FALSE;
  138. if(szSigner != NULL)
  139. {
  140. pThisFile->lpszSignedBy = new TCHAR[(_tcslen(szSigner) + 1) * sizeof(TCHAR)];
  141. _tcscpy(pThisFile->lpszSignedBy, szSigner);
  142. }
  143. //else
  144. // pThisFile->bSigned = FALSE;
  145. // now perform the LL patch
  146. pThisFile->pNext = m_FileList;
  147. m_FileList = pThisFile;
  148. return(TRUE);
  149. }
  150. BOOL CheckDevice::GetServiceNameAndDriver(void)
  151. {
  152. /**********
  153. Get service Name
  154. ***********/
  155. ULONG ulSize;
  156. CONFIGRET retval;
  157. ulSize = 0;
  158. retval = CM_Get_DevNode_Registry_Property (hDevnode,
  159. CM_DRP_SERVICE,
  160. NULL,
  161. NULL,
  162. &ulSize,
  163. 0);
  164. if ( retval )
  165. if ( (retval == CR_BUFFER_SMALL) )
  166. {
  167. if ( !ulSize )
  168. ulSize = 511;
  169. }
  170. else
  171. return(retval);
  172. lpszServiceName = new TCHAR [ulSize+1];
  173. if ( !lpszServiceName ) return(CR_OUT_OF_MEMORY);
  174. //Now get value
  175. retval = CM_Get_DevNode_Registry_Property (hDevnode,
  176. CM_DRP_SERVICE,
  177. NULL,
  178. lpszServiceName,
  179. &ulSize,
  180. 0);
  181. if ( retval )
  182. return(retval);
  183. TCHAR KeyName[BUFFSIZE];
  184. TCHAR KeyValue[BUFFSIZE];
  185. HKEY SrvcKey;
  186. sprintf(KeyName, _T("SYSTEM\\CurrentControlSet\\Services\\%s"), lpszServiceName);
  187. if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  188. KeyName,
  189. 0,
  190. KEY_READ,
  191. &SrvcKey) != ERROR_SUCCESS )
  192. return(FALSE);
  193. if ( RegQueryValueEx(SrvcKey,
  194. _T("ImagePath"),
  195. 0,
  196. NULL,
  197. NULL,
  198. &ulSize) != ERROR_SUCCESS )
  199. {
  200. RegCloseKey(SrvcKey);
  201. return(FALSE);
  202. }
  203. if ( RegQueryValueEx(SrvcKey,
  204. _T("ImagePath"),
  205. 0,
  206. NULL,
  207. (PBYTE)KeyValue,
  208. &ulSize) != ERROR_SUCCESS )
  209. {
  210. RegCloseKey(SrvcKey);
  211. return(FALSE);
  212. }
  213. else
  214. {
  215. // sometimes the service path is assumed
  216. // z.b. system32\foo
  217. // or %system32%\foo
  218. if ( !_tcsncmp(KeyValue, _T("System32\\"), _tcslen(_T("System32\\"))) )
  219. {
  220. sprintf(KeyName, _T("%%WINDIR%%\\%s"), KeyValue);
  221. ExpandEnvironmentStrings(KeyName, KeyValue, BUFFSIZE);
  222. lpszServiceImage = new TCHAR[strlen(KeyValue) + 1];
  223. if ( lpszServiceImage )
  224. strcpy(lpszServiceImage, KeyValue);
  225. }
  226. }
  227. // should be everything
  228. RegCloseKey(SrvcKey);
  229. return(TRUE);
  230. }
  231. BOOL CheckDevice::CreateFileNode(void)
  232. {
  233. // also going to add the inf as a file
  234. TCHAR infname[512];
  235. TCHAR tempname[512];
  236. if ( InfName() )
  237. {
  238. // BUGBUG is this correct, or in some subdir??
  239. sprintf(tempname, _T("%%WINDIR%%\\inf\\%s"), InfName());
  240. ExpandEnvironmentStrings(tempname, infname, 512);
  241. AddFileNode(infname);
  242. }
  243. else
  244. return(FALSE);
  245. if ( GetServiceNameAndDriver() )
  246. AddFileNode(lpszServiceImage);
  247. //CreateFileNode_Class();
  248. CreateFileNode_Driver();
  249. return(TRUE);
  250. }
  251. BOOL CheckDevice::CreateFileNode_Class(void)
  252. {
  253. SP_DEVINSTALL_PARAMS DevInstallParams, DevTemp;
  254. SP_DEVINFO_DATA DevInfoData;
  255. SP_DRVINFO_DATA DrvInfoData;
  256. DWORD dwScanResult;
  257. HDEVINFO hDevInfo;
  258. HSPFILEQ hFileQueue;
  259. BOOL bProceed = TRUE;
  260. // Reset all structures to empty
  261. memset(&DevInstallParams, 0, sizeof(DevInstallParams));
  262. memset(&DevInfoData, 0, sizeof(DevInfoData));
  263. memset(&DrvInfoData, 0, sizeof(DrvInfoData));
  264. memset(&DevTemp, 0, sizeof(DevInstallParams));
  265. DrvInfoData.cbSize = sizeof(DrvInfoData);
  266. DevInfoData.cbSize = sizeof(DevInfoData);
  267. DevInstallParams.cbSize = sizeof(DevInstallParams);
  268. hFileQueue = SetupOpenFileQueue();
  269. // We need to build a driver node for the devnode
  270. hDevInfo = m_hDevInfo;
  271. if ( INVALID_HANDLE_VALUE == hDevInfo )
  272. return(0);
  273. DevInfoData.Reserved = 0;
  274. if ( !SetupDiOpenDeviceInfo(hDevInfo, DeviceID(), NULL, NULL , &DevInfoData) )
  275. {
  276. SetupDiDestroyDeviceInfoList(hDevInfo);
  277. return(FALSE);
  278. }
  279. /*
  280. if (SetupDiGetDeviceInstallParams(hDevInfo,
  281. &DevInfoData,
  282. &DevInstallParams
  283. ))
  284. {
  285. DevInstallParams.FlagsEx = (DI_FLAGSEX_INSTALLEDDRIVER |
  286. DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
  287. SetupDiSetDeviceInstallParams(hDevInfo,
  288. &DevInfoData,
  289. &DevInstallParams
  290. );
  291. }
  292. */
  293. if ( !SetupDiBuildDriverInfoList(hDevInfo, &DevInfoData, SPDIT_CLASSDRIVER) )
  294. {
  295. SetupDiDestroyDeviceInfoList(hDevInfo);
  296. return(FALSE);
  297. }
  298. // select a driver
  299. if ( DeviceName() )
  300. strcpy(DrvInfoData.Description, DeviceName());
  301. if ( MFG() )
  302. strcpy(DrvInfoData.MfgName, MFG());
  303. if ( InfProvider() )
  304. strcpy(DrvInfoData.ProviderName, InfProvider());
  305. DrvInfoData.DriverType = SPDIT_CLASSDRIVER;
  306. if ( !SetupDiSetSelectedDriver(hDevInfo,
  307. &DevInfoData,
  308. &DrvInfoData) )
  309. {
  310. //BUGBUG put goo here
  311. DWORD err = GetLastError();
  312. return(FALSE);
  313. }
  314. if ( SetupDiGetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams) )
  315. {
  316. memcpy(&DevTemp, &DevInfoData, sizeof(DevInfoData));
  317. }
  318. DevInstallParams.FileQueue = hFileQueue;
  319. DevInstallParams.Flags |= (DI_NOVCP | DI_ENUMSINGLEINF | DI_DONOTCALLCONFIGMG | DI_NOFILECOPY | DI_NOWRITE_IDS) ;
  320. DevInstallParams.Flags &= ~(DI_NODI_DEFAULTACTION);
  321. DevInstallParams.FlagsEx |= DI_FLAGSEX_NO_DRVREG_MODIFY;
  322. DevInstallParams.InstallMsgHandler = ScanQueueCallback;
  323. DevInstallParams.InstallMsgHandlerContext = this;
  324. strcpy(DevInstallParams.DriverPath, InfName());
  325. SetLastError(0);
  326. SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams);
  327. if ( !SetupDiCallClassInstaller(DIF_INSTALLCLASSDRIVERS, hDevInfo, &DevInfoData) )
  328. {
  329. DWORD err = GetLastError();
  330. }
  331. SetupScanFileQueue(hFileQueue,
  332. SPQ_SCAN_USE_CALLBACKEX,
  333. NULL,
  334. ScanQueueCallback,
  335. this,
  336. &dwScanResult);
  337. if ( DevTemp.cbSize )
  338. {
  339. SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevTemp);
  340. }
  341. return(FALSE);
  342. }
  343. BOOL CheckDevice::CreateFileNode_Driver(void)
  344. {
  345. SP_DEVINSTALL_PARAMS DevInstallParams, DevTemp;
  346. SP_DEVINFO_DATA DevInfoData;
  347. SP_DRVINFO_DATA DrvInfoData;
  348. DWORD dwScanResult;
  349. HDEVINFO hDevInfo;
  350. HSPFILEQ hFileQueue;
  351. BOOL bProceed = TRUE;
  352. // Reset all structures to empty
  353. memset(&DevInstallParams, 0, sizeof(DevInstallParams));
  354. memset(&DevInfoData, 0, sizeof(DevInfoData));
  355. memset(&DrvInfoData, 0, sizeof(DrvInfoData));
  356. memset(&DevTemp, 0, sizeof(DevInstallParams));
  357. DrvInfoData.cbSize = sizeof(DrvInfoData);
  358. DevInfoData.cbSize = sizeof(DevInfoData);
  359. DevInstallParams.cbSize = sizeof(DevInstallParams);
  360. hFileQueue = SetupOpenFileQueue();
  361. // We need to build a driver node for the devnode
  362. hDevInfo = m_hDevInfo;
  363. if ( INVALID_HANDLE_VALUE == hDevInfo )
  364. return(0);
  365. DevInfoData.Reserved = 0;
  366. if ( !SetupDiOpenDeviceInfo(hDevInfo, DeviceID(), NULL, NULL , &DevInfoData) )
  367. {
  368. SetupDiDestroyDeviceInfoList(hDevInfo);
  369. return(FALSE);
  370. }
  371. if ( !SetupDiBuildDriverInfoList(hDevInfo, &DevInfoData, SPDIT_COMPATDRIVER) )
  372. {
  373. SetupDiDestroyDeviceInfoList(hDevInfo);
  374. return(FALSE);
  375. }
  376. // select a driver
  377. if ( DeviceName() )
  378. strcpy(DrvInfoData.Description, DeviceName());
  379. if ( MFG() )
  380. strcpy(DrvInfoData.MfgName, MFG());
  381. if ( InfProvider() )
  382. strcpy(DrvInfoData.ProviderName, InfProvider());
  383. DrvInfoData.DriverType = SPDIT_COMPATDRIVER;
  384. if ( !SetupDiSetSelectedDriver(hDevInfo,
  385. &DevInfoData,
  386. &DrvInfoData) )
  387. {
  388. DWORD err = GetLastError();
  389. return(FALSE);
  390. }
  391. if ( SetupDiGetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams) )
  392. {
  393. memcpy(&DevTemp, &DevInfoData, sizeof(DevInfoData));
  394. }
  395. DevInstallParams.FileQueue = hFileQueue;
  396. DevInstallParams.Flags |= (DI_NOVCP /*| DI_ENUMSINGLEINF | DI_DONOTCALLCONFIGMG | DI_NOFILECOPY | DI_NOWRITE_IDS*/) ;
  397. //DevInstallParams.Flags &= ~(DI_NODI_DEFAULTACTION);
  398. //DevInstallParams.FlagsEx |= DI_FLAGSEX_NO_DRVREG_MODIFY;
  399. //DevInstallParams.InstallMsgHandler = ScanQueueCallback;
  400. //DevInstallParams.InstallMsgHandlerContext = this;
  401. strcpy(DevInstallParams.DriverPath, InfName());
  402. SetLastError(0);
  403. SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevInstallParams);
  404. if ( !SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDevInfo, &DevInfoData) )
  405. {
  406. DWORD err = GetLastError();
  407. }
  408. SetupScanFileQueue(hFileQueue,
  409. SPQ_SCAN_USE_CALLBACKEX,
  410. NULL,
  411. ScanQueueCallback,
  412. this,
  413. &dwScanResult);
  414. if ( DevTemp.cbSize )
  415. {
  416. SetupDiSetDeviceInstallParams(hDevInfo, &DevInfoData, &DevTemp);
  417. }
  418. return(FALSE);
  419. }
  420. FileNode * CheckDevice::GetFileList(void)
  421. {
  422. return(m_FileList);
  423. }
  424. FileNode::FileNode()
  425. {
  426. lpszFileName = NULL;
  427. lpszFilePath = NULL;
  428. lpszFileExt = NULL;
  429. baHashValue = NULL;
  430. dwHashSize = 0;
  431. pNext = NULL;
  432. FileSize = 0;
  433. lpszCatalogPath = NULL;
  434. lpszCatalogName = NULL;
  435. lpszSignedBy = NULL;
  436. m_pCatAttrib = NULL;
  437. bSigned = FALSE;
  438. }
  439. FileNode::~FileNode()
  440. {
  441. if ( lpszFilePath )
  442. {
  443. delete lpszFilePath;
  444. }
  445. lpszFileName = NULL;
  446. lpszFilePath = NULL;
  447. lpszFileExt = NULL;
  448. if ( baHashValue )
  449. {
  450. delete baHashValue;
  451. }
  452. baHashValue = NULL;
  453. dwHashSize = 0;
  454. if ( lpszCatalogPath )
  455. {
  456. delete lpszCatalogPath;
  457. }
  458. lpszCatalogPath = NULL;
  459. lpszCatalogName = NULL;
  460. if ( pNext )
  461. {
  462. delete pNext;
  463. }
  464. pNext = NULL;
  465. if ( m_pCatAttrib )
  466. {
  467. delete m_pCatAttrib;
  468. }
  469. m_pCatAttrib = NULL;
  470. }
  471. BOOL FileNode::GetFileInformation(void)
  472. {
  473. UINT dwSize;
  474. DWORD dwHandle;
  475. BYTE *pBuf;
  476. VS_FIXEDFILEINFO *lpVerData;
  477. HANDLE hFile;
  478. BY_HANDLE_FILE_INFORMATION FileInfo;
  479. // get version of the file
  480. dwSize = GetFileVersionInfoSize(lpszFilePath, &dwHandle);
  481. pBuf = new BYTE[dwSize];
  482. if ( GetFileVersionInfo(lpszFilePath, dwHandle, dwSize, pBuf) )
  483. {
  484. if ( VerQueryValue(pBuf, _T("\\"), (void **)&lpVerData, &dwSize) )
  485. {
  486. Version.dwProductVersionLS = lpVerData->dwProductVersionLS;
  487. Version.dwProductVersionMS = lpVerData->dwProductVersionMS;
  488. Version.dwFileVersionLS = lpVerData->dwFileVersionLS;
  489. Version.dwFileVersionMS = lpVerData->dwFileVersionMS;
  490. // while we're here get the file time as well)
  491. TimeStamp.dwLowDateTime = lpVerData->dwFileDateLS;
  492. TimeStamp.dwHighDateTime = lpVerData->dwFileDateMS;
  493. }
  494. }
  495. delete pBuf;
  496. // get file hash
  497. if ( BADHANDLE(hCatAdmin) )
  498. {
  499. CryptCATAdminAcquireContext(&hCatAdmin, NULL, 0);
  500. }
  501. hFile = CreateFile(lpszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  502. FILE_ATTRIBUTE_NORMAL, NULL);
  503. // BUGBUG: on for win9x inf.s, they might be in the inf\other directory
  504. // BUGBUG: for whatever reason, sometimes setupapi will give c:\windows\system\driver dir, and not the sytem32\drivers
  505. if ( BADHANDLE(hFile) )
  506. {
  507. int foo = GetLastError();
  508. return(FALSE);
  509. }
  510. if ( CryptCATAdminCalcHashFromFileHandle(hFile, &dwHashSize, NULL, 0) )
  511. {
  512. baHashValue = new BYTE[dwHashSize];
  513. ZeroMemory(baHashValue, dwHashSize);
  514. CryptCATAdminCalcHashFromFileHandle(hFile, &dwHashSize, baHashValue, 0);
  515. }
  516. else
  517. {
  518. baHashValue = 0;
  519. }
  520. // get file size
  521. FileSize = GetFileSize(hFile, NULL);
  522. // get time stamp
  523. if ( GetFileInformationByHandle(hFile, &FileInfo) )
  524. {
  525. TimeStamp = FileInfo.ftCreationTime;
  526. }
  527. CloseHandle(hFile);
  528. return(TRUE);
  529. }
  530. BOOL FileNode::VerifyFile(void)
  531. {
  532. USES_CONVERSION;
  533. BOOL bRet;
  534. HCATINFO hCatInfo = NULL;
  535. HCATINFO PrevCat;
  536. WINTRUST_DATA WinTrustData;
  537. WINTRUST_CATALOG_INFO WinTrustCatalogInfo;
  538. DRIVER_VER_INFO VerInfo;
  539. GUID gSubSystemDriver = DRIVER_ACTION_VERIFY;
  540. //GUID gSubSystemDriver = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  541. HRESULT hRes;
  542. CATALOG_INFO CatInfo;
  543. LPTSTR lpFilePart;
  544. WCHAR UnicodeKey[MAX_PATH];
  545. TCHAR szBuffer[MAX_PATH];
  546. // make sure that we can find the file
  547. if ( !baHashValue || !dwHashSize || !FileSize )
  548. {
  549. // seems that there is no file to check, or couldn't find it
  550. return(FALSE);
  551. }
  552. //
  553. // Need to lower case file tag for old-style catalog files
  554. //
  555. lstrcpy(szBuffer, lpszFilePath);
  556. CharLowerBuff(szBuffer, lstrlen(szBuffer));
  557. #ifdef _UNICODE
  558. CopyMemory(UnicodeKey, szBuffer, MAX_PATH * sizeof(WCHAR));
  559. #else
  560. MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, UnicodeKey, MAX_PATH);
  561. #endif
  562. ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO));
  563. VerInfo.cbStruct = sizeof(DRIVER_VER_INFO);
  564. //
  565. // Now we have the file's hash. Initialize the structures that
  566. // will be used later on in calls to WinVerifyTrust.
  567. //
  568. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  569. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  570. WinTrustData.dwUIChoice = WTD_UI_NONE;
  571. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  572. WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG;
  573. WinTrustData.dwStateAction = WTD_STATEACTION_VERIFY;
  574. WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo;
  575. WinTrustData.dwProvFlags = WTD_REVOCATION_CHECK_NONE;
  576. WinTrustData.pCatalog = &WinTrustCatalogInfo;
  577. ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO));
  578. WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  579. WinTrustCatalogInfo.pbCalculatedFileHash = baHashValue;
  580. WinTrustCatalogInfo.cbCalculatedFileHash = dwHashSize;
  581. WinTrustCatalogInfo.pcwszMemberTag = UnicodeKey;
  582. WinTrustCatalogInfo.pcwszMemberFilePath = UnicodeKey;
  583. //
  584. // Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash
  585. //
  586. PrevCat = NULL;
  587. hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, baHashValue, dwHashSize, 0, &PrevCat);
  588. //
  589. // We want to cycle through the matching catalogs until we find one that matches both hash and member tag
  590. //
  591. bRet = FALSE;
  592. while ( hCatInfo && !bRet )
  593. {
  594. ZeroMemory(&CatInfo, sizeof(CATALOG_INFO));
  595. CatInfo.cbStruct = sizeof(CATALOG_INFO);
  596. if ( CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0) )
  597. {
  598. WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
  599. // Now verify that the file is an actual member of the catalog.
  600. hRes = WinVerifyTrust(NULL, &gSubSystemDriver, &WinTrustData);
  601. if ( hRes == ERROR_SUCCESS )
  602. {
  603. #ifdef _UNICODE
  604. CopyMemory(szBuffer, CatInfo.wszCatalogFile, MAX_PATH * sizeof(TCHAR));
  605. #else
  606. WideCharToMultiByte(CP_ACP, 0, CatInfo.wszCatalogFile, -1, szBuffer, MAX_PATH, NULL, NULL);
  607. #endif
  608. //Commented because of some weird prob!!
  609. //GetFullPathName(szBuffer, MAX_PATH, szBuffer, &lpFilePart);
  610. lpszCatalogPath = new TCHAR[(lstrlen(szBuffer) + 1) * sizeof(TCHAR)];
  611. lstrcpy(lpszCatalogPath, szBuffer);
  612. lpszCatalogName = _tcsrchr(lpszCatalogPath, '\\');
  613. lpszCatalogName++;
  614. bRet = TRUE;
  615. if ( VerInfo.pcSignerCertContext != NULL )
  616. {
  617. CertFreeCertificateContext(VerInfo.pcSignerCertContext);
  618. VerInfo.pcSignerCertContext = NULL;
  619. }
  620. // file is signed, so need to walk the cert chain to see who signed it
  621. bSigned = WalkCertChain(WinTrustData.hWVTStateData);
  622. }
  623. }
  624. if ( !bRet )
  625. {
  626. // The hash was in this catalog, but the file wasn't a member... so off to the next catalog
  627. PrevCat = hCatInfo;
  628. hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, baHashValue, dwHashSize, 0, &PrevCat);
  629. }
  630. }
  631. if ( !hCatInfo )
  632. {
  633. //
  634. // If it wasn't found in the catalogs, check if the file is individually signed.
  635. //
  636. bRet = VerifyIsFileSigned(lpszFilePath, (PDRIVER_VER_INFO) &VerInfo);
  637. if ( bRet )
  638. {
  639. // If so, mark the file as being signed.
  640. bSigned = TRUE;
  641. }
  642. }
  643. else
  644. {
  645. GetCatalogInfo(CatInfo.wszCatalogFile, hCatAdmin, hCatInfo);
  646. // The file was verified in the catalogs, so mark it as signed and free the catalog context.
  647. CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
  648. }
  649. if ( hRes == ERROR_SUCCESS )
  650. {
  651. #ifdef _UNICODE
  652. CopyMemory(szBuffer, VerInfo.wszSignedBy, MAX_PATH * sizeof(TCHAR));
  653. #else
  654. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszSignedBy, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  655. #endif
  656. lpszSignedBy = new TCHAR[(lstrlen(szBuffer) + 1) * sizeof(TCHAR)];
  657. lstrcpy(lpszSignedBy, szBuffer);
  658. }
  659. //
  660. // close wintrust state
  661. //
  662. WinTrustData.dwStateAction = WTD_STATEACTION_CLOSE;
  663. WinVerifyTrust(NULL,
  664. &gSubSystemDriver,
  665. &WinTrustData);
  666. return(bSigned);
  667. }
  668. /*************************************************************************
  669. * Function : VerifyIsFileSigned
  670. * Purpose : Calls WinVerifyTrust with Policy Provider GUID to
  671. * verify if an individual file is signed.
  672. **************************************************************************/
  673. BOOL FileNode::VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo)
  674. {
  675. USES_CONVERSION;
  676. INT iRet;
  677. HRESULT hRes;
  678. WINTRUST_DATA WinTrustData;
  679. WINTRUST_FILE_INFO WinTrustFile;
  680. GUID gOSVerCheck = DRIVER_ACTION_VERIFY;
  681. GUID gPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  682. WCHAR wszFileName[MAX_PATH];
  683. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  684. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  685. WinTrustData.dwUIChoice = WTD_UI_NONE;
  686. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  687. WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
  688. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  689. WinTrustData.pFile = &WinTrustFile;
  690. WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo;
  691. ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO));
  692. lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO);
  693. ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO));
  694. WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO);
  695. #ifdef _UNICODE
  696. CopyMemory(wszFileName, pcszMatchFile, MAX_PATH * sizeof(WCHAR));
  697. #else
  698. iRet = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, (LPWSTR)&wszFileName, wcslen(wszFileName));
  699. #endif
  700. WinTrustFile.pcwszFilePath = wszFileName;
  701. hRes = WinVerifyTrust((HWND__ *)INVALID_HANDLE_VALUE, &gOSVerCheck, &WinTrustData);
  702. if ( hRes != ERROR_SUCCESS )
  703. hRes = WinVerifyTrust((HWND__ *)INVALID_HANDLE_VALUE, &gPublishedSoftware, &WinTrustData);
  704. return(hRes == ERROR_SUCCESS);
  705. }
  706. LogoFileVersion::LogoFileVersion()
  707. {
  708. dwProductVersionLS = 0;
  709. dwProductVersionMS = 0;
  710. dwFileVersionLS = 0;
  711. dwFileVersionMS = 0;
  712. }
  713. CatalogAttribute::CatalogAttribute()
  714. {
  715. Attrib = NULL;
  716. Value = NULL;
  717. pNext = NULL;
  718. }
  719. CatalogAttribute::~CatalogAttribute()
  720. {
  721. if ( Attrib ) delete Attrib;
  722. if ( Value ) delete Value;
  723. if ( pNext ) delete pNext;
  724. Attrib = NULL;
  725. Value = NULL;
  726. pNext = NULL;
  727. }
  728. // Function: ScanQueueCallback
  729. // Parameters:
  730. // pvContext: Pointer to a context that contains any data needed
  731. // Notify: The type of message received
  732. // Param1: The pointer to the string containing the filename
  733. // Param2: Not used
  734. // Purpose: This function gets called when you tell the setup environment to scan
  735. // through the file queue. Basically it receives the filenames and copies
  736. // them into a string.
  737. // Returns: NO_ERROR if nothing went wrong and ERROR_NOT_ENOUGH_MEMORY if their is no
  738. // free memory
  739. UINT __stdcall ScanQueueCallback(PVOID pvContext, UINT Notify, UINT_PTR Param1, UINT_PTR Param2)
  740. {
  741. CheckDevice *pDevice = (CheckDevice *)pvContext;
  742. PFILEPATHS pfilepaths;
  743. if ( (SPFILENOTIFY_QUEUESCAN == Notify) && Param1 )
  744. {
  745. pDevice->AddFileNode((TCHAR *)Param1);
  746. }
  747. if ( (SPFILENOTIFY_QUEUESCAN_EX == Notify) && Param1 )
  748. {
  749. pfilepaths = (PFILEPATHS)Param1;
  750. ////////////////Put Signer in the 3rd param whenever its available!
  751. pDevice->AddFileNode((LPTSTR)pfilepaths->Target , pfilepaths->Win32Error , /*pfilepaths->csSigner*/ NULL);
  752. }
  753. return(NO_ERROR);
  754. }
  755. BOOL FileNode::GetCatalogInfo(LPWSTR lpwzCatName, HCATADMIN hCatAdmin, HCATINFO hCatInfo)
  756. {
  757. USES_CONVERSION;
  758. HANDLE hCat;
  759. CRYPTCATATTRIBUTE *pCatAttrib;
  760. TCHAR szBuffer[512];
  761. CRYPTCATMEMBER *pMember = NULL;
  762. PSIP_INDIRECT_DATA pSipData;
  763. CatalogAttribute *CatAttribute;
  764. hCat = CryptCATOpen(lpwzCatName, CRYPTCAT_OPEN_EXISTING, NULL, 0, 0);
  765. if ( BADHANDLE(hCat) )
  766. {
  767. return(FALSE);
  768. }
  769. pCatAttrib = NULL;
  770. while ( pCatAttrib = CryptCATEnumerateCatAttr(hCat, pCatAttrib) )
  771. {
  772. if ( pCatAttrib->dwAttrTypeAndAction | CRYPTCAT_ATTR_NAMEASCII )
  773. {
  774. #ifdef _UNICODE
  775. CopyMemory(szBuffer, pCatAttrib->pwszReferenceTag, 511 * sizeof(TCHAR));
  776. #else
  777. WideCharToMultiByte(CP_ACP, 0, pCatAttrib->pwszReferenceTag, -1, szBuffer, 511, NULL, NULL);
  778. #endif
  779. CatAttribute = new CatalogAttribute;
  780. if ( !CatAttribute )
  781. {
  782. return(FALSE);
  783. }
  784. CatAttribute->Attrib = new TCHAR[strlen(szBuffer) +1];
  785. if ( !CatAttribute->Attrib )
  786. {
  787. delete CatAttribute;
  788. return(FALSE);
  789. }
  790. _tcscpy(CatAttribute->Attrib, szBuffer);
  791. #ifdef _UNICODE
  792. CopyMemory(szBuffer, (PUSHORT)pCatAttrib->pbValue, 511 * sizeof(TCHAR));
  793. #else
  794. WideCharToMultiByte(CP_ACP, 0, (PUSHORT)pCatAttrib->pbValue, -1, szBuffer, 511, NULL, NULL);
  795. #endif
  796. CatAttribute->Value = new TCHAR[strlen(szBuffer) + 1];
  797. if ( !CatAttribute->Value )
  798. {
  799. delete CatAttribute;
  800. return(FALSE);
  801. }
  802. _tcscpy(CatAttribute->Value, szBuffer);
  803. // add to node
  804. CatAttribute->pNext = (void *)m_pCatAttrib;
  805. m_pCatAttrib = CatAttribute;
  806. }
  807. }
  808. while ( pMember = CryptCATEnumerateMember(hCat, pMember) )
  809. {
  810. pSipData = pMember->pIndirectData;
  811. }
  812. CryptCATClose(hCat);
  813. return(TRUE);
  814. }
  815. BOOL CheckFile (TCHAR *szFileName)
  816. {
  817. FileNode *pThisFile = NULL;
  818. BOOL bRet = FALSE; // v-jammar; fix prefix bug 427999
  819. try //v-stlowe: 3/20/2001: to fix prefix bug where memory was leaking on out-of-mem throw
  820. {
  821. pThisFile = new FileNode;
  822. if ( !pThisFile )
  823. {
  824. return(FALSE);
  825. }
  826. pThisFile->lpszFilePath = new TCHAR[strlen(szFileName) + 1];
  827. if ( !pThisFile->lpszFilePath )
  828. {
  829. delete pThisFile;
  830. return(FALSE);
  831. }
  832. _tcscpy(pThisFile->lpszFilePath, szFileName);
  833. // copyed the data
  834. pThisFile->lpszFileName = _tcsrchr(pThisFile->lpszFilePath, '\\');
  835. pThisFile->lpszFileName++;
  836. pThisFile->lpszFileExt = _tcsrchr(pThisFile->lpszFilePath, '.');
  837. pThisFile->lpszFileExt++;
  838. // get the version information
  839. pThisFile->GetFileInformation();
  840. bRet = pThisFile->VerifyFile();
  841. }
  842. catch(...)
  843. {
  844. }
  845. // BUGBUG, need to check out the signer of this file to determine
  846. // who actually signed it.
  847. if(pThisFile)
  848. {
  849. delete pThisFile;
  850. pThisFile = NULL;
  851. }
  852. return(bRet);
  853. }
  854. BOOL Share_CloseHandle(void)
  855. {
  856. if ( !BADHANDLE(hCatAdmin) )
  857. {
  858. CryptCATAdminReleaseContext(hCatAdmin, 0);
  859. hCatAdmin = 0;
  860. }
  861. return(TRUE);
  862. }
  863. BOOL FileNode::GetCertInfo(PCCERT_CONTEXT pCertContext)
  864. {
  865. DWORD Size = 200;
  866. #if 0
  867. Size = 200;
  868. if ( CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pArray, &Size) )
  869. {
  870. printf("\nSH1 Hash (%u):", Size);
  871. for ( UINT index = 0; index < Size; index++ )
  872. {
  873. printf("%s0x%02X", index == 0 ? " " : ", ", pArray[index]);
  874. }
  875. printf("\n");
  876. }
  877. Size = 200;
  878. if ( CertGetCertificateContextProperty(pCertContext, CERT_SIGNATURE_HASH_PROP_ID, pArray, &Size) )
  879. {
  880. printf("\nCert Hash (%u):", Size);
  881. for ( UINT index = 0; index < Size; index++ )
  882. {
  883. printf("%s0x%02X", index == 0 ? " " : ", ", pArray[index]);
  884. }
  885. printf("\n");
  886. }
  887. // Get Chain information
  888. CERT_CHAIN_PARA ChainPara;
  889. PCCERT_CHAIN_CONTEXT pChainContext = NULL;
  890. memset (&CharinPara, 0, sizeof (CERT_CHAIN_PARA));
  891. ChainPara.cbSize = sizeof (CERT_CHAIN_PARA);
  892. ChainPara.RequestedUsage.
  893. if ( CertGetCertificateChain(NULL, pCertContext, NULL, NULL, ) )
  894. {
  895. }
  896. #endif
  897. return(TRUE);
  898. }
  899. BOOL WalkCertChain(HANDLE hWVTStateData)
  900. {
  901. CRYPT_PROVIDER_DATA * pProvData;
  902. CRYPT_PROVIDER_SGNR * pProvSigner = NULL;
  903. CRYPT_PROVIDER_CERT * pCryptProviderCert;
  904. BYTE pArray[21];
  905. UINT i;
  906. DWORD size;
  907. pProvData = WTHelperProvDataFromStateData(hWVTStateData);
  908. // did it work?
  909. if ( !pProvData )
  910. {
  911. return(FALSE);
  912. }
  913. pProvSigner = WTHelperGetProvSignerFromChain(
  914. (PCRYPT_PROVIDER_DATA) pProvData,
  915. 0, // first signer
  916. FALSE, //not counter signature
  917. 0); // index of counter sig, obviously not used
  918. if ( pProvSigner == NULL )
  919. {
  920. return(FALSE);
  921. }
  922. //
  923. // walk all certs, the leaf cert is index 0, the root is the last index
  924. //
  925. pCryptProviderCert = NULL;
  926. for ( i = 0; i < pProvSigner->csCertChain; i++ )
  927. {
  928. pCryptProviderCert = WTHelperGetProvCertFromChain(pProvSigner, i);
  929. if ( pCryptProviderCert == NULL )
  930. {
  931. // error
  932. }
  933. size = 20;
  934. if ( CertGetCertificateContextProperty(
  935. pCryptProviderCert->pCert,
  936. CERT_SHA1_HASH_PROP_ID,
  937. pArray,
  938. &size) )
  939. {
  940. /*
  941. printf("\nSH1 Hash (%u):{", size);
  942. for ( UINT index = 0; index < size; index++ )
  943. {
  944. printf("%s0x%02X", index == 0 ? " " : ", ", pArray[index]);
  945. }
  946. printf("}\n");
  947. */
  948. for ( UINT j = 0; j < NumberTestCerts; j++ )
  949. {
  950. if ( !memcmp(pArray, TestCertHashes[j], 20) )
  951. {
  952. // This cert is a test cert, not a real one, fail
  953. //printf("This file is signed by the testcert, and is therefor not trusted\n");
  954. //pritnf("please check the certification for this device");
  955. return (TRUE);
  956. }
  957. }
  958. }
  959. }
  960. return(FALSE);
  961. }