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.

868 lines
32 KiB

  1. //
  2. // VERIFY.C
  3. //
  4. #include "sigverif.h"
  5. //
  6. // Find the file extension and place it in the lpFileNode->lpTypeName field
  7. //
  8. void MyGetFileTypeName(LPFILENODE lpFileInfo)
  9. {
  10. TCHAR szBuffer[MAX_PATH];
  11. TCHAR szBuffer2[MAX_PATH];
  12. TCHAR szExt[MAX_PATH];
  13. LPTSTR lpExtension;
  14. // Initialize szBuffer to be an empty string.
  15. szBuffer[0] = 0;
  16. // Walk to the end of lpFileName
  17. for(lpExtension = lpFileInfo->lpFileName; *lpExtension; lpExtension++);
  18. // Walk backwards until we hit a '.' and we'll use that as our extension
  19. for(lpExtension--; *lpExtension && lpExtension >= lpFileInfo->lpFileName; lpExtension--)
  20. {
  21. if (lpExtension[0] == TEXT('.'))
  22. {
  23. lstrcpy(szExt, lpExtension + 1);
  24. CharUpperBuff(szExt, lstrlen(szExt));
  25. MyLoadString(szBuffer2, IDS_FILETYPE);
  26. wsprintf(szBuffer, szBuffer2, szExt);
  27. }
  28. }
  29. // If there's no extension, then just call this a "File".
  30. if (szBuffer[0] == 0)
  31. {
  32. MyLoadString(szBuffer, IDS_FILE);
  33. }
  34. lpFileInfo->lpTypeName = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  35. if (lpFileInfo->lpTypeName)
  36. {
  37. lstrcpy(lpFileInfo->lpTypeName, szBuffer);
  38. }
  39. }
  40. //
  41. // Use SHGetFileInfo to get the icon index for the specified file.
  42. //
  43. void MyGetFileInfo(LPFILENODE lpFileInfo)
  44. {
  45. SHFILEINFO sfi;
  46. ZeroMemory(&sfi, sizeof(SHFILEINFO));
  47. SHGetFileInfo( lpFileInfo->lpFileName,
  48. 0,
  49. &sfi,
  50. sizeof(SHFILEINFO),
  51. SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_TYPENAME);
  52. lpFileInfo->iIcon = sfi.iIcon;
  53. if (*sfi.szTypeName)
  54. {
  55. lpFileInfo->lpTypeName = MALLOC((lstrlen(sfi.szTypeName) + 1) * sizeof(TCHAR));
  56. if (lpFileInfo->lpTypeName)
  57. {
  58. lstrcpy(lpFileInfo->lpTypeName, sfi.szTypeName);
  59. }
  60. } else {
  61. MyGetFileTypeName(lpFileInfo);
  62. }
  63. }
  64. void GetFileVersion(LPFILENODE lpFileInfo)
  65. {
  66. DWORD dwHandle, dwRet, dwLength;
  67. BOOL bRet;
  68. LPVOID lpData = NULL;
  69. LPVOID lpBuffer;
  70. VS_FIXEDFILEINFO *lpInfo;
  71. TCHAR szBuffer[MAX_PATH];
  72. TCHAR szBuffer2[MAX_PATH];
  73. dwRet = GetFileVersionInfoSize(lpFileInfo->lpFileName, &dwHandle);
  74. if (dwRet)
  75. {
  76. lpData = MALLOC(dwRet + 1);
  77. if (lpData)
  78. {
  79. bRet = GetFileVersionInfo(lpFileInfo->lpFileName, dwHandle, dwRet, lpData);
  80. if (bRet)
  81. {
  82. lpBuffer = NULL;
  83. dwLength = 0;
  84. bRet = VerQueryValue(lpData, TEXT("\\"), &lpBuffer, &dwLength);
  85. if (bRet)
  86. {
  87. lpInfo = (VS_FIXEDFILEINFO *) lpBuffer;
  88. MyLoadString(szBuffer2, IDS_VERSION);
  89. wsprintf(szBuffer, szBuffer2, HIWORD(lpInfo->dwFileVersionMS), LOWORD(lpInfo->dwFileVersionMS),
  90. HIWORD(lpInfo->dwFileVersionLS), LOWORD(lpInfo->dwFileVersionLS));
  91. lpFileInfo->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  92. if (lpFileInfo->lpVersion)
  93. {
  94. lstrcpy(lpFileInfo->lpVersion, szBuffer);
  95. }
  96. }
  97. }
  98. FREE(lpData);
  99. }
  100. }
  101. if (!lpFileInfo->lpVersion)
  102. {
  103. MyLoadString(szBuffer, IDS_NOVERSION);
  104. lpFileInfo->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  105. if (lpFileInfo->lpVersion)
  106. {
  107. lstrcpy(lpFileInfo->lpVersion, szBuffer);
  108. }
  109. }
  110. }
  111. /*************************************************************************
  112. * Function : VerifyIsFileSigned
  113. * Purpose : Calls WinVerifyTrust with Policy Provider GUID to
  114. * verify if an individual file is signed.
  115. **************************************************************************/
  116. BOOL VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo)
  117. {
  118. INT iRet;
  119. HRESULT hRes;
  120. WINTRUST_DATA WinTrustData;
  121. WINTRUST_FILE_INFO WinTrustFile;
  122. GUID gOSVerCheck = DRIVER_ACTION_VERIFY;
  123. GUID gPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  124. #ifndef UNICODE
  125. WCHAR wszFileName[MAX_PATH];
  126. #endif
  127. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  128. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  129. WinTrustData.dwUIChoice = WTD_UI_NONE;
  130. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  131. WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
  132. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  133. WinTrustData.pFile = &WinTrustFile;
  134. WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo;
  135. ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO));
  136. lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO);
  137. ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO));
  138. WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO);
  139. #ifndef UNICODE
  140. iRet = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, (LPWSTR)&wszFileName, cA(wszFileName));
  141. WinTrustFile.pcwszFilePath = wszFileName;
  142. #else
  143. WinTrustFile.pcwszFilePath = pcszMatchFile;
  144. #endif
  145. hRes = WinVerifyTrust(g_App.hDlg, &gOSVerCheck, &WinTrustData);
  146. if (hRes != ERROR_SUCCESS)
  147. hRes = WinVerifyTrust(g_App.hDlg, &gPublishedSoftware, &WinTrustData);
  148. //
  149. // Free the pcSignerCertContext member of the DRIVER_VER_INFO struct
  150. // that was allocated in our call to WinVerifyTrust.
  151. //
  152. if (lpVerInfo && lpVerInfo->pcSignerCertContext) {
  153. CertFreeCertificateContext(lpVerInfo->pcSignerCertContext);
  154. lpVerInfo->pcSignerCertContext = NULL;
  155. }
  156. return (hRes == ERROR_SUCCESS);
  157. }
  158. //
  159. // Given a specific LPFILENODE, verify that the file is signed or unsigned.
  160. // Fill in all the necessary structures so the listview control can display properly.
  161. //
  162. BOOL VerifyFileNode(LPFILENODE lpFileNode)
  163. {
  164. HANDLE hFile;
  165. BOOL bRet;
  166. HCATINFO hCatInfo = NULL;
  167. HCATINFO PrevCat;
  168. WINTRUST_DATA WinTrustData;
  169. WINTRUST_CATALOG_INFO WinTrustCatalogInfo;
  170. DRIVER_VER_INFO VerInfo;
  171. GUID gSubSystemDriver = DRIVER_ACTION_VERIFY;
  172. HRESULT hRes;
  173. DWORD cbHash = HASH_SIZE;
  174. BYTE szHash[HASH_SIZE];
  175. LPBYTE lpHash = szHash;
  176. CATALOG_INFO CatInfo;
  177. LPTSTR lpFilePart;
  178. TCHAR szBuffer[MAX_PATH];
  179. static TCHAR szCurrentDirectory[MAX_PATH];
  180. #ifndef UNICODE
  181. WCHAR UnicodeKey[MAX_PATH];
  182. #endif
  183. // If this is the first item we are verifying, then initialize the static buffer.
  184. if (lpFileNode == g_App.lpFileList)
  185. {
  186. ZeroMemory(szCurrentDirectory, sizeof(szCurrentDirectory));
  187. }
  188. //
  189. // Check the current directory against the one in the lpFileNode.
  190. // We only want to call SetCurrentDirectory if the path is different.
  191. //
  192. if (lstrcmp(szCurrentDirectory, lpFileNode->lpDirName))
  193. {
  194. if (!SetCurrentDirectory(lpFileNode->lpDirName))
  195. return FALSE;
  196. lstrcpy(szCurrentDirectory, lpFileNode->lpDirName);
  197. }
  198. //
  199. // Get the handle to the file, so we can call CryptCATAdminCalcHashFromFileHandle
  200. //
  201. hFile = CreateFile( lpFileNode->lpFileName,
  202. GENERIC_READ,
  203. FILE_SHARE_READ | FILE_SHARE_WRITE,
  204. NULL,
  205. OPEN_EXISTING,
  206. FILE_ATTRIBUTE_NORMAL,
  207. NULL);
  208. if (hFile == INVALID_HANDLE_VALUE)
  209. {
  210. return FALSE;
  211. }
  212. // Initialize the hash buffer
  213. ZeroMemory(lpHash, HASH_SIZE);
  214. // Generate the hash from the file handle and store it in lpHash
  215. if (!CryptCATAdminCalcHashFromFileHandle(hFile, &cbHash, lpHash, 0))
  216. {
  217. //
  218. // If we couldn't generate a hash, it might be an individually signed catalog.
  219. // If it's a catalog, zero out lpHash and cbHash so we know there's no hash to check.
  220. //
  221. if (IsCatalogFile(hFile, NULL))
  222. {
  223. lpHash = NULL;
  224. cbHash = 0;
  225. }
  226. else // If it wasn't a catalog, we'll bail and this file will show up as unscanned.
  227. {
  228. CloseHandle(hFile);
  229. return FALSE;
  230. }
  231. }
  232. // Close the file handle
  233. CloseHandle(hFile);
  234. //
  235. // Now we have the file's hash. Initialize the structures that
  236. // will be used later on in calls to WinVerifyTrust.
  237. //
  238. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  239. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  240. WinTrustData.dwUIChoice = WTD_UI_NONE;
  241. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  242. WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG;
  243. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  244. WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo;
  245. ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO));
  246. VerInfo.cbStruct = sizeof(DRIVER_VER_INFO);
  247. WinTrustData.pCatalog = &WinTrustCatalogInfo;
  248. ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO));
  249. WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  250. WinTrustCatalogInfo.pbCalculatedFileHash = lpHash;
  251. WinTrustCatalogInfo.cbCalculatedFileHash = cbHash;
  252. #ifdef UNICODE
  253. WinTrustCatalogInfo.pcwszMemberTag = lpFileNode->lpFileName;
  254. #else
  255. MultiByteToWideChar(CP_ACP, 0, lpFileNode->lpFileName, -1, UnicodeKey, cA(UnicodeKey));
  256. WinTrustCatalogInfo.pcwszMemberTag = UnicodeKey;
  257. #endif
  258. //
  259. // Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash
  260. //
  261. PrevCat = NULL;
  262. hCatInfo = CryptCATAdminEnumCatalogFromHash(g_App.hCatAdmin, lpHash, cbHash, 0, &PrevCat);
  263. //
  264. // We want to cycle through the matching catalogs until we find one that matches both hash and member tag
  265. //
  266. bRet = FALSE;
  267. while(hCatInfo && !bRet)
  268. {
  269. ZeroMemory(&CatInfo, sizeof(CATALOG_INFO));
  270. CatInfo.cbStruct = sizeof(CATALOG_INFO);
  271. if(CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0))
  272. {
  273. WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
  274. // Now verify that the file is an actual member of the catalog.
  275. hRes = WinVerifyTrust(g_App.hDlg, &gSubSystemDriver, &WinTrustData);
  276. if (hRes == ERROR_SUCCESS)
  277. {
  278. #ifdef UNICODE
  279. GetFullPathName(CatInfo.wszCatalogFile, MAX_PATH, szBuffer, &lpFilePart);
  280. #else
  281. WideCharToMultiByte(CP_ACP, 0, CatInfo.wszCatalogFile, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  282. GetFullPathName(szBuffer, MAX_PATH, szBuffer, &lpFilePart);
  283. #endif
  284. lpFileNode->lpCatalog = MALLOC((lstrlen(lpFilePart) + 1) * sizeof(TCHAR));
  285. if (lpFileNode->lpCatalog) {
  286. lstrcpy(lpFileNode->lpCatalog, lpFilePart);
  287. }
  288. bRet = TRUE;
  289. }
  290. //
  291. // Free the pcSignerCertContext member of the DRIVER_VER_INFO struct
  292. // that was allocated in our call to WinVerifyTrust.
  293. //
  294. if (VerInfo.pcSignerCertContext != NULL) {
  295. CertFreeCertificateContext(VerInfo.pcSignerCertContext);
  296. VerInfo.pcSignerCertContext = NULL;
  297. }
  298. }
  299. if (!bRet)
  300. {
  301. // The hash was in this catalog, but the file wasn't a member... so off to the next catalog
  302. PrevCat = hCatInfo;
  303. hCatInfo = CryptCATAdminEnumCatalogFromHash(g_App.hCatAdmin, lpHash, cbHash, 0, &PrevCat);
  304. }
  305. }
  306. // Mark this file as having been scanned.
  307. lpFileNode->bScanned = TRUE;
  308. if (!hCatInfo)
  309. {
  310. //
  311. // If it wasn't found in the catalogs, check if the file is individually signed.
  312. //
  313. bRet = VerifyIsFileSigned(lpFileNode->lpFileName, (PDRIVER_VER_INFO) &VerInfo);
  314. if (bRet)
  315. {
  316. // If so, mark the file as being signed.
  317. lpFileNode->bSigned = TRUE;
  318. }
  319. }
  320. else
  321. {
  322. // The file was verified in the catalogs, so mark it as signed and free the catalog context.
  323. lpFileNode->bSigned = TRUE;
  324. CryptCATAdminReleaseCatalogContext(g_App.hCatAdmin, hCatInfo, 0);
  325. }
  326. if (lpFileNode->bSigned)
  327. {
  328. #ifdef UNICODE
  329. lpFileNode->lpVersion = MALLOC((lstrlen(VerInfo.wszVersion) + 1) * sizeof(TCHAR));
  330. if (lpFileNode->lpVersion)
  331. {
  332. lstrcpy(lpFileNode->lpVersion, VerInfo.wszVersion);
  333. }
  334. lpFileNode->lpSignedBy = MALLOC((lstrlen(VerInfo.wszSignedBy) + 1) * sizeof(TCHAR));
  335. if (lpFileNode->lpSignedBy)
  336. {
  337. lstrcpy(lpFileNode->lpSignedBy, VerInfo.wszSignedBy);
  338. }
  339. #else
  340. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszVersion, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  341. lpFileNode->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  342. if (lpFileNode->lpVersion)
  343. {
  344. lstrcpy(lpFileNode->lpVersion, szBuffer);
  345. }
  346. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszSignedBy, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  347. lpFileNode->lpSignedBy = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  348. if (lpFileNode->lpSignedBy)
  349. {
  350. lstrcpy(lpFileNode->lpSignedBy, szBuffer);
  351. }
  352. #endif
  353. }
  354. else
  355. {
  356. //
  357. // Get the icon (if the file isn't signed) so we can display it in the listview faster.
  358. //
  359. MyGetFileInfo(lpFileNode);
  360. }
  361. return lpFileNode->bSigned;
  362. }
  363. //
  364. // This function loops through g_App.lpFileList to verify each file. We want to make this loop as tight
  365. // as possible and keep the progress bar updating as we go. When we are done, we want to pop up a
  366. // dialog that allows the user to choose "Details" which will give them the listview control.
  367. //
  368. BOOL VerifyFileList(void)
  369. {
  370. LPFILENODE lpFileNode;
  371. DWORD dwCount = 0;
  372. DWORD dwPercent = 0;
  373. DWORD dwCurrent = 0;
  374. TCHAR szBuffer[MAX_PATH];
  375. TCHAR szBuffer2[MAX_PATH];
  376. LPTSTR lpString;
  377. DWORD dwBytesWritten;
  378. HANDLE hSigverif = INVALID_HANDLE_VALUE;
  379. HANDLE hTotals = INVALID_HANDLE_VALUE;
  380. HANDLE hFileSigned = INVALID_HANDLE_VALUE;
  381. HANDLE hFileUnsigned = INVALID_HANDLE_VALUE;
  382. HANDLE hFileUnscanned = INVALID_HANDLE_VALUE;
  383. INT iRet;
  384. // Initialize the signed and unsigned counts
  385. g_App.dwSigned = 0;
  386. g_App.dwUnsigned = 0;
  387. // If we don't already have an g_App.hCatAdmin handle, acquire one.
  388. if (!g_App.hCatAdmin)
  389. {
  390. CryptCATAdminAcquireContext(&g_App.hCatAdmin, NULL, 0);
  391. }
  392. //
  393. // If the user specified test switches, then we want to open log files to record
  394. // the scanning results as they happen. SIGVERIF.TXT has every file before it is
  395. // scanned (in case of a fault), SIGNED.TXT gets signed files, UNSIGNED.TXT gets
  396. // unsigned files, UNSCANNED.TXT gets everything else. TOTALS.TXT was added last
  397. // and gets the text from the status window on the results dialog.
  398. //
  399. if (g_App.bLogToRoot)
  400. {
  401. if (*g_App.szLogDir)
  402. {
  403. lstrcpy(szBuffer, g_App.szLogDir);
  404. lstrcat(szBuffer, TEXT("\\"));
  405. }
  406. else
  407. {
  408. MyGetWindowsDirectory(szBuffer, MAX_PATH);
  409. szBuffer[3] = 0;
  410. }
  411. lstrcat(szBuffer, TEXT("SIGVERIF.CSV"));
  412. hSigverif = CreateFile( szBuffer,
  413. GENERIC_READ | GENERIC_WRITE,
  414. FILE_SHARE_READ,
  415. NULL,
  416. CREATE_ALWAYS,
  417. FILE_ATTRIBUTE_NORMAL,
  418. NULL);
  419. SetFilePointer(hSigverif, 0, NULL, FILE_BEGIN);
  420. SetEndOfFile(hSigverif);
  421. if (*g_App.szLogDir)
  422. {
  423. lstrcpy(szBuffer, g_App.szLogDir);
  424. lstrcat(szBuffer, TEXT("\\"));
  425. }
  426. else
  427. {
  428. MyGetWindowsDirectory(szBuffer, MAX_PATH);
  429. szBuffer[3] = 0;
  430. }
  431. lstrcat(szBuffer, TEXT("TOTALS.TXT"));
  432. hTotals = CreateFile( szBuffer,
  433. GENERIC_READ | GENERIC_WRITE,
  434. FILE_SHARE_READ,
  435. NULL,
  436. CREATE_ALWAYS,
  437. FILE_ATTRIBUTE_NORMAL,
  438. NULL);
  439. SetFilePointer(hTotals, 0, NULL, FILE_BEGIN);
  440. SetEndOfFile(hTotals);
  441. if (*g_App.szLogDir)
  442. {
  443. lstrcpy(szBuffer, g_App.szLogDir);
  444. lstrcat(szBuffer, TEXT("\\"));
  445. }
  446. else
  447. {
  448. MyGetWindowsDirectory(szBuffer, MAX_PATH);
  449. szBuffer[3] = 0;
  450. }
  451. lstrcat(szBuffer, TEXT("SIGNED.CSV"));
  452. hFileSigned = CreateFile( szBuffer,
  453. GENERIC_READ | GENERIC_WRITE,
  454. FILE_SHARE_READ,
  455. NULL,
  456. CREATE_ALWAYS,
  457. FILE_ATTRIBUTE_NORMAL,
  458. NULL);
  459. SetFilePointer(hFileSigned, 0, NULL, FILE_BEGIN);
  460. SetEndOfFile(hFileSigned);
  461. if (*g_App.szLogDir)
  462. {
  463. lstrcpy(szBuffer, g_App.szLogDir);
  464. lstrcat(szBuffer, TEXT("\\"));
  465. }
  466. else
  467. {
  468. MyGetWindowsDirectory(szBuffer, MAX_PATH);
  469. szBuffer[3] = 0;
  470. }
  471. lstrcat(szBuffer, TEXT("UNSIGNED.CSV"));
  472. hFileUnsigned = CreateFile( szBuffer,
  473. GENERIC_READ | GENERIC_WRITE,
  474. FILE_SHARE_READ,
  475. NULL,
  476. CREATE_ALWAYS,
  477. FILE_ATTRIBUTE_NORMAL,
  478. NULL);
  479. SetFilePointer(hFileUnsigned, 0, NULL, FILE_BEGIN);
  480. SetEndOfFile(hFileUnsigned);
  481. if (*g_App.szLogDir)
  482. {
  483. lstrcpy(szBuffer, g_App.szLogDir);
  484. lstrcat(szBuffer, TEXT("\\"));
  485. }
  486. else
  487. {
  488. MyGetWindowsDirectory(szBuffer, MAX_PATH);
  489. szBuffer[3] = 0;
  490. }
  491. lstrcat(szBuffer, TEXT("UNSCANNED.CSV"));
  492. hFileUnscanned = CreateFile( szBuffer,
  493. GENERIC_READ | GENERIC_WRITE,
  494. FILE_SHARE_READ,
  495. NULL,
  496. CREATE_ALWAYS,
  497. FILE_ATTRIBUTE_NORMAL,
  498. NULL);
  499. SetFilePointer(hFileUnscanned, 0, NULL, FILE_BEGIN);
  500. SetEndOfFile(hFileUnscanned);
  501. #ifdef UNICODE
  502. // If we are using UNICODE, then write the 0xFF and 0xFE bytes at the beginning of the file.
  503. ZeroMemory(szBuffer, sizeof(szBuffer));
  504. szBuffer[0] = 0xFEFF;
  505. WriteFile(hSigverif, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL);
  506. WriteFile(hTotals, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL);
  507. WriteFile(hFileSigned, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL);
  508. WriteFile(hFileUnsigned, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL);
  509. WriteFile(hFileUnscanned, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL);
  510. #endif
  511. }
  512. //
  513. // Start looping through each file and update the progress bar if we cross a percentage boundary.
  514. //
  515. for(lpFileNode=g_App.lpFileList;lpFileNode && !g_App.bStopScan;lpFileNode=lpFileNode->next,dwCount++)
  516. {
  517. // Figure out the current percentage and update if it has increased.
  518. dwPercent = (dwCount * 100) / g_App.dwFiles;
  519. if (dwPercent > dwCurrent)
  520. {
  521. dwCurrent = dwPercent;
  522. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) dwCurrent, (LPARAM) 0);
  523. }
  524. // Here's the call to VerifyFileNode!
  525. VerifyFileNode(lpFileNode);
  526. // In case something went wrong, make sure the version information gets filled in.
  527. if (!lpFileNode->lpVersion)
  528. {
  529. GetFileVersion(lpFileNode);
  530. }
  531. // Log the current file to hSigverif, in case something bad happens.
  532. if (g_App.bLogToRoot && hSigverif != INVALID_HANDLE_VALUE)
  533. {
  534. *szBuffer = '\0';
  535. wsprintf(szBuffer, lpFileNode->lpFileName);
  536. lstrcat(szBuffer, TEXT(","));
  537. WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  538. *szBuffer = '\0';
  539. GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL);
  540. lstrcat(szBuffer, TEXT(","));
  541. WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  542. *szBuffer = '\0';
  543. // Get the date format, so we are localizable...
  544. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  545. DATE_SHORTDATE,
  546. &lpFileNode->LastModified,
  547. NULL,
  548. NULL,
  549. 0);
  550. if (iRet)
  551. {
  552. lpString = MALLOC((iRet + 1) * sizeof(TCHAR));
  553. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  554. DATE_SHORTDATE,
  555. &lpFileNode->LastModified,
  556. NULL,
  557. lpString,
  558. iRet);
  559. if (iRet)
  560. {
  561. lstrcpy(szBuffer, lpString);
  562. }
  563. FREE(lpString);
  564. }
  565. lstrcat(szBuffer, TEXT(","));
  566. WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  567. *szBuffer = '\0';
  568. lstrcpy(szBuffer, lpFileNode->lpVersion);
  569. WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  570. MyLoadString(szBuffer, IDS_LINEFEED);
  571. WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  572. FlushFileBuffers(hSigverif);
  573. }
  574. if (lpFileNode->bScanned)
  575. {
  576. // If the file was signed, increment the g_App.dwSigned or g_App.dwUnsigned counter.
  577. if (lpFileNode->bSigned)
  578. {
  579. g_App.dwSigned++;
  580. if (g_App.bLogToRoot && hFileSigned != INVALID_HANDLE_VALUE)
  581. {
  582. *szBuffer = '\0';
  583. wsprintf(szBuffer, lpFileNode->lpFileName);
  584. lstrcat(szBuffer, TEXT(","));
  585. WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  586. *szBuffer = '\0';
  587. GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL);
  588. lstrcat(szBuffer, TEXT(","));
  589. WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  590. *szBuffer = '\0';
  591. // Get the date format, so we are localizable...
  592. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  593. DATE_SHORTDATE,
  594. &lpFileNode->LastModified,
  595. NULL,
  596. NULL,
  597. 0);
  598. if (iRet)
  599. {
  600. lpString = MALLOC((iRet + 1) * sizeof(TCHAR));
  601. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  602. DATE_SHORTDATE,
  603. &lpFileNode->LastModified,
  604. NULL,
  605. lpString,
  606. iRet);
  607. if (iRet)
  608. {
  609. lstrcpy(szBuffer, lpString);
  610. }
  611. FREE(lpString);
  612. }
  613. lstrcat(szBuffer, TEXT(","));
  614. WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  615. *szBuffer = '\0';
  616. lstrcpy(szBuffer, lpFileNode->lpVersion);
  617. WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  618. MyLoadString(szBuffer, IDS_LINEFEED);
  619. WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  620. FlushFileBuffers(hFileSigned);
  621. }
  622. }
  623. else
  624. {
  625. g_App.dwUnsigned++;
  626. if (g_App.bLogToRoot && hFileUnsigned != INVALID_HANDLE_VALUE)
  627. {
  628. *szBuffer = '\0';
  629. wsprintf(szBuffer, lpFileNode->lpFileName);
  630. lstrcat(szBuffer, TEXT(","));
  631. WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  632. *szBuffer = '\0';
  633. GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL);
  634. lstrcat(szBuffer, TEXT(","));
  635. WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  636. *szBuffer = '\0';
  637. // Get the date format, so we are localizable...
  638. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  639. DATE_SHORTDATE,
  640. &lpFileNode->LastModified,
  641. NULL,
  642. NULL,
  643. 0);
  644. if (iRet)
  645. {
  646. lpString = MALLOC((iRet + 1) * sizeof(TCHAR));
  647. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  648. DATE_SHORTDATE,
  649. &lpFileNode->LastModified,
  650. NULL,
  651. lpString,
  652. iRet);
  653. if (iRet)
  654. {
  655. lstrcpy(szBuffer, lpString);
  656. }
  657. FREE(lpString);
  658. }
  659. lstrcat(szBuffer, TEXT(","));
  660. WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  661. *szBuffer = '\0';
  662. lstrcpy(szBuffer, lpFileNode->lpVersion);
  663. WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  664. MyLoadString(szBuffer, IDS_LINEFEED);
  665. WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  666. FlushFileBuffers(hFileUnsigned);
  667. }
  668. }
  669. }
  670. else
  671. {
  672. if (g_App.bLogToRoot && hFileUnscanned != INVALID_HANDLE_VALUE)
  673. {
  674. *szBuffer = '\0';
  675. wsprintf(szBuffer, lpFileNode->lpFileName);
  676. lstrcat(szBuffer, TEXT(","));
  677. WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  678. *szBuffer = '\0';
  679. GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL);
  680. lstrcat(szBuffer, TEXT(","));
  681. WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  682. *szBuffer = '\0';
  683. // Get the date format, so we are localizable...
  684. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  685. DATE_SHORTDATE,
  686. &lpFileNode->LastModified,
  687. NULL,
  688. NULL,
  689. 0);
  690. if (iRet)
  691. {
  692. lpString = MALLOC((iRet + 1) * sizeof(TCHAR));
  693. iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  694. DATE_SHORTDATE,
  695. &lpFileNode->LastModified,
  696. NULL,
  697. lpString,
  698. iRet);
  699. if (iRet)
  700. {
  701. lstrcpy(szBuffer, lpString);
  702. }
  703. FREE(lpString);
  704. }
  705. lstrcat(szBuffer, TEXT(","));
  706. WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  707. *szBuffer = '\0';
  708. lstrcpy(szBuffer, lpFileNode->lpVersion);
  709. WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  710. MyLoadString(szBuffer, IDS_LINEFEED);
  711. WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL);
  712. FlushFileBuffers(hFileUnscanned);
  713. }
  714. }
  715. }
  716. if (g_App.bLogToRoot)
  717. {
  718. // Load the status string and fill it in with the correct values.
  719. MyLoadString(szBuffer, IDS_NUMFILES);
  720. wsprintf(szBuffer2, szBuffer, g_App.dwFiles, g_App.dwSigned, g_App.dwUnsigned,
  721. g_App.dwFiles - g_App.dwSigned - g_App.dwUnsigned);
  722. WriteFile(hTotals, szBuffer2, lstrlen(szBuffer2) * sizeof(TCHAR), &dwBytesWritten, NULL);
  723. if (hTotals != INVALID_HANDLE_VALUE)
  724. CloseHandle(hTotals);
  725. if (hSigverif != INVALID_HANDLE_VALUE)
  726. CloseHandle(hSigverif);
  727. if (hFileSigned != INVALID_HANDLE_VALUE)
  728. CloseHandle(hFileSigned);
  729. if (hFileUnsigned != INVALID_HANDLE_VALUE)
  730. CloseHandle(hFileUnsigned);
  731. if (hFileUnsigned != INVALID_HANDLE_VALUE)
  732. CloseHandle(hFileUnscanned);
  733. }
  734. // If we had an g_App.hCatAdmin, free it and set it to zero so we can acquire a new one in the future.
  735. if (g_App.hCatAdmin)
  736. {
  737. CryptCATAdminReleaseContext(g_App.hCatAdmin,0);
  738. g_App.hCatAdmin = NULL;
  739. }
  740. if (!g_App.bStopScan && !g_App.bFullSystemScan)
  741. {
  742. // If the user never clicked STOP, then make sure the progress bar hits 100%
  743. if (!g_App.bStopScan)
  744. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 100, (LPARAM) 0);
  745. if (!g_App.dwUnsigned)
  746. {
  747. // If there weren't any unsigned files, then we want to tell the user that everything is dandy!
  748. if (g_App.dwSigned)
  749. MyMessageBoxId(IDS_ALLSIGNED);
  750. else MyMessageBoxId(IDS_NOPROBLEMS);
  751. }
  752. else
  753. {
  754. // Show the user the results by going directly to IDD_RESULTS
  755. DialogBox(g_App.hInstance, MAKEINTRESOURCE(IDD_RESULTS), g_App.hDlg, ListView_DlgProc);
  756. }
  757. }
  758. return TRUE;
  759. }