BOOL IsDriverWHQL(LPWSTR szFileName) { WCHAR szCatFile[MAX_PATH]; HANDLE hCat; BOOL bRet = FALSE; /* get the driver's cat file */ if (!GetCatFileFromDriverPath(szFileName, szCatFile)) { /* driver has no cat so its definately not WHQL signed */ return FALSE; } /* open the CAT file */ hCat = CryptCATOpen(szCatFile, CRYPTCAT_OPEN_EXISTING, 0, 0, 0); if (hCat == INVALID_HANDLE_VALUE) { /* couldnt open cat */ return FALSE; } /* FIXME * build certificate chain with CertGetCertificateChain * verify certificate chain (WinVerifyTrust) * retrieve signer (WTHelperGetProvSignerFromChain) */ /* close CAT file */ CryptCATClose(hCat); return bRet; }
/*********************************************************************** * CryptCATAdminEnumCatalogFromHash (WINTRUST.@) */ HCATINFO WINAPI CryptCATAdminEnumCatalogFromHash(HCATADMIN hCatAdmin, BYTE* pbHash, DWORD cbHash, DWORD dwFlags, HCATINFO* phPrevCatInfo ) { static const WCHAR slashW[] = {'\\',0}; static const WCHAR globW[] = {'\\','*','.','c','a','t',0}; struct catadmin *ca = hCatAdmin; WIN32_FIND_DATAW data; HCATINFO prev = NULL; HCRYPTPROV prov; DWORD size; BOOL ret; TRACE("%p %p %d %x %p\n", hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo); if (!ca || ca->magic != CATADMIN_MAGIC || !pbHash || cbHash != 20 || dwFlags) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } if (phPrevCatInfo) prev = *phPrevCatInfo; ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!ret) return NULL; if (!prev) { WCHAR *path; size = strlenW(ca->path) * sizeof(WCHAR) + sizeof(globW); if (!(path = HeapAlloc(GetProcessHeap(), 0, size))) { CryptReleaseContext(prov, 0); SetLastError(ERROR_OUTOFMEMORY); return NULL; } strcpyW(path, ca->path); strcatW(path, globW); FindClose(ca->find); ca->find = FindFirstFileW(path, &data); HeapFree(GetProcessHeap(), 0, path); if (ca->find == INVALID_HANDLE_VALUE) { CryptReleaseContext(prov, 0); return NULL; } } else if (!FindNextFileW(ca->find, &data)) { CryptCATAdminReleaseCatalogContext(hCatAdmin, prev, 0); CryptReleaseContext(prov, 0); return NULL; } while (1) { WCHAR *filename; CRYPTCATMEMBER *member = NULL; struct catinfo *ci; HANDLE hcat; size = (strlenW(ca->path) + strlenW(data.cFileName) + 2) * sizeof(WCHAR); if (!(filename = HeapAlloc(GetProcessHeap(), 0, size))) { SetLastError(ERROR_OUTOFMEMORY); return NULL; } strcpyW(filename, ca->path); strcatW(filename, slashW); strcatW(filename, data.cFileName); hcat = CryptCATOpen(filename, CRYPTCAT_OPEN_EXISTING, prov, 0, 0); if (hcat == INVALID_HANDLE_VALUE) { WARN("couldn't open %s (%u)\n", debugstr_w(filename), GetLastError()); continue; } while ((member = CryptCATEnumerateMember(hcat, member))) { if (member->pIndirectData->Digest.cbData != cbHash) { WARN("amount of hash bytes differs: %u/%u\n", member->pIndirectData->Digest.cbData, cbHash); continue; } if (!memcmp(member->pIndirectData->Digest.pbData, pbHash, cbHash)) { TRACE("file %s matches\n", debugstr_w(data.cFileName)); CryptCATClose(hcat); CryptReleaseContext(prov, 0); if (!phPrevCatInfo) { FindClose(ca->find); ca->find = INVALID_HANDLE_VALUE; } ci = create_catinfo(filename); HeapFree(GetProcessHeap(), 0, filename); return ci; } } CryptCATClose(hcat); HeapFree(GetProcessHeap(), 0, filename); if (!FindNextFileW(ca->find, &data)) { FindClose(ca->find); ca->find = INVALID_HANDLE_VALUE; CryptReleaseContext(prov, 0); return NULL; } } return NULL; }