ReactOS 0.4.16-dev-1494-gd054f63
volume.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winternl.h"
#include "winioctl.h"
#include "ntddcdrm.h"
#include "ddk/mountmgr.h"
#include "ddk/wdm.h"
#include "kernelbase.h"
#include "wine/debug.h"
Include dependency graph for volume.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 
#define WINE_MOUNTMGR_EXTENSIONS
 
#define BLOCK_SIZE   2048
 
#define SUPERBLOCK_SIZE   BLOCK_SIZE
 
#define SYMBOLIC_LINK_QUERY   0x0001
 
#define CDFRAMES_PERSEC   75
 
#define CDFRAMES_PERMIN   (CDFRAMES_PERSEC * 60)
 
#define FRAME_OF_ADDR(a)   ((a)[1] * CDFRAMES_PERMIN + (a)[2] * CDFRAMES_PERSEC + (a)[3])
 
#define FRAME_OF_TOC(toc, idx)   FRAME_OF_ADDR((toc)->TrackData[(idx) - (toc)->FirstTrack].Address)
 
#define GETWORD(buf, off)   MAKEWORD(buf[(off)],buf[(off+1)])
 
#define GETLONG(buf, off)   MAKELONG(GETWORD(buf,off),GETWORD(buf,off+2))
 

Enumerations

enum  fs_type {
  FS_ERROR , FS_UNKNOWN , FS_FAT1216 , FS_FAT32 ,
  FS_ISO9660 , FS_UDF
}
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (volume)
 
static NTSTATUS read_nt_symlink (const WCHAR *name, WCHAR *target, DWORD size)
 
static BOOL open_device_root (LPCWSTR root, HANDLE *handle)
 
static DWORD get_mountmgr_drive_type (LPCWSTR root)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetVolumeInformationW (LPCWSTR root, LPWSTR label, DWORD label_len, DWORD *serial, DWORD *filename_len, DWORD *flags, LPWSTR fsname, DWORD fsname_len)
 
BOOL WINAPI GetVolumeInformationA (LPCSTR root, LPSTR label, DWORD label_len, DWORD *serial, DWORD *filename_len, DWORD *flags, LPSTR fsname, DWORD fsname_len)
 
BOOL WINAPI GetVolumeNameForVolumeMountPointW (LPCWSTR path, LPWSTR volume, DWORD size)
 
BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW (DWORD flags, const WCHAR *device, const WCHAR *target)
 
DWORD WINAPI QueryDosDeviceW (LPCWSTR devname, LPWSTR target, DWORD bufsize)
 
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives (void)
 
UINT WINAPI DECLSPEC_HOTPATCH GetLogicalDriveStringsW (UINT len, LPWSTR buffer)
 
UINT WINAPI DECLSPEC_HOTPATCH GetDriveTypeW (LPCWSTR root)
 
UINT WINAPI DECLSPEC_HOTPATCH GetDriveTypeA (LPCSTR root)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExW (LPCWSTR root, PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER totalfree)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExA (LPCSTR root, PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER totalfree)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceW (LPCWSTR root, LPDWORD cluster_sectors, LPDWORD sector_bytes, LPDWORD free_clusters, LPDWORD total_clusters)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceA (LPCSTR root, LPDWORD cluster_sectors, LPDWORD sector_bytes, LPDWORD free_clusters, LPDWORD total_clusters)
 
static BOOL is_dos_path (const UNICODE_STRING *path)
 
static BOOL resolve_symlink (UNICODE_STRING *path)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetVolumePathNameW (const WCHAR *path, WCHAR *volume_path, DWORD length)
 
static MOUNTMGR_MOUNT_POINTSquery_mount_points (HANDLE mgr, MOUNTMGR_MOUNT_POINT *input, DWORD insize)
 
BOOL WINAPI DECLSPEC_HOTPATCH GetVolumePathNamesForVolumeNameW (LPCWSTR volumename, LPWSTR volumepathname, DWORD buflen, PDWORD returnlen)
 
HANDLE WINAPI DECLSPEC_HOTPATCH FindFirstVolumeW (LPWSTR volume, DWORD len)
 
