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