[NTDLL_APITEST] Add test for RtlComputePrivatizedDllName_U
[reactos.git] / modules / rostests / apitests / ntdll / RtlComputePrivatizedDllName_U.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Test for RtlComputePrivatizedDllName_U
5 * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8 #include "precomp.h"
9
10
11 static WCHAR ProcessDir[MAX_PATH];
12 static WCHAR LocalDir[MAX_PATH + 10];
13
14 static BOOL InitTestData()
15 {
16 static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/");
17 UNICODE_STRING StrU;
18 USHORT PathDivider;
19
20 GetModuleFileNameW(NULL, ProcessDir, RTL_NUMBER_OF(ProcessDir));
21 GetModuleFileNameW(NULL, LocalDir, RTL_NUMBER_OF(LocalDir));
22
23 RtlInitUnicodeString(&StrU, ProcessDir);
24
25 if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END,
26 &StrU, &PathDividerFind, &PathDivider)))
27 {
28 skip("Failed to find path divider\n");
29 return FALSE;
30 }
31 ProcessDir[PathDivider / sizeof(WCHAR) + 1] = UNICODE_NULL;
32
33 RtlInitUnicodeString(&StrU, LocalDir);
34 StrU.MaximumLength = sizeof(LocalDir);
35
36 if (!NT_SUCCESS(RtlAppendUnicodeToString(&StrU, L".Local\\")))
37 {
38 skip("Failed to append .Local\\\n");
39 return FALSE;
40 }
41 return TRUE;
42 }
43
44 static void ok_strings_(PCUNICODE_STRING RealName, PCUNICODE_STRING LocalName, LPCWSTR DllName, int line)
45 {
46 WCHAR ExpectReal[MAX_PATH*2];
47 WCHAR ExpectLocal[MAX_PATH*2];
48 int RealLen;
49 int ExpectLen;
50
51 RealLen = swprintf(ExpectReal, L"%s%s", ProcessDir, DllName) * sizeof(WCHAR);
52 ExpectLen = swprintf(ExpectLocal, L"%s%s", LocalDir, DllName) * sizeof(WCHAR);
53
54 ok_(__FILE__, line)(RealLen == RealName->Length, "Expected Real %u, got %u\n",
55 (UINT)RealLen, (UINT)RealName->Length);
56 ok_(__FILE__, line)(ExpectLen == LocalName->Length, "Expected Local %u, got %u\n",
57 (UINT)ExpectLen, (UINT)LocalName->Length);
58
59 ok_(__FILE__, line)(!wcscmp(RealName->Buffer, ExpectReal), "Expected Real %s, got %s\n",
60 wine_dbgstr_w(ExpectReal), wine_dbgstr_w(RealName->Buffer));
61 ok_(__FILE__, line)(!wcscmp(LocalName->Buffer, ExpectLocal), "Expected Local %s, got %s\n",
62 wine_dbgstr_w(ExpectLocal), wine_dbgstr_w(LocalName->Buffer));
63 }
64 #define ok_strings(Real, Local, Dll) ok_strings_(Real, Local, Dll, __LINE__)
65
66
67 static void cleanup(PUNICODE_STRING String, WCHAR* Buffer, USHORT BufferSize)
68 {
69 if (String->Buffer != Buffer)
70 {
71 RtlFreeUnicodeString(String);
72 RtlInitEmptyUnicodeString(String, Buffer, BufferSize);
73 }
74 }
75
76
77 static void test_dllnames(void)
78 {
79 WCHAR Buf1[MAX_PATH];
80 WCHAR Buf2[MAX_PATH];
81
82 UNICODE_STRING Str1, Str2;
83 UNICODE_STRING DllName;
84 NTSTATUS Status;
85
86 RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1));
87 RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2));
88
89 RtlInitUnicodeString(&DllName, L"kernel32.dll");
90 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
91 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
92 ok_strings(&Str1, &Str2, L"kernel32.dll");
93 cleanup(&Str1, Buf1, sizeof(Buf1));
94 cleanup(&Str2, Buf2, sizeof(Buf2));
95
96
97 RtlInitUnicodeString(&DllName, L"kernel32");
98 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
99 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
100 ok_strings(&Str1, &Str2, L"kernel32.DLL");
101 cleanup(&Str1, Buf1, sizeof(Buf1));
102 cleanup(&Str2, Buf2, sizeof(Buf2));
103
104 RtlInitUnicodeString(&DllName, L"kernel32.dll.dll");
105 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
106 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
107 ok_strings(&Str1, &Str2, L"kernel32.dll.dll");
108 cleanup(&Str1, Buf1, sizeof(Buf1));
109 cleanup(&Str2, Buf2, sizeof(Buf2));
110
111 RtlInitUnicodeString(&DllName, L"kernel32.dll.exe");
112 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
113 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
114 ok_strings(&Str1, &Str2, L"kernel32.dll.exe");
115 cleanup(&Str1, Buf1, sizeof(Buf1));
116 cleanup(&Str2, Buf2, sizeof(Buf2));
117
118 RtlInitUnicodeString(&DllName, L"kernel32.");
119 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
120 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
121 ok_strings(&Str1, &Str2, L"kernel32.");
122 cleanup(&Str1, Buf1, sizeof(Buf1));
123 cleanup(&Str2, Buf2, sizeof(Buf2));
124
125 RtlInitUnicodeString(&DllName, L".kernel32");
126 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
127 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
128 ok_strings(&Str1, &Str2, L".kernel32.DLL");
129 cleanup(&Str1, Buf1, sizeof(Buf1));
130 cleanup(&Str2, Buf2, sizeof(Buf2));
131
132 RtlInitUnicodeString(&DllName, L"..kernel32");
133 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
134 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
135 ok_strings(&Str1, &Str2, L"..kernel32");
136 cleanup(&Str1, Buf1, sizeof(Buf1));
137 cleanup(&Str2, Buf2, sizeof(Buf2));
138
139 RtlInitUnicodeString(&DllName, L".kernel32.");
140 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
141 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
142 ok_strings(&Str1, &Str2, L".kernel32.");
143 cleanup(&Str1, Buf1, sizeof(Buf1));
144 cleanup(&Str2, Buf2, sizeof(Buf2));
145
146
147 RtlInitUnicodeString(&DllName, L"test\\kernel32.dll");
148 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
149 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
150 ok_strings(&Str1, &Str2, L"kernel32.dll");
151 cleanup(&Str1, Buf1, sizeof(Buf1));
152 cleanup(&Str2, Buf2, sizeof(Buf2));
153
154 RtlInitUnicodeString(&DllName, L"test/kernel32.dll");
155 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
156 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
157 ok_strings(&Str1, &Str2, L"kernel32.dll");
158 cleanup(&Str1, Buf1, sizeof(Buf1));
159 cleanup(&Str2, Buf2, sizeof(Buf2));
160
161 RtlInitUnicodeString(&DllName, L"test.dll/kernel32");
162 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
163 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
164 ok_strings(&Str1, &Str2, L"kernel32.DLL");
165 cleanup(&Str1, Buf1, sizeof(Buf1));
166 cleanup(&Str2, Buf2, sizeof(Buf2));
167
168 RtlInitUnicodeString(&DllName, L"test.dll\\kernel32");
169 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
170 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
171 ok_strings(&Str1, &Str2, L"kernel32.DLL");
172 cleanup(&Str1, Buf1, sizeof(Buf1));
173 cleanup(&Str2, Buf2, sizeof(Buf2));
174
175 RtlInitUnicodeString(&DllName, L"//");
176 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
177 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
178 ok_strings(&Str1, &Str2, L".DLL");
179 cleanup(&Str1, Buf1, sizeof(Buf1));
180 cleanup(&Str2, Buf2, sizeof(Buf2));
181
182 // Bug :)
183 RtlInitUnicodeString(&DllName, L"\\");
184 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
185 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
186 if (wcsstr(Str1.Buffer, L"\\\\"))
187 {
188 trace("Allowing bug found in windows' implementation\n");
189 ok_strings(&Str1, &Str2, L"\\.DLL");
190 }
191 else
192 {
193 ok_strings(&Str1, &Str2, L".DLL");
194 }
195 cleanup(&Str1, Buf1, sizeof(Buf1));
196 cleanup(&Str2, Buf2, sizeof(Buf2));
197
198 RtlInitUnicodeString(&DllName, L"");
199 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
200 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
201 ok_strings(&Str1, &Str2, L".DLL");
202 cleanup(&Str1, Buf1, sizeof(Buf1));
203 cleanup(&Str2, Buf2, sizeof(Buf2));
204 }
205
206 static void test_allocations(void)
207 {
208 WCHAR Buf1[10];
209 WCHAR Buf2[10];
210
211 UNICODE_STRING Str1, Str2;
212 UNICODE_STRING DllName;
213 NTSTATUS Status;
214
215 RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1));
216 RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2));
217
218 RtlInitUnicodeString(&DllName, L"kernel32.dll");
219 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
220 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
221 ok_strings(&Str1, &Str2, L"kernel32.dll");
222 ok(Str1.Buffer != Buf1, "Expected a changed buffer\n");
223 ok(Str2.Buffer != Buf2, "Expected a changed buffer\n");
224 cleanup(&Str1, Buf1, sizeof(Buf1));
225 cleanup(&Str2, Buf2, sizeof(Buf2));
226 }
227
228
229 START_TEST(RtlComputePrivatizedDllName_U)
230 {
231 if (!InitTestData())
232 return;
233
234 test_dllnames();
235 test_allocations();
236 }