[NTDLL] Add implementation for RtlNtPathNameToDosPathName. CORE-12847 #resolve
[reactos.git] / rostests / apitests / ntdll / RtlNtPathNameToDosPathName.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlNtPathNameToDosPathName
5 * PROGRAMMER: Mark Jansen
6 */
7
8 #include <apitest.h>
9
10 #define WIN32_NO_STATUS
11 #include <ndk/rtlfuncs.h>
12
13 NTSTATUS (NTAPI *pRtlNtPathNameToDosPathName)(ULONG Flags, RTL_UNICODE_STRING_BUFFER* Path, ULONG* Type, ULONG* Unknown4);
14
15 #define ok_hex_(expression, result) \
16 do { \
17 int _value = (expression); \
18 winetest_ok(_value == (result), "Wrong value for '%s', expected: " #result " (0x%x), got: 0x%x\n", \
19 #expression, (int)(result), _value); \
20 } while (0)
21
22
23 #define ok_ptr_(expression, result) \
24 do { \
25 void *_value = (expression); \
26 winetest_ok(_value == (result), "Wrong value for '%s', expected: " #result " (%p), got: %p\n", \
27 #expression, (void*)(result), _value); \
28 } while (0)
29
30 #define ok_wstr_(x, y) \
31 winetest_ok(wcscmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x)
32
33
34
35 struct test_entry
36 {
37 WCHAR* InputPath;
38 WCHAR* OutputPath;
39 ULONG Type;
40
41 const char* File;
42 int Line;
43 };
44
45
46 static struct test_entry test_data[] =
47 {
48 /* Originally from RtlGetFullPathName_*.c (edited) */
49 { L"", L"", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
50 { L".\\test", L".\\test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
51 { L"/test", L"/test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
52 { L"??\\", L"??\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
53 { L"??\\C:", L"??\\C:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
54 { L"??\\C:\\", L"??\\C:\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
55 { L"??\\C:\\test", L"??\\C:\\test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
56 { L"??\\C:\\test\\", L"??\\C:\\test\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
57 { L"C:", L"C:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
58 { L"C:/test/", L"C:/test/", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
59 { L"C:\\", L"C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
60 { L"C:\\", L"C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
61 { L"C:\\\\test", L"C:\\\\test", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
62 { L"C:\\test", L"C:\\test", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
63 { L"C:\\test", L"C:\\test", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
64 { L"C:\\test", L"C:\\test", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
65 { L"C:\\test\\", L"C:\\test\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
66 { L"C:\\test\\", L"C:\\test\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
67 { L"C:\\test\\", L"C:\\test\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
68 { L"\\.", L"\\.", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
69 { L"\\.\\", L"\\.\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
70 { L"\\??\\", L"", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
71 { L"\\??\\C:", L"C:", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
72 { L"\\??\\C:\\", L"C:\\", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
73 { L"\\??\\C:\\test", L"C:\\test", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
74 { L"\\??\\C:\\test\\", L"C:\\test\\", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
75 { L"\\\\.", L"\\\\.", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
76 { L"\\\\.\\", L"\\\\.\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
77 { L"\\\\.\\", L"\\\\.\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
78 { L"\\\\.\\", L"\\\\.\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
79 { L"\\\\.\\Something\\", L"\\\\.\\Something\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
80 { L"\\\\.\\Something\\", L"\\\\.\\Something\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
81 { L"\\\\??\\", L"\\\\??\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
82 { L"\\\\??\\", L"\\\\??\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
83 { L"\\\\??\\C:", L"\\\\??\\C:", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
84 { L"\\\\??\\C:", L"\\\\??\\C:", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
85 { L"\\\\??\\C:\\", L"\\\\??\\C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
86 { L"\\\\??\\C:\\", L"\\\\??\\C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
87 { L"\\\\??\\C:\\test", L"\\\\??\\C:\\test", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
88 { L"\\\\??\\C:\\test", L"\\\\??\\C:\\test", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
89 { L"\\\\??\\C:\\test\\", L"\\\\??\\C:\\test\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
90 { L"\\\\??\\C:\\test\\", L"\\\\??\\C:\\test\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
91 { L"\\test", L"\\test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
92 { L"\\test", L"\\test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
93 { L"\\test", L"\\test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
94 { L"test", L"test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
95 { L"test", L"test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
96 { L"test", L"test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
97
98 /* Originally from RtlDetermineDosPathNameType.c (edited) */
99 { L"", L"", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
100 { L" ", L" ", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
101 { L"xyz", L"xyz", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
102 { L"CON", L"CON", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
103 { L"NUL", L"NUL", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
104 { L":", L":", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
105 { L"::", L"::", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
106 { L":::", L":::", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
107 { L"::::", L"::::", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
108 { L"::\\", L"::\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
109 { L"\\", L"\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
110 { L"\\:", L"\\:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
111 { L"\\C:", L"\\C:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
112 { L"\\C:\\", L"\\C:\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
113 { L"/", L"/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
114 { L"/:", L"/:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
115 { L"/C:", L"/C:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
116 { L"/C:/", L"/C:/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
117 { L"C", L"C", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
118 { L"C:", L"C:", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
119 { L"C:a", L"C:a", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
120 { L"C:a\\", L"C:a\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
121 { L"C:\\", L"C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
122 { L"C:/", L"C:/", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
123 { L"C:\\a", L"C:\\a", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
124 { L"C:/a", L"C:/a", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
125 { L"C:\\\\", L"C:\\\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
126 { L"\\\\", L"\\\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
127 { L"\\\\\\", L"\\\\\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
128 { L"\\\\;", L"\\\\;", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
129 { L"\\\\f\\b\\", L"\\\\f\\b\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
130 { L"\\\\f\\b", L"\\\\f\\b", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
131 { L"\\\\f\\", L"\\\\f\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
132 { L"\\\\f", L"\\\\f", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
133 { L"\\??\\UNC", L"UNC", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
134 { L"\\??\\UNC\\", L"\\\\", RTL_CONVERTED_UNC_PATH, __FILE__, __LINE__ },
135 { L"\\??\\UNC\\pth1\\pth2", L"\\\\pth1\\pth2", RTL_CONVERTED_UNC_PATH, __FILE__, __LINE__ },
136 { L"\\??\\UNC\\path1", L"\\\\path1", RTL_CONVERTED_UNC_PATH, __FILE__, __LINE__ },
137 { L"\\?", L"\\?", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
138 { L"\\?\\", L"\\?\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
139 { L"\\?\\UNC", L"\\?\\UNC", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
140 { L"\\?\\UNC\\", L"\\?\\UNC\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
141 { L"\\\\?\\UNC\\", L"\\\\?\\UNC\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
142 { L"\\??\\unc", L"unc", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
143 { L"\\??\\unc\\", L"\\\\", RTL_CONVERTED_UNC_PATH, __FILE__, __LINE__ },
144 { L"\\??\\unc\\pth1\\pth2", L"\\\\pth1\\pth2", RTL_CONVERTED_UNC_PATH, __FILE__, __LINE__ },
145 { L"\\??\\unc\\path1", L"\\\\path1", RTL_CONVERTED_UNC_PATH, __FILE__, __LINE__ },
146 { L"\\?", L"\\?", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
147 { L"\\?\\", L"\\?\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
148 { L"\\?\\unc", L"\\?\\unc", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
149 { L"\\?\\unc\\", L"\\?\\unc\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
150 { L"\\\\?\\unc\\", L"\\\\?\\unc\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
151 { L"\\\\?", L"\\\\?", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
152 { L"\\\\??", L"\\\\??", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
153 { L"\\\\??\\", L"\\\\??\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
154 { L"\\\\??\\C:\\", L"\\\\??\\C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
155 { L"\\\\.", L"\\\\.", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
156 { L"\\\\.\\", L"\\\\.\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
157 { L"\\\\.\\C:\\", L"\\\\.\\C:\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
158 { L"\\/", L"\\/", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
159 { L"/\\", L"/\\", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
160 { L"//", L"//", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
161 { L"///", L"///", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
162 { L"//;", L"//;", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
163 { L"//?", L"//?", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
164 { L"/\\?", L"/\\?", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
165 { L"\\/?", L"\\/?", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
166 { L"//??", L"//??", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
167 { L"//?" L"?/", L"//?" L"?/", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
168 { L"//?" L"?/C:/", L"//?" L"?/C:/", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
169 { L"//.", L"//.", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
170 { L"\\/.", L"\\/.", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
171 { L"/\\.", L"/\\.", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
172 { L"//./", L"//./", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
173 { L"//./C:/", L"//./C:/", RTL_UNCHANGED_DOS_PATH, __FILE__, __LINE__ },
174 { L"%SystemRoot%", L"%SystemRoot%", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
175
176
177 /* Tests from RtlGetLengthWithoutTrailingPathSeperators.c */
178 { L"", L"", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
179 { L"T", L"T", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
180 { L"Te", L"Te", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
181 { L"Tes", L"Tes", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
182 { L"Test", L"Test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
183
184 /* Separators tests */
185 { L"\\.", L"\\.", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
186 { L"\\.", L"\\.", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
187 { L"\\.\\", L"\\.\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
188 { L"\\.\\T", L"\\.\\T", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
189 { L"\\.\\Te", L"\\.\\Te", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
190 { L"\\.\\Tes", L"\\.\\Tes", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
191 { L"\\.\\Test", L"\\.\\Test", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
192 { L"\\.\\Test\\", L"\\.\\Test\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
193 { L"\\.\\Test\\s", L"\\.\\Test\\s", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
194 { L"\\.\\T\\est", L"\\.\\T\\est", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
195 { L"\\.\\T\\e\\st", L"\\.\\T\\e\\st", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
196 { L"\\.\\T\\e\\s\\t", L"\\.\\T\\e\\s\\t", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
197 { L"\\.\\T\\e\\s\\t\\", L"\\.\\T\\e\\s\\t\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
198 { L"\\Tests\\String\\", L"\\Tests\\String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
199 { L"\\.\\Test\\String\\", L"\\.\\Test\\String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
200 { L"\\.\\Tests\\String\\", L"\\.\\Tests\\String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
201 { L"\\.\\Tests\\String\\s", L"\\.\\Tests\\String\\s", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
202
203 /* Separator-only tests */
204 { L"\\", L"\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
205 { L"/", L"/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
206
207 /* Mixed separators tests */
208 { L"/Test/String", L"/Test/String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
209 { L"\\Test/String", L"\\Test/String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
210 { L"/Test\\String", L"/Test\\String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
211 { L"\\Test/String", L"\\Test/String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
212 { L"/Test/String\\", L"/Test/String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
213 { L"\\Test/String\\", L"\\Test/String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
214 { L"/Test\\String\\", L"/Test\\String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
215 { L"\\Test/String\\", L"\\Test/String\\", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
216 { L"/Test/String/", L"/Test/String/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
217 { L"\\Test/String/", L"\\Test/String/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
218 { L"/Test\\String/", L"/Test\\String/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
219 { L"\\Test/String/", L"\\Test/String/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
220 { L"\\Test/String/", L"\\Test/String/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
221 { L"\\Test\\\\String/", L"\\Test\\\\String/", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
222
223 /* Common path formats tests */
224 { L"Test\\String", L"Test\\String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
225 { L"\\Test\\String", L"\\Test\\String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
226 { L".\\Test\\String", L".\\Test\\String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
227 { L"\\.\\Test\\String", L"\\.\\Test\\String", RTL_UNCHANGED_UNK_PATH, __FILE__, __LINE__ },
228 { L"\\??\\Test\\String", L"Test\\String", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
229
230 /* Redundant trailing tests */
231 { L"\\??\\Test\\String\\", L"Test\\String\\", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
232 { L"\\??\\Test\\String\\\\",L"Test\\String\\\\", RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
233 { L"\\??\\Test\\String\\\\\\\\\\", L"Test\\String\\\\\\\\\\",RTL_CONVERTED_NT_PATH, __FILE__, __LINE__ },
234 };
235
236
237 static void test_specialhandling()
238 {
239 RTL_UNICODE_STRING_BUFFER Buffer;
240 const WCHAR TestString[] = L"\\??\\C:\\Test";
241 WCHAR StaticBuffer[_countof(TestString)];
242 ULONG Type;
243 //PUCHAR Ptr;
244
245 /* Just initializing the ByteBuffer does not work */
246 memset(&Buffer, 0, sizeof(Buffer));
247 RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
248 memcpy(StaticBuffer, TestString, sizeof(TestString));
249 Type = 0x12345;
250
251 ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
252 ok_hex(Type, RTL_UNCHANGED_UNK_PATH);
253 ok_ptr(Buffer.String.Buffer, NULL);
254 ok_int(Buffer.String.Length, 0);
255 ok_int(Buffer.String.MaximumLength, 0);
256 ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
257 ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
258 RtlFreeBuffer(&Buffer.ByteBuffer);
259
260 /* Different strings in the String and ByteBuffer part */
261 memset(&Buffer, 0, sizeof(Buffer));
262 RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
263 memcpy(StaticBuffer, TestString, sizeof(TestString));
264 Type = 0x12345;
265
266 RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
267
268 ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
269 ok_hex(Type, RTL_CONVERTED_NT_PATH);
270 ok_wstr(Buffer.String.Buffer, L"C:\\Test");
271 ok_int(Buffer.String.Length, 14);
272 ok_int(Buffer.String.MaximumLength, 24);
273 ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
274 ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
275 RtlFreeBuffer(&Buffer.ByteBuffer);
276
277
278 /* Different strings, Buffer.String is not prefixed with \??\ */
279 memset(&Buffer, 0, sizeof(Buffer));
280 RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
281 memcpy(StaticBuffer, TestString, sizeof(TestString));
282 Type = 0x12345;
283
284 RtlInitUnicodeString(&Buffer.String, L"D:\\1234");
285
286 ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
287 ok_hex(Type, RTL_UNCHANGED_DOS_PATH);
288 ok_wstr(Buffer.String.Buffer, L"D:\\1234");
289 ok_int(Buffer.String.Length, 14);
290 ok_int(Buffer.String.MaximumLength, 16);
291 ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
292 ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
293 RtlFreeBuffer(&Buffer.ByteBuffer);
294
295
296 /* Different strings, smaller ByteBuffer */
297 memset(&Buffer, 0, sizeof(Buffer));
298 RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
299 memcpy(StaticBuffer, TestString, sizeof(TestString));
300 Type = 0x12345;
301
302 RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
303 Buffer.ByteBuffer.Size -= 4 * sizeof(WCHAR);
304
305 ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
306 ok_hex(Type, RTL_CONVERTED_NT_PATH);
307 ok_wstr(Buffer.String.Buffer, L"C:\\Test");
308 ok_int(Buffer.String.Length, 14);
309 ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
310 ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize - 4 * sizeof(WCHAR));
311 RtlFreeBuffer(&Buffer.ByteBuffer);
312
313
314 /* These tests show that the size of the ByteBuffer should
315 at least equal the size of the string (minus 4, in case of \??\)!
316 The results are all over the place, and are most likely the result of implementation details.. */
317
318 #if 0
319 /* Different strings, too small ByteBuffer
320 --> corrupt buffer, but none of the output params suggests so? */
321 memset(&Buffer, 0, sizeof(Buffer));
322 Buffer.ByteBuffer.Size = wcslen(TestString) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
323 Buffer.ByteBuffer.Buffer = Ptr = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Buffer.ByteBuffer.Size);
324 memcpy(Buffer.ByteBuffer.Buffer, TestString, Buffer.ByteBuffer.Size);
325 Type = 0x12345;
326
327 RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
328 Buffer.ByteBuffer.Size -= 5 * sizeof(WCHAR);
329
330 ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
331 ok_hex(Type, RTL_CONVERTED_NT_PATH);
332 //ok_wstr(Buffer.String.Buffer, L"C:\\");
333 ok_int(Buffer.String.Length, 14);
334 ok_int(Buffer.String.MaximumLength, 16);
335 //ok_ptr(Buffer.ByteBuffer.Buffer, Ptr); // An attempt is made at allocating a buffer, but the move fails because the size of ByteBuffer seems to be used??
336 ok_int(Buffer.ByteBuffer.Size, 16);
337
338 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer.ByteBuffer.Buffer);
339
340 /* Different strings, too small ByteBuffer, different path separators
341 --> corrupt buffer, but none of the output params suggests so? */
342 memset(&Buffer, 0, sizeof(Buffer));
343 Buffer.ByteBuffer.Size = wcslen(L"\\??\\C://Test") * sizeof(WCHAR) + sizeof(UNICODE_NULL);
344 Buffer.ByteBuffer.Buffer = Ptr = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Buffer.ByteBuffer.Size);
345 memcpy(Buffer.ByteBuffer.Buffer, L"\\??\\C://Test", Buffer.ByteBuffer.Size);
346 Type = 0x12345;
347
348 RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
349 Buffer.ByteBuffer.Size -= 5 * sizeof(WCHAR);
350
351 ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
352 ok_hex(Type, RTL_CONVERTED_NT_PATH);
353 //ok_wstr(Buffer.String.Buffer, L"C:\\");
354 ok_int(Buffer.String.Length, 14);
355 ok_int(Buffer.String.MaximumLength, 16);
356 ok_ptr(Buffer.ByteBuffer.Buffer, Ptr);
357 ok_int(Buffer.ByteBuffer.Size, 16);
358
359 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer.ByteBuffer.Buffer);
360 #endif
361 }
362
363 static void test_table(struct test_entry* Entry)
364 {
365 RTL_UNICODE_STRING_BUFFER Buffer = { { 0 } };
366 WCHAR StaticBuffer[MAX_PATH];
367 ULONG Type = 0x12345;
368
369 RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
370
371 RtlInitUnicodeString(&Buffer.String, Entry->InputPath);
372 RtlEnsureBufferSize(RTL_SKIP_BUFFER_COPY, &Buffer.ByteBuffer, Buffer.String.MaximumLength);
373 memcpy(Buffer.ByteBuffer.Buffer, Buffer.String.Buffer, Buffer.String.MaximumLength);
374
375 ok_hex_(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
376
377 ok_hex_(Type, Entry->Type);
378 ok_wstr_(Buffer.String.Buffer, Entry->OutputPath);
379 /* If there is no change in the path, the pointer is unchanged */
380 if (!wcscmp(Entry->InputPath, Entry->OutputPath))
381 {
382 ok_ptr_(Buffer.String.Buffer, Entry->InputPath);
383 }
384 else
385 {
386 /* If there is a change in the path, the 'ByteBuffer' is used */
387 winetest_ok((PUCHAR)Buffer.String.Buffer >= Buffer.ByteBuffer.StaticBuffer &&
388 (PUCHAR)Buffer.String.Buffer <= (Buffer.ByteBuffer.StaticBuffer + Buffer.ByteBuffer.StaticSize),
389 "Expected Buffer to point inside StaticBuffer\n");
390 }
391 ok_wstr_((const WCHAR *)Buffer.ByteBuffer.Buffer, Entry->OutputPath);
392
393 ok_hex_(Buffer.MinimumStaticBufferForTerminalNul, 0);
394
395 /* For none of our tests should we exceed the StaticBuffer size! */
396 ok_ptr_(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
397 ok_hex_(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
398
399 ok_hex_(Buffer.ByteBuffer.ReservedForAllocatedSize, 0);
400 ok_ptr_(Buffer.ByteBuffer.ReservedForIMalloc, NULL);
401
402 RtlFreeBuffer(&Buffer.ByteBuffer);
403 }
404
405
406 START_TEST(RtlNtPathNameToDosPathName)
407 {
408 RTL_UNICODE_STRING_BUFFER Buffer = { { 0 } };
409 ULONG Type;
410 size_t n;
411
412 HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
413 pRtlNtPathNameToDosPathName = (void *)GetProcAddress(ntdll, "RtlNtPathNameToDosPathName");
414
415 if (!pRtlNtPathNameToDosPathName)
416 {
417 skip("RtlNtPathNameToDosPathName not found?\n");
418 return;
419 }
420
421 ok_ntstatus(pRtlNtPathNameToDosPathName(0, NULL, NULL, NULL), STATUS_INVALID_PARAMETER);
422 ok_ntstatus(pRtlNtPathNameToDosPathName(0, &Buffer, NULL, NULL), STATUS_SUCCESS);
423 ok_ntstatus(pRtlNtPathNameToDosPathName(1, &Buffer, NULL, NULL), STATUS_INVALID_PARAMETER);
424
425 Type = 0x12345;
426 ok_ntstatus(pRtlNtPathNameToDosPathName(0, NULL, &Type, NULL), STATUS_INVALID_PARAMETER);
427 ok_int(Type, 0);
428 Type = 0x12345;
429 ok_ntstatus(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
430 ok_int(Type, RTL_UNCHANGED_UNK_PATH);
431 Type = 0x12345;
432 ok_ntstatus(pRtlNtPathNameToDosPathName(1, &Buffer, &Type, NULL), STATUS_INVALID_PARAMETER);
433 ok_int(Type, 0);
434
435 test_specialhandling();
436
437 for (n = 0; n < _countof(test_data); ++n)
438 {
439 winetest_set_location(test_data[n].File, test_data[n].Line);
440 test_table(test_data + n);
441 }
442 }