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, PRTL_UNICODE_STRING_BUFFER Path, PULONG Type, PULONG 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 }
443