1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Tests for CachedGetUserFromSid
5  * COPYRIGHT:   Copyright 2020 Serge Gautherie <reactos-git_serge_171003@gautherie.fr>
6  */
7 
8 #include <apitest.h>
9 
10 #include <lmcons.h>
11 #include <wchar.h>
12 
13 static VOID (WINAPI *pCachedGetUserFromSid)(PSID pSid, LPWSTR pUserName, PULONG pcwcUserName);
14 
15 static void test_Sid_Null(void)
16 {
17     const WCHAR szUserNameFromNull[] = L"(unknown)";
18     const ULONG cchUserNameFromNull = (ULONG)wcslen(szUserNameFromNull);
19 
20     WCHAR szUserName[UNLEN + 1];
21     ULONG cchUserName;
22 
23     // First, full success case, to load result into cache.
24     // Otherwise, expect misbehavior/corruption/crash!
25     // Same issues with 'NULL' or '0' arguments.
26     // Behavior changed on NT6.0 then NT6.1+...
27 
28     wmemset(szUserName, L'?', _countof(szUserName));
29     cchUserName = _countof(szUserName);
30     pCachedGetUserFromSid(NULL, szUserName, &cchUserName);
31     ok(cchUserName == cchUserNameFromNull, "cchUserName: expected %lu, got %lu\n", cchUserNameFromNull, cchUserName);
32     ok(wcscmp(szUserName, szUserNameFromNull) == 0, "szUserName: expected \"%S\", got \"%.*S\"\n", szUserNameFromNull, (int)cchUserName, szUserName);
33 
34     wmemset(szUserName, L'?', _countof(szUserName));
35     cchUserName = 1;
36     pCachedGetUserFromSid(NULL, szUserName, &cchUserName);
37     ok(cchUserName == 0, "cchUserName: expected 0, got %lu\n", cchUserName);
38     ok(szUserName[0] == UNICODE_NULL, "szUserName: missing UNICODE_NULL, got \"%.*S\"\n", (int)cchUserName, szUserName);
39 
40     wmemset(szUserName, L'?', _countof(szUserName));
41     cchUserName = 2;
42     pCachedGetUserFromSid(NULL, szUserName, &cchUserName);
43     ok(cchUserName == 1, "cchUserName: expected 0, got %lu\n", cchUserName);
44     ok(szUserName[1] == UNICODE_NULL, "szUserName: missing UNICODE_NULL, got \"%.*S\"\n", (int)cchUserName, szUserName);
45     ok(wcsncmp(szUserName, szUserNameFromNull, 1) == 0, "szUserName: expected \"%.*S\", got \"%.*S\"\n", 1, szUserNameFromNull, (int)cchUserName, szUserName);
46 
47     wmemset(szUserName, L'?', _countof(szUserName));
48     cchUserName = cchUserNameFromNull;
49     pCachedGetUserFromSid(NULL, szUserName, &cchUserName);
50     ok(cchUserName == cchUserNameFromNull - 1, "cchUserName: expected %lu, got %lu\n", cchUserNameFromNull - 1, cchUserName);
51     ok(szUserName[cchUserNameFromNull - 1] == UNICODE_NULL, "szUserName: missing UNICODE_NULL, got \"%.*S\"\n", (int)cchUserName, szUserName);
52     ok(wcsncmp(szUserName, szUserNameFromNull, cchUserNameFromNull - 1) == 0, "szUserName: expected \"%.*S\", got \"%.*S\"\n", (int)cchUserNameFromNull - 1, szUserNameFromNull, (int)cchUserName, szUserName);
53 
54     wmemset(szUserName, L'?', _countof(szUserName));
55     cchUserName = cchUserNameFromNull + 1;
56     pCachedGetUserFromSid(NULL, szUserName, &cchUserName);
57     ok(cchUserName == cchUserNameFromNull, "cchUserName: expected %lu, got %lu\n", cchUserNameFromNull, cchUserName);
58     ok(wcscmp(szUserName, szUserNameFromNull) == 0, "szUserName: expected \"%S\", got \"%.*S\"\n", szUserNameFromNull, (int)cchUserName, szUserName);
59 }
60 
61 START_TEST(CachedGetUserFromSid)
62 {
63     const char szFunction[] = "CachedGetUserFromSid";
64     void* pFunction;
65 
66     // TODO: Dynamically checking, until ReactOS implements this dll.
67     HMODULE hModule;
68     DWORD dwLE;
69 
70     hModule = LoadLibraryW(L"utildll.dll");
71     if (!hModule)
72     {
73         dwLE = GetLastError();
74         ok(FALSE, "LoadLibraryW(\"%S\") failed! (dwLE = %lu)\n", L"utildll.dll", dwLE);
75         skip("No DLL\n");
76         return;
77     }
78 
79     pFunction = (void*)GetProcAddress(hModule, szFunction);
80     if (!pFunction)
81     {
82         dwLE = GetLastError();
83         ok(FALSE, "GetProcAddress(\"%s\") failed! (dwLE = %lu)\n", szFunction, dwLE);
84         skip("No function\n");
85         FreeLibrary(hModule);
86         return;
87     }
88 
89     pCachedGetUserFromSid = pFunction;
90 
91     test_Sid_Null();
92 
93     FreeLibrary(hModule);
94 }
95