// // VERIFY.C // #include "sigverif.h" // // Find the file extension and place it in the lpFileNode->lpTypeName field // void MyGetFileTypeName(LPFILENODE lpFileInfo) { TCHAR szBuffer[MAX_PATH]; TCHAR szBuffer2[MAX_PATH]; TCHAR szExt[MAX_PATH]; LPTSTR lpExtension; // Initialize szBuffer to be an empty string. szBuffer[0] = 0; // Walk to the end of lpFileName for(lpExtension = lpFileInfo->lpFileName; *lpExtension; lpExtension++); // Walk backwards until we hit a '.' and we'll use that as our extension for(lpExtension--; *lpExtension && lpExtension >= lpFileInfo->lpFileName; lpExtension--) { if (lpExtension[0] == TEXT('.')) { lstrcpy(szExt, lpExtension + 1); CharUpperBuff(szExt, lstrlen(szExt)); MyLoadString(szBuffer2, IDS_FILETYPE); wsprintf(szBuffer, szBuffer2, szExt); } } // If there's no extension, then just call this a "File". if (szBuffer[0] == 0) { MyLoadString(szBuffer, IDS_FILE); } lpFileInfo->lpTypeName = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR)); if (lpFileInfo->lpTypeName) { lstrcpy(lpFileInfo->lpTypeName, szBuffer); } } // // Use SHGetFileInfo to get the icon index for the specified file. // void MyGetFileInfo(LPFILENODE lpFileInfo) { SHFILEINFO sfi; ZeroMemory(&sfi, sizeof(SHFILEINFO)); SHGetFileInfo( lpFileInfo->lpFileName, 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_TYPENAME); lpFileInfo->iIcon = sfi.iIcon; if (*sfi.szTypeName) { lpFileInfo->lpTypeName = MALLOC((lstrlen(sfi.szTypeName) + 1) * sizeof(TCHAR)); if (lpFileInfo->lpTypeName) { lstrcpy(lpFileInfo->lpTypeName, sfi.szTypeName); } } else { MyGetFileTypeName(lpFileInfo); } } void GetFileVersion(LPFILENODE lpFileInfo) { DWORD dwHandle, dwRet, dwLength; BOOL bRet; LPVOID lpData = NULL; LPVOID lpBuffer; VS_FIXEDFILEINFO *lpInfo; TCHAR szBuffer[MAX_PATH]; TCHAR szBuffer2[MAX_PATH]; dwRet = GetFileVersionInfoSize(lpFileInfo->lpFileName, &dwHandle); if (dwRet) { lpData = MALLOC(dwRet + 1); if (lpData) { bRet = GetFileVersionInfo(lpFileInfo->lpFileName, dwHandle, dwRet, lpData); if (bRet) { lpBuffer = NULL; dwLength = 0; bRet = VerQueryValue(lpData, TEXT("\\"), &lpBuffer, &dwLength); if (bRet) { lpInfo = (VS_FIXEDFILEINFO *) lpBuffer; MyLoadString(szBuffer2, IDS_VERSION); wsprintf(szBuffer, szBuffer2, HIWORD(lpInfo->dwFileVersionMS), LOWORD(lpInfo->dwFileVersionMS), HIWORD(lpInfo->dwFileVersionLS), LOWORD(lpInfo->dwFileVersionLS)); lpFileInfo->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR)); if (lpFileInfo->lpVersion) { lstrcpy(lpFileInfo->lpVersion, szBuffer); } } } FREE(lpData); } } if (!lpFileInfo->lpVersion) { MyLoadString(szBuffer, IDS_NOVERSION); lpFileInfo->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR)); if (lpFileInfo->lpVersion) { lstrcpy(lpFileInfo->lpVersion, szBuffer); } } } /************************************************************************* * Function : VerifyIsFileSigned * Purpose : Calls WinVerifyTrust with Policy Provider GUID to * verify if an individual file is signed. **************************************************************************/ BOOL VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo) { INT iRet; HRESULT hRes; WINTRUST_DATA WinTrustData; WINTRUST_FILE_INFO WinTrustFile; GUID gOSVerCheck = DRIVER_ACTION_VERIFY; GUID gPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2; #ifndef UNICODE WCHAR wszFileName[MAX_PATH]; #endif ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA)); WinTrustData.cbStruct = sizeof(WINTRUST_DATA); WinTrustData.dwUIChoice = WTD_UI_NONE; WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; WinTrustData.dwUnionChoice = WTD_CHOICE_FILE; WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE; WinTrustData.pFile = &WinTrustFile; WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo; ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO)); lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO); ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO)); WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO); #ifndef UNICODE iRet = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, (LPWSTR)&wszFileName, cA(wszFileName)); WinTrustFile.pcwszFilePath = wszFileName; #else WinTrustFile.pcwszFilePath = pcszMatchFile; #endif hRes = WinVerifyTrust(g_App.hDlg, &gOSVerCheck, &WinTrustData); if (hRes != ERROR_SUCCESS) hRes = WinVerifyTrust(g_App.hDlg, &gPublishedSoftware, &WinTrustData); // // Free the pcSignerCertContext member of the DRIVER_VER_INFO struct // that was allocated in our call to WinVerifyTrust. // if (lpVerInfo && lpVerInfo->pcSignerCertContext) { CertFreeCertificateContext(lpVerInfo->pcSignerCertContext); lpVerInfo->pcSignerCertContext = NULL; } return (hRes == ERROR_SUCCESS); } // // Given a specific LPFILENODE, verify that the file is signed or unsigned. // Fill in all the necessary structures so the listview control can display properly. // BOOL VerifyFileNode(LPFILENODE lpFileNode) { HANDLE hFile; BOOL bRet; HCATINFO hCatInfo = NULL; HCATINFO PrevCat; WINTRUST_DATA WinTrustData; WINTRUST_CATALOG_INFO WinTrustCatalogInfo; DRIVER_VER_INFO VerInfo; GUID gSubSystemDriver = DRIVER_ACTION_VERIFY; HRESULT hRes; DWORD cbHash = HASH_SIZE; BYTE szHash[HASH_SIZE]; LPBYTE lpHash = szHash; CATALOG_INFO CatInfo; LPTSTR lpFilePart; TCHAR szBuffer[MAX_PATH]; static TCHAR szCurrentDirectory[MAX_PATH]; #ifndef UNICODE WCHAR UnicodeKey[MAX_PATH]; #endif // If this is the first item we are verifying, then initialize the static buffer. if (lpFileNode == g_App.lpFileList) { ZeroMemory(szCurrentDirectory, sizeof(szCurrentDirectory)); } // // Check the current directory against the one in the lpFileNode. // We only want to call SetCurrentDirectory if the path is different. // if (lstrcmp(szCurrentDirectory, lpFileNode->lpDirName)) { if (!SetCurrentDirectory(lpFileNode->lpDirName)) return FALSE; lstrcpy(szCurrentDirectory, lpFileNode->lpDirName); } // // Get the handle to the file, so we can call CryptCATAdminCalcHashFromFileHandle // hFile = CreateFile( lpFileNode->lpFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return FALSE; } // Initialize the hash buffer ZeroMemory(lpHash, HASH_SIZE); // Generate the hash from the file handle and store it in lpHash if (!CryptCATAdminCalcHashFromFileHandle(hFile, &cbHash, lpHash, 0)) { // // If we couldn't generate a hash, it might be an individually signed catalog. // If it's a catalog, zero out lpHash and cbHash so we know there's no hash to check. // if (IsCatalogFile(hFile, NULL)) { lpHash = NULL; cbHash = 0; } else // If it wasn't a catalog, we'll bail and this file will show up as unscanned. { CloseHandle(hFile); return FALSE; } } // Close the file handle CloseHandle(hFile); // // Now we have the file's hash. Initialize the structures that // will be used later on in calls to WinVerifyTrust. // ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA)); WinTrustData.cbStruct = sizeof(WINTRUST_DATA); WinTrustData.dwUIChoice = WTD_UI_NONE; WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG; WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE; WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo; ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO)); VerInfo.cbStruct = sizeof(DRIVER_VER_INFO); WinTrustData.pCatalog = &WinTrustCatalogInfo; ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO)); WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO); WinTrustCatalogInfo.pbCalculatedFileHash = lpHash; WinTrustCatalogInfo.cbCalculatedFileHash = cbHash; #ifdef UNICODE WinTrustCatalogInfo.pcwszMemberTag = lpFileNode->lpFileName; #else MultiByteToWideChar(CP_ACP, 0, lpFileNode->lpFileName, -1, UnicodeKey, cA(UnicodeKey)); WinTrustCatalogInfo.pcwszMemberTag = UnicodeKey; #endif // // Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash // PrevCat = NULL; hCatInfo = CryptCATAdminEnumCatalogFromHash(g_App.hCatAdmin, lpHash, cbHash, 0, &PrevCat); // // We want to cycle through the matching catalogs until we find one that matches both hash and member tag // bRet = FALSE; while(hCatInfo && !bRet) { ZeroMemory(&CatInfo, sizeof(CATALOG_INFO)); CatInfo.cbStruct = sizeof(CATALOG_INFO); if(CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0)) { WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile; // Now verify that the file is an actual member of the catalog. hRes = WinVerifyTrust(g_App.hDlg, &gSubSystemDriver, &WinTrustData); if (hRes == ERROR_SUCCESS) { #ifdef UNICODE GetFullPathName(CatInfo.wszCatalogFile, MAX_PATH, szBuffer, &lpFilePart); #else WideCharToMultiByte(CP_ACP, 0, CatInfo.wszCatalogFile, -1, szBuffer, sizeof(szBuffer), NULL, NULL); GetFullPathName(szBuffer, MAX_PATH, szBuffer, &lpFilePart); #endif lpFileNode->lpCatalog = MALLOC((lstrlen(lpFilePart) + 1) * sizeof(TCHAR)); if (lpFileNode->lpCatalog) { lstrcpy(lpFileNode->lpCatalog, lpFilePart); } bRet = TRUE; } // // Free the pcSignerCertContext member of the DRIVER_VER_INFO struct // that was allocated in our call to WinVerifyTrust. // if (VerInfo.pcSignerCertContext != NULL) { CertFreeCertificateContext(VerInfo.pcSignerCertContext); VerInfo.pcSignerCertContext = NULL; } } if (!bRet) { // The hash was in this catalog, but the file wasn't a member... so off to the next catalog PrevCat = hCatInfo; hCatInfo = CryptCATAdminEnumCatalogFromHash(g_App.hCatAdmin, lpHash, cbHash, 0, &PrevCat); } } // Mark this file as having been scanned. lpFileNode->bScanned = TRUE; if (!hCatInfo) { // // If it wasn't found in the catalogs, check if the file is individually signed. // bRet = VerifyIsFileSigned(lpFileNode->lpFileName, (PDRIVER_VER_INFO) &VerInfo); if (bRet) { // If so, mark the file as being signed. lpFileNode->bSigned = TRUE; } } else { // The file was verified in the catalogs, so mark it as signed and free the catalog context. lpFileNode->bSigned = TRUE; CryptCATAdminReleaseCatalogContext(g_App.hCatAdmin, hCatInfo, 0); } if (lpFileNode->bSigned) { #ifdef UNICODE lpFileNode->lpVersion = MALLOC((lstrlen(VerInfo.wszVersion) + 1) * sizeof(TCHAR)); if (lpFileNode->lpVersion) { lstrcpy(lpFileNode->lpVersion, VerInfo.wszVersion); } lpFileNode->lpSignedBy = MALLOC((lstrlen(VerInfo.wszSignedBy) + 1) * sizeof(TCHAR)); if (lpFileNode->lpSignedBy) { lstrcpy(lpFileNode->lpSignedBy, VerInfo.wszSignedBy); } #else WideCharToMultiByte(CP_ACP, 0, VerInfo.wszVersion, -1, szBuffer, sizeof(szBuffer), NULL, NULL); lpFileNode->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR)); if (lpFileNode->lpVersion) { lstrcpy(lpFileNode->lpVersion, szBuffer); } WideCharToMultiByte(CP_ACP, 0, VerInfo.wszSignedBy, -1, szBuffer, sizeof(szBuffer), NULL, NULL); lpFileNode->lpSignedBy = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR)); if (lpFileNode->lpSignedBy) { lstrcpy(lpFileNode->lpSignedBy, szBuffer); } #endif } else { // // Get the icon (if the file isn't signed) so we can display it in the listview faster. // MyGetFileInfo(lpFileNode); } return lpFileNode->bSigned; } // // This function loops through g_App.lpFileList to verify each file. We want to make this loop as tight // as possible and keep the progress bar updating as we go. When we are done, we want to pop up a // dialog that allows the user to choose "Details" which will give them the listview control. // BOOL VerifyFileList(void) { LPFILENODE lpFileNode; DWORD dwCount = 0; DWORD dwPercent = 0; DWORD dwCurrent = 0; TCHAR szBuffer[MAX_PATH]; TCHAR szBuffer2[MAX_PATH]; LPTSTR lpString; DWORD dwBytesWritten; HANDLE hSigverif = INVALID_HANDLE_VALUE; HANDLE hTotals = INVALID_HANDLE_VALUE; HANDLE hFileSigned = INVALID_HANDLE_VALUE; HANDLE hFileUnsigned = INVALID_HANDLE_VALUE; HANDLE hFileUnscanned = INVALID_HANDLE_VALUE; INT iRet; // Initialize the signed and unsigned counts g_App.dwSigned = 0; g_App.dwUnsigned = 0; // If we don't already have an g_App.hCatAdmin handle, acquire one. if (!g_App.hCatAdmin) { CryptCATAdminAcquireContext(&g_App.hCatAdmin, NULL, 0); } // // If the user specified test switches, then we want to open log files to record // the scanning results as they happen. SIGVERIF.TXT has every file before it is // scanned (in case of a fault), SIGNED.TXT gets signed files, UNSIGNED.TXT gets // unsigned files, UNSCANNED.TXT gets everything else. TOTALS.TXT was added last // and gets the text from the status window on the results dialog. // if (g_App.bLogToRoot) { if (*g_App.szLogDir) { lstrcpy(szBuffer, g_App.szLogDir); lstrcat(szBuffer, TEXT("\\")); } else { MyGetWindowsDirectory(szBuffer, MAX_PATH); szBuffer[3] = 0; } lstrcat(szBuffer, TEXT("SIGVERIF.CSV")); hSigverif = CreateFile( szBuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hSigverif, 0, NULL, FILE_BEGIN); SetEndOfFile(hSigverif); if (*g_App.szLogDir) { lstrcpy(szBuffer, g_App.szLogDir); lstrcat(szBuffer, TEXT("\\")); } else { MyGetWindowsDirectory(szBuffer, MAX_PATH); szBuffer[3] = 0; } lstrcat(szBuffer, TEXT("TOTALS.TXT")); hTotals = CreateFile( szBuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hTotals, 0, NULL, FILE_BEGIN); SetEndOfFile(hTotals); if (*g_App.szLogDir) { lstrcpy(szBuffer, g_App.szLogDir); lstrcat(szBuffer, TEXT("\\")); } else { MyGetWindowsDirectory(szBuffer, MAX_PATH); szBuffer[3] = 0; } lstrcat(szBuffer, TEXT("SIGNED.CSV")); hFileSigned = CreateFile( szBuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hFileSigned, 0, NULL, FILE_BEGIN); SetEndOfFile(hFileSigned); if (*g_App.szLogDir) { lstrcpy(szBuffer, g_App.szLogDir); lstrcat(szBuffer, TEXT("\\")); } else { MyGetWindowsDirectory(szBuffer, MAX_PATH); szBuffer[3] = 0; } lstrcat(szBuffer, TEXT("UNSIGNED.CSV")); hFileUnsigned = CreateFile( szBuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hFileUnsigned, 0, NULL, FILE_BEGIN); SetEndOfFile(hFileUnsigned); if (*g_App.szLogDir) { lstrcpy(szBuffer, g_App.szLogDir); lstrcat(szBuffer, TEXT("\\")); } else { MyGetWindowsDirectory(szBuffer, MAX_PATH); szBuffer[3] = 0; } lstrcat(szBuffer, TEXT("UNSCANNED.CSV")); hFileUnscanned = CreateFile( szBuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hFileUnscanned, 0, NULL, FILE_BEGIN); SetEndOfFile(hFileUnscanned); #ifdef UNICODE // If we are using UNICODE, then write the 0xFF and 0xFE bytes at the beginning of the file. ZeroMemory(szBuffer, sizeof(szBuffer)); szBuffer[0] = 0xFEFF; WriteFile(hSigverif, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL); WriteFile(hTotals, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL); WriteFile(hFileSigned, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL); WriteFile(hFileUnsigned, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL); WriteFile(hFileUnscanned, szBuffer, sizeof(TCHAR), &dwBytesWritten, NULL); #endif } // // Start looping through each file and update the progress bar if we cross a percentage boundary. // for(lpFileNode=g_App.lpFileList;lpFileNode && !g_App.bStopScan;lpFileNode=lpFileNode->next,dwCount++) { // Figure out the current percentage and update if it has increased. dwPercent = (dwCount * 100) / g_App.dwFiles; if (dwPercent > dwCurrent) { dwCurrent = dwPercent; SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) dwCurrent, (LPARAM) 0); } // Here's the call to VerifyFileNode! VerifyFileNode(lpFileNode); // In case something went wrong, make sure the version information gets filled in. if (!lpFileNode->lpVersion) { GetFileVersion(lpFileNode); } // Log the current file to hSigverif, in case something bad happens. if (g_App.bLogToRoot && hSigverif != INVALID_HANDLE_VALUE) { *szBuffer = '\0'; wsprintf(szBuffer, lpFileNode->lpFileName); lstrcat(szBuffer, TEXT(",")); WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL); lstrcat(szBuffer, TEXT(",")); WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; // Get the date format, so we are localizable... iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, NULL, 0); if (iRet) { lpString = MALLOC((iRet + 1) * sizeof(TCHAR)); iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, lpString, iRet); if (iRet) { lstrcpy(szBuffer, lpString); } FREE(lpString); } lstrcat(szBuffer, TEXT(",")); WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; lstrcpy(szBuffer, lpFileNode->lpVersion); WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); MyLoadString(szBuffer, IDS_LINEFEED); WriteFile(hSigverif, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); FlushFileBuffers(hSigverif); } if (lpFileNode->bScanned) { // If the file was signed, increment the g_App.dwSigned or g_App.dwUnsigned counter. if (lpFileNode->bSigned) { g_App.dwSigned++; if (g_App.bLogToRoot && hFileSigned != INVALID_HANDLE_VALUE) { *szBuffer = '\0'; wsprintf(szBuffer, lpFileNode->lpFileName); lstrcat(szBuffer, TEXT(",")); WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL); lstrcat(szBuffer, TEXT(",")); WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; // Get the date format, so we are localizable... iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, NULL, 0); if (iRet) { lpString = MALLOC((iRet + 1) * sizeof(TCHAR)); iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, lpString, iRet); if (iRet) { lstrcpy(szBuffer, lpString); } FREE(lpString); } lstrcat(szBuffer, TEXT(",")); WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; lstrcpy(szBuffer, lpFileNode->lpVersion); WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); MyLoadString(szBuffer, IDS_LINEFEED); WriteFile(hFileSigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); FlushFileBuffers(hFileSigned); } } else { g_App.dwUnsigned++; if (g_App.bLogToRoot && hFileUnsigned != INVALID_HANDLE_VALUE) { *szBuffer = '\0'; wsprintf(szBuffer, lpFileNode->lpFileName); lstrcat(szBuffer, TEXT(",")); WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL); lstrcat(szBuffer, TEXT(",")); WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; // Get the date format, so we are localizable... iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, NULL, 0); if (iRet) { lpString = MALLOC((iRet + 1) * sizeof(TCHAR)); iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, lpString, iRet); if (iRet) { lstrcpy(szBuffer, lpString); } FREE(lpString); } lstrcat(szBuffer, TEXT(",")); WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; lstrcpy(szBuffer, lpFileNode->lpVersion); WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); MyLoadString(szBuffer, IDS_LINEFEED); WriteFile(hFileUnsigned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); FlushFileBuffers(hFileUnsigned); } } } else { if (g_App.bLogToRoot && hFileUnscanned != INVALID_HANDLE_VALUE) { *szBuffer = '\0'; wsprintf(szBuffer, lpFileNode->lpFileName); lstrcat(szBuffer, TEXT(",")); WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; GetFullPathName(lpFileNode->lpFileName, SIZECHARS(szBuffer), szBuffer, NULL); lstrcat(szBuffer, TEXT(",")); WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; // Get the date format, so we are localizable... iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, NULL, 0); if (iRet) { lpString = MALLOC((iRet + 1) * sizeof(TCHAR)); iRet = GetDateFormat( LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE, &lpFileNode->LastModified, NULL, lpString, iRet); if (iRet) { lstrcpy(szBuffer, lpString); } FREE(lpString); } lstrcat(szBuffer, TEXT(",")); WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); *szBuffer = '\0'; lstrcpy(szBuffer, lpFileNode->lpVersion); WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); MyLoadString(szBuffer, IDS_LINEFEED); WriteFile(hFileUnscanned, szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &dwBytesWritten, NULL); FlushFileBuffers(hFileUnscanned); } } } if (g_App.bLogToRoot) { // Load the status string and fill it in with the correct values. MyLoadString(szBuffer, IDS_NUMFILES); wsprintf(szBuffer2, szBuffer, g_App.dwFiles, g_App.dwSigned, g_App.dwUnsigned, g_App.dwFiles - g_App.dwSigned - g_App.dwUnsigned); WriteFile(hTotals, szBuffer2, lstrlen(szBuffer2) * sizeof(TCHAR), &dwBytesWritten, NULL); if (hTotals != INVALID_HANDLE_VALUE) CloseHandle(hTotals); if (hSigverif != INVALID_HANDLE_VALUE) CloseHandle(hSigverif); if (hFileSigned != INVALID_HANDLE_VALUE) CloseHandle(hFileSigned); if (hFileUnsigned != INVALID_HANDLE_VALUE) CloseHandle(hFileUnsigned); if (hFileUnsigned != INVALID_HANDLE_VALUE) CloseHandle(hFileUnscanned); } // If we had an g_App.hCatAdmin, free it and set it to zero so we can acquire a new one in the future. if (g_App.hCatAdmin) { CryptCATAdminReleaseContext(g_App.hCatAdmin,0); g_App.hCatAdmin = NULL; } if (!g_App.bStopScan && !g_App.bFullSystemScan) { // If the user never clicked STOP, then make sure the progress bar hits 100% if (!g_App.bStopScan) SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 100, (LPARAM) 0); if (!g_App.dwUnsigned) { // If there weren't any unsigned files, then we want to tell the user that everything is dandy! if (g_App.dwSigned) MyMessageBoxId(IDS_ALLSIGNED); else MyMessageBoxId(IDS_NOPROBLEMS); } else { // Show the user the results by going directly to IDD_RESULTS DialogBox(g_App.hInstance, MAKEINTRESOURCE(IDD_RESULTS), g_App.hDlg, ListView_DlgProc); } } return TRUE; }