diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index fcef859a7c1..d5235c6adb9 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 bd3585f8d06..55e42400c6d 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -104,6 +104,64 @@ static void* ADVAPI_GetDomainName(unsigned sz, unsigned ofs) return ptr; } +/****************************************************************************** + * LsaGetUserName [ADVAPI32.@] + * + */ +NTSTATUS WINAPI LsaGetUserName(PUNICODE_STRING *user_name, PUNICODE_STRING *domain_name) +{ + UNICODE_STRING *user; + DWORD user_size; + + user_size = 0; + if (GetUserNameW(NULL, &user_size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return STATUS_UNSUCCESSFUL; + + user = heap_alloc(sizeof(*user) + user_size * sizeof(WCHAR)); + if (!user) return STATUS_NO_MEMORY; + + user->Buffer = (WCHAR *)(user + 1); + user->MaximumLength = user_size * sizeof(WCHAR); + user->Length = user->MaximumLength - sizeof(WCHAR); + if (!GetUserNameW(user->Buffer, &user_size)) + { + heap_free(user); + return STATUS_UNSUCCESSFUL; + } + + if (domain_name) + { + UNICODE_STRING *domain; + WCHAR computer[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD domain_size; + + domain_size = ARRAY_SIZE(computer); + if (!GetComputerNameW(computer, &domain_size)) + { + heap_free(user); + return STATUS_UNSUCCESSFUL; + } + + domain = heap_alloc(sizeof(*domain) + (domain_size + 1) * 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); + + *domain_name = domain; + } + + *user_name = user; + + return STATUS_SUCCESS; +} + /****************************************************************************** * LsaAddAccountRights [ADVAPI32.@] * diff --git a/dlls/advapi32/tests/lsa.c b/dlls/advapi32/tests/lsa.c index 54a8528bc21..f8c822a7de2 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); + check_unicode_string(lsa_user, user); + 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))); + check_unicode_string(lsa_user, user); + check_unicode_string(lsa_domain, computer); + 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(); }