push 4e98c31ec75caed2ea3040ac2e710b58ba1ca0e1
[wine/hacks.git] / dlls / ntdll / tests / path.c
blobe1b17676bedae3222e56d9de4694de6ad69b1b92
1 /*
2 * Unit test suite for ntdll path functions
4 * Copyright 2002 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "ntdll_test.h"
23 static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
24 LPCSTR src, DWORD srclen );
25 static NTSTATUS (WINAPI *pRtlUnicodeToMultiByteN)(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD);
26 static UINT (WINAPI *pRtlDetermineDosPathNameType_U)( PCWSTR path );
27 static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name );
28 static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN );
29 static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
30 static DWORD (WINAPI *pRtlGetFullPathName_U)(const WCHAR*,ULONG,WCHAR*,WCHAR**);
33 static void test_RtlDetermineDosPathNameType(void)
35 struct test
37 const char *path;
38 UINT ret;
41 static const struct test tests[] =
43 { "\\\\foo", 1 },
44 { "//foo", 1 },
45 { "\\/foo", 1 },
46 { "/\\foo", 1 },
47 { "\\\\", 1 },
48 { "//", 1 },
49 { "c:\\foo", 2 },
50 { "c:/foo", 2 },
51 { "c://foo", 2 },
52 { "c:\\", 2 },
53 { "c:/", 2 },
54 { "c:foo", 3 },
55 { "c:f\\oo", 3 },
56 { "c:foo/bar", 3 },
57 { "\\foo", 4 },
58 { "/foo", 4 },
59 { "\\", 4 },
60 { "/", 4 },
61 { "foo", 5 },
62 { "", 5 },
63 { "\0:foo", 5 },
64 { "\\\\.\\foo", 6 },
65 { "//./foo", 6 },
66 { "/\\./foo", 6 },
67 { "\\\\.foo", 1 },
68 { "//.foo", 1 },
69 { "\\\\.", 7 },
70 { "//.", 7 },
71 { NULL, 0 }
74 const struct test *test;
75 WCHAR buffer[MAX_PATH];
76 UINT ret;
78 for (test = tests; test->path; test++)
80 pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 );
81 ret = pRtlDetermineDosPathNameType_U( buffer );
82 ok( ret == test->ret, "Wrong result %d/%d for %s\n", ret, test->ret, test->path );
87 static void test_RtlIsDosDeviceName(void)
89 struct test
91 const char *path;
92 WORD pos;
93 WORD len;
96 static const struct test tests[] =
98 { "\\\\.\\CON", 8, 6 },
99 { "\\\\.\\con", 8, 6 },
100 { "\\\\.\\CON2", 0, 0 },
101 { "", 0, 0 },
102 { "\\\\foo\\nul", 0, 0 },
103 { "c:\\nul:", 6, 6 },
104 { "c:\\nul::", 6, 6 },
105 { "c:\\nul::::::", 6, 6 },
106 { "c:prn ", 4, 6 },
107 { "c:prn.......", 4, 6 },
108 { "c:prn... ...", 4, 6 },
109 { "c:NUL .... ", 4, 6 },
110 { "c: . . .", 0, 0 },
111 { "c:", 0, 0 },
112 { " . . . :", 0, 0 },
113 { ":", 0, 0 },
114 { "c:nul. . . :", 4, 6 },
115 { "c:nul . . :", 4, 6 },
116 { "c:nul0", 0, 0 },
117 { "c:PRN:.txt", 4, 6 },
118 { "c:aux:.txt...", 4, 6 },
119 { "c:prn:.txt:", 4, 6 },
120 { "con:", 0, 6 },
121 { "lpt1:", 0, 8 },
122 { "c:com5:", 4, 8 },
123 { "CoM4:", 0, 8 },
124 { "lpt9:", 0, 8 },
125 { "c:\\lpt0.txt", 0, 0 },
126 { "c:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
127 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
128 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
129 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
130 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
131 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
132 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6 },
133 { NULL, 0 }
136 const struct test *test;
137 WCHAR buffer[2000];
138 ULONG ret;
140 for (test = tests; test->path; test++)
142 pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 );
143 ret = pRtlIsDosDeviceName_U( buffer );
144 ok( ret == MAKELONG( test->len, test->pos ),
145 "Wrong result (%d,%d)/(%d,%d) for %s\n",
146 HIWORD(ret), LOWORD(ret), test->pos, test->len, test->path );
149 pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, "c:prn:aaa", strlen("c:prn:aaa")+1 );
150 ret = pRtlIsDosDeviceName_U( buffer );
151 ok( ret == MAKELONG( 6, 4 ) || /* NT */
152 ret == MAKELONG( 0, 0), /* win9x */
153 "Wrong result (%d,%d)/(4,6) or (0,0) for c:prn:aaa\n", HIWORD(ret), LOWORD(ret) );
155 pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, "c:nul:aaa", strlen("c:nul:aaa")+1 );
156 ret = pRtlIsDosDeviceName_U( buffer );
157 ok( ret == MAKELONG( 6, 4 ) || /* NT */
158 ret == MAKELONG( 0, 0), /* win9x */
159 "Wrong result (%d,%d)/(4,6) or (0,0) for c:nul:aaa\n", HIWORD(ret), LOWORD(ret) );
162 static void test_RtlIsNameLegalDOS8Dot3(void)
164 struct test
166 const char *path;
167 BOOLEAN result;
168 BOOLEAN spaces;
171 static const struct test tests[] =
173 { "12345678", TRUE, FALSE },
174 { "123 5678", TRUE, TRUE },
175 { "12345678.", FALSE, 2 /*not set*/ },
176 { "1234 678.", FALSE, 2 /*not set*/ },
177 { "12345678.a", TRUE, FALSE },
178 { "12345678.a ", FALSE, 2 /*not set*/ },
179 { "12345678.a c", TRUE, TRUE },
180 { " 2345678.a ", FALSE, 2 /*not set*/ },
181 { "1 345678.abc", TRUE, TRUE },
182 { "1 8.a c", TRUE, TRUE },
183 { "1 3 5 7 .abc", FALSE, 2 /*not set*/ },
184 { "12345678. c", TRUE, TRUE },
185 { "123456789.a", FALSE, 2 /*not set*/ },
186 { "12345.abcd", FALSE, 2 /*not set*/ },
187 { "12345.ab d", FALSE, 2 /*not set*/ },
188 { ".abc", FALSE, 2 /*not set*/ },
189 { "12.abc.d", FALSE, 2 /*not set*/ },
190 { ".", TRUE, FALSE },
191 { "..", TRUE, FALSE },
192 { "...", FALSE, 2 /*not set*/ },
193 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", FALSE, 2 /*not set*/ },
194 { NULL, 0 }
197 const struct test *test;
198 UNICODE_STRING ustr;
199 OEM_STRING oem, oem_ret;
200 WCHAR buffer[200];
201 char buff2[12];
202 BOOLEAN ret, spaces;
204 ustr.MaximumLength = sizeof(buffer);
205 ustr.Buffer = buffer;
206 for (test = tests; test->path; test++)
208 char path[100];
209 strcpy(path, test->path);
210 oem.Buffer = path;
211 oem.Length = strlen(test->path);
212 oem.MaximumLength = oem.Length + 1;
213 pRtlOemStringToUnicodeString( &ustr, &oem, FALSE );
214 spaces = 2;
215 oem_ret.Length = oem_ret.MaximumLength = sizeof(buff2);
216 oem_ret.Buffer = buff2;
217 ret = pRtlIsNameLegalDOS8Dot3( &ustr, &oem_ret, &spaces );
218 ok( ret == test->result, "Wrong result %d/%d for '%s'\n", ret, test->result, test->path );
219 ok( spaces == test->spaces, "Wrong spaces value %d/%d for '%s'\n", spaces, test->spaces, test->path );
220 if (strlen(test->path) <= 12)
222 char str[13];
223 int i;
224 strcpy( str, test->path );
225 for (i = 0; str[i]; i++) str[i] = toupper(str[i]);
226 ok( oem_ret.Length == strlen(test->path), "Wrong length %d/%d for '%s'\n",
227 oem_ret.Length, lstrlenA(test->path), test->path );
228 ok( !memcmp( oem_ret.Buffer, str, oem_ret.Length ),
229 "Wrong string '%.*s'/'%s'\n", oem_ret.Length, oem_ret.Buffer, str );
233 static void test_RtlGetFullPathName_U(void)
235 struct test
237 const char *path;
238 const char *rname;
239 const char *rfile;
242 static const struct test tests[] =
244 { "c:/test", "c:\\test", "test"},
245 { "c:/test ", "c:\\test", "test"},
246 { "c:/test.", "c:\\test", "test"},
247 { "c:/test .... .. ", "c:\\test", "test"},
248 { "c:/test/ .... .. ", "c:\\test\\", NULL},
249 { "c:/test/..", "c:\\", NULL},
250 { "c:/test/.. ", "c:\\test\\", NULL},
251 { "c:/TEST", "c:\\test", "test"},
252 { "c:/test/file", "c:\\test\\file", "file"},
253 { "c:/test./file", "c:\\test\\file", "file"},
254 { "c:/test.. /file", "c:\\test.. \\file","file"},
255 { "c:/test/././file", "c:\\test\\file", "file"},
256 { "c:/test\\.\\.\\file", "c:\\test\\file", "file"},
257 { "c:/test/\\.\\.\\file", "c:\\test\\file", "file"},
258 { "c:/test\\\\.\\.\\file", "c:\\test\\file", "file"},
259 { "c:/test\\test1\\..\\.\\file", "c:\\test\\file", "file"},
260 { "c:///test\\.\\.\\file//", "c:\\test\\file\\", NULL},
261 { "c:///test\\..\\file\\..\\//", "c:\\", NULL},
262 { NULL, NULL, NULL}
265 const struct test *test;
266 WCHAR pathbufW[2*MAX_PATH], rbufferW[MAX_PATH];
267 CHAR rbufferA[MAX_PATH], rfileA[MAX_PATH];
268 ULONG ret;
269 NTSTATUS status;
270 WCHAR *file_part;
271 DWORD reslen;
272 UINT len;
274 for (test = tests; test->path; test++)
276 len= strlen(test->rname) * sizeof(WCHAR);
277 pRtlMultiByteToUnicodeN(pathbufW , sizeof(pathbufW), NULL, test->path, strlen(test->path)+1 );
278 ret = pRtlGetFullPathName_U( pathbufW,MAX_PATH, rbufferW, &file_part);
279 ok( ret == len, "Wrong result %d/%d for \"%s\"\n", ret, len, test->path );
280 ok(pRtlUnicodeToMultiByteN(rbufferA,MAX_PATH,&reslen,rbufferW,(lstrlenW(rbufferW) + 1) * sizeof(WCHAR)) == STATUS_SUCCESS,
281 "RtlUnicodeToMultiByteN failed\n");
282 ok(lstrcmpiA(rbufferA,test->rname) == 0, "Got \"%s\" expected \"%s\"\n",rbufferA,test->rname);
283 if (file_part)
285 ok(pRtlUnicodeToMultiByteN(rfileA,MAX_PATH,&reslen,file_part,(lstrlenW(file_part) + 1) * sizeof(WCHAR)) == STATUS_SUCCESS,
286 "RtlUnicodeToMultiByteN failed\n");
287 ok(test->rfile && !lstrcmpiA(rfileA,test->rfile), "Got \"%s\" expected \"%s\"\n",rfileA,test->rfile);
289 else
291 ok( !test->rfile, "Got NULL expected \"%s\"\n", test->rfile );
295 /* "c:/test../file", "c:\\test.\\file", "file"}, */
296 pRtlMultiByteToUnicodeN(pathbufW, sizeof(pathbufW), NULL,
297 "c:/test../file", strlen("c:/test../file") + 1);
298 ret = pRtlGetFullPathName_U(pathbufW, MAX_PATH, rbufferW, &file_part);
299 ok(ret == strlen("c:\\test.\\file") * sizeof(WCHAR) ||
300 ret == strlen("c:\\test..\\file") * sizeof(WCHAR), /* Vista */
301 "Expected 26 or 28, got %d\n", ret);
302 status = pRtlUnicodeToMultiByteN(rbufferA, MAX_PATH, &reslen, rbufferW,
303 (lstrlenW(rbufferW) + 1) * sizeof(WCHAR));
304 ok(status == STATUS_SUCCESS, "RtlUnicodeToMultiByteN failed\n");
305 ok(!lstrcmpiA(rbufferA, "c:\\test.\\file") ||
306 !lstrcmpiA(rbufferA, "c:\\test..\\file"),
307 "Expected \"c:\\test.\\file\" or \"c:\\test..\\file\", got \"%s\"\n", rbufferA);
308 status = pRtlUnicodeToMultiByteN(rfileA, MAX_PATH, &reslen, file_part,
309 (lstrlenW(file_part) + 1) * sizeof(WCHAR));
310 ok(status == STATUS_SUCCESS, "RtlUnicodeToMultiByteN failed\n");
311 ok(!lstrcmpiA(rfileA, "file"), "Got \"%s\" expected \"file\"\n", rfileA);
314 START_TEST(path)
316 HMODULE mod = GetModuleHandleA("ntdll.dll");
317 if (!mod)
319 win_skip("Not running on NT, skipping tests\n");
320 return;
323 pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN");
324 pRtlUnicodeToMultiByteN = (void *)GetProcAddress(mod,"RtlUnicodeToMultiByteN");
325 pRtlDetermineDosPathNameType_U = (void *)GetProcAddress(mod,"RtlDetermineDosPathNameType_U");
326 pRtlIsDosDeviceName_U = (void *)GetProcAddress(mod,"RtlIsDosDeviceName_U");
327 pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString");
328 pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3");
329 pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U");
330 if (pRtlDetermineDosPathNameType_U)
331 test_RtlDetermineDosPathNameType();
332 if (pRtlIsDosDeviceName_U)
333 test_RtlIsDosDeviceName();
334 if (pRtlIsNameLegalDOS8Dot3)
335 test_RtlIsNameLegalDOS8Dot3();
336 if (pRtlGetFullPathName_U && pRtlMultiByteToUnicodeN)
337 test_RtlGetFullPathName_U();