Juan Lang : crypt32: Implement CertGetStoreProperty and CertSetStoreProperty.

Alexandre Julliard julliard at wine.codeweavers.com
Tue May 15 14:02:15 CDT 2007


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

Author: Juan Lang <juan_lang at yahoo.com>
Date:   Mon May 14 18:05:43 2007 -0700

crypt32: Implement CertGetStoreProperty and CertSetStoreProperty.

---

 dlls/crypt32/crypt32.spec  |    2 +
 dlls/crypt32/store.c       |  106 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/crypt32/tests/store.c |   74 ++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+), 3 deletions(-)

diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec
index a3e3039..aba9065 100644
--- a/dlls/crypt32/crypt32.spec
+++ b/dlls/crypt32/crypt32.spec
@@ -59,6 +59,7 @@
 @ stdcall CertGetNameStringA(ptr long long ptr ptr long)
 @ stdcall CertGetNameStringW(ptr long long ptr ptr long)
 @ stdcall CertGetPublicKeyLength(long ptr)
+@ stdcall CertGetStoreProperty(long long ptr ptr)
 @ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
 @ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
 @ stub CertIsRDNAttrsInCertificateName
@@ -81,6 +82,7 @@
 @ stdcall CertSetCTLContextProperty(ptr long long ptr)
 @ stdcall CertSetCertificateContextProperty(ptr long long ptr)
 @ stdcall CertSetEnhancedKeyUsage(ptr ptr)
+@ stdcall CertSetStoreProperty(ptr long long ptr)
 @ stdcall CertStrToNameA(long str long ptr ptr ptr ptr)
 @ stdcall CertStrToNameW(long wstr long ptr ptr ptr ptr)
 @ stdcall CertVerifyCRLRevocation(long ptr long ptr)
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index 5f44be4..46556d8 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -138,6 +138,7 @@ typedef struct WINE_CRYPTCERTSTORE
     CONTEXT_STORE               certs;
     CONTEXT_STORE               crls;
     PFN_CERT_STORE_PROV_CONTROL control; /* optional */
+    PCONTEXT_PROPERTY_LIST      properties;
 } WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;
 
 typedef struct _WINE_MEMSTORE
@@ -216,6 +217,14 @@ static void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv,
     }
     store->cryptProv = hCryptProv;
     store->dwOpenFlags = dwFlags;
+    store->properties = NULL;
+}
+
+static void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
+{
+    if (store->properties)
+        ContextPropertyList_Free(store->properties);
+    CryptMemFree(store);
 }
 
 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
@@ -316,7 +325,7 @@ static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
 
     ContextList_Free(store->certs);
     ContextList_Free(store->crls);
-    CryptMemFree(store);
+    CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
 }
 
 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
@@ -371,7 +380,7 @@ static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
     }
     cs->cs.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&cs->cs);
-    CryptMemFree(cs);
+    CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
 }
 
 static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
@@ -692,7 +701,7 @@ static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
         store->provCloseStore(store->hStoreProv, dwFlags);
     if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
         CertCloseStore(store->memStore, dwFlags);
-    CryptMemFree(store);
+    CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
 }
 
 static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
@@ -2476,6 +2485,97 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
     return ret;
 }
 
+BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
+ void *pvData, DWORD *pcbData)
+{
+    PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
+    BOOL ret = FALSE;
+
+    TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
+
+    switch (dwPropId)
+    {
+    case CERT_ACCESS_STATE_PROP_ID:
+        if (!pvData)
+        {
+            *pcbData = sizeof(DWORD);
+            ret = TRUE;
+        }
+        else if (*pcbData < sizeof(DWORD))
+        {
+            SetLastError(ERROR_MORE_DATA);
+            *pcbData = sizeof(DWORD);
+        }
+        else
+        {
+            *(DWORD *)pvData = CertStore_GetAccessState(hCertStore);
+            ret = TRUE;
+        }
+        break;
+    default:
+        if (store->properties)
+        {
+            CRYPT_DATA_BLOB blob;
+
+            ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
+             &blob);
+            if (ret)
+            {
+                if (!pvData)
+                    *pcbData = blob.cbData;
+                else if (*pcbData < blob.cbData)
+                {
+                    SetLastError(ERROR_MORE_DATA);
+                    *pcbData = blob.cbData;
+                    ret = FALSE;
+                }
+                else
+                {
+                    memcpy(pvData, blob.pbData, blob.cbData);
+                    *pcbData = blob.cbData;
+                }
+            }
+            else
+                SetLastError(CRYPT_E_NOT_FOUND);
+        }
+        else
+            SetLastError(CRYPT_E_NOT_FOUND);
+    }
+    return ret;
+}
+
+BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
+ DWORD dwFlags, const void *pvData)
+{
+    PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
+    BOOL ret = FALSE;
+
+    TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
+
+    if (!store->properties)
+        store->properties = ContextPropertyList_Create();
+    switch (dwPropId)
+    {
+    case CERT_ACCESS_STATE_PROP_ID:
+        SetLastError(E_INVALIDARG);
+        break;
+    default:
+        if (pvData)
+        {
+            const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
+
+            ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
+             blob->pbData, blob->cbData);
+        }
+        else
+        {
+            ContextPropertyList_RemoveProperty(store->properties, dwPropId);
+            ret = TRUE;
+        }
+    }
+    return ret;
+}
+
 DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
  DWORD dwPropId)
 {
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index e464abb..d00adb4 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -1426,6 +1426,79 @@ static void testCertEnumSystemStore(void)
      "Expected at least 3 stores\n");
 }
 
+static void testStoreProperty(void)
+{
+    HCERTSTORE store;
+    BOOL ret;
+    DWORD propID, size = 0, state;
+    CRYPT_DATA_BLOB blob;
+
+    /* Crash
+    ret = CertGetStoreProperty(NULL, 0, NULL, NULL);
+    ret = CertGetStoreProperty(NULL, 0, NULL, &size);
+    ret = CertGetStoreProperty(store, 0, NULL, NULL);
+     */
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+     CERT_STORE_CREATE_NEW_FLAG, NULL);
+    /* Check a missing prop ID */
+    SetLastError(0xdeadbeef);
+    ret = CertGetStoreProperty(store, 0, NULL, &size);
+    ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+     "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+    /* Contrary to MSDN, CERT_ACCESS_STATE_PROP_ID is supported for stores.. */
+    size = sizeof(state);
+    ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size);
+    ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n",
+     GetLastError());
+    ok(!state, "Expected a non-persisted store\n");
+    /* and CERT_STORE_LOCALIZED_NAME_PROP_ID isn't supported by default. */
+    size = 0;
+    ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL,
+     &size);
+    ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+     "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+    /* Delete an arbitrary property on a store */
+    ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL);
+    ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
+    /* Set an arbitrary property on a store */
+    blob.pbData = (LPBYTE)&state;
+    blob.cbData = sizeof(state);
+    ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, &blob);
+    ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
+    /* Get an arbitrary property that's been set */
+    ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size);
+    ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
+    ok(size == sizeof(state), "Unexpected data size %d\n", size);
+    ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, &propID, &size);
+    ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
+    ok(propID == state, "CertGetStoreProperty got the wrong value\n");
+    /* Delete it again */
+    ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL);
+    ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
+    /* And check that it's missing */
+    SetLastError(0xdeadbeef);
+    ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size);
+    ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+     "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+    CertCloseStore(store, 0);
+
+    /* Recheck on the My store.. */
+    store = CertOpenSystemStoreW(0, MyW);
+    size = sizeof(state);
+    ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size);
+    ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n",
+     GetLastError());
+    ok(state, "Expected a persisted store\n");
+    SetLastError(0xdeadbeef);
+    size = 0;
+    ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL,
+     &size);
+    ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+     "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+    CertCloseStore(store, 0);
+}
+
 static void testAddSerialized(void)
 {
     BOOL ret;
@@ -1593,6 +1666,7 @@ START_TEST(store)
 
     testCertOpenSystemStore();
     testCertEnumSystemStore();
+    testStoreProperty();
 
     testAddSerialized();
 }




More information about the wine-cvs mailing list