[KMTestSuite]
[reactos.git] / winetests / kernel32 / dosdev.c
1 /*
2 * Unit test suite for virtual substituted drive functions.
3 *
4 * Copyright 2011 Sam Arun Raj
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <stdarg.h>
22
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27
28 #define SUBST_DRIVE_LETTER 'M'
29 #define SUBST_DRIVE "M:"
30 #define SUBST_DRIVE_NON_EXIST_DIR "M:\\deadbeef"
31 #define SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR "M:\\"
32 #define SUBST_DRIVE_SEARCH "M:\\*"
33 #define SUBST_DRIVE_LOWERCASE "m:"
34 #define SUBST_DRIVE_LOWERCASE_SEARCH "m:\\*"
35 #define SUBST_DRIVE2_LETTER 'R'
36 #define SUBST_DRIVE2 "R:"
37 #define SUBST_DRIVE2_WITH_TRAILING_PATH_SEPERATOR "R:\\"
38 #define SUBST_DRIVE2_SEARCH "R:\\*"
39
40 static void test_DefineDosDeviceA(void)
41 {
42 CHAR Buffer[MAX_PATH], Target[MAX_PATH];
43 BOOL Result;
44 UINT CharCount;
45 HANDLE hnd;
46 WIN32_FIND_DATAA Data;
47 UINT SystemDriveType, DriveType1, DriveType2;
48 DWORD dwMaskPrev, dwMaskCur;
49 CHAR c;
50
51 /* Choose the symbolic link target */
52 CharCount = GetSystemWindowsDirectoryA(Target, MAX_PATH);
53 ok(CharCount > 0, "Failed to get windows directory\n");
54 c = Target[3];
55 Target[3] = '\0';
56 SystemDriveType = GetDriveTypeA(Target);
57 Target[3] = c;
58
59 /* Test with a subst drive pointing to another substed drive */
60 dwMaskPrev = GetLogicalDrives();
61 Result = DefineDosDeviceA(0, SUBST_DRIVE, Target);
62 ok(Result, "Failed to subst drive\n");
63 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
64 Result = DefineDosDeviceA(0, SUBST_DRIVE2, SUBST_DRIVE);
65 ok(Result, "Failed to subst drive\n");
66 DriveType2 = GetDriveTypeA(SUBST_DRIVE2_WITH_TRAILING_PATH_SEPERATOR);
67 dwMaskCur = GetLogicalDrives();
68 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
69 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
70 ok((dwMaskCur & (1 << (SUBST_DRIVE2_LETTER - 'A'))), "Drive bit is not set\n");
71 hnd = FindFirstFileA(SUBST_DRIVE2_SEARCH, &Data);
72 ok(hnd != INVALID_HANDLE_VALUE, "Failed to open subst drive\n");
73 if (hnd) FindClose(hnd);
74 ok(DriveType1 == DriveType2, "subst drive types don't match\n");
75 ok(DriveType1 == SystemDriveType, "subst drive types don't match\n");
76 ok(DriveType2 == SystemDriveType, "subst drive types don't match\n");
77 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, Target);
78 ok(Result, "Failed to remove subst drive using NULL Target name\n");
79 hnd = FindFirstFileA(SUBST_DRIVE2_SEARCH, &Data);
80 ok(hnd == INVALID_HANDLE_VALUE, "Opened subst drive when it should fail, we removed the target\n");
81 if (hnd) FindClose(hnd);
82 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE2, SUBST_DRIVE);
83 ok(Result, "Failed to remove subst drive using NULL Target name\n");
84 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
85 ok(!Result, "Subst drive is present even after remove attempt\n");
86 Result = QueryDosDeviceA(SUBST_DRIVE2, Buffer, MAX_PATH);
87 ok(!Result, "Subst drive is present even after remove attempt\n");
88 dwMaskCur = GetLogicalDrives();
89 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
90
91 /* Test using lowercase drive letter */
92 dwMaskPrev = GetLogicalDrives();
93 Result = DefineDosDeviceA(0, SUBST_DRIVE_LOWERCASE, Target);
94 ok(Result, "Failed to subst drive using lowercase drive letter\n");
95 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
96 ok(DriveType1 == SystemDriveType, "subst drive types don't match\n");
97 dwMaskCur = GetLogicalDrives();
98 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
99 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
100 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
101 ok(hnd != INVALID_HANDLE_VALUE, "Failed to open subst drive\n");
102 if (hnd) FindClose(hnd);
103 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE_LOWERCASE, Target);
104 ok(Result, "Failed to remove subst drive using lowercase drive letter\n");
105 Result = QueryDosDeviceA(SUBST_DRIVE_LOWERCASE, Buffer, MAX_PATH);
106 ok(!Result, "Subst drive is present even after remove attempt\n");
107 dwMaskCur = GetLogicalDrives();
108 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
109
110 /* Test remove without using DDD_EXACT_MATCH_ON_REMOVE */
111 dwMaskPrev = GetLogicalDrives();
112 Result = DefineDosDeviceA(0, SUBST_DRIVE, Target);
113 ok(Result, "Failed to subst drive\n");
114 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
115 ok(DriveType1 == SystemDriveType, "subst drive types don't match\n");
116 dwMaskCur = GetLogicalDrives();
117 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
118 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
119 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
120 ok(hnd != INVALID_HANDLE_VALUE, "Failed to open subst drive\n");
121 if (hnd) FindClose(hnd);
122 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION, SUBST_DRIVE, NULL);
123 ok(Result, "Failed to remove subst drive using NULL Target name\n");
124 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
125 ok(!Result, "Subst drive is present even after remove attempt\n");
126 dwMaskCur = GetLogicalDrives();
127 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
128
129 /* Test multiple adds and multiple removes in add order */
130 dwMaskPrev = GetLogicalDrives();
131 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp1");
132 ok(Result, "Failed to subst drive\n");
133 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp2");
134 ok(Result, "Failed to subst drive\n");
135 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp3");
136 ok(Result, "Failed to subst drive\n");
137 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
138 ok(DriveType1 != SystemDriveType, "subst drive types match when it shouldn't\n");
139 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() reports unexpected error code\n");
140 dwMaskCur = GetLogicalDrives();
141 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
142 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
143 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp1");
144 ok(Result, "Failed to remove subst drive\n");
145 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
146 ok(Result, "Failed to query subst drive\n");
147 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp3") == 0), "Subst drive is not pointing to correct target\n");
148 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp2");
149 ok(Result, "Failed to remove subst drive\n");
150 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
151 ok(Result, "Failed to query subst drive\n");
152 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp3") == 0), "Subst drive is not pointing to correct target\n");
153 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp3");
154 ok(Result, "Failed to remove subst drive\n");
155 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
156 ok(!Result, "Subst drive is present even after remove attempt\n");
157 dwMaskCur = GetLogicalDrives();
158 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
159
160 /* Test multiple adds and multiple removes in reverse order */
161 dwMaskPrev = GetLogicalDrives();
162 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp1");
163 ok(Result, "Failed to subst drive\n");
164 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp2");
165 ok(Result, "Failed to subst drive\n");
166 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp3");
167 ok(Result, "Failed to subst drive\n");
168 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
169 ok(DriveType1 != SystemDriveType, "subst drive types match when it shouldn't\n");
170 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() reports unexpected error code\n");
171 dwMaskCur = GetLogicalDrives();
172 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
173 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
174 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp3");
175 ok(Result, "Failed to remove subst drive\n");
176 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
177 ok(Result, "Failed to query subst drive\n");
178 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp2") == 0), "Subst drive is not pointing to correct target\n");
179 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp2");
180 ok(Result, "Failed to remove subst drive\n");
181 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
182 ok(Result, "Failed to query subst drive\n");
183 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp1") == 0), "Subst drive is not pointing to correct target\n");
184 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp1");
185 ok(Result, "Failed to remove subst drive\n");
186 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
187 ok(!Result, "Subst drive is present even after remove attempt\n");
188 dwMaskCur = GetLogicalDrives();
189 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
190
191 /* Test multiple adds and multiple removes out of order */
192 dwMaskPrev = GetLogicalDrives();
193 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp1");
194 ok(Result, "Failed to subst drive\n");
195 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp2");
196 ok(Result, "Failed to subst drive\n");
197 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp3");
198 ok(Result, "Failed to subst drive\n");
199 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp4");
200 ok(Result, "Failed to subst drive\n");
201 Result = DefineDosDeviceA(0, SUBST_DRIVE, "C:\\temp5");
202 ok(Result, "Failed to subst drive\n");
203 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
204 ok(DriveType1 != SystemDriveType, "subst drive types match when it shouldn't\n");
205 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() reports unexpected error code\n");
206 dwMaskCur = GetLogicalDrives();
207 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
208 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
209 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp2");
210 ok(Result, "Failed to remove subst drive\n");
211 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
212 ok(Result, "Failed to query subst drive\n");
213 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp5") == 0), "Subst drive is not pointing to correct target\n");
214 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp5");
215 ok(Result, "Failed to remove subst drive\n");
216 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
217 ok(Result, "Failed to query subst drive\n");
218 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp4") == 0), "Subst drive is not pointing to correct target\n");
219 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp1");
220 ok(Result, "Failed to remove subst drive\n");
221 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
222 ok(Result, "Failed to query subst drive\n");
223 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp4") == 0), "Subst drive is not pointing to correct target\n");
224 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp3");
225 ok(Result, "Failed to remove subst drive\n");
226 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
227 ok(Result, "Failed to query subst drive\n");
228 if (Result) ok((_stricmp(Buffer, "\\??\\C:\\temp4") == 0), "Subst drive is not pointing to correct target");
229 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, "C:\\temp4");
230 ok(Result, "Failed to remove subst drive\n");
231 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
232 ok(!Result, "Subst drive is present even after remove attempt\n");
233 dwMaskCur = GetLogicalDrives();
234 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
235
236 /* Test with trailing '\' appended to TargetPath */
237 dwMaskPrev = GetLogicalDrives();
238 strcpy_s(Buffer, MAX_PATH, Target);
239 strcat_s(Buffer, MAX_PATH, "\\\\\\");
240 Result = DefineDosDeviceA(0, SUBST_DRIVE, Buffer);
241 ok(Result, "Failed to subst drive\n");
242 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
243 ok(DriveType1 == SystemDriveType, "subst drive types don't match\n");
244 dwMaskCur = GetLogicalDrives();
245 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
246 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
247 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
248 ok(hnd != INVALID_HANDLE_VALUE, "Failed to open subst drive\n");
249 if (hnd) FindClose(hnd);
250 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, Buffer);
251 ok(Result, "Failed to remove subst drive using NULL Target name\n");
252 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
253 ok(!Result, "Subst drive is present even after remove attempt\n");
254 dwMaskCur = GetLogicalDrives();
255 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
256
257 /* Test with trailing '\' appended to TargetPath and DDD_RAW_TARGET_PATH flag */
258 dwMaskPrev = GetLogicalDrives();
259 strcpy_s(Buffer, MAX_PATH, "\\??\\");
260 strcat_s(Buffer, MAX_PATH, Target);
261 strcat_s(Buffer, MAX_PATH, "\\\\\\");
262 Result = DefineDosDeviceA(DDD_RAW_TARGET_PATH, SUBST_DRIVE, Buffer);
263 ok(Result, "Failed to subst drive\n");
264 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
265 ok(DriveType1 != SystemDriveType, "subst drive types match when they shouldn't\n");
266 dwMaskCur = GetLogicalDrives();
267 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
268 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
269 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
270 ok(hnd == INVALID_HANDLE_VALUE, "Opened subst drive when it should fail\n");
271 ok(GetLastError() == ERROR_INVALID_NAME, "GetLastError() reports unexpected error code\n");
272 if (hnd) FindClose(hnd);
273 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION, SUBST_DRIVE, NULL);
274 ok(Result, "Failed to remove subst drive using NULL Target name\n");
275 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
276 ok(!Result, "Subst drive is present even after remove attempt\n");
277 dwMaskCur = GetLogicalDrives();
278 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
279
280 /* Test using trailing \ against drive letter */
281 dwMaskPrev = GetLogicalDrives();
282 Result = DefineDosDeviceA(0, SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR, Target);
283 ok(!Result, "Subst drive using trailing path seperator, this should not happen\n");
284 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
285 ok(DriveType1 != SystemDriveType, "subst drive types match when it shouldn't\n");
286 dwMaskCur = GetLogicalDrives();
287 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
288 ok(!(dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is set when it shouldn't\n");
289 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
290 ok(hnd == INVALID_HANDLE_VALUE, "Opened subst drive when it should fail\n");
291 if (hnd) FindClose(hnd);
292 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR, Target);
293 ok(!Result, "Removing Subst drive using trailing path seperator passed when it should fail\n");
294 Result = QueryDosDeviceA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR, Buffer, MAX_PATH);
295 ok(!Result, "Subst drive is present when it should not be created in the first place\n");
296 dwMaskCur = GetLogicalDrives();
297 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
298
299 /* Test using arbitary string, not necessarily a DOS drive letter */
300 dwMaskPrev = GetLogicalDrives();
301 Result = DefineDosDeviceA(0, "!QHello:", Target);
302 ok(Result, "Failed to subst drive using non-DOS drive name\n");
303 dwMaskCur = GetLogicalDrives();
304 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
305 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, "!QHello:", Target);
306 ok(Result, "Failed to subst drive using non-DOS drive name\n");
307 Result = QueryDosDeviceA("!QHello:", Buffer, MAX_PATH);
308 ok(!Result, "Subst drive is present even after remove attempt\n");
309 dwMaskCur = GetLogicalDrives();
310 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
311
312 /* Test by subst a drive to itself */
313 dwMaskPrev = GetLogicalDrives();
314 Result = DefineDosDeviceA(0, SUBST_DRIVE, SUBST_DRIVE);
315 ok(Result, "Failed to subst drive\n");
316 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
317 ok(DriveType1 != SystemDriveType, "subst drive types match when it shouldn't\n");
318 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() reports unexpected error code\n");
319 dwMaskCur = GetLogicalDrives();
320 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
321 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
322 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
323 ok(hnd == INVALID_HANDLE_VALUE, "Opened subst drive when it should fail\n");
324 if (hnd) FindClose(hnd);
325 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, SUBST_DRIVE);
326 ok(Result, "Failed to remove subst drive using lowercase drive letter\n");
327 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
328 ok(!Result, "Subst drive is present even after remove attempt\n");
329 dwMaskCur = GetLogicalDrives();
330 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
331
332 /* Test by subst a drive to an non-existent folder under itself */
333 dwMaskPrev = GetLogicalDrives();
334 Result = DefineDosDeviceA(0, SUBST_DRIVE, SUBST_DRIVE_NON_EXIST_DIR);
335 ok(Result, "Failed to subst drive\n");
336 DriveType1 = GetDriveTypeA(SUBST_DRIVE_WITH_TRAILING_PATH_SEPERATOR);
337 ok(DriveType1 != SystemDriveType, "subst drive types match when it shouldn't\n");
338 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() reports unexpected error code\n");
339 dwMaskCur = GetLogicalDrives();
340 ok(dwMaskCur != dwMaskPrev, "Drive masks match when it shouldn't\n");
341 ok((dwMaskCur & (1 << (SUBST_DRIVE_LETTER - 'A'))), "Drive bit is not set\n");
342 hnd = FindFirstFileA(SUBST_DRIVE_SEARCH, &Data);
343 ok(hnd == INVALID_HANDLE_VALUE, "Opened subst drive when it should fail\n");
344 if (hnd) FindClose(hnd);
345 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, SUBST_DRIVE_NON_EXIST_DIR);
346 ok(Result, "Failed to remove subst drive using lowercase drive letter\n");
347 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
348 ok(!Result, "Subst drive is present even after remove attempt\n");
349 dwMaskCur = GetLogicalDrives();
350 ok(dwMaskCur == dwMaskPrev, "Drive masks don't match\n");
351 }
352
353 static void test_QueryDosDeviceA(void)
354 {
355 CHAR Buffer[MAX_PATH], Target[MAX_PATH];
356 BOOL Result;
357 UINT CharCount;
358
359 /* Choose the symbolic link target */
360 CharCount = GetSystemWindowsDirectoryA(Target, MAX_PATH);
361 ok(CharCount > 0, "Failed to get windows directory\n");
362
363 Result = DefineDosDeviceA(0, SUBST_DRIVE, Target);
364 ok(Result, "Failed to subst drive\n");
365 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, 0);
366 ok(!Result, "Should fail as the buffer passed is supposed to be small\n");
367 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() reports unexpected error code\n");
368 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
369 ok(Result, "failed to get target path\n");
370 ok(_strnicmp(Buffer, "\\??\\", 4) == 0, "The target returned does have correct prefix set\n");
371 ok(stricmp(&Buffer[4], Target) == 0, "The target returned does not match the one set\n");
372 Result = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, SUBST_DRIVE, Target);
373 ok(Result, "Failed to remove subst drive using lowercase drive letter\n");
374 Result = QueryDosDeviceA(SUBST_DRIVE, Buffer, MAX_PATH);
375
376 /* This will try to retrieve all existing MS-DOS device names */
377 Result = QueryDosDeviceA(NULL, Buffer, 0);
378 ok(!Result, "Should fail as the buffer passed is supposed to be small\n");
379 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() reports unexpected error code\n");
380 }
381
382 START_TEST(dosdev)
383 {
384 test_DefineDosDeviceA();
385 test_QueryDosDeviceA();
386 }