Rob Shearman : advapi32: Implement CredEnumerateW.

Alexandre Julliard julliard at winehq.org
Wed Oct 31 08:35:22 CDT 2007


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

Author: Rob Shearman <rob at codeweavers.com>
Date:   Tue Oct 30 12:37:26 2007 +0000

advapi32: Implement CredEnumerateW.

---

 dlls/advapi32/advapi.c |    8 --
 dlls/advapi32/cred.c   |  166 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+), 8 deletions(-)

diff --git a/dlls/advapi32/advapi.c b/dlls/advapi32/advapi.c
index 1a2c7da..9f9cf8b 100644
--- a/dlls/advapi32/advapi.c
+++ b/dlls/advapi32/advapi.c
@@ -301,11 +301,3 @@ BOOL WINAPI CredEnumerateA(LPCSTR filter, DWORD flags, DWORD *count,
             credentials);
     return FALSE;
 }
-
-BOOL WINAPI CredEnumerateW(LPCWSTR filter, DWORD flags, DWORD *count,
- PCREDENTIALW **credentials)
-{
-    FIXME("(%s, %08x, %p, %p)\n", debugstr_w(filter), flags, count,
-            credentials);
-    return FALSE;
-}
diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index 714d1af..39d369d 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -436,6 +436,172 @@ BOOL WINAPI CredDeleteW(LPCWSTR TargetName, DWORD Type, DWORD Flags)
     return TRUE;
 }
 
+static BOOL credential_matches_filter(HKEY hkeyCred, LPCWSTR filter)
+{
+    if (!filter) return TRUE;
+
+    FIXME("%s\n", debugstr_w(filter));
+    return TRUE;
+}
+
+/******************************************************************************
+ * CredEnumerateW [ADVAPI32.@]
+ */
+BOOL WINAPI CredEnumerateW(LPCWSTR Filter, DWORD Flags, DWORD *Count,
+                           PCREDENTIALW **Credentials)
+{
+    HKEY hkeyMgr;
+    HKEY hkeyCred;
+    DWORD ret;
+    LPWSTR target_name;
+    DWORD target_name_len;
+    DWORD len;
+    char *buffer;
+    DWORD i;
+    BYTE key_data[KEY_SIZE];
+
+    TRACE("(%s, 0x%x, %p, %p)\n", debugstr_w(Filter), Flags, Count, Credentials);
+
+    if (Flags)
+    {
+        SetLastError(ERROR_INVALID_FLAGS);
+        return FALSE;
+    }
+
+    ret = open_cred_mgr_key(&hkeyMgr, FALSE);
+    if (ret != ERROR_SUCCESS)
+    {
+        WARN("couldn't open/create manager key, error %d\n", ret);
+        SetLastError(ERROR_NO_SUCH_LOGON_SESSION);
+        return FALSE;
+    }
+
+    ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
+    if (ret != ERROR_SUCCESS)
+    {
+        RegCloseKey(hkeyMgr);
+        SetLastError(ret);
+        return FALSE;
+    }
+
+    ret = RegQueryInfoKeyW(hkeyMgr, NULL, NULL, NULL, NULL, &target_name_len, NULL, NULL, NULL, NULL, NULL, NULL);
+    if (ret != ERROR_SUCCESS)
+    {
+        RegCloseKey(hkeyMgr);
+        SetLastError(ret);
+        return FALSE;
+    }
+
+    target_name = HeapAlloc(GetProcessHeap(), 0, (target_name_len+1)*sizeof(WCHAR));
+    if (!target_name)
+    {
+        RegCloseKey(hkeyMgr);
+        SetLastError(ERROR_OUTOFMEMORY);
+        return FALSE;
+    }
+
+    *Count = 0;
+    len = 0;
+    for (i = 0;; i++)
+    {
+        ret = RegEnumKeyW(hkeyMgr, i, target_name, target_name_len+1);
+        if (ret == ERROR_NO_MORE_ITEMS)
+        {
+            ret = ERROR_SUCCESS;
+            break;
+        }
+        else if (ret != ERROR_SUCCESS)
+        {
+            ret = ERROR_SUCCESS;
+            continue;
+        }
+        ret = RegOpenKeyExW(hkeyMgr, target_name, 0, KEY_QUERY_VALUE, &hkeyCred);
+        if (ret != ERROR_SUCCESS)
+        {
+            ret = ERROR_SUCCESS;
+            continue;
+        }
+        if (!credential_matches_filter(hkeyCred, Filter))
+        {
+            RegCloseKey(hkeyCred);
+            continue;
+        }
+        len += sizeof(CREDENTIALW);
+        ret = read_credential(hkeyCred, NULL, key_data, NULL, &len);
+        RegCloseKey(hkeyCred);
+        if (ret != ERROR_SUCCESS) break;
+        (*Count)++;
+    }
+    if (ret == ERROR_SUCCESS && *Count == 0)
+        ret = ERROR_NOT_FOUND;
+    if (ret != ERROR_SUCCESS)
+    {
+        HeapFree(GetProcessHeap(), 0, target_name);
+        RegCloseKey(hkeyMgr);
+        SetLastError(ret);
+        return FALSE;
+    }
+    len += *Count + sizeof(PCREDENTIALW);
+
+    if (ret == ERROR_SUCCESS)
+    {
+        buffer = HeapAlloc(GetProcessHeap(), 0, len);
+        *Credentials = (PCREDENTIALW *)buffer;
+        if (buffer)
+        {
+            buffer += *Count * sizeof(PCREDENTIALW);
+            *Count = 0;
+            for (i = 0;; i++)
+            {
+                ret = RegEnumKeyW(hkeyMgr, i, target_name, target_name_len+1);
+                if (ret == ERROR_NO_MORE_ITEMS)
+                {
+                    ret = ERROR_SUCCESS;
+                    break;
+                }
+                else if (ret != ERROR_SUCCESS)
+                {
+                    ret = ERROR_SUCCESS;
+                    continue;
+                }
+                TRACE("target_name = %s\n", debugstr_w(target_name));
+                ret = RegOpenKeyExW(hkeyMgr, target_name, 0, KEY_QUERY_VALUE, &hkeyCred);
+                if (ret != ERROR_SUCCESS)
+                {
+                    ret = ERROR_SUCCESS;
+                    continue;
+                }
+                if (!credential_matches_filter(hkeyCred, Filter))
+                {
+                    RegCloseKey(hkeyCred);
+                    continue;
+                }
+                len = sizeof(CREDENTIALW);
+                (*Credentials)[*Count] = (PCREDENTIALW)buffer;
+                ret = read_credential(hkeyCred, (*Credentials)[*Count],
+                                      key_data,
+                                      buffer + sizeof(CREDENTIALW), &len);
+                RegCloseKey(hkeyCred);
+                if (ret != ERROR_SUCCESS) break;
+                buffer += len;
+                (*Count)++;
+            }
+        }
+        else
+            ret = ERROR_OUTOFMEMORY;
+    }
+
+    HeapFree(GetProcessHeap(), 0, target_name);
+    RegCloseKey(hkeyMgr);
+
+    if (ret != ERROR_SUCCESS)
+    {
+        SetLastError(ret);
+        return FALSE;
+    }
+    return TRUE;
+}
+
 /******************************************************************************
  * CredFree [ADVAPI32.@]
  */




More information about the wine-cvs mailing list