ReactOS 0.4.16-dev-1409-g71b6fab
volume.c
Go to the documentation of this file.
1/*
2 * Volume management functions
3 *
4 * Copyright 1993 Erik Bos
5 * Copyright 1996, 2004 Alexandre Julliard
6 * Copyright 1999 Petr Tomasek
7 * Copyright 2000 Andreas Mohr
8 * Copyright 2003 Eric Pouech
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <stdarg.h>
26#include <stdlib.h>
27#include <stdio.h>
28
29#include "ntstatus.h"
30#define WIN32_NO_STATUS
31#include "windef.h"
32#include "winbase.h"
33#include "winnls.h"
34#include "winternl.h"
35#include "winioctl.h"
36#include "ntddcdrm.h"
37#define WINE_MOUNTMGR_EXTENSIONS
38#include "ddk/mountmgr.h"
39#include "ddk/wdm.h"
40#include "kernelbase.h"
41#include "wine/debug.h"
42
44
45#define BLOCK_SIZE 2048
46#define SUPERBLOCK_SIZE BLOCK_SIZE
47#define SYMBOLIC_LINK_QUERY 0x0001
48
49#define CDFRAMES_PERSEC 75
50#define CDFRAMES_PERMIN (CDFRAMES_PERSEC * 60)
51#define FRAME_OF_ADDR(a) ((a)[1] * CDFRAMES_PERMIN + (a)[2] * CDFRAMES_PERSEC + (a)[3])
52#define FRAME_OF_TOC(toc, idx) FRAME_OF_ADDR((toc)->TrackData[(idx) - (toc)->FirstTrack].Address)
53
54#define GETWORD(buf,off) MAKEWORD(buf[(off)],buf[(off+1)])
55#define GETLONG(buf,off) MAKELONG(GETWORD(buf,off),GETWORD(buf,off+2))
56
58{
59 FS_ERROR, /* error accessing the device */
60 FS_UNKNOWN, /* unknown file system */
64 FS_UDF /* For reference [E] = Ecma-167.pdf, [U] = udf260.pdf */
65};
66
67/* read the contents of an NT symlink object */
69{
74
75 attr.Length = sizeof(attr);
76 attr.RootDirectory = 0;
77 attr.Attributes = OBJ_CASE_INSENSITIVE;
78 attr.ObjectName = &nameW;
79 attr.SecurityDescriptor = NULL;
80 attr.SecurityQualityOfService = NULL;
82
84 {
85 UNICODE_STRING targetW;
86 targetW.Buffer = target;
87 targetW.MaximumLength = (size - 1) * sizeof(WCHAR);
89 if (!status) target[targetW.Length / sizeof(WCHAR)] = 0;
90 NtClose( handle );
91 }
92 return status;
93}
94
95/* open a handle to a device root */
97{
98 UNICODE_STRING nt_name;
102
103 if (!root) root = L"\\";
104 if (!RtlDosPathNameToNtPathName_U( root, &nt_name, NULL, NULL ))
105 {
107 return FALSE;
108 }
109 attr.Length = sizeof(attr);
110 attr.RootDirectory = 0;
111 attr.Attributes = OBJ_CASE_INSENSITIVE;
112 attr.ObjectName = &nt_name;
113 attr.SecurityDescriptor = NULL;
114 attr.SecurityQualityOfService = NULL;
115
118 RtlFreeUnicodeString( &nt_name );
119 return set_ntstatus( status );
120}
121
122/* query the type of a drive from the mount manager */
124{
125 HANDLE mgr;
126 struct mountmgr_unix_drive data;
127 DWORD br;
128
129 memset( &data, 0, sizeof(data) );
130 if (root) data.letter = root[0];
131 else
132 {
133 WCHAR curdir[MAX_PATH];
135 if (curdir[1] != ':' || curdir[2] != '\\') return DRIVE_UNKNOWN;
136 data.letter = curdir[0];
137 }
138
141 if (mgr == INVALID_HANDLE_VALUE) return DRIVE_UNKNOWN;
142
143 if (!DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, &data, sizeof(data), &data,
144 sizeof(data), &br, NULL ) && GetLastError() != ERROR_MORE_DATA)
145 data.type = DRIVE_UNKNOWN;
146
147 CloseHandle( mgr );
148 return data.type;
149}
150
151
152/***********************************************************************
153 * GetVolumeInformationW (kernelbase.@)
154 */
156 DWORD *serial, DWORD *filename_len, DWORD *flags,
157 LPWSTR fsname, DWORD fsname_len )
158{
161 UNICODE_STRING nt_name;
164 unsigned int i;
165 BOOL ret = FALSE;
166
167 if (!root) root = L"\\";
168 if (!RtlDosPathNameToNtPathName_U( root, &nt_name, NULL, NULL ))
169 {
171 return FALSE;
172 }
173 /* there must be exactly one backslash in the name, at the end */
174 for (i = 4; i < nt_name.Length / sizeof(WCHAR); i++) if (nt_name.Buffer[i] == '\\') break;
175 if (i != nt_name.Length / sizeof(WCHAR) - 1)
176 {
177 /* check if root contains an explicit subdir */
178 if (root[0] && root[1] == ':') root += 2;
179 while (*root == '\\') root++;
180 if (wcschr( root, '\\' ))
182 else
184 goto done;
185 }
186
187 attr.Length = sizeof(attr);
188 attr.RootDirectory = 0;
189 attr.Attributes = OBJ_CASE_INSENSITIVE;
190 attr.ObjectName = &nt_name;
191 attr.SecurityDescriptor = NULL;
192 attr.SecurityQualityOfService = NULL;
193
194 nt_name.Length -= sizeof(WCHAR); /* without trailing slash */
197 nt_name.Length += sizeof(WCHAR);
198
199 if (status)
200 {
201 TRACE( "cannot open device %s: %lx\n", debugstr_w(nt_name.Buffer), status );
204 }
205
206 if (!set_ntstatus( status )) goto done;
207
208 ret = GetVolumeInformationByHandleW( handle, label, label_len, serial, filename_len, flags,
209 fsname, fsname_len );
210 NtClose( handle );
211
212done:
213 RtlFreeUnicodeString( &nt_name );
214 return ret;
215}
216
217
218/***********************************************************************
219 * GetVolumeInformationA (kernelbase.@)
220 */
222 DWORD label_len, DWORD *serial,
223 DWORD *filename_len, DWORD *flags,
224 LPSTR fsname, DWORD fsname_len )
225{
226 WCHAR *rootW = NULL;
227 LPWSTR labelW, fsnameW;
228 BOOL ret;
229
230 if (root && !(rootW = file_name_AtoW( root, FALSE ))) return FALSE;
231
232 labelW = label ? HeapAlloc(GetProcessHeap(), 0, label_len * sizeof(WCHAR)) : NULL;
233 fsnameW = fsname ? HeapAlloc(GetProcessHeap(), 0, fsname_len * sizeof(WCHAR)) : NULL;
234
235 if ((ret = GetVolumeInformationW(rootW, labelW, label_len, serial,
236 filename_len, flags, fsnameW, fsname_len)))
237 {
238 if (label) file_name_WtoA( labelW, -1, label, label_len );
239 if (fsname) file_name_WtoA( fsnameW, -1, fsname, fsname_len );
240 }
241
243 HeapFree( GetProcessHeap(), 0, fsnameW );
244 return ret;
245}
246
247
248/***********************************************************************
249 * GetVolumeNameForVolumeMountPointW (kernelbase.@)
250 */
252{
254 MOUNTMGR_MOUNT_POINTS *output = NULL;
255 WCHAR *p;
256 char *r;
257 DWORD i, i_size = 1024, o_size = 1024;
258 WCHAR *nonpersist_name;
259 WCHAR symlink_name[MAX_PATH];
262 BOOL ret = FALSE;
263 DWORD br;
264
265 TRACE("(%s, %p, %lx)\n", debugstr_w(path), volume, size);
266 if (path[lstrlenW(path)-1] != '\\')
267 {
269 return FALSE;
270 }
271
272 if (size < 50)
273 {
275 return FALSE;
276 }
277 /* if length of input is > 3 then it must be a mounted folder */
278 if (lstrlenW(path) > 3)
279 {
280 FIXME("Mounted Folders are not yet supported\n");
282 return FALSE;
283 }
284
286 NULL, OPEN_EXISTING, 0, 0 );
287 if (mgr == INVALID_HANDLE_VALUE) return FALSE;
288
289 if (!(input = HeapAlloc( GetProcessHeap(), 0, i_size )))
290 {
292 goto err_ret;
293 }
294
295 if (!(output = HeapAlloc( GetProcessHeap(), 0, o_size )))
296 {
298 goto err_ret;
299 }
300
301 /* construct the symlink name as "\DosDevices\C:" */
302 lstrcpyW( symlink_name, L"\\DosDevices\\" );
303 lstrcatW( symlink_name, path );
304 symlink_name[lstrlenW(symlink_name)-1] = 0;
305
306 /* Take the mount point and get the "nonpersistent name" */
307 /* We will then take that and get the volume name */
308 nonpersist_name = (WCHAR *)(input + 1);
309 status = read_nt_symlink( symlink_name, nonpersist_name, (i_size - sizeof(*input)) / sizeof(WCHAR) );
310 TRACE("read_nt_symlink got stat=%lx, for %s, got <%s>\n", status,
311 debugstr_w(symlink_name), debugstr_w(nonpersist_name));
312 if (status != STATUS_SUCCESS)
313 {
315 goto err_ret;
316 }
317
318 /* Now take the "nonpersistent name" and ask the mountmgr */
319 /* to give us all the mount points. One of them will be */
320 /* the volume name (format of \??\Volume{). */
321 memset( input, 0, sizeof(*input) ); /* clear all input parameters */
322 input->DeviceNameOffset = sizeof(*input);
323 input->DeviceNameLength = lstrlenW( nonpersist_name) * sizeof(WCHAR);
324 i_size = input->DeviceNameOffset + input->DeviceNameLength;
325
326 output->Size = o_size;
327
328 /* now get the true volume name from the mountmgr */
330 output, o_size, &br, NULL ))
331 goto err_ret;
332
333 /* Verify and return the data, note string is not null terminated */
334 TRACE("found %ld matching mount points\n", output->NumberOfMountPoints);
335 if (output->NumberOfMountPoints < 1)
336 {
338 goto err_ret;
339 }
340 o1 = &output->MountPoints[0];
341
342 /* look for the volume name in returned values */
343 for(i=0;i<output->NumberOfMountPoints;i++)
344 {
345 p = (WCHAR*)((char *)output + o1->SymbolicLinkNameOffset);
346 r = (char *)output + o1->UniqueIdOffset;
347 TRACE("found symlink=%s, unique=%s, devname=%s\n",
348 debugstr_wn(p, o1->SymbolicLinkNameLength/sizeof(WCHAR)),
349 debugstr_an(r, o1->UniqueIdLength),
350 debugstr_wn((WCHAR*)((char *)output + o1->DeviceNameOffset),
351 o1->DeviceNameLength/sizeof(WCHAR)));
352
353 if (!wcsncmp( p, L"\\??\\Volume{", wcslen(L"\\??\\Volume{") ))
354 {
355 /* is there space in the return variable ?? */
356 if ((o1->SymbolicLinkNameLength/sizeof(WCHAR))+2 > size)
357 {
359 goto err_ret;
360 }
361 memcpy( volume, p, o1->SymbolicLinkNameLength );
362 volume[o1->SymbolicLinkNameLength / sizeof(WCHAR)] = 0;
363 lstrcatW( volume, L"\\" );
364 /* change second char from '?' to '\' */
365 volume[1] = '\\';
366 ret = TRUE;
367 break;
368 }
369 o1++;
370 }
371
372err_ret:
374 HeapFree( GetProcessHeap(), 0, output );
375 CloseHandle( mgr );
376 return ret;
377}
378
379
380/***********************************************************************
381 * DefineDosDeviceW (kernelbase.@)
382 */
384{
385 WCHAR link_name[15] = L"\\DosDevices\\";
386 UNICODE_STRING nt_name, nt_target;
390
391 TRACE("%#lx, %s, %s\n", flags, debugstr_w(device), debugstr_w(target));
392
394 FIXME("Ignoring flags %#lx.\n", flags & ~(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION));
395
396 lstrcatW( link_name, device );
397 RtlInitUnicodeString( &nt_name, link_name );
400 {
402 return FALSE;
403
405 NtClose( handle );
406
407 return set_ntstatus( status );
408 }
409
410 if (!(flags & DDD_RAW_TARGET_PATH))
411 {
412 if (!RtlDosPathNameToNtPathName_U( target, &nt_target, NULL, NULL))
413 {
415 return FALSE;
416 }
417 }
418 else
419 RtlInitUnicodeString( &nt_target, target );
420
422 NtClose( handle );
423 return set_ntstatus( status );
424}
425
426
427/***********************************************************************
428 * QueryDosDeviceW (kernelbase.@)
429 *
430 * returns array of strings terminated by \0, terminated by \0
431 */
433{
435
436 if (!bufsize)
437 {
439 return 0;
440 }
441
442 if (devname)
443 {
444 WCHAR name[8];
445 WCHAR *buffer;
446 DWORD dosdev, ret = 0;
447
448 if ((dosdev = RtlIsDosDeviceName_U( devname )))
449 {
450 memcpy( name, devname + HIWORD(dosdev)/sizeof(WCHAR), LOWORD(dosdev) );
451 name[LOWORD(dosdev)/sizeof(WCHAR)] = 0;
452 devname = name;
453 }
454
455 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(L"\\DosDevices\\") + lstrlenW(devname)*sizeof(WCHAR) )))
456 {
458 return 0;
459 }
460 lstrcpyW( buffer, L"\\DosDevices\\" );
461 lstrcatW( buffer, devname );
464 if (!set_ntstatus( status )) return 0;
465 ret = lstrlenW( target ) + 1;
466 if (ret < bufsize) target[ret++] = 0; /* add an extra null */
467 return ret;
468 }
469 else /* return a list of all devices */
470 {
471 UNICODE_STRING nt_name = RTL_CONSTANT_STRING( L"\\DosDevices" );
474 WCHAR *p = target;
475
476 attr.Length = sizeof(attr);
477 attr.RootDirectory = 0;
478 attr.ObjectName = &nt_name;
479 attr.Attributes = OBJ_CASE_INSENSITIVE;
480 attr.SecurityDescriptor = NULL;
481 attr.SecurityQualityOfService = NULL;
483 if (!status)
484 {
485 char data[1024];
487 ULONG ctx = 0, len;
488
489 while (!NtQueryDirectoryObject( handle, info, sizeof(data), 1, 0, &ctx, &len ))
490 {
491 if (p + info->ObjectName.Length/sizeof(WCHAR) + 1 >= target + bufsize)
492 {
494 NtClose( handle );
495 return 0;
496 }
497 memcpy( p, info->ObjectName.Buffer, info->ObjectName.Length );
498 p += info->ObjectName.Length/sizeof(WCHAR);
499 *p++ = 0;
500 }
501 NtClose( handle );
502 }
503
504 *p++ = 0; /* terminating null */
505 return p - target;
506 }
507}
508
509
510/***********************************************************************
511 * GetLogicalDrives (kernelbase.@)
512 */
514{
516 UNICODE_STRING nt_name = RTL_CONSTANT_STRING( L"\\DosDevices\\" );
517 DWORD bitmask = 0;
520
521 nt_name.Length -= sizeof(WCHAR); /* without trailing slash */
522 attr.Length = sizeof(attr);
523 attr.RootDirectory = 0;
524 attr.ObjectName = &nt_name;
525 attr.Attributes = OBJ_CASE_INSENSITIVE;
526 attr.SecurityDescriptor = NULL;
527 attr.SecurityQualityOfService = NULL;
529 if (!status)
530 {
531 char data[1024];
533 ULONG ctx = 0, len;
534
535 while (!NtQueryDirectoryObject( handle, info, sizeof(data), 1, 0, &ctx, &len ))
536 if(info->ObjectName.Length == 2*sizeof(WCHAR) && info->ObjectName.Buffer[1] == ':')
537 bitmask |= 1 << (info->ObjectName.Buffer[0] - 'A');
538
539 NtClose( handle );
540 }
541
542 return bitmask;
543}
544
545
546/***********************************************************************
547 * GetLogicalDriveStringsW (kernelbase.@)
548 */
550{
551 DWORD drives = GetLogicalDrives();
553
554 for (drive = count = 0; drive < 26; drive++) if (drives & (1 << drive)) count++;
555 if ((count * 4) + 1 > len) return count * 4 + 1;
556
557 for (drive = 0; drive < 26; drive++)
558 {
559 if (drives & (1 << drive))
560 {
561 *buffer++ = 'A' + drive;
562 *buffer++ = ':';
563 *buffer++ = '\\';
564 *buffer++ = 0;
565 }
566 }
567 *buffer = 0;
568 return count * 4;
569}
570
571
572/***********************************************************************
573 * GetDriveTypeW (kernelbase.@)
574 */
576{
581 UINT ret;
582
583 if (!open_device_root( root, &handle ))
584 {
585 /* CD ROM devices do not necessarily have a volume, but a drive type */
587 if (ret == DRIVE_CDROM || ret == DRIVE_REMOVABLE)
588 return ret;
589
590 return DRIVE_NO_ROOT_DIR;
591 }
592
594 NtClose( handle );
595 if (status != STATUS_SUCCESS)
596 {
599 }
600 else
601 {
602 switch (info.DeviceType)
603 {
608 if (info.Characteristics & FILE_REMOTE_DEVICE) ret = DRIVE_REMOTE;
609 else if (info.Characteristics & FILE_REMOVABLE_MEDIA) ret = DRIVE_REMOVABLE;
611 break;
612 default:
614 break;
615 }
616 }
617 TRACE( "%s -> %d\n", debugstr_w(root), ret );
618 return ret;
619}
620
621
622/***********************************************************************
623 * GetDriveTypeA (kernelbase.@)
624 */
626{
627 WCHAR *rootW = NULL;
628
629 if (root && !(rootW = file_name_AtoW( root, FALSE ))) return DRIVE_NO_ROOT_DIR;
630 return GetDriveTypeW( rootW );
631}
632
633
634/***********************************************************************
635 * GetDiskFreeSpaceExW (kernelbase.@)
636 */
639{
644 UINT units;
645
646 TRACE( "%s,%p,%p,%p\n", debugstr_w(root), avail, total, totalfree );
647
648 if (!open_device_root( root, &handle )) return FALSE;
649
651 NtClose( handle );
652 if (!set_ntstatus( status )) return FALSE;
653
654 units = info.SectorsPerAllocationUnit * info.BytesPerSector;
655 if (total) total->QuadPart = info.TotalAllocationUnits.QuadPart * units;
656 if (totalfree) totalfree->QuadPart = info.AvailableAllocationUnits.QuadPart * units;
657 /* FIXME: this one should take quotas into account */
658 if (avail) avail->QuadPart = info.AvailableAllocationUnits.QuadPart * units;
659 return TRUE;
660}
661
662
663/***********************************************************************
664 * GetDiskFreeSpaceExA (kernelbase.@)
665 */
668{
669 WCHAR *rootW = NULL;
670
671 if (root && !(rootW = file_name_AtoW( root, FALSE ))) return FALSE;
672 return GetDiskFreeSpaceExW( rootW, avail, total, totalfree );
673}
674
675
676/***********************************************************************
677 * GetDiskFreeSpaceW (kernelbase.@)
678 */
680 LPDWORD sector_bytes, LPDWORD free_clusters,
681 LPDWORD total_clusters )
682{
687 UINT units;
688
689 TRACE( "%s,%p,%p,%p,%p\n", debugstr_w(root),
690 cluster_sectors, sector_bytes, free_clusters, total_clusters );
691
692 if (!open_device_root( root, &handle )) return FALSE;
693
695 NtClose( handle );
696 if (!set_ntstatus( status )) return FALSE;
697
698 units = info.SectorsPerAllocationUnit * info.BytesPerSector;
699
700 if( GetVersion() & 0x80000000) { /* win3.x, 9x, ME */
701 /* cap the size and available at 2GB as per specs */
702 if (info.TotalAllocationUnits.QuadPart * units > 0x7fffffff) {
703 info.TotalAllocationUnits.QuadPart = 0x7fffffff / units;
704 if (info.AvailableAllocationUnits.QuadPart * units > 0x7fffffff)
705 info.AvailableAllocationUnits.QuadPart = 0x7fffffff / units;
706 }
707 /* nr. of clusters is always <= 65335 */
708 while( info.TotalAllocationUnits.QuadPart > 65535 ) {
709 info.TotalAllocationUnits.QuadPart /= 2;
710 info.AvailableAllocationUnits.QuadPart /= 2;
711 info.SectorsPerAllocationUnit *= 2;
712 }
713 }
714
715 if (cluster_sectors) *cluster_sectors = info.SectorsPerAllocationUnit;
716 if (sector_bytes) *sector_bytes = info.BytesPerSector;
717 if (free_clusters) *free_clusters = info.AvailableAllocationUnits.u.LowPart;
718 if (total_clusters) *total_clusters = info.TotalAllocationUnits.u.LowPart;
719 TRACE("%#08lx, %#08lx, %#08lx, %#08lx\n", info.SectorsPerAllocationUnit, info.BytesPerSector,
720 info.AvailableAllocationUnits.u.LowPart, info.TotalAllocationUnits.u.LowPart);
721 return TRUE;
722}
723
724
725/***********************************************************************
726 * GetDiskFreeSpaceA (kernelbase.@)
727 */
729 LPDWORD sector_bytes, LPDWORD free_clusters,
730 LPDWORD total_clusters )
731{
732 WCHAR *rootW = NULL;
733
734 if (root && !(rootW = file_name_AtoW( root, FALSE ))) return FALSE;
735 return GetDiskFreeSpaceW( rootW, cluster_sectors, sector_bytes, free_clusters, total_clusters );
736}
737
738
740{
741 static const WCHAR global_prefix[4] = {'\\','?','?','\\'};
742 return path->Length >= 7 * sizeof(WCHAR)
743 && !memcmp(path->Buffer, global_prefix, sizeof(global_prefix))
744 && path->Buffer[5] == ':' && path->Buffer[6] == '\\';
745}
746
747/* resolve all symlinks in a path in-place; return FALSE if allocation failed */
749{
754 HANDLE file;
755 ULONG size;
756
760 return TRUE;
761
763 {
764 NtClose( file );
765 return TRUE;
766 }
767
768 if (!(info = HeapAlloc( GetProcessHeap(), 0, size )))
769 {
770 NtClose( file );
771 return FALSE;
772 }
773
775 NtClose( file );
776 if (status)
777 return TRUE;
778
782 return !status;
783}
784
785/***********************************************************************
786 * GetVolumePathNameW (kernelbase.@)
787 */
789{
791 FILE_BASIC_INFORMATION basic_info;
793 UNICODE_STRING nt_name;
795
796 if (path && !wcsncmp(path, L"\\??\\", 4))
797 {
798 WCHAR current_drive[MAX_PATH];
799
800 GetCurrentDirectoryW( ARRAY_SIZE(current_drive), current_drive );
801 if (length >= 3)
802 {
803 WCHAR ret_path[4] = {current_drive[0], ':', '\\', 0};
804 lstrcpynW( volume_path, ret_path, length );
805 return TRUE;
806 }
807
809 return FALSE;
810 }
811
812 if (!volume_path || !length || !RtlDosPathNameToNtPathName_U( path, &nt_name, NULL, NULL ))
813 {
815 return FALSE;
816 }
817
818 if (!is_dos_path( &nt_name ))
819 {
820 RtlFreeUnicodeString( &nt_name );
821 WARN("invalid path %s\n", debugstr_w(path));
823 return FALSE;
824 }
825
827
828 while (nt_name.Length > 7 * sizeof(WCHAR))
829 {
831 HANDLE file;
832
833 if (!NtQueryAttributesFile( &attr, &basic_info )
839 {
840 status = NtQueryInformationFile( file, &io, &attr_info,
841 sizeof(attr_info), FileAttributeTagInformation );
842 NtClose( file );
843 if (!status)
844 {
845
846 if (attr_info.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
847 break;
848
849 if (!resolve_symlink( &nt_name ))
850 {
852 return FALSE;
853 }
854 }
855 }
856
857 if (nt_name.Buffer[(nt_name.Length / sizeof(WCHAR)) - 1] == '\\')
858 nt_name.Length -= sizeof(WCHAR);
859 while (nt_name.Length && nt_name.Buffer[(nt_name.Length / sizeof(WCHAR)) - 1] != '\\')
860 nt_name.Length -= sizeof(WCHAR);
861 }
862
863 nt_name.Buffer[nt_name.Length / sizeof(WCHAR)] = 0;
864
865 if (NtQueryAttributesFile( &attr, &basic_info ))
866 {
867 RtlFreeUnicodeString( &nt_name );
868 WARN("nonexistent path %s -> %s\n", debugstr_w(path), debugstr_w( nt_name.Buffer ));
870 return FALSE;
871 }
872
873 if (!wcsncmp(path, L"\\\\.\\", 4) || !wcsncmp(path, L"\\\\?\\", 4))
874 {
875 if (length >= nt_name.Length / sizeof(WCHAR))
876 {
877 memcpy(volume_path, path, 4 * sizeof(WCHAR));
878 lstrcpynW( volume_path + 4, nt_name.Buffer + 4, length - 4 );
879
880 TRACE("%s -> %s\n", debugstr_w(path), debugstr_w(volume_path));
881
882 RtlFreeUnicodeString( &nt_name );
883 return TRUE;
884 }
885 }
886 else if (length >= (nt_name.Length / sizeof(WCHAR)) - 4)
887 {
888 lstrcpynW( volume_path, nt_name.Buffer + 4, length );
889 volume_path[0] = towupper(volume_path[0]);
890
891 TRACE("%s -> %s\n", debugstr_w(path), debugstr_w(volume_path));
892
893 RtlFreeUnicodeString( &nt_name );
894 return TRUE;
895 }
896
897 RtlFreeUnicodeString( &nt_name );
899 return FALSE;
900}
901
902
904{
905 MOUNTMGR_MOUNT_POINTS *output;
906 DWORD outsize = 1024;
907 DWORD br;
908
909 for (;;)
910 {
911 if (!(output = HeapAlloc( GetProcessHeap(), 0, outsize )))
912 {
914 return NULL;
915 }
916 if (DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_POINTS, input, insize, output, outsize, &br, NULL )) break;
917 outsize = output->Size;
918 HeapFree( GetProcessHeap(), 0, output );
919 if (GetLastError() != ERROR_MORE_DATA) return NULL;
920 }
921 return output;
922}
923
924/***********************************************************************
925 * GetVolumePathNamesForVolumeNameW (kernelbase.@)
926 */
928 DWORD buflen, PDWORD returnlen )
929{
930 static const WCHAR dosdevicesW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\'};
931 HANDLE mgr;
932 DWORD len, size;
935 WCHAR *name, *path;
936 BOOL ret = FALSE;
937 UINT i, j;
938
939 TRACE("%s, %p, %lu, %p\n", debugstr_w(volumename), volumepathname, buflen, returnlen);
940
941 if (!volumename || (len = lstrlenW( volumename )) != 49)
942 {
944 return FALSE;
945 }
947 if (mgr == INVALID_HANDLE_VALUE) return FALSE;
948
949 size = sizeof(*spec) + sizeof(WCHAR) * (len - 1); /* remove trailing backslash */
950 if (!(spec = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) goto done;
951 spec->SymbolicLinkNameOffset = sizeof(*spec);
952 spec->SymbolicLinkNameLength = size - sizeof(*spec);
953 name = (WCHAR *)((char *)spec + spec->SymbolicLinkNameOffset);
954 memcpy( name, volumename, size - sizeof(*spec) );
955 name[1] = '?'; /* map \\?\ to \??\ */
956
957 target = query_mount_points( mgr, spec, size );
958 HeapFree( GetProcessHeap(), 0, spec );
959 if (!target)
960 {
961 goto done;
962 }
963 if (!target->NumberOfMountPoints)
964 {
966 goto done;
967 }
968 len = 0;
969 path = volumepathname;
970 for (i = 0; i < target->NumberOfMountPoints; i++)
971 {
972 link = NULL;
973 if (target->MountPoints[i].DeviceNameOffset)
974 {
975 const WCHAR *device = (const WCHAR *)((const char *)target + target->MountPoints[i].DeviceNameOffset);
976 USHORT device_len = target->MountPoints[i].DeviceNameLength;
977
978 size = sizeof(*spec) + device_len;
979 if (!(spec = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) goto done;
980 spec->DeviceNameOffset = sizeof(*spec);
981 spec->DeviceNameLength = device_len;
982 memcpy( (char *)spec + spec->DeviceNameOffset, device, device_len );
983
984 link = query_mount_points( mgr, spec, size );
985 HeapFree( GetProcessHeap(), 0, spec );
986 }
987 else if (target->MountPoints[i].UniqueIdOffset)
988 {
989 const WCHAR *id = (const WCHAR *)((const char *)target + target->MountPoints[i].UniqueIdOffset);
990 USHORT id_len = target->MountPoints[i].UniqueIdLength;
991
992 size = sizeof(*spec) + id_len;
993 if (!(spec = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) goto done;
994 spec->UniqueIdOffset = sizeof(*spec);
995 spec->UniqueIdLength = id_len;
996 memcpy( (char *)spec + spec->UniqueIdOffset, id, id_len );
997
998 link = query_mount_points( mgr, spec, size );
999 HeapFree( GetProcessHeap(), 0, spec );
1000 }
1001 if (!link) continue;
1002 for (j = 0; j < link->NumberOfMountPoints; j++)
1003 {
1004 const WCHAR *linkname;
1005
1006 if (!link->MountPoints[j].SymbolicLinkNameOffset) continue;
1007 linkname = (const WCHAR *)((const char *)link + link->MountPoints[j].SymbolicLinkNameOffset);
1008
1009 if (link->MountPoints[j].SymbolicLinkNameLength == sizeof(dosdevicesW) + 2 * sizeof(WCHAR) &&
1010 !wcsnicmp( linkname, dosdevicesW, ARRAY_SIZE( dosdevicesW )))
1011 {
1012 len += 4;
1013 if (volumepathname && len < buflen)
1014 {
1015 path[0] = linkname[ARRAY_SIZE( dosdevicesW )];
1016 path[1] = ':';
1017 path[2] = '\\';
1018 path[3] = 0;
1019 path += 4;
1020 }
1021 }
1022 }
1023 HeapFree( GetProcessHeap(), 0, link );
1024 }
1025 if (buflen <= len) SetLastError( ERROR_MORE_DATA );
1026 else if (volumepathname)
1027 {
1028 volumepathname[len] = 0;
1029 ret = TRUE;
1030 }
1031 if (returnlen) *returnlen = len + 1;
1032
1033done:
1035 CloseHandle( mgr );
1036 return ret;
1037}
1038
1039
1040/***********************************************************************
1041 * FindFirstVolumeW (kernelbase.@)
1042 */
1044{
1045 DWORD size = 1024;
1046 DWORD br;
1048 NULL, OPEN_EXISTING, 0, 0 );
1049 if (mgr == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;
1050
1051 for (;;)
1052 {
1054 MOUNTMGR_MOUNT_POINTS *output;
1055
1056 if (!(output = HeapAlloc( GetProcessHeap(), 0, size )))
1057 {
1059 break;
1060 }
1061 memset( &input, 0, sizeof(input) );
1062
1064 output, size, &br, NULL ))
1065 {
1066 if (GetLastError() != ERROR_MORE_DATA) break;
1067 size = output->Size;
1068 HeapFree( GetProcessHeap(), 0, output );
1069 continue;
1070 }
1071 CloseHandle( mgr );
1072 /* abuse the Size field to store the current index */
1073 output->Size = 0;
1074 if (!FindNextVolumeW( output, volume, len ))
1075 {
1076 HeapFree( GetProcessHeap(), 0, output );
1077 return INVALID_HANDLE_VALUE;
1078 }
1079 return output;
1080 }
1081 CloseHandle( mgr );
1082 return INVALID_HANDLE_VALUE;
1083}
1084
1085
1086/***********************************************************************
1087 * FindNextVolumeW (kernelbase.@)
1088 */
1090{
1092
1093 while (data->Size < data->NumberOfMountPoints)
1094 {
1095 static const WCHAR volumeW[] = {'\\','?','?','\\','V','o','l','u','m','e','{',};
1096 WCHAR *link = (WCHAR *)((char *)data + data->MountPoints[data->Size].SymbolicLinkNameOffset);
1097 DWORD size = data->MountPoints[data->Size].SymbolicLinkNameLength;
1098 data->Size++;
1099 /* skip non-volumes */
1100 if (size < sizeof(volumeW) || memcmp( link, volumeW, sizeof(volumeW) )) continue;
1101 if (size + sizeof(WCHAR) >= len * sizeof(WCHAR))
1102 {
1104 return FALSE;
1105 }
1106 memcpy( volume, link, size );
1107 volume[1] = '\\'; /* map \??\ to \\?\ */
1108 volume[size / sizeof(WCHAR)] = '\\'; /* Windows appends a backslash */
1109 volume[size / sizeof(WCHAR) + 1] = 0;
1110 TRACE( "returning entry %lu %s\n", data->Size - 1, debugstr_w(volume) );
1111 return TRUE;
1112 }
1114 return FALSE;
1115}
1116
1117
1118/***********************************************************************
1119 * FindVolumeClose (kernelbase.@)
1120 */
1122{
1123 return HeapFree( GetProcessHeap(), 0, handle );
1124}
1125
1126
1127/***********************************************************************
1128 * DeleteVolumeMountPointW (kernelbase.@)
1129 */
1130BOOL WINAPI /* DECLSPEC_HOTPATCH */ DeleteVolumeMountPointW( LPCWSTR mountpoint )
1131{
1132 FIXME("(%s), stub!\n", debugstr_w(mountpoint));
1133 return FALSE;
1134}
1135
1136
1137/***********************************************************************
1138 * GetVolumeInformationByHandleW (kernelbase.@)
1139 */
1141 DWORD *serial, DWORD *filename_len, DWORD *flags,
1142 WCHAR *fsname, DWORD fsname_len )
1143{
1145
1146 TRACE( "%p\n", handle );
1147
1148 if (label || serial)
1149 {
1150 char buffer[sizeof(FILE_FS_VOLUME_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
1152
1155 return FALSE;
1156
1157 if (label)
1158 {
1159 if (label_len < info->VolumeLabelLength / sizeof(WCHAR) + 1)
1160 {
1162 return FALSE;
1163 }
1164 memcpy( label, info->VolumeLabel, info->VolumeLabelLength );
1165 label[info->VolumeLabelLength / sizeof(WCHAR)] = 0;
1166 }
1167 if (serial) *serial = info->VolumeSerialNumber;
1168 }
1169
1170 if (filename_len || flags || fsname)
1171 {
1172 char buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
1174
1177 return FALSE;
1178
1179 if (fsname)
1180 {
1181 if (fsname_len < info->FileSystemNameLength / sizeof(WCHAR) + 1)
1182 {
1184 return FALSE;
1185 }
1186 memcpy( fsname, info->FileSystemName, info->FileSystemNameLength );
1187 fsname[info->FileSystemNameLength / sizeof(WCHAR)] = 0;
1188 }
1189 if (filename_len) *filename_len = info->MaximumComponentNameLength;
1190 if (flags) *flags = info->FileSystemAttributes;
1191 }
1192
1193 return TRUE;
1194}
@ ObjectNameInformation
Definition: DriverTester.h:55
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static int avail
Definition: adh-main.c:39
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:49
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const WCHAR * link
Definition: db.cpp:997
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
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 __inline BOOL set_ntstatus(NTSTATUS status)
Definition: security.c:227
static const WCHAR rootW[]
Definition: chain.c:69
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsnicmp
Definition: compat.h:14
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define lstrcpyW
Definition: compat.h:749
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
UINT WINAPI GetDriveTypeA(IN LPCSTR lpRootPathName)
Definition: disk.c:468
BOOL WINAPI FindNextVolumeW(IN HANDLE handle, IN LPWSTR volume, IN DWORD len)
Definition: volume.c:1082
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
BOOL WINAPI GetVolumeInformationA(IN LPCSTR lpRootPathName, IN LPSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:32
HANDLE WINAPI FindFirstVolumeW(IN LPWSTR volume, IN DWORD len)
Definition: volume.c:660
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:815
BOOL WINAPI FindVolumeClose(IN HANDLE hFindVolume)
Definition: volume.c:741
BOOL WINAPI GetVolumePathNamesForVolumeNameW(IN LPCWSTR lpszVolumeName, IN LPWSTR lpszVolumePathNames, IN DWORD cchBufferLength, OUT PDWORD lpcchReturnLength)
Definition: volume.c:1227
WCHAR * file_name_AtoW(LPCSTR name, BOOL alloc)
Definition: file.c:411
DWORD file_name_WtoA(LPCWSTR src, INT srclen, LPSTR dest, INT destlen)
Definition: file.c:438
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
static BOOL is_dos_path(const UNICODE_STRING *path)
Definition: volume.c:739
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExA(LPCSTR root, PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER totalfree)
Definition: volume.c:666
#define SYMBOLIC_LINK_QUERY
Definition: volume.c:47
static BOOL resolve_symlink(UNICODE_STRING *path)
Definition: volume.c:748
static MOUNTMGR_MOUNT_POINTS * query_mount_points(HANDLE mgr, MOUNTMGR_MOUNT_POINT *input, DWORD insize)
Definition: volume.c:903
BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW(DWORD flags, const WCHAR *device, const WCHAR *target)
Definition: volume.c:383
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExW(LPCWSTR root, PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER totalfree)
Definition: volume.c:637
BOOL WINAPI DeleteVolumeMountPointW(LPCWSTR mountpoint)
Definition: volume.c:1130
static DWORD get_mountmgr_drive_type(LPCWSTR root)
Definition: volume.c:123
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceA(LPCSTR root, LPDWORD cluster_sectors, LPDWORD sector_bytes, LPDWORD free_clusters, LPDWORD total_clusters)
Definition: volume.c:728
UINT WINAPI DECLSPEC_HOTPATCH GetLogicalDriveStringsW(UINT len, LPWSTR buffer)
Definition: volume.c:549
fs_type
Definition: volume.c:58
@ FS_UNKNOWN
Definition: volume.c:60
@ FS_ERROR
Definition: volume.c:59
@ FS_FAT32
Definition: volume.c:62
@ FS_FAT1216
Definition: volume.c:61
@ FS_UDF
Definition: volume.c:64
@ FS_ISO9660
Definition: volume.c:63
DWORD WINAPI QueryDosDeviceW(LPCWSTR devname, LPWSTR target, DWORD bufsize)
Definition: volume.c:432
static BOOL open_device_root(LPCWSTR root, HANDLE *handle)
Definition: volume.c:96
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
UINT WINAPI DECLSPEC_HOTPATCH GetDriveTypeW(LPCWSTR root)
Definition: volume.c:575
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceW(LPCWSTR root, LPDWORD cluster_sectors, LPDWORD sector_bytes, LPDWORD free_clusters, LPDWORD total_clusters)
Definition: volume.c:679
BOOL WINAPI GetVolumeInformationByHandleW(HANDLE handle, WCHAR *label, DWORD label_len, DWORD *serial, DWORD *filename_len, DWORD *flags, WCHAR *fsname, DWORD fsname_len)
Definition: volume.c:1140
static NTSTATUS read_nt_symlink(const WCHAR *name, WCHAR *target, DWORD size)
Definition: volume.c:68
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
@ FileAttributeTagInformation
Definition: from_kernel.h:96
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
uint32_t serial
Definition: fsck.fat.h:29
size_t total
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLfloat units
Definition: glext.h:11727
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLenum target
Definition: glext.h:7315
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
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 GLint GLint j
Definition: glfuncs.h:250
static const WCHAR labelW[]
Definition: htmlelem.c:32
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
const unsigned char size_t insize
Definition: jpeglib.h:984
unsigned char size_t * outsize
Definition: jpeglib.h:981
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define DRIVE_CDROM
Definition: machpc98.h:119
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOL WINAPI GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint, OUT LPWSTR VolumeName, IN DWORD VolumeNameLength)
Definition: mntpoint.c:496
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static const WCHAR label[]
Definition: itemdlg.c:1546
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:49
#define MOUNTMGR_DOS_DEVICE_NAME
Definition: mountmgr.h:37
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DELETE
Definition: nt_native.h:57
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
NTSTATUS NTAPI NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation)
Definition: file.c:3979
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:490
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1473
#define LOWORD(l)
Definition: pedump.c:82
DWORD * PDWORD
Definition: pedump.c:68
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:65
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:81
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define DECLSPEC_HOTPATCH
Definition: config.h:9
#define memset(x, y, z)
Definition: compat.h:39
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:175
USHORT DeviceNameLength
Definition: imports.h:169
USHORT SymbolicLinkNameLength
Definition: imports.h:165
ULONG SymbolicLinkNameOffset
Definition: imports.h:164
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cookie.c:202
Definition: devices.h:37
Definition: fci.c:127
Definition: name.c:39
Definition: ps.c:97
#define towupper(c)
Definition: wctype.h:99
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define DRIVE_UNKNOWN
Definition: winbase.h:289
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:290
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DDD_RAW_TARGET_PATH
Definition: winbase.h:559
#define DRIVE_REMOTE
Definition: winbase.h:286
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:560
#define DRIVE_RAMDISK
Definition: winbase.h:288
#define DRIVE_FIXED
Definition: winbase.h:285
#define DRIVE_REMOVABLE
Definition: winbase.h:284
#define WINAPI
Definition: msvc.h:6
#define ERROR_BAD_LENGTH
Definition: winerror.h:127
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_NO_VOLUME_ID
Definition: winerror.h:695
#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
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7232
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185