wintrust: Implement CryptCATAdminCalcHashFromFileHandle.

Hans Leidekker hans at codeweavers.com
Thu Dec 18 08:53:42 CST 2008


Based on work done by Maarten Lankhorst.

 -Hans

diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c
index b03740c..6337a85 100644
--- a/dlls/wintrust/crypt.c
+++ b/dlls/wintrust/crypt.c
@@ -176,10 +176,59 @@ HCATINFO WINAPI CryptCATAdminAddCatalog(HCATADMIN catAdmin, PWSTR catalogFile,
 BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD* pcbHash,
                                                 BYTE* pbHash, DWORD dwFlags )
 {
-    FIXME("%p %p %p %x\n", hFile, pcbHash, pbHash, dwFlags);
+    BOOL ret = FALSE;
 
-    if (pbHash && pcbHash) memset(pbHash, 0, *pcbHash);
-    return TRUE;
+    TRACE("%p %p %p %x\n", hFile, pcbHash, pbHash, dwFlags);
+
+    if (!hFile || !pcbHash || dwFlags)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if (*pcbHash < 20)
+    {
+        *pcbHash = 20;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return TRUE;
+    }
+
+    *pcbHash = 20;
+    if (pbHash)
+    {
+        HCRYPTPROV prov;
+        HCRYPTHASH hash;
+        DWORD bytes_read;
+        BYTE *buffer;
+
+        if (!(buffer = HeapAlloc(GetProcessHeap(), 0, 4096)))
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+        if (!ret)
+        {
+            HeapFree(GetProcessHeap(), 0, buffer);
+            return FALSE;
+        }
+        ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
+        if (!ret)
+        {
+            HeapFree(GetProcessHeap(), 0, buffer);
+            CryptReleaseContext(prov, 0);
+            return FALSE;
+        }
+        while ((ret = ReadFile(hFile, buffer, 4096, &bytes_read, NULL)) && bytes_read)
+        {
+            CryptHashData(hash, buffer, bytes_read, 0);
+        }
+        if (ret) ret = CryptGetHashParam(hash, HP_HASHVAL, pbHash, pcbHash, 0);
+
+        HeapFree(GetProcessHeap(), 0, buffer);
+        CryptDestroyHash(hash);
+        CryptReleaseContext(prov, 0);
+    }
+    return ret;
 }
 
 /***********************************************************************
diff --git a/dlls/wintrust/tests/crypt.c b/dlls/wintrust/tests/crypt.c
index dc748c9..0b7f825 100644
--- a/dlls/wintrust/tests/crypt.c
+++ b/dlls/wintrust/tests/crypt.c
@@ -271,45 +271,33 @@ static void test_calchash(void)
     /* All NULL */
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(NULL, NULL, NULL, 0);
-    todo_wine
-    {
     ok(!ret, "Expected failure\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER,
        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
-    }
 
     /* NULL filehandle, rest is legal */
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(NULL, &hashsize, NULL, 0);
-    todo_wine
-    {
     ok(!ret, "Expected failure\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER,
        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
-    }
 
     /* Correct filehandle, rest is NULL */
     file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, NULL, NULL, 0);
-    todo_wine
-    {
     ok(!ret, "Expected failure\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER,
        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
-    }
     CloseHandle(file);
 
     /* All OK, but dwFlags set to 1 */
     file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, NULL, 1);
-    todo_wine
-    {
     ok(!ret, "Expected failure\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER,
        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
-    }
     CloseHandle(file);
 
     /* All OK, requesting the size of the hash */
@@ -318,12 +306,9 @@ static void test_calchash(void)
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, NULL, 0);
     ok(ret, "Expected success %u\n", GetLastError());
-    todo_wine
-    {
     ok(hashsize == 20," Expected a hash size of 20, got %d\n", hashsize);
     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
-    }
     CloseHandle(file);
 
     /* All OK, retrieve the hash
@@ -335,12 +320,9 @@ static void test_calchash(void)
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, hash, 0);
     ok(ret, "Expected success %u\n", GetLastError());
-    todo_wine
-    {
     ok(hashsize == 20," Expected a hash size of 20, got %d\n", hashsize);
     ok(GetLastError() == ERROR_SUCCESS,
        "Expected ERROR_SUCCESS, got %d\n", GetLastError());
-    }
     CloseHandle(file);
     HeapFree(GetProcessHeap(), 0, hash);
 
@@ -360,14 +342,11 @@ static void test_calchash(void)
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, hash, 0);
     ok(ret, "Expected success\n");
-    todo_wine
-    {
     ok(GetLastError() == ERROR_SUCCESS,
        "Expected ERROR_SUCCESS, got %d\n", GetLastError());
     ok(hashsize == sizeof(expectedhash) &&
        !memcmp(hash, expectedhash, sizeof(expectedhash)),
        "Hashes didn't match\n");
-    }
     CloseHandle(file);
 
     HeapFree(GetProcessHeap(), 0, hash);



More information about the wine-patches mailing list