Hans Leidekker : wintrust: Implement CryptCATEnumerateMember.

Alexandre Julliard julliard at winehq.org
Tue Dec 23 13:41:01 CST 2008


Module: wine
Branch: master
Commit: dffccbf1f2c7af506d444b6ed4f7650dc1fd7d95
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dffccbf1f2c7af506d444b6ed4f7650dc1fd7d95

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Tue Dec 23 11:50:37 2008 +0100

wintrust: Implement CryptCATEnumerateMember.

Based on work done by Maarten Lankhorst.

---

 dlls/wintrust/crypt.c |  145 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c
index 6a16254..7b30ede 100644
--- a/dlls/wintrust/crypt.c
+++ b/dlls/wintrust/crypt.c
@@ -30,6 +30,7 @@
 #include "mscat.h"
 #include "mssip.h"
 #include "imagehlp.h"
+#include "winternl.h"
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
@@ -499,9 +500,149 @@ BOOL WINAPI CryptCATClose(HANDLE hCatalog)
 /***********************************************************************
  *      CryptCATEnumerateMember  (WINTRUST.@)
  */
-CRYPTCATMEMBER *WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER* pPrevMember)
+CRYPTCATMEMBER * WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER *prev)
 {
-    FIXME("(%p, %p) stub\n", hCatalog, pPrevMember);
+    struct cryptcat *cc = hCatalog;
+    CRYPTCATMEMBER *member = prev;
+    CTL_ENTRY *entry;
+    DWORD size, i;
+
+    TRACE("%p, %p\n", hCatalog, prev);
+
+    if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
+
+    /* dumping the contents makes me think that dwReserved is the iteration number */
+    if (!member)
+    {
+        if (!(member = HeapAlloc(GetProcessHeap(), 0, sizeof(*member))))
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return NULL;
+        }
+        member->cbStruct = sizeof(*member);
+        member->pwszFileName = member->pwszReferenceTag = NULL;
+        member->dwReserved = 0;
+        member->hReserved = NULL;
+        member->gSubjectType = cc->subject;
+        member->fdwMemberFlags = 0;
+        member->pIndirectData = NULL;
+        member->dwCertVersion = cc->inner->dwVersion;
+    }
+    else member->dwReserved++;
+
+    if (member->dwReserved >= cc->inner->cCTLEntry)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        goto error;
+    }
+
+    /* list them backwards, like native */
+    entry = &cc->inner->rgCTLEntry[cc->inner->cCTLEntry - member->dwReserved - 1];
+
+    member->sEncodedIndirectData.cbData = member->sEncodedMemberInfo.cbData = 0;
+    member->sEncodedIndirectData.pbData = member->sEncodedMemberInfo.pbData = NULL;
+    HeapFree(GetProcessHeap(), 0, member->pIndirectData);
+    member->pIndirectData = NULL;
+
+    for (i = 0; i < entry->cAttribute; i++)
+    {
+        CRYPT_ATTRIBUTE *attr = entry->rgAttribute + i;
+
+        if (attr->cValue != 1)
+        {
+            ERR("Can't handle attr->cValue of %u\n", attr->cValue);
+            continue;
+        }
+        if (!strcmp(attr->pszObjId, CAT_MEMBERINFO_OBJID))
+        {
+            CAT_MEMBERINFO *mi;
+            BOOL ret;
+
+            member->sEncodedMemberInfo.cbData = attr->rgValue->cbData;
+            member->sEncodedMemberInfo.pbData = attr->rgValue->pbData;
+
+            CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size);
+
+            if (!(mi = HeapAlloc(GetProcessHeap(), 0, size)))
+            {
+                SetLastError(ERROR_OUTOFMEMORY);
+                goto error;
+            }
+            ret = CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, mi, &size);
+            if (ret)
+            {
+                UNICODE_STRING guid;
+
+                member->dwCertVersion = mi->dwCertVersion;
+                RtlInitUnicodeString(&guid, mi->pwszSubjGuid);
+                if (RtlGUIDFromString(&guid, &member->gSubjectType))
+                {
+                    HeapFree(GetProcessHeap(), 0, mi);
+                    goto error;
+                }
+            }
+            HeapFree(GetProcessHeap(), 0, mi);
+            if (!ret) goto error;
+        }
+        else if (!strcmp(attr->pszObjId, SPC_INDIRECT_DATA_OBJID))
+        {
+            /* SPC_INDIRECT_DATA_CONTENT is equal to SIP_INDIRECT_DATA */
+
+            member->sEncodedIndirectData.cbData = attr->rgValue->cbData;
+            member->sEncodedIndirectData.pbData = attr->rgValue->pbData;
+
+            CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size);
+
+            if (!(member->pIndirectData = HeapAlloc(GetProcessHeap(), 0, size)))
+            {
+                SetLastError(ERROR_OUTOFMEMORY);
+                goto error;
+            }
+            CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, member->pIndirectData, &size);
+        }
+        else
+            /* this object id should probably be handled in CryptCATEnumerateAttr */
+            FIXME("unhandled object id \"%s\"\n", attr->pszObjId);
+    }
+
+    if (!member->sEncodedMemberInfo.cbData || !member->sEncodedIndirectData.cbData)
+    {
+        ERR("Corrupted catalog entry?\n");
+        SetLastError(CRYPT_E_ATTRIBUTES_MISSING);
+        goto error;
+    }
+    size = (2 * member->pIndirectData->Digest.cbData + 1) * sizeof(WCHAR);
+    if (member->pwszReferenceTag)
+        member->pwszReferenceTag = HeapReAlloc(GetProcessHeap(), 0, member->pwszReferenceTag, size);
+    else
+        member->pwszReferenceTag = HeapAlloc(GetProcessHeap(), 0, size);
+
+    if (!member->pwszReferenceTag)
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        goto error;
+    }
+    /* FIXME: reference tag is usually the file hash but doesn't have to be */
+    for (i = 0; i < member->pIndirectData->Digest.cbData; i++)
+    {
+        DWORD sub;
+
+        sub = member->pIndirectData->Digest.pbData[i] >> 4;
+        member->pwszReferenceTag[i * 2] = (sub < 10 ? '0' + sub : 'A' + sub - 10);
+        sub = member->pIndirectData->Digest.pbData[i] & 0xf;
+        member->pwszReferenceTag[i * 2 + 1] = (sub < 10 ? '0' + sub : 'A' + sub - 10);
+    }
+    member->pwszReferenceTag[i * 2] = 0;
+    return member;
+
+error:
+    HeapFree(GetProcessHeap(), 0, member->pIndirectData);
+    HeapFree(GetProcessHeap(), 0, member->pwszReferenceTag);
+    HeapFree(GetProcessHeap(), 0, member);
     return NULL;
 }
 




More information about the wine-cvs mailing list