Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/advapi32/advapi32.spec | 2 +- dlls/advapi32/lsa.c | 47 ++++++++++++++++++++++++++++++++++ dlls/advapi32/tests/lsa.c | 50 ++++++++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index fcef859a7c..d5235c6adb 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -463,7 +463,7 @@ # @ stub LsaGetQuotasForAccount # @ stub LsaGetRemoteUserName @ stub LsaGetSystemAccessAccount -# @ stub LsaGetUserName +@ stdcall LsaGetUserName(ptr ptr) @ stub LsaICLookupNames # @ stub LsaICLookupNamesWithCreds @ stub LsaICLookupSids diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c index bd3585f8d0..a7c5e93ef5 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -104,6 +104,53 @@ static void* ADVAPI_GetDomainName(unsigned sz, unsigned ofs) return ptr; }
+/****************************************************************************** + * LsaGetUserName [ADVAPI32.@] + * + */ +NTSTATUS WINAPI LsaGetUserName(PUNICODE_STRING *user, PUNICODE_STRING *domain) +{ + WCHAR computer[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD user_size, domain_size; + + user_size = 0; + if (GetUserNameW(NULL, &user_size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return STATUS_UNSUCCESSFUL; + + domain_size = ARRAY_SIZE(computer); + if (!GetComputerNameW(computer, &domain_size)) + return STATUS_UNSUCCESSFUL; + + *user = heap_alloc(sizeof(*user) + user_size * sizeof(WCHAR)); + if (!*user) return STATUS_NO_MEMORY; + + (*user)->Buffer = (WCHAR *)(*user + 1); + (*user)->Length = user_size * sizeof(WCHAR); + (*user)->MaximumLength = (*user)->Length + sizeof(WCHAR); + if (!GetUserNameW((*user)->Buffer, &user_size)) + { + heap_free(*user); + return STATUS_UNSUCCESSFUL; + } + + if (domain) + { + *domain = heap_alloc(sizeof(*domain) + domain_size * sizeof(WCHAR)); + if (!*domain) + { + heap_free(*user); + return STATUS_NO_MEMORY; + } + + (*domain)->Buffer = (WCHAR *)(*domain + 1); + (*domain)->Length = domain_size * sizeof(WCHAR); + (*domain)->MaximumLength = (*domain)->Length + sizeof(WCHAR); + wcscpy((*domain)->Buffer, computer); + } + + return STATUS_SUCCESS; +} + /****************************************************************************** * LsaAddAccountRights [ADVAPI32.@] * diff --git a/dlls/advapi32/tests/lsa.c b/dlls/advapi32/tests/lsa.c index f2e10671a4..d616d509c8 100644 --- a/dlls/advapi32/tests/lsa.c +++ b/dlls/advapi32/tests/lsa.c @@ -2,6 +2,7 @@ * Unit tests for lsa functions * * Copyright (c) 2006 Robert Reif + * Copyright (c) 2020 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,6 +39,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*); +static NTSTATUS (WINAPI *pLsaGetUserName)(PUNICODE_STRING *user, PUNICODE_STRING *domain);
static void test_lsa(void) { @@ -463,13 +465,59 @@ static void test_LsaLookupPrivilegeName(void) LsaFreeMemory(name); }
+static void test_LsaGetUserName(void) +{ + NTSTATUS status; + BOOL ret; + UNICODE_STRING *lsa_user, *lsa_domain; + WCHAR user[256], computer[256]; + DWORD size; + + if (!pLsaGetUserName) + { + skip("LsaGetUserName is not available on this platform\n"); + return; + } + + size = ARRAY_SIZE(user); + ret = GetUserNameW(user, &size); + ok(ret, "GetUserName error %u\n", GetLastError()); + + size = ARRAY_SIZE(computer); + ret = GetComputerNameW(computer, &size); + ok(ret, "GetComputerName error %u\n", GetLastError()); + + if (0) /* crashes under Windows */ + status = pLsaGetUserName(NULL, NULL); + + if (0) /* crashes under Windows */ + status = pLsaGetUserName(NULL, &lsa_domain); + + status = pLsaGetUserName(&lsa_user, NULL); + ok(!status, "got %#x\n", status); + ok(!lstrcmpW(user, lsa_user->Buffer), "%s != %s\n", wine_dbgstr_w(user), wine_dbgstr_wn(lsa_user->Buffer, lsa_user->Length/sizeof(WCHAR))); + LsaFreeMemory(lsa_user); + + status = pLsaGetUserName(&lsa_user, &lsa_domain); + ok(!status, "got %#x\n", status); + ok(!lstrcmpW(user, lsa_user->Buffer), "%s != %s\n", wine_dbgstr_w(user), wine_dbgstr_wn(lsa_user->Buffer, lsa_user->Length/sizeof(WCHAR))); + /* Some Windows versions need case insensitive comparison */ + ok(!lstrcmpiW(computer, lsa_domain->Buffer), "%s != %s\n", wine_dbgstr_w(computer), wine_dbgstr_wn(lsa_domain->Buffer, lsa_domain->Length/sizeof(WCHAR))); + LsaFreeMemory(lsa_user); + LsaFreeMemory(lsa_domain); +} + START_TEST(lsa) { - HMODULE hkernel32 = GetModuleHandleA("kernel32"); + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); + HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + pGetSystemPreferredUILanguages = (void*)GetProcAddress(hkernel32, "GetSystemPreferredUILanguages"); + pLsaGetUserName = (void *)GetProcAddress(hadvapi32, "LsaGetUserName");
test_lsa(); test_LsaLookupNames2(); test_LsaLookupSids(); test_LsaLookupPrivilegeName(); + test_LsaGetUserName(); }
Dmitry Timoshkov dmitry@baikal.ru writes:
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru
dlls/advapi32/advapi32.spec | 2 +- dlls/advapi32/lsa.c | 47 ++++++++++++++++++++++++++++++++++ dlls/advapi32/tests/lsa.c | 50 ++++++++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 2 deletions(-)
This breaks the tests:
tools/runtest -q -P wine -T . -M advapi32.dll -p dlls/advapi32/tests/advapi32_test.exe lsa && touch dlls/advapi32/tests/lsa.ok wine: Unhandled page fault on read access to 00C8AB20 at address 7BC27BB6 (thread 0024), starting debugger... Unhandled exception: page fault on read access to 0x00c8ab20 in 32-bit code (0x7bc27bb6). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:7bc27bb6 ESP:0072fd80 EBP:0072fd98 EFLAGS:00010202( R- -- I - - - ) EAX:00c8ab20 EBX:00b80000 ECX:000cffe8 EDX:00bbab38 ESI:00c90000 EDI:00bbab48 Stack dump: 0x0072fd80: 0072fdb0 00000002 00bc0000 00bbab10 0x0072fd90: 00000020 00000020 0072fda8 7bc27d3b 0x0072fda0: 00000002 00110000 0072fe08 7bc29b2b 0x0072fdb0: 00110094 00bba168 00bba0d8 0000cafe 0x0072fdc0: 00000002 00000000 00000000 00000000 0x0072fdd0: 00000000 00000000 00bbab10 00000000 Backtrace: =>0 0x7bc27bb6 HEAP_CreateFreeBlock+0x66(subheap=<is not available>, ptr=0xbbab38, size=<is not available>) [Z:\home\julliard\wine\wine\dlls\ntdll\heap.c:601] in ntdll (0x0072fd98) 1 0x7bc27d3b HEAP_ShrinkBlock+0x3a(subheap=<is not available>, pArena=<is not available>, size=<is not available>) [Z:\home\julliard\wine\wine\dlls\ntdll\heap.c:704] in ntdll (0x0072fda8) 2 0x7bc29b2b RtlAllocateHeap+0xb5(heap=<is not available>, flags=<is not available>, size=<is not available>) [Z:\home\julliard\wine\wine\dlls\ntdll\heap.c:1704] in ntdll (0x0072fe08) 3 0x7bc1df2c RtlInitializeCriticalSectionEx+0x9b(spincount=0, flags=0) [Z:\home\julliard\wine\wine\dlls\ntdll\critsection.c:175] in ntdll (0x0072fe38) 4 0x7bc1dfe1 RtlInitializeCriticalSection+0x20() [Z:\home\julliard\wine\wine\dlls\ntdll\critsection.c:110] in ntdll (0x0072fe58) 5 0x7ea1ed9c (0x0072fe88) 6 0x7ea0ccca (0x0072fec8) 7 0x7ea0cf3f (0x0072fee8) 8 0x00469a7f mainCRTStartup+0x7e() [Z:\home\julliard\wine\wine\dlls\msvcrt\crt_main.c:64] in advapi32_test (0x0072ff30) 9 0x7b653910 in kernel32 (+0x3390f) (0x0072ff48) 10 0x7bc55dc7 RtlSleepConditionVariableSRW+0x196(lock=<is not available>, timeout=<is not available>, flags=<is not available>) [Z:\home\julliard\wine\wine\dlls\ntdll\sync.c:556] in ntdll (0x0072ff5c) 11 0x7bc55ff0 call_thread_func+0xaf(arg=0x7ffde000) [Z:\home\julliard\wine\wine\dlls\ntdll\thread.c:133] in ntdll (0x0072ffec) 0x7bc27bb6 HEAP_CreateFreeBlock+0x66 [Z:\home\julliard\wine\wine\dlls\ntdll\heap.c:601] in ntdll: movl 0x0(%eax),%edi 601 (*(DWORD *)((char *)ptr + size) & ARENA_FLAG_FREE))