[PATCH] wintrust: Implement CryptCATAdminCalcHashFromFileHandle

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


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

diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c
index 136f795..dd04f17 100644
--- a/dlls/wintrust/crypt.c
+++ b/dlls/wintrust/crypt.c
@@ -83,9 +83,64 @@ 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)
+    {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
+    }
+
+    *pcbHash = 20;
+
+    if (pbHash)
+    {
+        BOOL ret;
+        HCRYPTPROV prov;
+        HCRYPTHASH hash;
+        BYTE *tempbuffer;
+        LARGE_INTEGER oldpos, curpos;
+        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)
+            goto out;
+
+        curpos.QuadPart = 0;
+        SetFilePointerEx(hFile, curpos, &oldpos, FILE_CURRENT);
+        SetFilePointerEx(hFile, curpos, NULL, FILE_BEGIN);
+
+        while (ReadFile(hFile, tempbuffer, TEMP_BLOCK_SIZE, &readbytes, NULL) && readbytes)
+            CryptHashData(hash, tempbuffer, readbytes, 0);
+
+        ret = CryptGetHashParam(hash, HP_HASHVAL, pbHash, pcbHash, 0);
+        SetFilePointerEx(hFile, oldpos, NULL, FILE_BEGIN);
+        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


--------------020000080902050704090409--



More information about the wine-patches mailing list