andrey.turkin@gmail.com: [resend 2] [try4] advapi32: Implement CredReadDomainCredentials stuband tests

9 views
Skip to first unread message

Patchwatcher

unread,
Nov 1, 2008, 3:01:53 AM11/1/08
to wine-patch...@googlegroups.com
From: Andrey Turkin <andrey...@gmail.com>
Subject: [resend 2] [try4] advapi32: Implement CredReadDomainCredentials stuband tests
Date: Sat, 01 Nov 2008 09:50:47 +0300

[use win_skip in tests]
Got no feedback on last sends so resending

Implement CredReadDomainCredentialsA and CredReadDomainCredentialsW
stubs and few tests for them. Required for MSN Messenger 7.0
---
dlls/advapi32/advapi32.spec | 4 +-
dlls/advapi32/cred.c | 163 +++++++++++++++++++++++++++++++++++++++++++
dlls/advapi32/tests/cred.c | 60 ++++++++++++++++
include/wincred.h | 39 ++++++++++
4 files changed, 264 insertions(+), 2 deletions(-)

diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index cb4dd4d..d6c805b 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -116,8 +116,8 @@
# @ stub CredMarshalCredentialW
@ stub CredProfileLoaded
@ stdcall CredReadA(str long long ptr)
-# @ stub CredReadDomainCredentialsA
-# @ stub CredReadDomainCredentialsW
+@ stdcall CredReadDomainCredentialsA(ptr long ptr ptr)
+@ stdcall CredReadDomainCredentialsW(ptr long ptr ptr)
@ stdcall CredReadW(wstr long long ptr)
# @ stub CredRenameA
# @ stub CredRenameW
diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index 6600912..48aa3af 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -1545,6 +1545,169 @@ BOOL WINAPI CredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW
}

/******************************************************************************
+ * CredReadDomainCredentialsA [ADVAPI32.@]
+ */
+BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInformation,
+ DWORD Flags, DWORD *Size, PCREDENTIALA **Credentials)
+{
+ PCREDENTIAL_TARGET_INFORMATIONW TargetInformationW;
+ DWORD len, i;
+ WCHAR *buffer;
+ BOOL ret;
+ PCREDENTIALW* CredentialsW;
+
+ TRACE("(%p, 0x%x, %p, %p)\n", TargetInformation, Flags, Size, Credentials);
+
+ /* follow Windows behavior - do not test for NULL, initialize early */
+ *Size = 0;
+ *Credentials = NULL;
+
+ if (!TargetInformation)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ len = sizeof(*TargetInformationW);
+ if (TargetInformation->TargetName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->TargetName, -1, NULL, 0);
+ if (TargetInformation->NetbiosServerName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosServerName, -1, NULL, 0);
+ if (TargetInformation->DnsServerName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsServerName, -1, NULL, 0);
+ if (TargetInformation->NetbiosDomainName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosDomainName, -1, NULL, 0);
+ if (TargetInformation->DnsDomainName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsDomainName, -1, NULL, 0);
+ if (TargetInformation->DnsTreeName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsTreeName, -1, NULL, 0);
+ if (TargetInformation->PackageName) len += sizeof(WCHAR) *
+ MultiByteToWideChar(CP_ACP, 0, TargetInformation->PackageName, -1, NULL, 0);
+
+ TargetInformationW = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!TargetInformationW)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+ buffer = (WCHAR*)(TargetInformationW + 1);
+
+ if (TargetInformation->TargetName)
+ {
+ TargetInformationW->TargetName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->TargetName, -1,
+ TargetInformationW->TargetName, -1);
+ } else
+ TargetInformationW->TargetName = NULL;
+
+ if (TargetInformation->NetbiosServerName)
+ {
+ TargetInformationW->NetbiosServerName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosServerName, -1,
+ TargetInformationW->NetbiosServerName, -1);
+ } else
+ TargetInformationW->NetbiosServerName = NULL;
+
+ if (TargetInformation->DnsServerName)
+ {
+ TargetInformationW->DnsServerName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsServerName, -1,
+ TargetInformationW->DnsServerName, -1);
+ } else
+ TargetInformationW->DnsServerName = NULL;
+
+ if (TargetInformation->NetbiosDomainName)
+ {
+ TargetInformationW->NetbiosDomainName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosDomainName, -1,
+ TargetInformationW->NetbiosDomainName, -1);
+ } else
+ TargetInformationW->NetbiosDomainName = NULL;
+
+ if (TargetInformation->DnsDomainName)
+ {
+ TargetInformationW->DnsDomainName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsDomainName, -1,
+ TargetInformationW->DnsDomainName, -1);
+ } else
+ TargetInformationW->DnsDomainName = NULL;
+
+ if (TargetInformation->DnsTreeName)
+ {
+ TargetInformationW->DnsTreeName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsTreeName, -1,
+ TargetInformationW->DnsTreeName, -1);
+ } else
+ TargetInformationW->DnsTreeName = NULL;
+
+ if (TargetInformation->PackageName)
+ {
+ TargetInformationW->PackageName = buffer;
+ buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->PackageName, -1,
+ TargetInformationW->PackageName, -1);
+ } else
+ TargetInformationW->PackageName = NULL;
+
+ TargetInformationW->Flags = TargetInformation->Flags;
+ TargetInformationW->CredTypeCount = TargetInformation->CredTypeCount;
+ TargetInformationW->CredTypes = TargetInformation->CredTypes;
+
+ ret = CredReadDomainCredentialsW(TargetInformationW, Flags, Size, &CredentialsW);
+
+ HeapFree(GetProcessHeap(), 0, TargetInformationW);
+
+ if (ret)
+ {
+ char *buf;
+
+ len = *Size * sizeof(PCREDENTIALA);
+ for (i = 0; i < *Size; i++)
+ convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, &len);
+
+ *Credentials = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!*Credentials)
+ {
+ CredFree(CredentialsW);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ buf = (char *)&(*Credentials)[*Size];
+ for (i = 0; i < *Size; i++)
+ {
+ len = 0;
+ (*Credentials)[i] = (PCREDENTIALA)buf;
+ convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], &len);
+ buf += len;
+ }
+
+ CredFree(CredentialsW);
+ }
+ return ret;
+}
+
+/******************************************************************************
+ * CredReadDomainCredentialsW [ADVAPI32.@]
+ */
+BOOL WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW TargetInformation, DWORD Flags,
+ DWORD *Size, PCREDENTIALW **Credentials)
+{
+ FIXME("(%p, 0x%x, %p, %p) stub\n", TargetInformation, Flags, Size, Credentials);
+
+ /* follow Windows behavior - do not test for NULL, initialize early */
+ *Size = 0;
+ *Credentials = NULL;
+ if (!TargetInformation)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ SetLastError(ERROR_NOT_FOUND);
+ return FALSE;
+}
+
+/******************************************************************************
* CredWriteA [ADVAPI32.@]
*/
BOOL WINAPI CredWriteA(PCREDENTIALA Credential, DWORD Flags)
diff --git a/dlls/advapi32/tests/cred.c b/dlls/advapi32/tests/cred.c
index df14439..30f505a 100644
--- a/dlls/advapi32/tests/cred.c
+++ b/dlls/advapi32/tests/cred.c
@@ -34,6 +34,8 @@ static BOOL (WINAPI *pCredGetSessionTypes)(DWORD,LPDWORD);
static BOOL (WINAPI *pCredReadA)(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
static BOOL (WINAPI *pCredRenameA)(LPCSTR,LPCSTR,DWORD,DWORD);
static BOOL (WINAPI *pCredWriteA)(PCREDENTIALA,DWORD);
+static BOOL (WINAPI *pCredReadDomainCredentialsA)(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD*,PCREDENTIALA**);
+

#define TEST_TARGET_NAME "credtest.winehq.org"
#define TEST_TARGET_NAME2 "credtest2.winehq.org"
@@ -136,6 +138,61 @@ static void test_CredDeleteA(void)
GetLastError());
}

