push 45342d27cd031b08b6cfabdf8789426cb53c1c53
[wine/hacks.git] / dlls / kernel32 / tests / volume.c
blob19fc6f08f7dcb57e8dd10be25141413c55716d03
1 /*
2 * Unit test suite
4 * Copyright 2006 Stefan Leichter
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
22 #include "winbase.h"
23 #include <stdio.h>
25 static HINSTANCE hdll;
26 static BOOL (WINAPI * pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
27 static BOOL (WINAPI * pGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD);
28 static HANDLE (WINAPI *pFindFirstVolumeA)(LPSTR,DWORD);
29 static BOOL (WINAPI *pFindNextVolumeA)(HANDLE,LPSTR,DWORD);
30 static BOOL (WINAPI *pFindVolumeClose)(HANDLE);
31 static UINT (WINAPI *pGetLogicalDriveStringsA)(UINT,LPSTR);
32 static UINT (WINAPI *pGetLogicalDriveStringsW)(UINT,LPWSTR);
33 static BOOL (WINAPI *pGetVolumeInformationA)(LPCSTR, LPSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPSTR, DWORD);
35 /* ############################### */
37 static void test_query_dos_deviceA(void)
39 char drivestr[] = "a:";
40 char *p, *buffer, buffer2[2000];
41 DWORD ret, ret2, buflen=32768;
42 BOOL found = FALSE;
44 if (!pFindFirstVolumeA) {
45 win_skip("On win9x, HARDDISK and RAMDISK not present\n");
46 return;
49 buffer = HeapAlloc( GetProcessHeap(), 0, buflen );
50 ret = QueryDosDeviceA( NULL, buffer, buflen );
51 ok(ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER,
52 "QueryDosDevice buffer too small\n");
53 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
54 HeapFree( GetProcessHeap(), 0, buffer );
55 return;
57 ok(ret, "QueryDosDeviceA failed to return list, last error %u\n", GetLastError());
58 if (ret) {
59 p = buffer;
60 for (;;) {
61 if (!strlen(p)) break;
62 ret2 = QueryDosDeviceA( p, buffer2, sizeof(buffer2) );
63 ok(ret2, "QueryDosDeviceA failed to return current mapping for %s, last error %u\n", p, GetLastError());
64 p += strlen(p) + 1;
65 if (ret <= (p-buffer)) break;
69 for (;drivestr[0] <= 'z'; drivestr[0]++) {
70 ret = QueryDosDeviceA( drivestr, buffer, buflen);
71 if(ret) {
72 for (p = buffer; *p; p++) *p = toupper(*p);
73 if (strstr(buffer, "HARDDISK") || strstr(buffer, "RAMDISK")) found = TRUE;
76 ok(found, "expected at least one devicename to contain HARDDISK or RAMDISK\n");
77 HeapFree( GetProcessHeap(), 0, buffer );
80 static void test_FindFirstVolume(void)
82 char volume[51];
83 HANDLE handle;
85 if (!pFindFirstVolumeA) {
86 skip("FindFirstVolumeA not found\n");
87 return;
90 handle = pFindFirstVolumeA( volume, 0 );
91 ok( handle == INVALID_HANDLE_VALUE, "succeeded with short buffer\n" );
92 ok( GetLastError() == ERROR_MORE_DATA || /* XP */
93 GetLastError() == ERROR_FILENAME_EXCED_RANGE, /* Vista */
94 "wrong error %u\n", GetLastError() );
95 handle = pFindFirstVolumeA( volume, 49 );
96 ok( handle == INVALID_HANDLE_VALUE, "succeeded with short buffer\n" );
97 ok( GetLastError() == ERROR_FILENAME_EXCED_RANGE, "wrong error %u\n", GetLastError() );
98 handle = pFindFirstVolumeA( volume, 51 );
99 ok( handle != INVALID_HANDLE_VALUE, "failed err %u\n", GetLastError() );
100 if (handle != INVALID_HANDLE_VALUE)
104 ok( strlen(volume) == 49, "bad volume name %s\n", volume );
105 ok( !memcmp( volume, "\\\\?\\Volume{", 11 ), "bad volume name %s\n", volume );
106 ok( !memcmp( volume + 47, "}\\", 2 ), "bad volume name %s\n", volume );
107 } while (pFindNextVolumeA( handle, volume, MAX_PATH ));
108 ok( GetLastError() == ERROR_NO_MORE_FILES, "wrong error %u\n", GetLastError() );
109 pFindVolumeClose( handle );
113 static void test_GetVolumeNameForVolumeMountPointA(void)
115 BOOL ret;
116 char volume[MAX_PATH], path[] = "c:\\";
117 DWORD len = sizeof(volume);
119 /* not present before w2k */
120 if (!pGetVolumeNameForVolumeMountPointA) {
121 skip("GetVolumeNameForVolumeMountPointA not found\n");
122 return;
125 ret = pGetVolumeNameForVolumeMountPointA(path, volume, 0);
126 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
128 if (0) { /* these crash on XP */
129 ret = pGetVolumeNameForVolumeMountPointA(path, NULL, len);
130 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
132 ret = pGetVolumeNameForVolumeMountPointA(NULL, volume, len);
133 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
136 ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
137 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
140 static void test_GetVolumeNameForVolumeMountPointW(void)
142 BOOL ret;
143 WCHAR volume[MAX_PATH], path[] = {'c',':','\\',0};
144 DWORD len = sizeof(volume) / sizeof(WCHAR);
146 /* not present before w2k */
147 if (!pGetVolumeNameForVolumeMountPointW) {
148 skip("GetVolumeNameForVolumeMountPointW not found\n");
149 return;
152 ret = pGetVolumeNameForVolumeMountPointW(path, volume, 0);
153 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n");
155 if (0) { /* these crash on XP */
156 ret = pGetVolumeNameForVolumeMountPointW(path, NULL, len);
157 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n");
159 ret = pGetVolumeNameForVolumeMountPointW(NULL, volume, len);
160 ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n");
163 ret = pGetVolumeNameForVolumeMountPointW(path, volume, len);
164 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointW failed\n");
167 static void test_GetLogicalDriveStringsA(void)
169 UINT size, size2;
170 char *buf, *ptr;
172 if(!pGetLogicalDriveStringsA) {
173 win_skip("GetLogicalDriveStringsA not available\n");
174 return;
177 size = pGetLogicalDriveStringsA(0, NULL);
178 ok(size%4 == 1, "size = %d\n", size);
180 buf = HeapAlloc(GetProcessHeap(), 0, size);
182 *buf = 0;
183 size2 = pGetLogicalDriveStringsA(2, buf);
184 ok(size2 == size, "size2 = %d\n", size2);
185 ok(!*buf, "buf changed\n");
187 size2 = pGetLogicalDriveStringsA(size, buf);
188 ok(size2 == size-1, "size2 = %d\n", size2);
190 for(ptr = buf; ptr < buf+size2; ptr += 4) {
191 ok(('A' <= *ptr && *ptr <= 'Z') ||
192 (broken('a' <= *ptr && *ptr <= 'z')), /* Win9x and WinMe */
193 "device name '%c' is not uppercase\n", *ptr);
194 ok(ptr[1] == ':', "ptr[1] = %c, expected ':'\n", ptr[1]);
195 ok(ptr[2] == '\\', "ptr[2] = %c expected '\\'\n", ptr[2]);
196 ok(!ptr[3], "ptr[3] = %c expected nullbyte\n", ptr[3]);
198 ok(!*ptr, "buf[size2] is not nullbyte\n");
200 HeapFree(GetProcessHeap(), 0, buf);
203 static void test_GetLogicalDriveStringsW(void)
205 UINT size, size2;
206 WCHAR *buf, *ptr;
208 if(!pGetLogicalDriveStringsW) {
209 win_skip("GetLogicalDriveStringsW not available\n");
210 return;
213 SetLastError(0xdeadbeef);
214 size = pGetLogicalDriveStringsW(0, NULL);
215 if (size == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
216 win_skip("GetLogicalDriveStringsW not implemented\n");
217 return;
219 ok(size%4 == 1, "size = %d\n", size);
221 buf = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
223 *buf = 0;
224 size2 = pGetLogicalDriveStringsW(2, buf);
225 ok(size2 == size, "size2 = %d\n", size2);
226 ok(!*buf, "buf changed\n");
228 size2 = pGetLogicalDriveStringsW(size, buf);
229 ok(size2 == size-1, "size2 = %d\n", size2);
231 for(ptr = buf; ptr < buf+size2; ptr += 4) {
232 ok('A' <= *ptr && *ptr <= 'Z', "device name '%c' is not uppercase\n", *ptr);
233 ok(ptr[1] == ':', "ptr[1] = %c, expected ':'\n", ptr[1]);
234 ok(ptr[2] == '\\', "ptr[2] = %c expected '\\'\n", ptr[2]);
235 ok(!ptr[3], "ptr[3] = %c expected nullbyte\n", ptr[3]);
237 ok(!*ptr, "buf[size2] is not nullbyte\n");
239 HeapFree(GetProcessHeap(), 0, buf);
242 static void test_GetVolumeInformationA(void)
244 BOOL ret;
245 UINT result;
246 char Root_Dir0[]="C:";
247 char Root_Dir1[]="C:\\";
248 char Root_Dir2[]="\\\\?\\C:\\";
249 char volume[MAX_PATH+1];
250 DWORD vol_name_size=MAX_PATH+1, vol_serial_num=-1, max_comp_len=0, fs_flags=0, fs_name_len=MAX_PATH+1;
251 char vol_name_buf[MAX_PATH+1], fs_name_buf[MAX_PATH+1];
252 char windowsdir[MAX_PATH+10];
254 if (!pGetVolumeInformationA) {
255 win_skip("GetVolumeInformationA not found\n");
256 return;
258 if (!pGetVolumeNameForVolumeMountPointA) {
259 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
260 return;
263 /* get windows drive letter and update strings for testing */
264 result = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
265 ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
266 ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError());
267 Root_Dir0[0] = windowsdir[0];
268 Root_Dir1[0] = windowsdir[0];
269 Root_Dir2[4] = windowsdir[0];
271 /* get the unique volume name for the windows drive */
272 ret = pGetVolumeNameForVolumeMountPointA(Root_Dir1, volume, MAX_PATH);
273 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
275 /* **** now start the tests **** */
276 /* check for error on no trailing \ */
277 ret = pGetVolumeInformationA(Root_Dir0, vol_name_buf, vol_name_size, NULL,
278 NULL, NULL, fs_name_buf, fs_name_len);
279 ok(!ret && GetLastError() == ERROR_INVALID_NAME,
280 "GetVolumeInformationA w/o '\\' did not fail, last error %u\n", GetLastError());
282 /* try null root directory to return "root of the current directory" */
283 ret = pGetVolumeInformationA(NULL, vol_name_buf, vol_name_size, NULL,
284 NULL, NULL, fs_name_buf, fs_name_len);
285 ok(ret, "GetVolumeInformationA failed on null root dir, last error %u\n", GetLastError());
287 /* Try normal drive letter with trailing \ */
288 ret = pGetVolumeInformationA(Root_Dir1, vol_name_buf, vol_name_size,
289 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
290 ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Dir1, GetLastError());
292 /* try again with dirve letter and the "disable parsing" prefix */
293 ret = pGetVolumeInformationA(Root_Dir2, vol_name_buf, vol_name_size,
294 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
295 todo_wine ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Dir2, GetLastError());
297 /* try again with unique voluem name */
298 ret = pGetVolumeInformationA(volume, vol_name_buf, vol_name_size,
299 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
300 todo_wine ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", volume, GetLastError());
302 /* try again with device name space */
303 Root_Dir2[2] = '.';
304 ret = pGetVolumeInformationA(Root_Dir2, vol_name_buf, vol_name_size,
305 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
306 todo_wine ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Dir2, GetLastError());
308 /* try again with a directory off the root - should generate error */
309 if (windowsdir[strlen(windowsdir)-1] != '\\') strcat(windowsdir, "\\");
310 ret = pGetVolumeInformationA(windowsdir, vol_name_buf, vol_name_size,
311 &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len);
312 todo_wine ok(!ret && GetLastError()==ERROR_DIR_NOT_ROOT,
313 "GetVolumeInformationA failed, root=%s, last error=%u\n", windowsdir, GetLastError());
316 /* Test to check that unique volume name from windows dir mount point */
317 /* matches at least one of the unique volume names returned from the */
318 /* FindFirstVolumeA/FindNextVolumeA list. */
319 static void test_enum_vols(void)
321 DWORD ret;
322 HANDLE hFind = INVALID_HANDLE_VALUE;
323 char Volume_1[MAX_PATH] = {0};
324 char Volume_2[MAX_PATH] = {0};
325 char path[] = "c:\\";
326 BOOL found = FALSE;
327 char windowsdir[MAX_PATH];
329 if (!pGetVolumeNameForVolumeMountPointA) {
330 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
331 return;
334 /*get windows drive letter and update strings for testing */
335 ret = GetWindowsDirectory( windowsdir, sizeof(windowsdir) );
336 ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
337 ok(ret != 0, "GetWindowsDirecory: error %d\n", GetLastError());
338 path[0] = windowsdir[0];
340 /* get the unique volume name for the windows drive */
341 ret = pGetVolumeNameForVolumeMountPointA( path, Volume_1, MAX_PATH );
342 ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
343 todo_wine
344 ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name %s\n", Volume_1);
346 /* get first unique volume name of list */
347 hFind = pFindFirstVolumeA( Volume_2, MAX_PATH );
348 ok(hFind != INVALID_HANDLE_VALUE, "FindFirstVolume failed, err=%u\n",
349 GetLastError());
353 /* validate correct length of unique volume name */
354 ok(strlen(Volume_2) == 49, "Find[First/Next]Volume returned wrong length name %s\n", Volume_1);
355 if (memcmp(Volume_1, Volume_2, 49) == 0)
357 found = TRUE;
358 break;
360 } while (pFindNextVolumeA( hFind, Volume_2, MAX_PATH ));
361 todo_wine
362 ok(found, "volume name %s not found by Find[First/Next]Volume\n", Volume_1);
363 pFindVolumeClose( hFind );
366 START_TEST(volume)
368 hdll = GetModuleHandleA("kernel32.dll");
369 pGetVolumeNameForVolumeMountPointA = (void *) GetProcAddress(hdll, "GetVolumeNameForVolumeMountPointA");
370 pGetVolumeNameForVolumeMountPointW = (void *) GetProcAddress(hdll, "GetVolumeNameForVolumeMountPointW");
371 pFindFirstVolumeA = (void *) GetProcAddress(hdll, "FindFirstVolumeA");
372 pFindNextVolumeA = (void *) GetProcAddress(hdll, "FindNextVolumeA");
373 pFindVolumeClose = (void *) GetProcAddress(hdll, "FindVolumeClose");
374 pGetLogicalDriveStringsA = (void *) GetProcAddress(hdll, "GetLogicalDriveStringsA");
375 pGetLogicalDriveStringsW = (void *) GetProcAddress(hdll, "GetLogicalDriveStringsW");
376 pGetVolumeInformationA = (void *) GetProcAddress(hdll, "GetVolumeInformationA");
378 test_query_dos_deviceA();
379 test_FindFirstVolume();
380 test_GetVolumeNameForVolumeMountPointA();
381 test_GetVolumeNameForVolumeMountPointW();
382 test_GetLogicalDriveStringsA();
383 test_GetLogicalDriveStringsW();
384 test_GetVolumeInformationA();
385 test_enum_vols();