From: Elias Norberg elias@aisle.se
--- dlls/wintrust/crypt.c | 84 +++++++++++++++++++++++++++++++------ dlls/wintrust/wintrust.spec | 2 +- 2 files changed, 73 insertions(+), 13 deletions(-)
diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c index 54bc558feeb..21248d7fcd1 100644 --- a/dlls/wintrust/crypt.c +++ b/dlls/wintrust/crypt.c @@ -327,28 +327,47 @@ done: return ret; }
-/*********************************************************************** - * CryptCATAdminCalcHashFromFileHandle (WINTRUST.@) - */ -BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BYTE *pbHash, DWORD dwFlags) +static BOOL catadmin_calc_hash_from_filehandle(HCATADMIN catAdmin, HANDLE hFile, DWORD *pcbHash, + BYTE *pbHash, DWORD dwFlags) { BOOL ret = FALSE; - - TRACE("%p %p %p %lx\n", hFile, pcbHash, pbHash, dwFlags); + struct catadmin *ca = catAdmin; + ALG_ID alg = CALG_SHA1; + const WCHAR *providerName = MS_DEF_PROV_W; + DWORD providerType = PROV_RSA_FULL; + DWORD hashLength;
if (!hFile || !pcbHash || dwFlags) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (*pcbHash < 20) - { - *pcbHash = 20; + + if (ca) { + alg = ca->alg; + providerName = ca->providerName; + providerType = ca->providerType; + } + + switch (alg) { + case CALG_SHA1: + hashLength = 20; + break; + case CALG_SHA_256: + hashLength = 32; + break; + default: + FIXME("unsupported algorithm %x\n", alg); + return FALSE; + } + + if (*pcbHash < hashLength) { + *pcbHash = hashLength; SetLastError(ERROR_INSUFFICIENT_BUFFER); return TRUE; }
- *pcbHash = 20; + *pcbHash = hashLength; if (pbHash) { HCRYPTPROV prov; @@ -361,13 +380,13 @@ BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BY SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ret = CryptAcquireContextW(&prov, NULL, providerName, providerType, CRYPT_VERIFYCONTEXT); if (!ret) { free(buffer); return FALSE; } - ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash); + ret = CryptCreateHash(prov, alg, 0, 0, &hash); if (!ret) { free(buffer); @@ -391,6 +410,47 @@ BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BY return ret; }
+/*********************************************************************** + * CryptCATAdminCalcHashFromFileHandle (WINTRUST.@) + */ +BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BYTE *pbHash, DWORD dwFlags) +{ + TRACE("%p %p %p %lx\n", hFile, pcbHash, pbHash, dwFlags); + return catadmin_calc_hash_from_filehandle(NULL, hFile, pcbHash, pbHash, dwFlags); +} + +/*********************************************************************** + * CryptCATAdminCalcHashFromFileHandle2 (WINTRUST.@) + * + * Calculate hash for a specific file using a catalog administrator context. + * + * PARAMS + * catAdmin [I] Catalog administrator context handle. + * hFile [I] Handle for the file to hash. + * pcbHash [I] Pointer to the length of the hash. + * pbHash [O] Pointer to the buffer that will store that hash + * dwFlags [I] Reserved. + * + * RETURNS + * Success: TRUE. If pcbHash is too small, LastError will be set to ERROR_INSUFFICIENT_BUFFER. + * pbHash contains the computed hash, if supplied. + * Failure: FALSE. + * + */ +BOOL WINAPI CryptCATAdminCalcHashFromFileHandle2(HCATADMIN catAdmin, HANDLE hFile, DWORD *pcbHash, + BYTE *pbHash, DWORD dwFlags) +{ + TRACE("%p %p %p %p %lx\n", catAdmin, hFile, pcbHash, pbHash, dwFlags); + + if (!catAdmin || ((struct catadmin *)catAdmin)->magic != CATADMIN_MAGIC) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return catadmin_calc_hash_from_filehandle(catAdmin, hFile, pcbHash, pbHash, dwFlags); +} + + /*********************************************************************** * CryptCATAdminEnumCatalogFromHash (WINTRUST.@) */ diff --git a/dlls/wintrust/wintrust.spec b/dlls/wintrust/wintrust.spec index 06db4a1159e..79e9bd32a75 100644 --- a/dlls/wintrust/wintrust.spec +++ b/dlls/wintrust/wintrust.spec @@ -7,7 +7,7 @@ @ stdcall CryptCATAdminAcquireContext2(ptr ptr wstr ptr long) @ stdcall CryptCATAdminAddCatalog(long wstr wstr long) @ stdcall CryptCATAdminCalcHashFromFileHandle(long ptr ptr long) -#@ stub CryptCATAdminCalcHashFromFileHandle2 +@ stdcall CryptCATAdminCalcHashFromFileHandle2(ptr ptr ptr ptr long) @ stdcall CryptCATAdminEnumCatalogFromHash(long ptr long long ptr) @ stub CryptCATAdminPauseServiceForBackup @ stdcall CryptCATAdminReleaseCatalogContext(long long long)