+static void test_CredReadDomainCredentialsA(void)
+{
+ BOOL ret;
+ char target_name[] = "no_such_target";
+ CREDENTIAL_TARGET_INFORMATIONA info = {target_name, NULL, target_name, NULL, NULL, NULL, NULL, 0, 0, NULL};
+ DWORD count;
+ PCREDENTIAL* creds;
+
+ if (!pCredReadDomainCredentialsA)
+ {
+ win_skip("CredReadDomainCredentialsA() is not implemented\n");
+ return;
+ }
+
+ /* these two tests would crash on both native and Wine. Implementations
+ * does not check for NULL output pointers and try to zero them out early */
+#if 0
+ ok(!pCredReadDomainCredentialsA(&info, 0, NULL, &creds) &&
+ GetLastError() == ERROR_INVALID_PARAMETER, "!");
+ ok(!pCredReadDomainCredentialsA(&info, 0, &count, NULL) &&
+ GetLastError() == ERROR_INVALID_PARAMETER, "!");
+#endif
+
+ SetLastError(0xdeadbeef);
+ ret = pCredReadDomainCredentialsA(NULL, 0, &count, &creds);
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "CredReadDomainCredentialsA should have failed with ERROR_INVALID_PARAMETER instead of %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ creds = (void*)0x12345;
+ count = 2;
+ ret = pCredReadDomainCredentialsA(&info, 0, &count, &creds);
+ ok(!ret && GetLastError() == ERROR_NOT_FOUND,
+ "CredReadDomainCredentialsA should have failed with ERROR_NOT_FOUND instead of %d\n",
+ GetLastError());
+ ok(count ==0 && creds == NULL, "CredReadDomainCredentialsA must not return any result\n");
+
+ info.TargetName = NULL;
+
+ SetLastError(0xdeadbeef);
+ ret = pCredReadDomainCredentialsA(&info, 0, &count, &creds);
+ ok(!ret && GetLastError() == ERROR_NOT_FOUND,
+ "CredReadDomainCredentialsA should have failed with ERROR_NOT_FOUND instead of %d\n",
+ GetLastError());
+
+ info.DnsServerName = NULL;
+
+ SetLastError(0xdeadbeef);
+ ret = pCredReadDomainCredentialsA(&info, 0, &count, &creds);
+ ok(!ret && GetLastError() == ERROR_NOT_FOUND,
+ "CredReadDomainCredentialsA should have failed with ERROR_NOT_FOUND instead of %d\n",
+ GetLastError());
+}
+
static void check_blob(int line, DWORD cred_type, PCREDENTIALA cred)
{
if (cred_type == CRED_TYPE_DOMAIN_PASSWORD)
@@ -279,6 +336,7 @@ START_TEST(cred)
pCredDeleteA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredDeleteA");
pCredReadA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadA");
pCredRenameA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredRenameA");
+ pCredReadDomainCredentialsA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadDomainCredentialsA");

if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA ||
!pCredReadA)
@@ -304,6 +362,8 @@ START_TEST(cred)
test_CredWriteA();
test_CredDeleteA();

