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.

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