[PATCH] wintrust: Implement CryptCATAdminCalcHashFromFileHandle

Maarten Lankhorst maarten at codeweavers.com
Wed Oct 15 10:58:26 CDT 2008


---
 dlls/wintrust/crypt.c       |   77 +++++++++++++++++++++++++++++++++++++++++-
 dlls/wintrust/tests/crypt.c |   21 ------------
 2 files changed, 75 insertions(+), 23 deletions(-)

diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c
index 9980e89..bf6d250 100644
--- a/dlls/wintrust/crypt.c
+++ b/dlls/wintrust/crypt.c
@@ -83,9 +83,82 @@ 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);
+    TRACE("%p %p %p %x\n", hFile, pcbHash, pbHash, dwFlags);
 
-    if (pbHash && pcbHash) memset(pbHash, 0, *pcbHash);
+    if (dwFlags || !hFile || !pcbHash)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (pbHash && *pcbHash < 20)
+    {
+        *pcbHash = 20;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
+    }
+
+    *pcbHash = 20;
+
+    if (pbHash)
+    {
+        BOOL ret;
+        HCRYPTPROV prov;
+        HCRYPTHASH hash;
+        BYTE *tempbuffer;
+        OVERLAPPED ol;
+        ULONG64 fileptr;
+        DWORD readbytes;
+
+#define TEMP_BLOCK_SIZE 4096
+
+        ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+        if (!ret)
+            return ret;
+        ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
+        if (!ret)
+        {
+            CryptReleaseContext(prov, 0);
+            return ret;
+        }
+
+        tempbuffer = HeapAlloc(GetProcessHeap(), 0, TEMP_BLOCK_SIZE);
+        if (!tempbuffer)
+        {
+            ret = FALSE;
+            SetLastError(ERROR_OUTOFMEMORY);
+            goto out;
+        }
+
+        ZeroMemory(&ol, sizeof(ol));
+        ol.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+        fileptr = 0;
+
+        while (((ret = ReadFile(hFile, tempbuffer, TEMP_BLOCK_SIZE, &readbytes, &ol)) && readbytes)
+               || GetLastError() == ERROR_IO_PENDING)
+        {
+            ret = GetOverlappedResult(hFile, &ol, &readbytes, TRUE);
+            if (ret)
+                CryptHashData(hash, tempbuffer, readbytes, 0);
+            if (!ret || !readbytes)
+                break;
+            fileptr += readbytes;
+            ol.Offset = (DWORD)fileptr;
+            ol.OffsetHigh = fileptr >> (ULONG64)32;
+        }
+        CloseHandle(ol.hEvent);
+
+        if (ret)
+            ret = CryptGetHashParam(hash, HP_HASHVAL, pbHash, pcbHash, 0);
+        HeapFree(GetProcessHeap(), 0, tempbuffer);
+out:
+        CryptDestroyHash(hash);
+        CryptReleaseContext(prov, 0);
+        return ret;
+#undef TEMP_BLOCK_SIZE
+    }
+
+    SetLastError(ERROR_INSUFFICIENT_BUFFER);
     return TRUE;
 }
 
diff --git a/dlls/wintrust/tests/crypt.c b/dlls/wintrust/tests/crypt.c
index a45f853..f47386d 100644
--- a/dlls/wintrust/tests/crypt.c
+++ b/dlls/wintrust/tests/crypt.c
@@ -243,45 +243,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 */
@@ -289,12 +277,9 @@ static void test_calchash(void)
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, NULL, 0);
     ok(ret, "Expected success\n");
-    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
@@ -306,12 +291,9 @@ static void test_calchash(void)
     SetLastError(0xdeadbeef);
     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, hash, 0);
     ok(ret, "Expected success\n");
-    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);
 
@@ -331,14 +313,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);
-- 
1.5.6.5


--------------000008050605090200010709--



More information about the wine-patches mailing list