+ test_CredReadDomainCredentialsA();
+
trace("generic:\n");
if (persists[CRED_TYPE_GENERIC] == CRED_PERSIST_NONE)
skip("CRED_TYPE_GENERIC credentials are not supported or are disabled. Skipping\n");
diff --git a/include/wincred.h b/include/wincred.h
index 5865063..59f2489 100644
--- a/include/wincred.h
+++ b/include/wincred.h
@@ -98,6 +98,37 @@ typedef struct _CREDENTIALW
DECL_WINELIB_TYPE_AW(CREDENTIAL)
DECL_WINELIB_TYPE_AW(PCREDENTIAL)

+typedef struct _CREDENTIAL_TARGET_INFORMATIONA
+{
+ LPSTR TargetName;
+ LPSTR NetbiosServerName;
+ LPSTR DnsServerName;
+ LPSTR NetbiosDomainName;
+ LPSTR DnsDomainName;
+ LPSTR DnsTreeName;
+ LPSTR PackageName;
+ DWORD Flags;
+ DWORD CredTypeCount;
+ LPDWORD CredTypes;
+} CREDENTIAL_TARGET_INFORMATIONA, *PCREDENTIAL_TARGET_INFORMATIONA;
+
+typedef struct _CREDENTIAL_TARGET_INFORMATIONW
+{
+ LPWSTR TargetName;
+ LPWSTR NetbiosServerName;
+ LPWSTR DnsServerName;
+ LPWSTR NetbiosDomainName;
+ LPWSTR DnsDomainName;
+ LPWSTR DnsTreeName;
+ LPWSTR PackageName;
+ DWORD Flags;
+ DWORD CredTypeCount;
+ LPDWORD CredTypes;
+} CREDENTIAL_TARGET_INFORMATIONW, *PCREDENTIAL_TARGET_INFORMATIONW;
+
+DECL_WINELIB_TYPE_AW(CREDENTIAL_TARGET_INFORMATION)
+DECL_WINELIB_TYPE_AW(PCREDENTIAL_TARGET_INFORMATION)
+
typedef struct _CREDUI_INFOA
{
DWORD cbSize;
@@ -157,6 +188,11 @@ DECL_WINELIB_TYPE_AW(PCREDUI_INFO)
#define CRED_PERSIST_LOCAL_MACHINE 2
#define CRED_PERSIST_ENTERPRISE 3

+/* values for CREDENTIAL_TARGET_INFORMATION::Flags */
+#define CRED_TI_SERVER_FORMAT_UNKNOWN 1
+#define CRED_TI_DOMAIN_FORMAT_UNKNOWN 2
+#define CRED_TI_ONLY_PASSWORD_REQUIRED 4
+
#define CREDUI_FLAGS_INCORRECT_PASSWORD 0x00000001
#define CREDUI_FLAGS_DO_NOT_PERSIST 0x00000002
#define CREDUI_FLAGS_REQUEST_ADMINISTRATOR 0x00000004
@@ -189,6 +225,9 @@ WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD,LPDWORD);
WINADVAPI BOOL WINAPI CredReadA(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
WINADVAPI BOOL WINAPI CredReadW(LPCWSTR,DWORD,DWORD,PCREDENTIALW *);
#define CredRead WINELIB_NAME_AW(CredRead)
+WINADVAPI BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD *,PCREDENTIALA **);
+WINADVAPI BOOL WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW,DWORD,DWORD *,PCREDENTIALW **);
+#define CredReadDomainCredentials WINELIB_NAME_AW(CredReadDomainCredentials)
WINADVAPI BOOL WINAPI CredRenameA(LPCSTR,LPCSTR,DWORD,DWORD);
WINADVAPI BOOL WINAPI CredRenameW(LPCWSTR,LPCWSTR,DWORD,DWORD);
#define CredRename WINELIB_NAME_AW(CredRename)

Reply all
Reply to author
Forward
0 new messages