BOOL WINAPI DECLSPEC_HOTPATCH FindNextVolumeW (HANDLE handle, LPWSTR volume, DWORD len)
 
BOOL WINAPI DECLSPEC_HOTPATCH FindVolumeClose (HANDLE handle)
 
BOOL WINAPI DeleteVolumeMountPointW (LPCWSTR mountpoint)
 
BOOL WINAPI GetVolumeInformationByHandleW (HANDLE handle, WCHAR *label, DWORD label_len, DWORD *serial, DWORD *filename_len, DWORD *flags, WCHAR *fsname, DWORD fsname_len)
 

Macro Definition Documentation

◆ BLOCK_SIZE

#define BLOCK_SIZE   2048

Definition at line 45 of file volume.c.

◆ CDFRAMES_PERMIN

#define CDFRAMES_PERMIN   (CDFRAMES_PERSEC * 60)

Definition at line 50 of file volume.c.

◆ CDFRAMES_PERSEC

#define CDFRAMES_PERSEC   75

Definition at line 49 of file volume.c.

◆ FRAME_OF_ADDR

#define FRAME_OF_ADDR (   a)    ((a)[1] * CDFRAMES_PERMIN + (a)[2] * CDFRAMES_PERSEC + (a)[3])

Definition at line 51 of file volume.c.

◆ FRAME_OF_TOC

#define FRAME_OF_TOC (   toc,
  idx 
)    FRAME_OF_ADDR((toc)->TrackData[(idx) - (toc)->FirstTrack].Address)

Definition at line 52 of file volume.c.

◆ GETLONG

#define GETLONG (   buf,
  off 
)    MAKELONG(GETWORD(buf,off),GETWORD(buf,off+2))

Definition at line 55 of file volume.c.

◆ GETWORD

#define GETWORD (   buf,
  off 
)    MAKEWORD(buf[(off)],buf[(off+1)])

Definition at line 54 of file volume.c.

◆ SUPERBLOCK_SIZE

#define SUPERBLOCK_SIZE   BLOCK_SIZE

Definition at line 46 of file volume.c.

◆ SYMBOLIC_LINK_QUERY

#define SYMBOLIC_LINK_QUERY   0x0001

Definition at line 47 of file volume.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 30 of file volume.c.

◆ WINE_MOUNTMGR_EXTENSIONS

#define WINE_MOUNTMGR_EXTENSIONS

Definition at line 37 of file volume.c.

Enumeration Type Documentation

◆ fs_type

Enumerator
FS_ERROR 
FS_UNKNOWN 
FS_FAT1216 
FS_FAT32 
FS_ISO9660 
FS_UDF 

Definition at line 57 of file volume.c.

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};
@ 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

Function Documentation

◆ DefineDosDeviceW()

BOOL WINAPI DECLSPEC_HOTPATCH DefineDosDeviceW ( DWORD  flags,
const WCHAR device,
const WCHAR target 
)

Definition at line 383 of file volume.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: precomp.h:53
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
static __inline BOOL set_ntstatus(NTSTATUS status)
Definition: security.c:227
#define SetLastError(x)
Definition: compat.h:752
#define L(x)
Definition: resources.c:13
GLbitfield flags
Definition: glext.h:7161
GLenum target
Definition: glext.h:7315
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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 VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DELETE
Definition: nt_native.h:57
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1473
#define TRACE(s)
Definition: solgame.cpp:4
Definition: cookie.c:202
Definition: devices.h:37
Definition: ps.c:97
#define DDD_RAW_TARGET_PATH
Definition: winbase.h:559
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:560
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ DeleteVolumeMountPointW()

BOOL WINAPI DeleteVolumeMountPointW ( LPCWSTR  mountpoint)

Definition at line 1130 of file volume.c.

1131{
1132 FIXME("(%s), stub!\n", debugstr_w(mountpoint));
1133 return FALSE;
1134}

◆ FindFirstVolumeW()

HANDLE WINAPI DECLSPEC_HOTPATCH FindFirstVolumeW ( LPWSTR  volume,
DWORD  len 
)

