Juan Lang : crypt32: Implement CertEnumSystemStore.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed May 9 07:43:07 CDT 2007
Module: wine
Branch: master
Commit: 21dce1d02d896d86c8cda122adf09ec1b5ccf0d5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=21dce1d02d896d86c8cda122adf09ec1b5ccf0d5
Author: Juan Lang <juan_lang at yahoo.com>
Date: Tue May 8 17:09:21 2007 -0700
crypt32: Implement CertEnumSystemStore.
---
dlls/crypt32/crypt32.spec | 1 +
dlls/crypt32/store.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
dlls/crypt32/tests/store.c | 48 ++++++++++++++++++++++++
3 files changed, 136 insertions(+), 0 deletions(-)
diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec
index 7ee23f4..81e6023 100644
--- a/dlls/crypt32/crypt32.spec
+++ b/dlls/crypt32/crypt32.spec
@@ -34,6 +34,7 @@
@ stdcall CertEnumCTLsInStore(ptr ptr)
@ stdcall CertEnumCertificateContextProperties(ptr long)
@ stdcall CertEnumCertificatesInStore(long ptr)
+@ stdcall CertEnumSystemStore(long ptr ptr ptr)
@ stdcall CertFindAttribute(str long ptr)
@ stdcall CertFindCRLInStore(long long long long ptr ptr)
@ stub CertFindCTLInStore
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index 77a75b1..b3c5fcd 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -2603,3 +2603,90 @@ void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
}
LeaveCriticalSection(&collection->cs);
}
+
+static LONG CRYPT_OpenParentStore(DWORD dwFlags,
+ void *pvSystemStoreLocationPara, HKEY *key)
+{
+ HKEY root;
+ LPCWSTR base;
+
+ TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
+
+ switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
+ {
+ case CERT_SYSTEM_STORE_LOCAL_MACHINE:
+ root = HKEY_LOCAL_MACHINE;
+ base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
+ break;
+ case CERT_SYSTEM_STORE_CURRENT_USER:
+ root = HKEY_CURRENT_USER;
+ base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
+ break;
+ case CERT_SYSTEM_STORE_CURRENT_SERVICE:
+ /* hklm\Software\Microsoft\Cryptography\Services\servicename\
+ * SystemCertificates
+ */
+ FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
+ return ERROR_FILE_NOT_FOUND;
+ case CERT_SYSTEM_STORE_SERVICES:
+ /* hklm\Software\Microsoft\Cryptography\Services\servicename\
+ * SystemCertificates
+ */
+ FIXME("CERT_SYSTEM_STORE_SERVICES");
+ return ERROR_FILE_NOT_FOUND;
+ case CERT_SYSTEM_STORE_USERS:
+ /* hku\user sid\Software\Microsoft\SystemCertificates */
+ FIXME("CERT_SYSTEM_STORE_USERS\n");
+ return ERROR_FILE_NOT_FOUND;
+ case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
+ root = HKEY_CURRENT_USER;
+ base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
+ break;
+ case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
+ root = HKEY_LOCAL_MACHINE;
+ base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
+ break;
+ case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
+ /* hklm\Software\Microsoft\EnterpriseCertificates */
+ FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
+ return ERROR_FILE_NOT_FOUND;
+ default:
+ return ERROR_FILE_NOT_FOUND;
+ }
+
+ return RegOpenKeyExW(root, base, 0, KEY_READ, key);
+}
+
+BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
+ void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
+{
+ BOOL ret = FALSE;
+ LONG rc;
+ HKEY key;
+
+ TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
+ pfnEnum);
+
+ rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
+ if (!rc)
+ {
+ DWORD index = 0;
+ CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
+
+ ret = TRUE;
+ do {
+ WCHAR name[MAX_PATH];
+ DWORD size = sizeof(name) / sizeof(name[0]);
+
+ rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
+ NULL);
+ if (!rc)
+ ret = pfnEnum(name, 0, &info, NULL, pvArg);
+ } while (ret && !rc);
+ if (ret && rc != ERROR_NO_MORE_ITEMS)
+ SetLastError(rc);
+ }
+ else
+ SetLastError(rc);
+ return ret;
+}
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index e251d98..e464abb 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -1379,6 +1379,53 @@ static void testCertOpenSystemStore(void)
RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
}
+struct EnumSystemStoreInfo
+{
+ BOOL goOn;
+ DWORD storeCount;
+};
+
+static BOOL CALLBACK enumSystemStoreCB(const void *systemStore, DWORD dwFlags,
+ PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg)
+{
+ struct EnumSystemStoreInfo *info = (struct EnumSystemStoreInfo *)pvArg;
+
+ info->storeCount++;
+ return info->goOn;
+}
+
+static void testCertEnumSystemStore(void)
+{
+ BOOL ret;
+ struct EnumSystemStoreInfo info = { FALSE, 0 };
+
+ SetLastError(0xdeadbeef);
+ ret = CertEnumSystemStore(0, NULL, NULL, NULL);
+ ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
+ "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
+ /* Crashes
+ ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, NULL,
+ NULL);
+ */
+
+ SetLastError(0xdeadbeef);
+ ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, &info,
+ enumSystemStoreCB);
+ /* Callback returning FALSE stops enumeration */
+ ok(!ret, "Expected CertEnumSystemStore to stop\n");
+ ok(info.storeCount == 0 || info.storeCount == 1,
+ "Expected 0 or 1 stores\n");
+
+ info.goOn = TRUE;
+ info.storeCount = 0;
+ ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, &info,
+ enumSystemStoreCB);
+ ok(ret, "CertEnumSystemStore failed: %08x\n", GetLastError());
+ /* There should always be at least My, Root, and CA stores */
+ ok(info.storeCount == 0 || info.storeCount >= 3,
+ "Expected at least 3 stores\n");
+}
+
static void testAddSerialized(void)
{
BOOL ret;
@@ -1545,6 +1592,7 @@ START_TEST(store)
testFileNameStore();
testCertOpenSystemStore();
+ testCertEnumSystemStore();
testAddSerialized();
}
More information about the wine-cvs
mailing list