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