Definition at line 1043 of file volume.c.

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}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h: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 CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI FindNextVolumeW(IN HANDLE handle, IN LPWSTR volume, IN DWORD len)
Definition: volume.c:1082
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:49
#define MOUNTMGR_DOS_DEVICE_NAME
Definition: mountmgr.h:37
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define memset(x, y, z)
Definition: compat.h:39
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

◆ FindNextVolumeW()

BOOL WINAPI DECLSPEC_HOTPATCH FindNextVolumeW ( HANDLE  handle,
LPWSTR  volume,
DWORD  len 
)

Definition at line 1089 of file volume.c.

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}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
const WCHAR * link
Definition: db.cpp:997
#define TRUE
Definition: types.h:120
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263

◆ FindVolumeClose()

BOOL WINAPI DECLSPEC_HOTPATCH FindVolumeClose ( HANDLE  handle)

Definition at line 1121 of file volume.c.

1122{
1123 return HeapFree( GetProcessHeap(), 0, handle );
1124}

◆ get_mountmgr_drive_type()

static DWORD get_mountmgr_drive_type ( LPCWSTR  root)
static

Definition at line 123 of file volume.c.

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}
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define DRIVE_UNKNOWN
Definition: winbase.h:289

Referenced by GetDriveTypeW().

◆ GetDiskFreeSpaceA()

BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceA ( LPCSTR  root,
LPDWORD  cluster_sectors,
LPDWORD  sector_bytes,
LPDWORD  free_clusters,
LPDWORD  total_clusters 
)

Definition at line 728 of file volume.c.

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}
static const WCHAR rootW[]
Definition: chain.c:69
WCHAR * file_name_AtoW(LPCSTR name, BOOL alloc)
Definition: file.c:411
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceW(LPCWSTR root, LPDWORD cluster_sectors, LPDWORD sector_bytes, LPDWORD free_clusters, LPDWORD total_clusters)
Definition: volume.c:679

◆ GetDiskFreeSpaceExA()

BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExA ( LPCSTR  root,
PULARGE_INTEGER  avail,
PULARGE_INTEGER  total,
PULARGE_INTEGER  totalfree 
)

Definition at line 666 of file volume.c.

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}
static int avail
Definition: adh-main.c:39
BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExW(LPCWSTR root, PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER totalfree)
Definition: volume.c:637
size_t total

◆ GetDiskFreeSpaceExW()

BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceExW ( LPCWSTR  root,
PULARGE_INTEGER  avail,
PULARGE_INTEGER  total,
PULARGE_INTEGER  totalfree 
)

Definition at line 637 of file volume.c.

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}
static BOOL open_device_root(LPCWSTR root, HANDLE *handle)
Definition: volume.c:96
@ FileFsSizeInformation
Definition: from_kernel.h:221
GLfloat units
Definition: glext.h:11727
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
unsigned int UINT
Definition: ndis.h:50
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185

Referenced by GetDiskFreeSpaceExA().

◆ GetDiskFreeSpaceW()

BOOL WINAPI DECLSPEC_HOTPATCH GetDiskFreeSpaceW ( LPCWSTR  root,
LPDWORD  cluster_sectors,
LPDWORD  sector_bytes,
LPDWORD  free_clusters,
LPDWORD  total_clusters 
)

Definition at line 679 of file volume.c.

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}
DWORD WINAPI GetVersion(void)
Definition: version.c:1458

Referenced by GetDiskFreeSpaceA().

◆ GetDriveTypeA()

UINT WINAPI DECLSPEC_HOTPATCH GetDriveTypeA ( LPCSTR  root)

Definition at line 625 of file volume.c.

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}
UINT WINAPI DECLSPEC_HOTPATCH GetDriveTypeW(LPCWSTR root)
Definition: volume.c:575
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:290

◆ GetDriveTypeW()

UINT WINAPI DECLSPEC_HOTPATCH GetDriveTypeW ( LPCWSTR  root)

