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