If using the default values, also set dwType to REG_SZ as our default
[wine] / dlls / ntdll / tests / path.c
1 /*
2  * Unit test suite for ntdll path functions
3  *
4  * Copyright 2002 Alexandre Julliard
5  *
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.
10  *
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.
15  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "wine/test.h"
24 #include "ntstatus.h"
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnt.h"
28 #include "winreg.h"
29 #include "winternl.h"
30
31 static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
32                                                    LPCSTR src, DWORD srclen );
33 static UINT (WINAPI *pRtlDetermineDosPathNameType_U)( PCWSTR path );
34 static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name );
35 static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN );
36 static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
37
38 static void test_RtlDetermineDosPathNameType(void)
39 {
40     struct test
41     {
42         const char *path;
43         int ret;
44     };
45
46     static const struct test tests[] =
47     {
48         { "\\\\foo", 1 },
49         { "//foo", 1 },
50         { "\\/foo", 1 },
51         { "/\\foo", 1 },
52         { "\\\\", 1 },
53         { "//", 1 },
54         { "c:\\foo", 2 },
55         { "c:/foo", 2 },
56         { "c://foo", 2 },
57         { "c:\\", 2 },
58         { "c:/", 2 },
59         { "c:foo", 3 },
60         { "c:f\\oo", 3 },
61         { "c:foo/bar", 3 },
62         { "\\foo", 4 },
63         { "/foo", 4 },
64         { "\\", 4 },
65         { "/", 4 },
66         { "foo", 5 },
67         { "", 5 },
68         { "\0:foo", 5 },
69         { "\\\\.\\foo", 6 },
70         { "//./foo", 6 },
71         { "/\\./foo", 6 },
72         { "\\\\.foo", 1 },
73         { "//.foo", 1 },
74         { "\\\\.", 7 },
75         { "//.", 7 },
76         { NULL, 0 }
77     };
78
79     const struct test *test;
80     WCHAR buffer[MAX_PATH];
81     UINT ret;
82
83     for (test = tests; test->path; test++)
84     {
85         pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 );
86         ret = pRtlDetermineDosPathNameType_U( buffer );
87         ok( ret == test->ret, "Wrong result %d/%d for %s", ret, test->ret, test->path );
88     }
89 }
90
91
92 static void test_RtlIsDosDeviceName(void)
93 {
94     struct test
95     {
96         const char *path;
97         WORD pos;
98         WORD len;
99     };
100
101     static const struct test tests[] =
102     {
103         { "\\\\.\\CON",    8, 6 },
104         { "\\\\.\\con",    8, 6 },
105         { "\\\\.\\CON2",   0, 0 },
106         { "",              0, 0 },
107         { "\\\\foo\\nul",  0, 0 },
108         { "c:\\nul:",      6, 6 },
109         { "c:\\nul::",     0, 0 },
110         { "c:prn     ",    4, 6 },
111         { "c:prn.......",  4, 6 },
112         { "c:prn... ...",  4, 6 },
113         { "c:NUL  ....  ", 0, 0 },
114         { "c: . . .",      0, 0 },
115         { "c:",            0, 0 },
116         { " . . . :",      0, 0 },
117         { ":",             0, 0 },
118         { "c:nul. . . :",  4, 6 },
119         { "c:nul . . :",   0, 0 },
120         { "c:nul0",        0, 0 },
121         { "c:prn:aaa",     0, 0 },
122         { "c:PRN:.txt",    4, 6 },
123         { "c:aux:.txt...", 4, 6 },
124         { "c:prn:.txt:",   4, 6 },
125         { "c:nul:aaa",     0, 0 },
126         { "con:",          0, 6 },
127         { "lpt1:",         0, 8 },
128         { "c:com5:",       4, 8 },
129         { "CoM4:",         0, 8 },
130         { "lpt9:",         0, 8 },
131         { "c:\\lpt0.txt",  0, 0 },
132         { "c:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
133           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
134           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
135           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
136           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
137           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
138           "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6 },
139         { NULL, 0 }
140     };
141
142     const struct test *test;
143     WCHAR buffer[2000];
144     ULONG ret;
145
146     for (test = tests; test->path; test++)
147     {
148         pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 );
149         ret = pRtlIsDosDeviceName_U( buffer );
150         ok( ret == MAKELONG( test->len, test->pos ),
151             "Wrong result (%d,%d)/(%d,%d) for %s",
152             HIWORD(ret), LOWORD(ret), test->pos, test->len, test->path );
153     }
154 }
155
156 static void test_RtlIsNameLegalDOS8Dot3(void)
157 {
158     struct test
159     {
160         const char *path;
161         BOOLEAN result;
162         BOOLEAN spaces;
163     };
164
165     static const struct test tests[] =
166     {
167         { "12345678",     TRUE,  FALSE },
168         { "123 5678",     TRUE,  TRUE  },
169         { "12345678.",    FALSE, 2 /*not set*/ },
170         { "1234 678.",    FALSE, 2 /*not set*/ },
171         { "12345678.a",   TRUE,  FALSE },
172         { "12345678.a ",  FALSE, 2 /*not set*/ },
173         { "12345678.a c", TRUE,  TRUE  },
174         { " 2345678.a ",  FALSE, 2 /*not set*/ },
175         { "1 345678.abc", TRUE,  TRUE },
176         { "1      8.a c", TRUE,  TRUE },
177         { "1 3 5 7 .abc", FALSE, 2 /*not set*/ },
178         { "12345678.  c", TRUE,  TRUE },
179         { "123456789.a",  FALSE, 2 /*not set*/ },
180         { "12345.abcd",   FALSE, 2 /*not set*/ },
181         { "12345.ab d",   FALSE, 2 /*not set*/ },
182         { ".abc",         FALSE, 2 /*not set*/ },
183         { "12.abc.d",     FALSE, 2 /*not set*/ },
184         { ".",            TRUE,  FALSE },
185         { "..",           TRUE,  FALSE },
186         { "...",          FALSE, 2 /*not set*/ },
187         { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", FALSE, 2 /*not set*/ },
188         { NULL, 0 }
189     };
190
191     const struct test *test;
192     UNICODE_STRING ustr;
193     OEM_STRING oem, oem_ret;
194     WCHAR buffer[200];
195     char buff2[12];
196     BOOLEAN ret, spaces;
197
198     ustr.MaximumLength = sizeof(buffer);
199     ustr.Buffer = buffer;
200     for (test = tests; test->path; test++)
201     {
202         char path[100];
203         strcpy(path, test->path);
204         oem.Buffer = path;
205         oem.Length = strlen(test->path);
206         oem.MaximumLength = oem.Length + 1;
207         pRtlOemStringToUnicodeString( &ustr, &oem, FALSE );
208         spaces = 2;
209         oem_ret.Length = oem_ret.MaximumLength = sizeof(buff2);
210         oem_ret.Buffer = buff2;
211         ret = pRtlIsNameLegalDOS8Dot3( &ustr, &oem_ret, &spaces );
212         ok( ret == test->result, "Wrong result %d/%d for '%s'", ret, test->result, test->path );
213         ok( spaces == test->spaces, "Wrong spaces value %d/%d for '%s'", spaces, test->spaces, test->path );
214         if (strlen(test->path) <= 12)
215         {
216             char str[13];
217             int i;
218             strcpy( str, test->path );
219             for (i = 0; str[i]; i++) str[i] = toupper(str[i]);
220             ok( oem_ret.Length == strlen(test->path), "Wrong length %d/%d for '%s'",
221                 oem_ret.Length, strlen(test->path), test->path );
222             ok( !memcmp( oem_ret.Buffer, str, oem_ret.Length ),
223                 "Wrong string '%.*s'/'%s'", oem_ret.Length, oem_ret.Buffer, str );
224         }
225     }
226 }
227
228
229 START_TEST(path)
230 {
231     HMODULE mod = GetModuleHandleA("ntdll.dll");
232     pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN");
233     pRtlDetermineDosPathNameType_U = (void *)GetProcAddress(mod,"RtlDetermineDosPathNameType_U");
234     pRtlIsDosDeviceName_U = (void *)GetProcAddress(mod,"RtlIsDosDeviceName_U");
235     pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString");
236     pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3");
237     test_RtlDetermineDosPathNameType();
238     test_RtlIsDosDeviceName();
239     test_RtlIsNameLegalDOS8Dot3();
240 }