Definition at line 575 of file volume.c.

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}
static DWORD get_mountmgr_drive_type(LPCWSTR root)
Definition: volume.c:123
return ret
Definition: mutex.c:146
@ FileFsDeviceInformation
Definition: from_kernel.h:222
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define DRIVE_CDROM
Definition: machpc98.h:119
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#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
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DRIVE_REMOTE
Definition: winbase.h:286
#define DRIVE_RAMDISK
Definition: winbase.h:288
#define DRIVE_FIXED
Definition: winbase.h:285
#define DRIVE_REMOVABLE
Definition: winbase.h:284

Referenced by GetDriveTypeA().

◆ GetLogicalDrives()

DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives ( void  )

Definition at line 513 of file volume.c.

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}
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
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
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t ULONG
Definition: typedefs.h:59

Referenced by _getdrives(), create_drivecoll(), DrivesMain(), RecycleBinGeneric::EmptyRecycleBin(), fill_cdromdrive(), fill_datafile(), fill_directory(), fill_diskdrive(), fill_diskpartition(), fill_logicaldisk(), FindOtherDrive(), get_empty_cddrive(), GetLocalDisksLocations(), GetLogicalDriveStringsA(), GetLogicalDriveStringsW(), InitDialog(), CDrivesFolderEnum::Initialize(), InitializeRecycleBinDlg(), CDesktopBrowser::OnDeviceChange(), PrepareFoldersToScan(), RecycleBinGenericEnum::Reset(), search_absolute_directory(), search_directory(), START_TEST(), test_cdrom_ioctl(), test_DefineDosDeviceA(), test_GetDiskFreeSpaceA(), test_GetDiskFreeSpaceW(), test_GetDriveTypeA(), test_GetDriveTypeW(), test_InitPathA(), test_Sign_Media(), VfdChooseLetter(), VfdGetLocalLink(), VfdSetGlobalLink(), and VfdSetLocalLink().

◆ GetLogicalDriveStringsW()

UINT WINAPI DECLSPEC_HOTPATCH GetLogicalDriveStringsW ( UINT  len,
LPWSTR  buffer 
)

Definition at line 549 of file volume.c.

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}
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915

◆ GetVolumeInformationA()

BOOL WINAPI GetVolumeInformationA ( LPCSTR  root,
LPSTR  label,
DWORD  label_len,
DWORD serial,
DWORD filename_len,
DWORD flags,
LPSTR  fsname,
DWORD  fsname_len 
)

Definition at line 221 of file volume.c.

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}
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
DWORD file_name_WtoA(LPCWSTR src, INT srclen, LPSTR dest, INT destlen)
Definition: file.c:438
unsigned int BOOL
Definition: ntddk_ex.h:94
uint32_t serial
Definition: fsck.fat.h:29
static const WCHAR labelW[]
Definition: htmlelem.c:32
static const WCHAR label[]
Definition: itemdlg.c:1546
WCHAR * LPWSTR
Definition: xmlstorage.h:184

◆ GetVolumeInformationByHandleW()

BOOL WINAPI GetVolumeInformationByHandleW ( HANDLE  handle,
WCHAR label,
DWORD  label_len,
DWORD serial,
DWORD filename_len,
DWORD flags,
WCHAR fsname,
DWORD  fsname_len 
)

Definition at line 1140 of file volume.c.

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}
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
#define ERROR_BAD_LENGTH
Definition: winerror.h:127

Referenced by GetVolumeInformationW().

◆ GetVolumeInformationW()

BOOL WINAPI DECLSPEC_HOTPATCH GetVolumeInformationW ( LPCWSTR  root,
LPWSTR  label,
DWORD  label_len,
DWORD serial,
DWORD filename_len,
DWORD flags,
LPWSTR  fsname,
DWORD  fsname_len 
)

Definition at line 155 of file volume.c.

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}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define wcschr
Definition: compat.h:17
#define ERROR_INVALID_NAME
Definition: compat.h:103
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
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
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
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 SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define ERROR_DIR_NOT_ROOT
Definition: winerror.h:216

◆ GetVolumeNameForVolumeMountPointW()

BOOL WINAPI GetVolumeNameForVolumeMountPointW ( LPCWSTR  path,
LPWSTR  volume,
DWORD  size 
)

