ReactOS 0.4.16-dev-334-g4d9f67c
volume.c
Go to the documentation of this file.
1/*
2 * Unit test suite for volume functions
3 *
4 * Copyright 2006 Stefan Leichter
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 "wine/test.h"
22#include "winbase.h"
23#include "winioctl.h"
24#include <stdio.h>
25#include "wine/ddk/ntddcdvd.h"
26
27#include <pshpack1.h>
29{
33};
34#include <poppack.h>
36
37#include <pshpack1.h>
39{
43};
44#include <poppack.h>
46
48static BOOL (WINAPI * pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
49static BOOL (WINAPI * pGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD);
50static HANDLE (WINAPI *pFindFirstVolumeA)(LPSTR,DWORD);
51static BOOL (WINAPI *pFindNextVolumeA)(HANDLE,LPSTR,DWORD);
52static BOOL (WINAPI *pFindVolumeClose)(HANDLE);
53static UINT (WINAPI *pGetLogicalDriveStringsA)(UINT,LPSTR);
54static UINT (WINAPI *pGetLogicalDriveStringsW)(UINT,LPWSTR);
55static BOOL (WINAPI *pGetVolumeInformationA)(LPCSTR, LPSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPSTR, DWORD);
56static BOOL (WINAPI *pGetVolumePathNameA)(LPCSTR, LPSTR, DWORD);
57static BOOL (WINAPI *pGetVolumePathNameW)(LPWSTR, LPWSTR, DWORD);
58static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameA)(LPCSTR, LPSTR, DWORD, LPDWORD);
59static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameW)(LPCWSTR, LPWSTR, DWORD, LPDWORD);
60
61/* ############################### */
62
63static void test_query_dos_deviceA(void)
64{
65 char drivestr[] = "a:";
66 char *p, *buffer, buffer2[2000];
67 DWORD ret, ret2, buflen=32768;
68 BOOL found = FALSE;
69
70 /* callers must guess the buffer size */
71 SetLastError(0xdeadbeef);
74 "QueryDosDeviceA(no buffer): returned %u, le=%u\n", ret, GetLastError());
75
76 buffer = HeapAlloc( GetProcessHeap(), 0, buflen );
77 SetLastError(0xdeadbeef);
78 ret = QueryDosDeviceA( NULL, buffer, buflen );
80 "QueryDosDeviceA failed to return list, last error %u\n", GetLastError());
81
83 p = buffer;
84 for (;;) {
85 if (!strlen(p)) break;
86 ret2 = QueryDosDeviceA( p, buffer2, sizeof(buffer2) );
87 ok(ret2, "QueryDosDeviceA failed to return current mapping for %s, last error %u\n", p, GetLastError());
88 p += strlen(p) + 1;
89 if (ret <= (p-buffer)) break;
90 }
91 }
92
93 for (;drivestr[0] <= 'z'; drivestr[0]++) {
94 /* Older W2K fails with ERROR_INSUFFICIENT_BUFFER when buflen is > 32767 */
95 ret = QueryDosDeviceA( drivestr, buffer, buflen - 1);
97 "QueryDosDeviceA failed to return current mapping for %s, last error %u\n", drivestr, GetLastError());
98 if(ret) {
99 for (p = buffer; *p; p++) *p = toupper(*p);
100 if (strstr(buffer, "HARDDISK") || strstr(buffer, "RAMDISK")) found = TRUE;
101 }
102 }
103 ok(found, "expected at least one devicename to contain HARDDISK or RAMDISK\n");
105}
106
107static void test_define_dos_deviceA(void)
108{
109 char drivestr[3];
110 char buf[MAX_PATH];
111 DWORD ret;
112
113 /* Find an unused drive letter */
114 drivestr[1] = ':';
115 drivestr[2] = 0;
116 for (drivestr[0] = 'a'; drivestr[0] <= 'z'; drivestr[0]++) {
117 ret = QueryDosDeviceA( drivestr, buf, sizeof(buf));
118 if (!ret) break;
119 }
120 if (drivestr[0] > 'z') {
121 skip("can't test creating a dos drive, none available\n");
122 return;
123 }
124
125 /* Map it to point to the current directory */
126 ret = GetCurrentDirectoryA(sizeof(buf), buf);
127 ok(ret, "GetCurrentDir\n");
128
129 ret = DefineDosDeviceA(0, drivestr, buf);
131 ok(ret, "Could not make drive %s point to %s!\n", drivestr, buf);
132
133 if (!ret) {
134 skip("can't test removing fake drive\n");
135 } else {
137 ok(ret, "Could not remove fake drive %s!\n", drivestr);
138 }
139}
140
141static void test_FindFirstVolume(void)
142{
143 char volume[51];
145
146 /* not present before w2k */
147 if (!pFindFirstVolumeA) {
148 win_skip("FindFirstVolumeA not found\n");
149 return;
150 }
151
152 handle = pFindFirstVolumeA( volume, 0 );
153 ok( handle == INVALID_HANDLE_VALUE, "succeeded with short buffer\n" );
154 ok( GetLastError() == ERROR_MORE_DATA || /* XP */
156 "wrong error %u\n", GetLastError() );
157 handle = pFindFirstVolumeA( volume, 49 );
158 ok( handle == INVALID_HANDLE_VALUE, "succeeded with short buffer\n" );
159 ok( GetLastError() == ERROR_FILENAME_EXCED_RANGE, "wrong error %u\n", GetLastError() );
160 handle = pFindFirstVolumeA( volume, 51 );
161 ok( handle != INVALID_HANDLE_VALUE, "failed err %u\n", GetLastError() );
163 {
164 do
165 {
166 ok( strlen(volume) == 49, "bad volume name %s\n", volume );
167 ok( !memcmp( volume, "\\\\?\\Volume{", 11 ), "bad volume name %s\n", volume );
168 ok( !memcmp( volume + 47, "}\\", 2 ), "bad volume name %s\n", volume );
169 } while (pFindNextVolumeA( handle, volume, MAX_PATH ));
170 ok( GetLastError() == ERROR_NO_MORE_FILES, "wrong error %u\n", GetLastError() );
171 pFindVolumeClose( handle );
172 }
173}
174
176{
177 BOOL ret;
178 char volume[MAX_PATH], path[] = "c:\\";
179 DWORD len = sizeof(volume), reti;
180 char temp_path[MAX_PATH];
181
182 /* not present before w2k */
183 if (!pGetVolumeNameForVolumeMountPointA) {
184 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
185 return;
186 }
187
189 ok(reti != 0, "GetTempPathA error %d\n", GetLastError());
190 ok(reti < MAX_PATH, "temp path should fit into MAX_PATH\n");
191
192 ret = pGetVolumeNameForVolumeMountPointA(path, volume, 0);
193 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
195 GetLastError() == ERROR_INVALID_PARAMETER, /* Vista */
196 "wrong error, last=%d\n", GetLastError());
197
198 if (0) { /* these crash on XP */
199 ret = pGetVolumeNameForVolumeMountPointA(path, NULL, len);
200 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
201
202 ret = pGetVolumeNameForVolumeMountPointA(NULL, volume, len);
203 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
204 }
205
206 ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
207 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
208 ok(!strncmp( volume, "\\\\?\\Volume{", 11),
209 "GetVolumeNameForVolumeMountPointA failed to return valid string <%s>\n",
210 volume);
211
212 /* test with too small buffer */
213 ret = pGetVolumeNameForVolumeMountPointA(path, volume, 10);
215 "GetVolumeNameForVolumeMountPointA failed, wrong error returned, was %d, should be ERROR_FILENAME_EXCED_RANGE\n",
216 GetLastError());
217
218 /* Try on an arbitrary directory */
219 /* On FAT filesystems it seems that GetLastError() is set to
220 ERROR_INVALID_FUNCTION. */
221 ret = pGetVolumeNameForVolumeMountPointA(temp_path, volume, len);
224 "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n",
226
227 /* Try on a nonexistent dos drive */
228 path[2] = 0;
229 for (;path[0] <= 'z'; path[0]++) {
231 if(!ret) break;
232 }
233 if (path[0] <= 'z')
234 {
235 path[2] = '\\';
236 ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
238 "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n",
239 path, GetLastError());
240
241 /* Try without trailing \ and on a nonexistent dos drive */
242 path[2] = 0;
243 ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
245 "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n",
246 path, GetLastError());
247 }
248}
249
251{
252 BOOL ret;
253 WCHAR volume[MAX_PATH], path[] = {'c',':','\\',0};
254 DWORD len = sizeof(volume) / sizeof(WCHAR);
255
256 /* not present before w2k */
257 if (!pGetVolumeNameForVolumeMountPointW) {
258 win_skip("GetVolumeNameForVolumeMountPointW not found\n");
259 return;
260 }
261
262 ret = pGetVolumeNameForVolumeMountPointW(path, volume, 0);
263 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n");
265 GetLastError() == ERROR_INVALID_PARAMETER, /* Vista */
266 "wrong error, last=%d\n", GetLastError());
267
268 if (0) { /* these crash on XP */
269 ret = pGetVolumeNameForVolumeMountPointW(path, NULL, len);
270 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n");
271
272 ret = pGetVolumeNameForVolumeMountPointW(NULL, volume, len);
273 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n");
274 }
275
276 ret = pGetVolumeNameForVolumeMountPointW(path, volume, len);
277 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointW failed\n");
278}
279
281{
282 UINT size, size2;
283 char *buf, *ptr;
284
285 ok( pGetLogicalDriveStringsA != NULL, "GetLogicalDriveStringsA not available\n");
286 if(!pGetLogicalDriveStringsA) {
287 return;
288 }
289
290 size = pGetLogicalDriveStringsA(0, NULL);
291 ok(size%4 == 1, "size = %d\n", size);
292
294
295 *buf = 0;
296 size2 = pGetLogicalDriveStringsA(2, buf);
297 ok(size2 == size, "size2 = %d\n", size2);
298 ok(!*buf, "buf changed\n");
299
300 size2 = pGetLogicalDriveStringsA(size, buf);
301 ok(size2 == size-1, "size2 = %d\n", size2);
302
303 for(ptr = buf; ptr < buf+size2; ptr += 4) {
304 ok(('A' <= *ptr && *ptr <= 'Z'), "device name '%c' is not uppercase\n", *ptr);
305 ok(ptr[1] == ':', "ptr[1] = %c, expected ':'\n", ptr[1]);
306 ok(ptr[2] == '\\', "ptr[2] = %c expected '\\'\n", ptr[2]);
307 ok(!ptr[3], "ptr[3] = %c expected nullbyte\n", ptr[3]);
308 }
309 ok(!*ptr, "buf[size2] is not nullbyte\n");
310
312}
313
315{
316 UINT size, size2;
317 WCHAR *buf, *ptr;
318
319 ok( pGetLogicalDriveStringsW != NULL, "GetLogicalDriveStringsW not available\n");
320 if(!pGetLogicalDriveStringsW) {
321 return;
322 }
323
324 SetLastError(0xdeadbeef);
325 size = pGetLogicalDriveStringsW(0, NULL);
327 win_skip("GetLogicalDriveStringsW not implemented\n");
328 return;
329 }
330 ok(size%4 == 1, "size = %d\n", size);
331
332 buf = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
333
334 *buf = 0;
335 size2 = pGetLogicalDriveStringsW(2, buf);
336 ok(size2 == size, "size2 = %d\n", size2);
337 ok(!*buf, "buf changed\n");
338
339 size2 = pGetLogicalDriveStringsW(size, buf);
340 ok(size2 == size-1, "size2 = %d\n", size2);
341
342 for(ptr = buf; ptr < buf+size2; ptr += 4) {
343 ok('A' <= *ptr && *ptr <= 'Z', "device name '%c' is not uppercase\n", *ptr);
344 ok(ptr[1] == ':', "ptr[1] = %c, expected ':'\n", ptr[1]);
345 ok(ptr[2] == '\\', "ptr[2] = %c expected '\\'\n", ptr[2]);
346 ok(!ptr[3], "ptr[3] = %c expected nullbyte\n", ptr[3]);
347 }
348 ok(!*ptr, "buf[size2] is not nullbyte\n");
349
351}
352
354{
355 BOOL ret;
356 UINT result;
357 char Root_Colon[]="C:";
358 char Root_Slash[]="C:\\";
359 char Root_UNC[]="\\\\?\\C:\\";
360 char volume[MAX_PATH+1];
361 DWORD vol_name_size=MAX_PATH+1, vol_serial_num=-1, max_comp_len=0, fs_flags=0, fs_name_len=MAX_PATH+1;
362 char vol_name_buf[MAX_PATH+1], fs_name_buf[MAX_PATH+1];
363 char windowsdir[MAX_PATH+10];
364 char currentdir[MAX_PATH+1];
365
366 ok( pGetVolumeInformationA != NULL, "GetVolumeInformationA not found\n");
367 if(!pGetVolumeInformationA) {
368 return;
369 }
370
371 /* get windows drive letter and update strings for testing */
372 result = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
373 ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
374 ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError());
375 Root_Colon[0] = windowsdir[0];
376 Root_Slash[0] = windowsdir[0];
377 Root_UNC[4] = windowsdir[0];
378
379 result = GetCurrentDirectoryA(MAX_PATH, currentdir);
380 ok(result, "GetCurrentDirectory: error %d\n", GetLastError());
381 /* Note that GetCurrentDir yields no trailing slash for subdirs */
382
383 /* check for NO error on no trailing \ when current dir is root dir */
384 ret = SetCurrentDirectoryA(Root_Slash);
385 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
386 ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL,
387 NULL, NULL, fs_name_buf, fs_name_len);
388 ok(ret, "GetVolumeInformationA root failed, last error %u\n", GetLastError());
389
390 /* check for error on no trailing \ when current dir is subdir (windows) of queried drive */
391 ret = SetCurrentDirectoryA(windowsdir);
392 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
393 SetLastError(0xdeadbeef);
394 ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL,
395 NULL, NULL, fs_name_buf, fs_name_len);
397 "GetVolumeInformationA did%s fail, last error %u\n", ret ? " not":"", GetLastError());
398
399 /* reset current directory */
400 ret = SetCurrentDirectoryA(currentdir);
401 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
402
403 if (toupper(currentdir[0]) == toupper(windowsdir[0])) {
404 skip("Please re-run from another device than %c:\n", windowsdir[0]);
405 /* FIXME: Use GetLogicalDrives to find another device to avoid this skip. */
406 } else {
407 char Root_Env[]="=C:"; /* where MS maintains the per volume directory */
408 Root_Env[1] = windowsdir[0];
409
410 /* C:\windows becomes the current directory on drive C: */
411 /* Note that paths to subdirs are stored without trailing slash, like what GetCurrentDir yields. */
412 ret = SetEnvironmentVariableA(Root_Env, windowsdir);
413 ok(ret, "SetEnvironmentVariable %s failed\n", Root_Env);
414
415 ret = SetCurrentDirectoryA(windowsdir);
416 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
417 ret = SetCurrentDirectoryA(currentdir);
418 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
419
420 /* windows dir is current on the root drive, call fails */
421 SetLastError(0xdeadbeef);
422 ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL,
423 NULL, NULL, fs_name_buf, fs_name_len);
425 "GetVolumeInformationA did%s fail, last error %u\n", ret ? " not":"", GetLastError());
426
427 /* Try normal drive letter with trailing \ */
428 ret = pGetVolumeInformationA(Root_Slash, vol_name_buf, vol_name_size, NULL,
429 NULL, NULL, fs_name_buf, fs_name_len);
430 ok(ret, "GetVolumeInformationA with \\ failed, last error %u\n", GetLastError());
431
432 ret = SetCurrentDirectoryA(Root_Slash);
433 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
434 ret = SetCurrentDirectoryA(currentdir);
435 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
436
437 /* windows dir is STILL CURRENT on root drive; the call fails as before, */
438 /* proving that SetCurrentDir did not remember the other drive's directory */
439 SetLastError(0xdeadbeef);
440 ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL,
441 NULL, NULL, fs_name_buf, fs_name_len);
443 "GetVolumeInformationA did%s fail, last error %u\n", ret ? " not":"", GetLastError());
444
445 /* Now C:\ becomes the current directory on drive C: */
446 ret = SetEnvironmentVariableA(Root_Env, Root_Slash); /* set =C:=C:\ */
447 ok(ret, "SetEnvironmentVariable %s failed\n", Root_Env);
448
449 /* \ is current on root drive, call succeeds */
450 ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL,
451 NULL, NULL, fs_name_buf, fs_name_len);
452 ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError());
453
454 /* again, SetCurrentDirectory on another drive does not matter */
455 ret = SetCurrentDirectoryA(Root_Slash);
456 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
457 ret = SetCurrentDirectoryA(currentdir);
458 ok(ret, "SetCurrentDirectory: error %d\n", GetLastError());
459
460 /* \ is current on root drive, call succeeds */
461 ret = pGetVolumeInformationA(Root_Colon, vol_name_buf, vol_name_size, NULL,
462 NULL, NULL, fs_name_buf, fs_name_len);
463 ok(ret, "GetVolumeInformationA failed, last error %u\n", GetLastError());
464 }
465
466 /* try null root directory to return "root of the current directory" */
467 ret = pGetVolumeInformationA(NULL, vol_name_buf, vol_name_size, NULL,
468 NULL, NULL, fs_name_buf, fs_name_len);
469 ok(ret, "GetVolumeInformationA failed on null root dir, last error %u\n", GetLastError());
470
471 /* Try normal drive letter with trailing \ */
472 ret = pGetVolumeInformationA(Root_Slash, vol_name_buf, vol_name_size,
473 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
474 ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Slash, GetLastError());
475
476 /* try again with drive letter and the "disable parsing" prefix */
477 SetLastError(0xdeadbeef);
478 ret = pGetVolumeInformationA(Root_UNC, vol_name_buf, vol_name_size,
479 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
480 ok(ret, "GetVolumeInformationA did%s fail, root=%s, last error=%u\n", ret ? " not":"", Root_UNC, GetLastError());
481
482 /* try again with device name space */
483 Root_UNC[2] = '.';
484 SetLastError(0xdeadbeef);
485 ret = pGetVolumeInformationA(Root_UNC, vol_name_buf, vol_name_size,
486 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
487 ok(ret, "GetVolumeInformationA did%s fail, root=%s, last error=%u\n", ret ? " not":"", Root_UNC, GetLastError());
488
489 /* try again with a directory off the root - should generate error */
490 if (windowsdir[strlen(windowsdir)-1] != '\\') strcat(windowsdir, "\\");
491 SetLastError(0xdeadbeef);
492 ret = pGetVolumeInformationA(windowsdir, vol_name_buf, vol_name_size,
493 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
495 "GetVolumeInformationA did%s fail, root=%s, last error=%u\n", ret ? " not":"", windowsdir, GetLastError());
496 /* A subdir with trailing \ yields DIR_NOT_ROOT instead of INVALID_NAME */
497 if (windowsdir[strlen(windowsdir)-1] == '\\') windowsdir[strlen(windowsdir)-1] = 0;
498 SetLastError(0xdeadbeef);
499 ret = pGetVolumeInformationA(windowsdir, vol_name_buf, vol_name_size,
500 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
502 "GetVolumeInformationA did%s fail, root=%s, last error=%u\n", ret ? " not":"", windowsdir, GetLastError());
503
504 if (!pGetVolumeNameForVolumeMountPointA) {
505 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
506 return;
507 }
508 /* get the unique volume name for the windows drive */
509 ret = pGetVolumeNameForVolumeMountPointA(Root_Slash, volume, MAX_PATH);
510 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
511
512 /* try again with unique volume name */
513 ret = pGetVolumeInformationA(volume, vol_name_buf, vol_name_size,
514 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
515 ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", volume, GetLastError());
516}
517
518/* Test to check that unique volume name from windows dir mount point */
519/* matches at least one of the unique volume names returned from the */
520/* FindFirstVolumeA/FindNextVolumeA list. */
521static void test_enum_vols(void)
522{
523 DWORD ret;
525 char Volume_1[MAX_PATH] = {0};
526 char Volume_2[MAX_PATH] = {0};
527 char path[] = "c:\\";
528 BOOL found = FALSE;
529 char windowsdir[MAX_PATH];
530
531 if (!pGetVolumeNameForVolumeMountPointA) {
532 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
533 return;
534 }
535
536 /*get windows drive letter and update strings for testing */
537 ret = GetWindowsDirectoryA( windowsdir, sizeof(windowsdir) );
538 ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
539 ok(ret != 0, "GetWindowsDirectory: error %d\n", GetLastError());
540 path[0] = windowsdir[0];
541
542 /* get the unique volume name for the windows drive */
543 ret = pGetVolumeNameForVolumeMountPointA( path, Volume_1, MAX_PATH );
544 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
545 ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name %s\n", Volume_1);
546
547 /* get first unique volume name of list */
548 hFind = pFindFirstVolumeA( Volume_2, MAX_PATH );
549 ok(hFind != INVALID_HANDLE_VALUE, "FindFirstVolume failed, err=%u\n",
550 GetLastError());
551 /* ReactOS */
552 if (hFind != INVALID_HANDLE_VALUE) {
553 do
554 {
555 /* validate correct length of unique volume name */
556 ok(strlen(Volume_2) == 49, "Find[First/Next]Volume returned wrong length name %s\n", Volume_1);
557 if (memcmp(Volume_1, Volume_2, 49) == 0)
558 {
559 found = TRUE;
560 break;
561 }
562 } while (pFindNextVolumeA( hFind, Volume_2, MAX_PATH ));
563 ok(found, "volume name %s not found by Find[First/Next]Volume\n", Volume_1);
564 pFindVolumeClose( hFind );
565 }
566}
567
568static void test_disk_extents(void)
569{
570 BOOL ret;
571 DWORD size;
573 static DWORD data[16];
574
577 {
578 win_skip("can't open c: drive %u\n", GetLastError());
579 return;
580 }
581 size = 0;
583 sizeof(data), &data, sizeof(data), &size, NULL );
585 {
586 win_skip("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS not supported\n");
588 return;
589 }
590 ok(ret, "DeviceIoControl failed %u\n", GetLastError());
591 ok(size == 32, "expected 32, got %u\n", size);
593}
594
595static void test_GetVolumePathNameA(void)
596{
597 char volume_path[MAX_PATH], cwd[MAX_PATH];
598 struct {
599 const char *file_name;
600 const char *path_name;
602 DWORD error;
603 DWORD broken_error;
604 } test_paths[] = {
605 { /* test 0: NULL parameters, 0 output length */
606 NULL, NULL, 0,
607 ERROR_INVALID_PARAMETER, 0xdeadbeef /* winxp */
608 },
609 { /* test 1: empty input, NULL output, 0 output length */
610 "", NULL, 0,
611 ERROR_INVALID_PARAMETER, 0xdeadbeef /* winxp */
612 },
613 { /* test 2: valid input, NULL output, 0 output length */
614 "C:\\", NULL, 0,
616 },
617 { /* test 3: valid input, valid output, 0 output length */
618 "C:\\", "C:\\", 0,
620 },
621 { /* test 4: valid input, valid output, 1 output length */
622 "C:\\", "C:\\", 1,
624 },
625 { /* test 5: valid input, valid output, valid output length */
626 "C:\\", "C:\\", sizeof(volume_path),
628 },
629 { /* test 6: lowercase input, uppercase output, valid output length */
630 "c:\\", "C:\\", sizeof(volume_path),
632 },
633 { /* test 7: poor quality input, valid output, valid output length */
634 "C::", "C:\\", sizeof(volume_path),
636 },
637 { /* test 8: really bogus input, valid output, 1 output length */
638 "\\\\$$$", "C:\\", 1,
640 },
641 { /* test 9: a reasonable DOS path that is guaranteed to exist */
642 "C:\\windows\\system32", "C:\\", sizeof(volume_path),
644 },
645 { /* test 10: a reasonable DOS path that shouldn't exist */
646 "C:\\windows\\system32\\AnInvalidFolder", "C:\\", sizeof(volume_path),
648 },
649 { /* test 11: a reasonable NT-converted DOS path that shouldn't exist */
650 "\\\\?\\C:\\AnInvalidFolder", "\\\\?\\C:\\", sizeof(volume_path),
652 },
653 { /* test 12: an unreasonable NT-converted DOS path */
654 "\\\\?\\InvalidDrive:\\AnInvalidFolder", "\\\\?\\InvalidDrive:\\" /* win2k, winxp */,
655 sizeof(volume_path),
657 },
658 { /* test 13: an unreasonable NT volume path */
659 "\\\\?\\Volume{00000000-00-0000-0000-000000000000}\\AnInvalidFolder",
660 "\\\\?\\Volume{00000000-00-0000-0000-000000000000}\\" /* win2k, winxp */,
661 sizeof(volume_path),
663 },
664 { /* test 14: an unreasonable NT-ish path */
665 "\\\\ReallyBogus\\InvalidDrive:\\AnInvalidFolder",
666 "\\\\ReallyBogus\\InvalidDrive:\\" /* win2k, winxp */, sizeof(volume_path),
668 },
669 { /* test 15: poor quality input, valid output, valid (but short) output length */
670 "C::", "C:\\", 4,
672 },
673 { /* test 16: unused drive letter */
674 "M::", "C:\\", 4,
676 },
677 { /* test 17: an unreasonable DOS path */
678 "InvalidDrive:\\AnInvalidFolder", "%CurrentDrive%\\", sizeof(volume_path),
680 },
681 { /* test 18: a reasonable device path */
682 "\\??\\CdRom0", "%CurrentDrive%\\", sizeof(volume_path),
684 },
685 { /* test 19: an unreasonable device path */
686 "\\??\\ReallyBogus", "%CurrentDrive%\\", sizeof(volume_path),
688 },
689 { /* test 20 */
690 "C:", "C:", 2,
692 },
693 { /* test 21 */
694 "C:", "C:", 3,
696 },
697 { /* test 22 */
698 "C:\\", "C:", 2,
700 },
701 { /* test 23 */
702 "C:\\", "C:", 3,
704 },
705 { /* test 24 */
706 "C::", "C:", 2,
708 },
709 { /* test 25 */
710 "C::", "C:", 3,
712 },
713 { /* test 26 */
714 "C::", "C:\\", 4,
716 },
717 { /* test 27 */
718 "C:\\windows\\system32\\AnInvalidFolder", "C:", 3,
720 },
721 { /* test 28 */
722 "\\\\?\\C:\\AnInvalidFolder", "\\\\?\\C:", 3,
724 },
725 { /* test 29 */
726 "\\\\?\\C:\\AnInvalidFolder", "\\\\?\\C:", 6,
728 },
729 { /* test 30 */
730 "\\\\?\\C:\\AnInvalidFolder", "\\\\?\\C:", 7,
732 },
733 { /* test 31 */
734 "\\\\?\\c:\\AnInvalidFolder", "\\\\?\\c:", 7,
736 },
737 { /* test 32 */
738 "C:/", "C:\\", 4,
740 },
741 { /* test 33 */
742 "M:/", "", 4,
744 },
745 { /* test 34 */
746 "C:ABC:DEF:\\AnInvalidFolder", "C:\\", 4,
748 },
749 { /* test 35 */
750 "?:ABC:DEF:\\AnInvalidFolder", "?:\\" /* win2k, winxp */, sizeof(volume_path),
752 },
753 { /* test 36 */
754 "relative/path", "%CurrentDrive%\\", sizeof(volume_path),
756 },
757 { /* test 37 */
758 "/unix-style/absolute/path", "%CurrentDrive%\\", sizeof(volume_path),
760 },
761 { /* test 38 */
762 "\\??\\C:\\NonExistent", "%CurrentDrive%\\", sizeof(volume_path),
764 },
765 { /* test 39 */
766 "\\??\\M:\\NonExistent", "%CurrentDrive%\\", sizeof(volume_path),
768 },
769 { /* test 40 */
770 "somefile:def", "%CurrentDrive%\\", sizeof(volume_path),
772 },
773 { /* test 41 */
774 "s:omefile", "S:\\" /* win2k, winxp */, sizeof(volume_path),
776 },
777 };
779 DWORD error;
780 UINT i;
781
782 /* GetVolumePathNameA is not present before w2k */
783 if (!pGetVolumePathNameA)
784 {
785 win_skip("required functions not found\n");
786 return;
787 }
788
789 /* Obtain the drive of the working directory */
790 ret = GetCurrentDirectoryA( sizeof(cwd), cwd );
791 ok( ret, "Failed to obtain the current working directory.\n" );
792 cwd[2] = 0;
793 ret = SetEnvironmentVariableA( "CurrentDrive", cwd );
794 ok( ret, "Failed to set an environment variable for the current working drive.\n" );
795
796 for (i=0; i<sizeof(test_paths)/sizeof(test_paths[0]); i++)
797 {
798 BOOL broken_ret = test_paths[i].broken_error == NO_ERROR;
799 char *output = (test_paths[i].path_name != NULL ? volume_path : NULL);
800 BOOL expected_ret = test_paths[i].error == NO_ERROR;
801
802 volume_path[0] = 0;
803 if (test_paths[i].path_len < sizeof(volume_path))
804 volume_path[ test_paths[i].path_len ] = 0x11;
805
806 SetLastError( 0xdeadbeef );
807 ret = pGetVolumePathNameA( test_paths[i].file_name, output, test_paths[i].path_len );
809 ok(ret == expected_ret || broken(ret == broken_ret),
810 "GetVolumePathName test %d %s unexpectedly.\n",
811 i, test_paths[i].error == NO_ERROR ? "failed" : "succeeded");
812
813 if (ret)
814 {
815 char path_name[MAX_PATH];
816
818 /* If we succeeded then make sure the path is correct */
819 success = (strcmp( volume_path, path_name ) == 0)
820 || broken(strcasecmp( volume_path, path_name ) == 0) /* XP */;
821 ok(success, "GetVolumePathName test %d unexpectedly returned path %s (expected %s).\n",
822 i, volume_path, path_name);
823 }
824 else
825 {
826 /* On success Windows always returns ERROR_MORE_DATA, so only worry about failure */
827 success = (error == test_paths[i].error || broken(error == test_paths[i].broken_error));
828 ok(success, "GetVolumePathName test %d unexpectedly returned error 0x%x (expected 0x%x).\n",
829 i, error, test_paths[i].error);
830 }
831
832 if (test_paths[i].path_len < sizeof(volume_path))
833 ok(volume_path[ test_paths[i].path_len ] == 0x11,
834 "GetVolumePathName test %d corrupted byte after end of buffer.\n", i);
835 }
836}
837
838static void test_GetVolumePathNameW(void)
839{
840 static WCHAR drive_c1[] = {'C',':',0};
841 static WCHAR drive_c2[] = {'C',':','\\',0};
842 WCHAR volume_path[MAX_PATH];
843 BOOL ret;
844
845 if (!pGetVolumePathNameW)
846 {
847 win_skip("required functions not found\n");
848 return;
849 }
850
851 volume_path[0] = 0;
852 volume_path[1] = 0x11;
853 ret = pGetVolumePathNameW( drive_c1, volume_path, 1 );
854 ok(!ret, "GetVolumePathNameW test succeeded unexpectedly.\n");
855 ok(GetLastError() == ERROR_FILENAME_EXCED_RANGE, "GetVolumePathNameW unexpectedly returned error 0x%x (expected 0x%x).\n",
857 ok(volume_path[1] == 0x11, "GetVolumePathW corrupted byte after end of buffer.\n");
858
859 volume_path[0] = 0;
860 volume_path[2] = 0x11;
861 ret = pGetVolumePathNameW( drive_c1, volume_path, 2 );
862 ok(!ret, "GetVolumePathNameW test succeeded unexpectedly.\n");
863 ok(GetLastError() == ERROR_FILENAME_EXCED_RANGE, "GetVolumePathNameW unexpectedly returned error 0x%x (expected 0x%x).\n",
865 ok(volume_path[2] == 0x11, "GetVolumePathW corrupted byte after end of buffer.\n");
866
867 volume_path[0] = 0;
868 volume_path[3] = 0x11;
869 ret = pGetVolumePathNameW( drive_c1, volume_path, 3 );
870 ok(ret || broken(!ret) /* win2k */, "GetVolumePathNameW test failed unexpectedly.\n");
871 ok(memcmp(volume_path, drive_c1, sizeof(drive_c1)) == 0
872 || broken(volume_path[0] == 0) /* win2k */,
873 "GetVolumePathNameW unexpectedly returned wrong path.\n");
874 ok(volume_path[3] == 0x11, "GetVolumePathW corrupted byte after end of buffer.\n");
875
876 volume_path[0] = 0;
877 volume_path[4] = 0x11;
878 ret = pGetVolumePathNameW( drive_c1, volume_path, 4 );
879 ok(ret, "GetVolumePathNameW test failed unexpectedly.\n");
880 ok(memcmp(volume_path, drive_c2, sizeof(drive_c2)) == 0, "GetVolumePathNameW unexpectedly returned wrong path.\n");
881 ok(volume_path[4] == 0x11, "GetVolumePathW corrupted byte after end of buffer.\n");
882}
883
885{
886 BOOL ret;
888 DWORD len, error;
889
890 if (!pGetVolumePathNamesForVolumeNameA || !pGetVolumeNameForVolumeMountPointA)
891 {
892 win_skip("required functions not found\n");
893 return;
894 }
895
896 ret = pGetVolumeNameForVolumeMountPointA( "c:\\", volume, sizeof(volume) );
897 ok(ret, "failed to get volume name %u\n", GetLastError());
898 trace("c:\\ -> %s\n", volume);
899
900 SetLastError( 0xdeadbeef );
901 ret = pGetVolumePathNamesForVolumeNameA( NULL, NULL, 0, NULL );
903 ok(!ret, "expected failure\n");
904 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
905
906 SetLastError( 0xdeadbeef );
907 ret = pGetVolumePathNamesForVolumeNameA( "", NULL, 0, NULL );
909 ok(!ret, "expected failure\n");
910 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
911
912 SetLastError( 0xdeadbeef );
913 ret = pGetVolumePathNamesForVolumeNameA( volume, NULL, 0, NULL );
915 ok(!ret, "expected failure\n");
916 ok(error == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", error);
917
918 SetLastError( 0xdeadbeef );
919 ret = pGetVolumePathNamesForVolumeNameA( volume, buffer, 0, NULL );
921 ok(!ret, "expected failure\n");
922 ok(error == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", error);
923
924 memset( buffer, 0xff, sizeof(buffer) );
925 ret = pGetVolumePathNamesForVolumeNameA( volume, buffer, sizeof(buffer), NULL );
926 ok(ret, "failed to get path names %u\n", GetLastError());
927 ok(!strcmp( "C:\\", buffer ), "expected \"\\C:\" got \"%s\"\n", buffer);
928 ok(!buffer[4], "expected double null-terminated buffer\n");
929
930 len = 0;
931 SetLastError( 0xdeadbeef );
932 ret = pGetVolumePathNamesForVolumeNameA( NULL, NULL, 0, &len );
934 ok(!ret, "expected failure\n");
935 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
936
937 len = 0;
938 SetLastError( 0xdeadbeef );
939 ret = pGetVolumePathNamesForVolumeNameA( NULL, NULL, sizeof(buffer), &len );
941 ok(!ret, "expected failure\n");
942 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
943
944 len = 0;
945 SetLastError( 0xdeadbeef );
946 ret = pGetVolumePathNamesForVolumeNameA( NULL, buffer, sizeof(buffer), &len );
948 ok(!ret, "expected failure\n");
949 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
950
951 len = 0;
952 SetLastError( 0xdeadbeef );
953 ret = pGetVolumePathNamesForVolumeNameA( NULL, buffer, sizeof(buffer), &len );
955 ok(!ret, "expected failure\n");
956 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
957
958 len = 0;
959 memset( buffer, 0xff, sizeof(buffer) );
960 ret = pGetVolumePathNamesForVolumeNameA( volume, buffer, sizeof(buffer), &len );
961 ok(ret, "failed to get path names %u\n", GetLastError());
962 ok(len == 5 || broken(len == 2), "expected 5 got %u\n", len);
963 ok(!strcmp( "C:\\", buffer ), "expected \"\\C:\" got \"%s\"\n", buffer);
964 ok(!buffer[4], "expected double null-terminated buffer\n");
965}
966
968{
969 static const WCHAR empty[] = {0};
970 static const WCHAR drive_c[] = {'c',':','\\',0};
971 static const WCHAR volume_null[] = {'\\','\\','?','\\','V','o','l','u','m','e',
972 '{','0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0','0',
973 '-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}','\\',0};
974 BOOL ret;
976 DWORD len, error;
977
978#ifdef __REACTOS__
979 /* due to failing all calls to GetVolumeNameForVolumeMountPointW, this
980 * buffer never gets initialized and could cause a buffer overflow later */
981 volume[0] = '$';
982 volume[1] = 0;
983#endif /* __REACTOS__ */
984
985 if (!pGetVolumePathNamesForVolumeNameW || !pGetVolumeNameForVolumeMountPointW)
986 {
987 win_skip("required functions not found\n");
988 return;
989 }
990
991 ret = pGetVolumeNameForVolumeMountPointW( drive_c, volume, sizeof(volume)/sizeof(volume[0]) );
992 ok(ret, "failed to get volume name %u\n", GetLastError());
993
994 SetLastError( 0xdeadbeef );
995 ret = pGetVolumePathNamesForVolumeNameW( empty, NULL, 0, NULL );
997 ok(!ret, "expected failure\n");
998 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
999
1000 SetLastError( 0xdeadbeef );
1001 ret = pGetVolumePathNamesForVolumeNameW( volume, NULL, 0, NULL );
1002 error = GetLastError();
1003 ok(!ret, "expected failure\n");
1004 ok(error == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", error);
1005
1006 SetLastError( 0xdeadbeef );
1007 ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, 0, NULL );
1008 error = GetLastError();
1009 ok(!ret, "expected failure\n");
1010 ok(error == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", error);
1011
1012 if (0) { /* crash */
1013 ret = pGetVolumePathNamesForVolumeNameW( volume, NULL, sizeof(buffer), NULL );
1014 ok(ret, "failed to get path names %u\n", GetLastError());
1015 }
1016
1017 ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), NULL );
1018 ok(ret, "failed to get path names %u\n", GetLastError());
1019
1020 len = 0;
1021 memset( buffer, 0xff, sizeof(buffer) );
1022 ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
1023 ok(ret, "failed to get path names %u\n", GetLastError());
1024 ok(len == 5, "expected 5 got %u\n", len);
1025 ok(!buffer[4], "expected double null-terminated buffer\n");
1026
1027 len = 0;
1028 volume[1] = '?';
1029 volume[lstrlenW( volume ) - 1] = 0;
1030 SetLastError( 0xdeadbeef );
1031 ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
1032 error = GetLastError();
1033 ok(!ret, "expected failure\n");
1034 ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
1035
1036 len = 0;
1037 volume[0] = '\\';
1038 volume[1] = 0;
1039 SetLastError( 0xdeadbeef );
1040 ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
1041 error = GetLastError();
1042 ok(!ret, "expected failure\n");
1043 todo_wine ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
1044
1045 len = 0;
1046 lstrcpyW( volume, volume_null );
1047 SetLastError( 0xdeadbeef );
1048 ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
1049 error = GetLastError();
1050 ok(!ret, "expected failure\n");
1051 ok(error == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND got %u\n", error);
1052}
1053
1055{
1056 int i;
1057 DWORD nbBytes;
1058 BOOL ret;
1059 DVD_READ_STRUCTURE dvdReadStructure;
1060 DVD_LAYER_DESCRIPTOR dvdLayerDescriptor;
1061 struct COMPLETE_DVD_LAYER_DESCRIPTOR completeDvdLayerDescriptor;
1062 DVD_COPYRIGHT_DESCRIPTOR dvdCopyrightDescriptor;
1063 struct COMPLETE_DVD_MANUFACTURER_DESCRIPTOR completeDvdManufacturerDescriptor;
1064
1065 dvdReadStructure.BlockByteOffset.QuadPart = 0;
1066 dvdReadStructure.SessionId = 0;
1067 dvdReadStructure.LayerNumber = 0;
1068
1069
1070 /* DvdPhysicalDescriptor */
1071 dvdReadStructure.Format = 0;
1072
1073 SetLastError(0xdeadbeef);
1074
1075 /* Test whether this ioctl is supported */
1077 &completeDvdLayerDescriptor, sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
1078
1079 if(!ret)
1080 {
1081 skip("IOCTL_DVD_READ_STRUCTURE not supported: %u\n", GetLastError());
1082 return;
1083 }
1084
1085 /* Confirm there is always a header before the actual data */
1086 ok( completeDvdLayerDescriptor.Header.Length == 0x0802, "Length is 0x%04x instead of 0x0802\n", completeDvdLayerDescriptor.Header.Length);
1087 ok( completeDvdLayerDescriptor.Header.Reserved[0] == 0, "Reserved[0] is %x instead of 0\n", completeDvdLayerDescriptor.Header.Reserved[0]);
1088 ok( completeDvdLayerDescriptor.Header.Reserved[1] == 0, "Reserved[1] is %x instead of 0\n", completeDvdLayerDescriptor.Header.Reserved[1]);
1089
1090 /* TODO: Also check completeDvdLayerDescriptor.Descriptor content (via IOCTL_SCSI_PASS_THROUGH_DIRECT ?) */
1091
1092 /* Insufficient output buffer */
1093 for(i=0; i<sizeof(DVD_DESCRIPTOR_HEADER); i++)
1094 {
1095 SetLastError(0xdeadbeef);
1096
1098 &completeDvdLayerDescriptor, i, &nbBytes, NULL);
1099 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,"IOCTL_DVD_READ_STRUCTURE should fail with small buffer\n");
1100 }
1101
1102 SetLastError(0xdeadbeef);
1103
1104 /* On newer version, an output buffer of sizeof(DVD_READ_STRUCTURE) size fails.
1105 I think this is to force developers to realize that there is a header before the actual content */
1107 &dvdLayerDescriptor, sizeof(DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
1108 ok( (!ret && GetLastError() == ERROR_INVALID_PARAMETER) || broken(ret) /* < Win7 */,
1109 "IOCTL_DVD_READ_STRUCTURE should have failed\n");
1110
1111 SetLastError(0xdeadbeef);
1112
1114 &completeDvdLayerDescriptor, sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
1116 "IOCTL_DVD_READ_STRUCTURE should have failed\n");
1117
1118 /* Test wrong input parameters */
1119 for(i=0; i<sizeof(DVD_READ_STRUCTURE); i++)
1120 {
1121 SetLastError(0xdeadbeef);
1122
1123 ret = DeviceIoControl(handle, IOCTL_DVD_READ_STRUCTURE, &dvdReadStructure, i,
1124 &completeDvdLayerDescriptor, sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
1126 "IOCTL_DVD_READ_STRUCTURE should have failed\n");
1127 }
1128
1129
1130 /* DvdCopyrightDescriptor */
1131 dvdReadStructure.Format = 1;
1132
1133 SetLastError(0xdeadbeef);
1134
1135 /* Strangely, with NULL lpOutBuffer, last error is insufficient buffer, not invalid parameter as we could expect */
1137 NULL, sizeof(DVD_COPYRIGHT_DESCRIPTOR), &nbBytes, NULL);
1138 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "IOCTL_DVD_READ_STRUCTURE should have failed %d %u\n", ret, GetLastError());
1139
1140 for(i=0; i<sizeof(DVD_COPYRIGHT_DESCRIPTOR); i++)
1141 {
1142 SetLastError(0xdeadbeef);
1143
1145 &dvdCopyrightDescriptor, i, &nbBytes, NULL);
1146 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "IOCTL_DVD_READ_STRUCTURE should have failed %d %u\n", ret, GetLastError());
1147 }
1148
1149
1150 /* DvdManufacturerDescriptor */
1151 dvdReadStructure.Format = 4;
1152
1153 SetLastError(0xdeadbeef);
1154
1156 &completeDvdManufacturerDescriptor, sizeof(DVD_MANUFACTURER_DESCRIPTOR), &nbBytes, NULL);
1158 "IOCTL_DVD_READ_STRUCTURE (DvdManufacturerDescriptor) failed, last error = %u\n", GetLastError());
1159 if(!ret)
1160 return;
1161
1162 /* Confirm there is always a header before the actual data */
1163 ok( completeDvdManufacturerDescriptor.Header.Length == 0x0802, "Length is 0x%04x instead of 0x0802\n", completeDvdManufacturerDescriptor.Header.Length);
1164 ok( completeDvdManufacturerDescriptor.Header.Reserved[0] == 0, "Reserved[0] is %x instead of 0\n", completeDvdManufacturerDescriptor.Header.Reserved[0]);
1165 ok( completeDvdManufacturerDescriptor.Header.Reserved[1] == 0, "Reserved[1] is %x instead of 0\n", completeDvdManufacturerDescriptor.Header.Reserved[1]);
1166
1167 SetLastError(0xdeadbeef);
1168
1169 /* Basic parameter check */
1171 NULL, sizeof(DVD_MANUFACTURER_DESCRIPTOR), &nbBytes, NULL);
1172 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "IOCTL_DVD_READ_STRUCTURE should have failed %d %u\n", ret, GetLastError());
1173}
1174
1175static void test_cdrom_ioctl(void)
1176{
1177 char drive_letter, drive_path[] = "A:\\", drive_full_path[] = "\\\\.\\A:";
1178 DWORD bitmask;
1179 HANDLE handle;
1180
1181 bitmask = GetLogicalDrives();
1182 if(!bitmask)
1183 {
1184 trace("GetLogicalDrives failed : %u\n", GetLastError());
1185 return;
1186 }
1187
1188 for(drive_letter='A'; drive_letter<='Z'; drive_letter++)
1189 {
1190 if(!(bitmask & (1 << (drive_letter-'A') )))
1191 continue;
1192
1193 drive_path[0] = drive_letter;
1194 if(GetDriveTypeA(drive_path) != DRIVE_CDROM)
1195 {
1196 trace("Skipping %c:, not a CDROM drive.\n", drive_letter);
1197 continue;
1198 }
1199
1200 trace("Testing with %c:\n", drive_letter);
1201
1202 drive_full_path[4] = drive_letter;
1205 {
1206 trace("Failed to open the device : %u\n", GetLastError());
1207 continue;
1208 }
1209
1210 /* Add your tests here */
1212
1214 }
1215
1216}
1217
1219{
1220 hdll = GetModuleHandleA("kernel32.dll");
1221 pGetVolumeNameForVolumeMountPointA = (void *) GetProcAddress(hdll, "GetVolumeNameForVolumeMountPointA");
1222 pGetVolumeNameForVolumeMountPointW = (void *) GetProcAddress(hdll, "GetVolumeNameForVolumeMountPointW");
1223 pFindFirstVolumeA = (void *) GetProcAddress(hdll, "FindFirstVolumeA");
1224 pFindNextVolumeA = (void *) GetProcAddress(hdll, "FindNextVolumeA");
1225 pFindVolumeClose = (void *) GetProcAddress(hdll, "FindVolumeClose");
1226 pGetLogicalDriveStringsA = (void *) GetProcAddress(hdll, "GetLogicalDriveStringsA");
1227 pGetLogicalDriveStringsW = (void *) GetProcAddress(hdll, "GetLogicalDriveStringsW");
1228 pGetVolumeInformationA = (void *) GetProcAddress(hdll, "GetVolumeInformationA");
1229 pGetVolumePathNameA = (void *) GetProcAddress(hdll, "GetVolumePathNameA");
1230 pGetVolumePathNameW = (void *) GetProcAddress(hdll, "GetVolumePathNameW");
1231 pGetVolumePathNamesForVolumeNameA = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameA");
1232 pGetVolumePathNamesForVolumeNameW = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameW");
1233
1249}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int toupper(int c)
Definition: utclib.c:881
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define IOCTL_DVD_READ_STRUCTURE
Definition: cdrw_usr.h:157
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR empty[]
Definition: main.c:47
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI QueryDosDeviceA(LPCSTR lpDeviceName, LPSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:422
BOOL WINAPI DefineDosDeviceA(DWORD dwFlags, LPCSTR lpDeviceName, LPCSTR lpTargetPath)
Definition: dosdev.c:162
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:218
UINT WINAPI GetDriveTypeA(IN LPCSTR lpRootPathName)
Definition: disk.c:468
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2337
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
struct _DVD_DESCRIPTOR_HEADER DVD_DESCRIPTOR_HEADER
struct _DVD_COPYRIGHT_DESCRIPTOR DVD_COPYRIGHT_DESCRIPTOR
#define strcasecmp
Definition: fake.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static char * path_name(DOS_FILE *file)
Definition: check.c:208
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define C_ASSERT(e)
Definition: intsafe.h:73
#define DRIVE_CDROM
Definition: machpc98.h:119
#define error(str)
Definition: mkdosfs.c:1605
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
static DWORD path_len
Definition: batch.c:31
static void test_define_dos_deviceA(void)
Definition: volume.c:107
static void test_GetLogicalDriveStringsA(void)
Definition: volume.c:280
static LPSTR
Definition: volume.c:48
static void test_dvd_read_structure(HANDLE handle)
Definition: volume.c:1054
static void test_GetVolumePathNameA(void)
Definition: volume.c:595
static void test_GetVolumeInformationA(void)
Definition: volume.c:353
static void test_query_dos_deviceA(void)
Definition: volume.c:63
static void test_FindFirstVolume(void)
Definition: volume.c:141
static LPWSTR
Definition: volume.c:49
static void test_cdrom_ioctl(void)
Definition: volume.c:1175
static void test_enum_vols(void)
Definition: volume.c:521
static DWORD
Definition: volume.c:48
static void test_GetVolumePathNameW(void)
Definition: volume.c:838
static void test_GetVolumePathNamesForVolumeNameW(void)
Definition: volume.c:967
static void test_GetLogicalDriveStringsW(void)
Definition: volume.c:314
static HINSTANCE hdll
Definition: volume.c:47
static LPDWORD
Definition: volume.c:55
static void test_GetVolumePathNamesForVolumeNameA(void)
Definition: volume.c:884
static void test_GetVolumeNameForVolumeMountPointA(void)
Definition: volume.c:175
static void test_GetVolumeNameForVolumeMountPointW(void)
Definition: volume.c:250
static void test_disk_extents(void)
Definition: volume.c:568
#define todo_wine
Definition: custom.c:89
static LPCWSTR file_name
Definition: protocol.c:147
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:44
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
DVD_DESCRIPTOR_HEADER Header
Definition: volume.c:30
DVD_LAYER_DESCRIPTOR Descriptor
Definition: volume.c:31
DVD_MANUFACTURER_DESCRIPTOR Descriptor
Definition: volume.c:41
DVD_DESCRIPTOR_HEADER Header
Definition: volume.c:40
LARGE_INTEGER BlockByteOffset
Definition: ntddcdvd.h:119
DVD_SESSION_ID SessionId
Definition: ntddcdvd.h:121
DVD_STRUCTURE_FORMAT Format
Definition: ntddcdvd.h:120
UCHAR Reserved[2]
Definition: scsi.h:2839
PVOID HANDLE
Definition: typedefs.h:73
LONGLONG QuadPart
Definition: typedefs.h:114
int ret
#define success(from, fromstr, to, tostr)
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetLogicalDrives(void)
Definition: disk.c:110
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:550
#define WINAPI
Definition: msvc.h:6
#define ERROR_NOT_READY
Definition: winerror.h:124
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define ERROR_DIR_NOT_ROOT
Definition: winerror.h:216
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
#define ERROR_NOT_A_REPARSE_POINT
Definition: winerror.h:1288
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185