Definition at line 251 of file volume.c.

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}
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
static NTSTATUS read_nt_symlink(const WCHAR *name, WCHAR *target, DWORD size)
Definition: volume.c:68
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLfloat GLfloat p
Definition: glext.h:8902
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_wn
Definition: kernel32.h:33
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
_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)
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:175
#define ERROR_NO_VOLUME_ID
Definition: winerror.h:695
#define ERROR_NOT_A_REPARSE_POINT
Definition: winerror.h:1288

◆ GetVolumePathNamesForVolumeNameW()

BOOL WINAPI DECLSPEC_HOTPATCH GetVolumePathNamesForVolumeNameW ( LPCWSTR  volumename,
LPWSTR  volumepathname,
DWORD  buflen,
PDWORD  returnlen 
)

Definition at line 927 of file volume.c.

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}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define wcsnicmp
Definition: compat.h:14
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static MOUNTMGR_MOUNT_POINTS * query_mount_points(HANDLE mgr, MOUNTMGR_MOUNT_POINT *input, DWORD insize)
Definition: volume.c:903
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
unsigned short USHORT
Definition: pedump.c:61
USHORT SymbolicLinkNameLength
Definition: imports.h:165
ULONG SymbolicLinkNameOffset
Definition: imports.h:164
Definition: name.c:39

◆ GetVolumePathNameW()

BOOL WINAPI DECLSPEC_HOTPATCH GetVolumePathNameW ( const WCHAR path,
WCHAR volume_path,
DWORD  length 
)

Definition at line 788 of file volume.c.

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}
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define lstrcpynW
Definition: compat.h:738
static BOOL is_dos_path(const UNICODE_STRING *path)
Definition: volume.c:739
static BOOL resolve_symlink(UNICODE_STRING *path)
Definition: volume.c:748
@ FileAttributeTagInformation
Definition: from_kernel.h:96
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
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
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#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
Definition: fci.c:127
#define towupper(c)
Definition: wctype.h:99
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7232

◆ is_dos_path()

static BOOL is_dos_path ( const UNICODE_STRING path)
static

Definition at line 739 of file volume.c.

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}

Referenced by GetVolumePathNameW().

◆ open_device_root()

static BOOL open_device_root ( LPCWSTR  root,
HANDLE handle 
)
static

Definition at line 96 of file volume.c.

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}

Referenced by GetDiskFreeSpaceExW(), GetDiskFreeSpaceW(), and GetDriveTypeW().

◆ query_mount_points()

static MOUNTMGR_MOUNT_POINTS * query_mount_points ( HANDLE  mgr,
MOUNTMGR_MOUNT_POINT input,
DWORD  insize 
)
static

Definition at line 903 of file volume.c.

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}
const unsigned char size_t insize
Definition: jpeglib.h:984
unsigned char size_t * outsize
Definition: jpeglib.h:981

Referenced by GetVolumePathNamesForVolumeNameW().

◆ QueryDosDeviceW()

DWORD WINAPI QueryDosDeviceW ( LPCWSTR  devname,
LPWSTR  target,
DWORD  bufsize 
)

Definition at line 432 of file volume.c.

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}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
#define LOWORD(l)
Definition: pedump.c:82
#define HIWORD(l)
Definition: typedefs.h:247

◆ read_nt_symlink()

static NTSTATUS read_nt_symlink ( const WCHAR name,
WCHAR target,
DWORD  size 
)
static

Definition at line 68 of file volume.c.

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}
static const WCHAR nameW[]
Definition: main.c:49
#define SYMBOLIC_LINK_QUERY
Definition: volume.c:47
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by GetVolumeNameForVolumeMountPointW(), and QueryDosDeviceW().

◆ resolve_symlink()

static BOOL resolve_symlink ( UNICODE_STRING path)
static

Definition at line 748 of file volume.c.

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}
@ ObjectNameInformation
Definition: DriverTester.h:55
NTSTATUS NtQueryObject(IN HANDLE Handle, IN OBJECT_INFO_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength)
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by GetVolumePathNameW().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( volume  )