ReactOS  0.4.14-dev-583-g2a1ba2c
disk.c File Reference
#include <k32.h>
#include <debug.h>
Include dependency graph for disk.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MAX_DOS_DRIVES   26
 

Functions

DWORD WINAPI GetLogicalDriveStringsA (IN DWORD nBufferLength, IN LPSTR lpBuffer)
 
DWORD WINAPI GetLogicalDriveStringsW (IN DWORD nBufferLength, IN LPWSTR lpBuffer)
 
DWORD WINAPI GetLogicalDrives (VOID)
 
BOOL WINAPI GetDiskFreeSpaceA (IN LPCSTR lpRootPathName, OUT LPDWORD lpSectorsPerCluster, OUT LPDWORD lpBytesPerSector, OUT LPDWORD lpNumberOfFreeClusters, OUT LPDWORD lpTotalNumberOfClusters)
 
BOOL WINAPI GetDiskFreeSpaceW (IN LPCWSTR lpRootPathName, OUT LPDWORD lpSectorsPerCluster, OUT LPDWORD lpBytesPerSector, OUT LPDWORD lpNumberOfFreeClusters, OUT LPDWORD lpTotalNumberOfClusters)
 
BOOL WINAPI GetDiskFreeSpaceExA (IN LPCSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
 
BOOL WINAPI GetDiskFreeSpaceExW (IN LPCWSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
 
UINT WINAPI GetDriveTypeA (IN LPCSTR lpRootPathName)
 
UINT WINAPI GetDriveTypeW (IN LPCWSTR lpRootPathName)
 

Macro Definition Documentation

◆ MAX_DOS_DRIVES

#define MAX_DOS_DRIVES   26

Definition at line 26 of file disk.c.

◆ NDEBUG

#define NDEBUG

Definition at line 23 of file disk.c.

Function Documentation

◆ GetDiskFreeSpaceA()

BOOL WINAPI GetDiskFreeSpaceA ( IN LPCSTR  lpRootPathName,
OUT LPDWORD  lpSectorsPerCluster,
OUT LPDWORD  lpBytesPerSector,
OUT LPDWORD  lpNumberOfFreeClusters,
OUT LPDWORD  lpTotalNumberOfClusters 
)

Definition at line 142 of file disk.c.

147 {
148  PCSTR RootPath;
149  PUNICODE_STRING RootPathU;
150 
151  RootPath = lpRootPathName;
152  if (RootPath == NULL)
153  {
154  RootPath = "\\";
155  }
156 
157  RootPathU = Basep8BitStringToStaticUnicodeString(RootPath);
158  if (RootPathU == NULL)
159  {
160  return FALSE;
161  }
162 
163  return GetDiskFreeSpaceW(RootPathU->Buffer, lpSectorsPerCluster,
164  lpBytesPerSector, lpNumberOfFreeClusters,
165  lpTotalNumberOfClusters);
166 }
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI GetDiskFreeSpaceW(IN LPCWSTR lpRootPathName, OUT LPDWORD lpSectorsPerCluster, OUT LPDWORD lpBytesPerSector, OUT LPDWORD lpNumberOfFreeClusters, OUT LPDWORD lpTotalNumberOfClusters)
Definition: disk.c:173
const char * PCSTR
Definition: typedefs.h:51

Referenced by _getdiskfree(), CookupNodeId(), DosInt21h(), and test_GetDiskFreeSpaceA().

◆ GetDiskFreeSpaceExA()

BOOL WINAPI GetDiskFreeSpaceExA ( IN LPCSTR lpDirectoryName  OPTIONAL,
OUT PULARGE_INTEGER  lpFreeBytesAvailableToCaller,
OUT PULARGE_INTEGER  lpTotalNumberOfBytes,
OUT PULARGE_INTEGER  lpTotalNumberOfFreeBytes 
)

Definition at line 313 of file disk.c.

317 {
318  PCSTR RootPath;
319  PUNICODE_STRING RootPathU;
320 
321  RootPath = lpDirectoryName;
322  if (RootPath == NULL)
323  {
324  RootPath = "\\";
325  }
326 
327  RootPathU = Basep8BitStringToStaticUnicodeString(RootPath);
328  if (RootPathU == NULL)
329  {
330  return FALSE;
331  }
332 
333  return GetDiskFreeSpaceExW(RootPathU->Buffer, lpFreeBytesAvailableToCaller,
334  lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes);
335 }
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
smooth NULL
Definition: ftsmooth.c:416
const char * PCSTR
Definition: typedefs.h:51
BOOL WINAPI GetDiskFreeSpaceExW(IN LPCWSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
Definition: disk.c:342

Referenced by CDrivesFolder::CompareIDs(), CDrivesFolder::GetDetailsOf(), and GetDiskInfoA().

◆ GetDiskFreeSpaceExW()

BOOL WINAPI GetDiskFreeSpaceExW ( IN LPCWSTR lpDirectoryName  OPTIONAL,
OUT PULARGE_INTEGER  lpFreeBytesAvailableToCaller,
OUT PULARGE_INTEGER  lpTotalNumberOfBytes,
OUT PULARGE_INTEGER  lpTotalNumberOfFreeBytes 
)

Definition at line 342 of file disk.c.

346 {
347  PCWSTR RootPath;
349  HANDLE RootHandle;
351  DWORD BytesPerAllocationUnit;
354  FILE_FS_SIZE_INFORMATION FileFsSize;
355 
356  /* If no path provided, get root path */
357  RootPath = lpDirectoryName;
358  if (lpDirectoryName == NULL)
359  {
360  RootPath = L"\\";
361  }
362 
363  /* Convert the path to NT path */
364  if (!RtlDosPathNameToNtPathName_U(RootPath, &FileName, NULL, NULL))
365  {
367  return FALSE;
368  }
369 
370  /* Open it for disk space query! */
376  if (!NT_SUCCESS(Status))
377  {
379  /* If error conversion lead to file not found, override to use path not found
380  * which is more accurate
381  */
383  {
385  }
386 
387  RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
388 
389  return FALSE;
390  }
391 
392  RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
393 
394  /* If user asks for lpTotalNumberOfFreeBytes, try to use full size information */
395  if (lpTotalNumberOfFreeBytes != NULL)
396  {
397  FILE_FS_FULL_SIZE_INFORMATION FileFsFullSize;
398 
399  /* Issue the full fs size request */
400  Status = NtQueryVolumeInformationFile(RootHandle, &IoStatusBlock, &FileFsFullSize,
403  /* If it succeed, complete out buffers */
404  if (NT_SUCCESS(Status))
405  {
406  /* We can close here, we'll return */
407  NtClose(RootHandle);
408 
409  /* Compute the size of an AU */
410  BytesPerAllocationUnit = FileFsFullSize.SectorsPerAllocationUnit * FileFsFullSize.BytesPerSector;
411 
412  /* And then return what was asked */
413  if (lpFreeBytesAvailableToCaller != NULL)
414  {
415  lpFreeBytesAvailableToCaller->QuadPart = FileFsFullSize.CallerAvailableAllocationUnits.QuadPart * BytesPerAllocationUnit;
416  }
417 
418  if (lpTotalNumberOfBytes != NULL)
419  {
420  lpTotalNumberOfBytes->QuadPart = FileFsFullSize.TotalAllocationUnits.QuadPart * BytesPerAllocationUnit;
421  }
422 
423  /* No need to check for nullness ;-) */
424  lpTotalNumberOfFreeBytes->QuadPart = FileFsFullSize.ActualAvailableAllocationUnits.QuadPart * BytesPerAllocationUnit;
425 
426  return TRUE;
427  }
428  }
429 
430  /* Otherwise, fallback to normal size information */
432  &FileFsSize, sizeof(FILE_FS_SIZE_INFORMATION),
434  NtClose(RootHandle);
435  if (!NT_SUCCESS(Status))
436  {
438  return FALSE;
439  }
440 
441  /* Compute the size of an AU */
442  BytesPerAllocationUnit = FileFsSize.SectorsPerAllocationUnit * FileFsSize.BytesPerSector;
443 
444  /* And then return what was asked, available is free, the same! */
445  if (lpFreeBytesAvailableToCaller != NULL)
446  {
447  lpFreeBytesAvailableToCaller->QuadPart = FileFsSize.AvailableAllocationUnits.QuadPart * BytesPerAllocationUnit;
448  }
449 
450  if (lpTotalNumberOfBytes != NULL)
451  {
452  lpTotalNumberOfBytes->QuadPart = FileFsSize.TotalAllocationUnits.QuadPart * BytesPerAllocationUnit;
453  }
454 
455  if (lpTotalNumberOfFreeBytes != NULL)
456  {
457  lpTotalNumberOfFreeBytes->QuadPart = FileFsSize.AvailableAllocationUnits.QuadPart * BytesPerAllocationUnit;
458  }
459 
460  return TRUE;
461 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:263
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
LARGE_INTEGER ActualAvailableAllocationUnits
Definition: from_kernel.h:272
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
smooth NULL
Definition: ftsmooth.c:416
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
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:3951
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
struct _FileName FileName
Definition: fatprocs.h:884
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define FILE_OPEN_FOR_FREE_SPACE_QUERY
Definition: constants.h:495
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
LARGE_INTEGER CallerAvailableAllocationUnits
Definition: from_kernel.h:271
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)
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:270
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by ACTION_CostFinalize(), ChkDskNow(), drive_get_AvailableSpace(), drive_get_FreeSpace(), drive_get_IsReady(), drive_get_TotalSize(), get_freespace(), GetDiskFreeSpaceExA(), CDrvDefExt::InitGeneralPage(), InitializeFormatDriveDlg(), InitializeRecycleBinDlg(), InsertDefaultClusterSizeForFs(), msi_dialog_vcl_add_drives(), DriveVolume::ObtainInfo(), set_space_status(), and wmain().

◆ GetDiskFreeSpaceW()

BOOL WINAPI GetDiskFreeSpaceW ( IN LPCWSTR  lpRootPathName,
OUT LPDWORD  lpSectorsPerCluster,
OUT LPDWORD  lpBytesPerSector,
OUT LPDWORD  lpNumberOfFreeClusters,
OUT LPDWORD  lpTotalNumberOfClusters 
)

Definition at line 173 of file disk.c.

178 {
179  BOOL Below2GB;
180  PCWSTR RootPath;
182  HANDLE RootHandle;
186  FILE_FS_SIZE_INFORMATION FileFsSize;
187 
188  /* If no path provided, get root path */
189  RootPath = lpRootPathName;
190  if (lpRootPathName == NULL)
191  {
192  RootPath = L"\\";
193  }
194 
195  /* Convert the path to NT path */
196  if (!RtlDosPathNameToNtPathName_U(RootPath, &FileName, NULL, NULL))
197  {
199  return FALSE;
200  }
201 
202  /* Open it for disk space query! */
208  if (!NT_SUCCESS(Status))
209  {
211  RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
212  if (lpBytesPerSector != NULL)
213  {
214  *lpBytesPerSector = 0;
215  }
216 
217  return FALSE;
218  }
219 
220  /* We don't need the name any longer */
221  RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
222 
223  /* Query disk space! */
224  Status = NtQueryVolumeInformationFile(RootHandle, &IoStatusBlock, &FileFsSize,
225  sizeof(FILE_FS_SIZE_INFORMATION),
227  NtClose(RootHandle);
228  if (!NT_SUCCESS(Status))
229  {
231  return FALSE;
232  }
233 
234  /* Are we in some compatibility mode where size must be below 2GB? */
235  Below2GB = ((NtCurrentPeb()->AppCompatFlags.LowPart & GetDiskFreeSpace2GB) == GetDiskFreeSpace2GB);
236 
237  /* If we're to overflow output, make sure we return the maximum */
238  if (FileFsSize.TotalAllocationUnits.HighPart != 0)
239  {
240  FileFsSize.TotalAllocationUnits.LowPart = -1;
241  }
242 
243  if (FileFsSize.AvailableAllocationUnits.HighPart != 0)
244  {
245  FileFsSize.AvailableAllocationUnits.LowPart = -1;
246  }
247 
248  /* Return what user asked for */
249  if (lpSectorsPerCluster != NULL)
250  {
251  *lpSectorsPerCluster = FileFsSize.SectorsPerAllocationUnit;
252  }
253 
254  if (lpBytesPerSector != NULL)
255  {
256  *lpBytesPerSector = FileFsSize.BytesPerSector;
257  }
258 
259  if (lpNumberOfFreeClusters != NULL)
260  {
261  if (!Below2GB)
262  {
263  *lpNumberOfFreeClusters = FileFsSize.AvailableAllocationUnits.LowPart;
264  }
265  /* If we have to remain below 2GB... */
266  else
267  {
269 
270  /* Compute how many clusters there are in less than 2GB: 2 * 1024 * 1024 * 1024- 1 */
271  FreeClusters = 0x7FFFFFFF / (FileFsSize.SectorsPerAllocationUnit * FileFsSize.BytesPerSector);
272  /* If that's higher than what was queried, then return the queried value, it's OK! */
274  {
276  }
277 
278  *lpNumberOfFreeClusters = FreeClusters;
279  }
280  }
281 
282  if (lpTotalNumberOfClusters != NULL)
283  {
284  if (!Below2GB)
285  {
286  *lpTotalNumberOfClusters = FileFsSize.TotalAllocationUnits.LowPart;
287  }
288  /* If we have to remain below 2GB... */
289  else
290  {
291  DWORD TotalClusters;
292 
293  /* Compute how many clusters there are in less than 2GB: 2 * 1024 * 1024 * 1024- 1 */
294  TotalClusters = 0x7FFFFFFF / (FileFsSize.SectorsPerAllocationUnit * FileFsSize.BytesPerSector);
295  /* If that's higher than what was queried, then return the queried value, it's OK! */
296  if (TotalClusters > FileFsSize.TotalAllocationUnits.LowPart)
297  {
298  TotalClusters = FileFsSize.TotalAllocationUnits.LowPart;
299  }
300 
301  *lpTotalNumberOfClusters = TotalClusters;
302  }
303  }
304 
305  return TRUE;
306 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:263
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
NTSTATUS FreeClusters(PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONG ClustersToFree)
Definition: attrib.c:1057
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
unsigned int BOOL
Definition: ntddk_ex.h:94
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
smooth NULL
Definition: ftsmooth.c:416
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
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:3951
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
ULONG LowPart
Definition: typedefs.h:104
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
struct _FileName FileName
Definition: fatprocs.h:884
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define FILE_OPEN_FOR_FREE_SPACE_QUERY
Definition: constants.h:495
#define NtCurrentPeb()
Definition: FLS.c:20
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h: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)

Referenced by GetDiskFreeSpaceA(), DriveVolume::ObtainInfo(), RecycleBin5_RecycleBin5_DeleteFile(), SetupCreateDiskSpaceListW(), SizeOfSector(), and test_GetDiskFreeSpaceW().

◆ GetDriveTypeA()

UINT WINAPI GetDriveTypeA ( IN LPCSTR  lpRootPathName)

Definition at line 468 of file disk.c.

469 {
470  PWSTR RootPathU;
471 
472  if (lpRootPathName != NULL)
473  {
474  PUNICODE_STRING RootPathUStr;
475 
476  RootPathUStr = Basep8BitStringToStaticUnicodeString(lpRootPathName);
477  if (RootPathUStr == NULL)
478  {
479  return DRIVE_NO_ROOT_DIR;
480  }
481 
482  RootPathU = RootPathUStr->Buffer;
483  }
484  else
485  {
486  RootPathU = NULL;
487  }
488 
489  return GetDriveTypeW(RootPathU);
490 }
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
uint16_t * PWSTR
Definition: typedefs.h:54
smooth NULL
Definition: ftsmooth.c:416
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:254

Referenced by CDrivesExtractIcon_CreateInstance(), DosDeviceIoControlDrive(), DosIsFileOnCdRom(), DrivesContextMenuCallback(), FD31_WMDrawItem(), FD31_WMInitDialog(), CDrivesFolder::GetDetailsOf(), GetVolumePathNameW(), IsNetDrive(), OpenFile(), RealDriveType(), search_absolute_directory(), test_AllowPermLayer(), test_cdrom_ioctl(), test_DefineDosDeviceA(), test_GetDiskFreeSpaceA(), test_GetDriveTypeA(), and WNetGetUniversalNameA().

◆ GetDriveTypeW()

UINT WINAPI GetDriveTypeW ( IN LPCWSTR  lpRootPathName)

Definition at line 497 of file disk.c.

498 {
499  BOOL RetryOpen;
500  PCWSTR RootPath;
502  WCHAR DriveLetter;
503  HANDLE RootHandle;
506  UNICODE_STRING PathName, VolumeString;
507  FILE_FS_DEVICE_INFORMATION FileFsDevice;
509 
510  /* If no path, get one */
511  if (lpRootPathName == NULL)
512  {
513  RootPath = Buffer;
514  /* This will be current drive (<letter>:\ - drop the rest)*/
515  if (RtlGetCurrentDirectory_U(sizeof(Buffer), Buffer) > 3 * sizeof(WCHAR))
516  {
517  Buffer[3] = UNICODE_NULL;
518  }
519  }
520  else
521  {
522  /* Handle broken value */
523  if (lpRootPathName == (PVOID)-1)
524  {
525  return DRIVE_UNKNOWN;
526  }
527 
528  RootPath = lpRootPathName;
529  /* If provided path is 2-len, it might be a drive letter... */
530  if (wcslen(lpRootPathName) == 2)
531  {
532  /* Check it! */
533  DriveLetter = RtlUpcaseUnicodeChar(lpRootPathName[0]);
534  /* That's a drive letter! */
535  if (DriveLetter >= L'A' && DriveLetter <= L'Z' && lpRootPathName[1] == L':')
536  {
537  /* Make it a volume */
538  Buffer[0] = DriveLetter;
539  Buffer[1] = L':';
540  Buffer[2] = L'\\';
541  Buffer[3] = UNICODE_NULL;
542  RootPath = Buffer;
543  }
544  }
545  }
546 
547  /* If the provided looks like a DOS device... Like <letter>:<0> */
548  DriveLetter = RtlUpcaseUnicodeChar(RootPath[0]);
549  /* We'll take the quick path!
550  * We'll find the device type looking at the device map (and types ;-))
551  * associated with the current process
552  */
553  if (DriveLetter >= L'A' && DriveLetter <= L'Z' && RootPath[1] == L':' &&
554  RootPath[2] == L'\\' && RootPath[3] == UNICODE_NULL)
555  {
556  USHORT Index;
558 
559  /* Query the device map */
562  &DeviceMap.Query,
563  sizeof(DeviceMap.Query),
564  NULL);
565  /* Zero output if we failed */
566  if (!NT_SUCCESS(Status))
567  {
568  RtlZeroMemory(&DeviceMap, sizeof(PROCESS_DEVICEMAP_INFORMATION));
569  }
570 
571  /* Get our index in the device map */
572  Index = DriveLetter - L'A';
573  /* Check we're in the device map (bit set) */
574  if (((1 << Index) & DeviceMap.Query.DriveMap) != 0)
575  {
576  /* Validate device type and return it */
577  if (DeviceMap.Query.DriveType[Index] >= DRIVE_REMOVABLE &&
578  DeviceMap.Query.DriveType[Index] <= DRIVE_RAMDISK)
579  {
580  return DeviceMap.Query.DriveType[Index];
581  }
582  /* Otherwise, return we don't know the type */
583  else
584  {
585  return DRIVE_UNKNOWN;
586  }
587  }
588 
589  /* We couldn't find ourselves, do it the slow way */
590  }
591 
592  /* No path provided, use root */
593  if (lpRootPathName == NULL)
594  {
595  RootPath = L"\\";
596  }
597 
598  /* Convert to NT path */
599  if (!RtlDosPathNameToNtPathName_U(RootPath, &PathName, NULL, NULL))
600  {
601  return DRIVE_NO_ROOT_DIR;
602  }
603 
604  /* If not a directory, fail, we need a volume */
605  if (PathName.Buffer[(PathName.Length / sizeof(WCHAR)) - 1] != L'\\')
606  {
607  RtlFreeHeap(RtlGetProcessHeap(), 0, PathName.Buffer);
608  return DRIVE_NO_ROOT_DIR;
609  }
610 
611  /* Let's probe for it, by forcing open failure! */
612  RetryOpen = TRUE;
619  /* It properly failed! */
621  {
622  /* It might be a mount point, then, query for target */
624  {
625  /* We'll reopen the target */
626  RtlInitUnicodeString(&VolumeString, VolumeName);
627  VolumeName[1] = L'?';
628  VolumeString.Length -= sizeof(WCHAR);
631  }
632  }
633  else
634  {
635  /* heh. It worked? Or failed for whatever other reason?
636  * Check we have a directory if we get farther in path
637  */
638  PathName.Length += sizeof(WCHAR);
639  if (IsThisARootDirectory(0, &PathName))
640  {
641  /* Yes? Heh, then it's fine, keep our current handle */
642  RetryOpen = FALSE;
643  }
644  else
645  {
646  /* Then, retry to open without forcing non directory type */
647  PathName.Length -= sizeof(WCHAR);
648  if (NT_SUCCESS(Status))
649  {
650  NtClose(RootHandle);
651  }
652  }
653  }
654 
655  /* Now, we retry without forcing file type - should work now */
656  if (RetryOpen)
657  {
662  }
663 
664  /* We don't need path any longer */
665  RtlFreeHeap(RtlGetProcessHeap(), 0, PathName.Buffer);
666  if (!NT_SUCCESS(Status))
667  {
668  return DRIVE_NO_ROOT_DIR;
669  }
670 
671  /* Query the device for its type */
673  &IoStatusBlock,
674  &FileFsDevice,
677  /* No longer required */
678  NtClose(RootHandle);
679  if (!NT_SUCCESS(Status))
680  {
681  return DRIVE_UNKNOWN;
682  }
683 
684  /* Do we have a remote device? Return so! */
685  if ((FileFsDevice.Characteristics & FILE_REMOTE_DEVICE) == FILE_REMOTE_DEVICE)
686  {
687  return DRIVE_REMOTE;
688  }
689 
690  /* Check the device type */
691  switch (FileFsDevice.DeviceType)
692  {
693  /* CDROM, easy */
694  case FILE_DEVICE_CD_ROM:
696  return DRIVE_CDROM;
697 
698  /* Disk... */
699  case FILE_DEVICE_DISK:
701  /* Removable media? Floppy is one */
704  {
705  return DRIVE_REMOVABLE;
706  }
707  else
708  {
709  return DRIVE_FIXED;
710  }
711 
712  /* Easy cases */
713  case FILE_DEVICE_NETWORK:
715  return DRIVE_REMOTE;
716 
718  return DRIVE_RAMDISK;
719  }
720 
721  /* Nothing matching, just fail */
722  return DRIVE_UNKNOWN;
723 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define TRUE
Definition: types.h:120
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define FILE_DEVICE_NETWORK
Definition: winioctl.h:123
BOOL BasepGetVolumeNameFromReparsePoint(IN LPCWSTR lpszMountPoint, OUT LPWSTR lpszVolumeName, IN DWORD cchBufferLength, OUT LPBOOL IsAMountPoint)
Definition: mntpoint.c:257
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define DRIVE_RAMDISK
Definition: winbase.h:252
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:141
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
#define FILE_SHARE_READ
Definition: compat.h:125
#define DRIVE_REMOVABLE
Definition: winbase.h:248
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
#define DRIVE_REMOTE
Definition: winbase.h:250
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
struct _PROCESS_DEVICEMAP_INFORMATION::@3804::@3806 Query
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
NTSYSAPI ULONG NTAPI RtlGetCurrentDirectory_U(_In_ ULONG MaximumLength, _Out_bytecap_(MaximumLength) PWSTR Buffer)
Definition: path.c:1542
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define DRIVE_UNKNOWN
Definition: winbase.h:253
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
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:3951
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
BOOL IsThisARootDirectory(IN HANDLE VolumeHandle, IN PUNICODE_STRING NtPathName)
Definition: volume.c:154
static const WCHAR L[]
Definition: oid.c:1250
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define SYNCHRONIZE
Definition: nt_native.h:61
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:254
#define DRIVE_FIXED
Definition: winbase.h:249
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
unsigned short USHORT
Definition: pedump.c:61
#define DRIVE_CDROM
Definition: winbase.h:251
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:125
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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)

Referenced by ACTION_SearchDirectory(), CDrvDefExt::AddPages(), AllowPermLayer(), create_drive_bar(), drive_get_DriveType(), DriveType(), filesys_DriveExists(), fill_cdromdrive(), fill_datafile(), fill_directory(), fill_diskdrive(), fill_diskpartition(), fill_logicaldisk(), FormatDrive(), get_drive_type(), get_empty_cddrive(), CDrivesFolder::GetDisplayNameOf(), GetDriveTypeA(), GetInstallSourceWin32(), GetVolumeNameForRoot(), CDrvDefExt::InitGeneralPage(), InitializeRecycleBinDlg(), LISTBOX_Directory(), map_security_uri_to_zone(), MCI_Open(), MCICDA_Open(), my_retrieve_vol_type(), PrepareFoldersToScan(), read_tree(), RecycleBinGeneric_RecycleBin_EmptyRecycleBin(), RecycleBinGenericEnum_RecycleBinEnumList_Next(), SdbpIsPathOnRemovableMedia(), SetupCreateDiskSpaceListW(), ShellLink_GetVolumeInfo(), START_TEST(), test_DriveExists(), test_GetDiskFreeSpaceW(), test_GetDrive(), test_GetDriveTypeW(), test_MsiApplyMultiplePatches(), test_WNetGetRemoteName(), test_WNetGetUniversalName(), TRASH_CanTrashFile(), wmain(), WNetGetConnectionW(), and WNetGetUniversalNameW().

◆ GetLogicalDrives()

DWORD WINAPI GetLogicalDrives ( VOID  )

Definition at line 110 of file disk.c.

111 {
113  PROCESS_DEVICEMAP_INFORMATION ProcessDeviceMapInfo;
114 
115  /* Get the Device Map for this Process */
118  &ProcessDeviceMapInfo.Query,
119  sizeof(ProcessDeviceMapInfo.Query),
120  NULL);
121 
122  /* Return the Drive Map */
123  if (!NT_SUCCESS(Status))
124  {
126  return 0;
127  }
128 
129  if (ProcessDeviceMapInfo.Query.DriveMap == 0)
130  {
132  }
133 
134  return ProcessDeviceMapInfo.Query.DriveMap;
135 }
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
struct _PROCESS_DEVICEMAP_INFORMATION::@3804::@3806 Query
smooth NULL
Definition: ftsmooth.c:416
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SetLastError(x)
Definition: compat.h:417
Status
Definition: gdiplustypes.h:24

Referenced by _getdrives(), ACTION_SearchDirectory(), create_drivecoll(), DrivesMain(), fill_cdromdrive(), fill_datafile(), fill_directory(), fill_diskdrive(), fill_diskpartition(), fill_logicaldisk(), FindOtherDrive(), get_empty_cddrive(), GetLogicalDriveStringsA(), GetLogicalDriveStringsW(), InitDialog(), CDrivesFolderEnum::Initialize(), InitializeRecycleBinDlg(), PrepareFoldersToScan(), RecycleBinGeneric_RecycleBin_EmptyRecycleBin(), RecycleBinGenericEnum_RecycleBinEnumList_Reset(), search_absolute_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().

◆ GetLogicalDriveStringsA()

DWORD WINAPI GetLogicalDriveStringsA ( IN DWORD  nBufferLength,
IN LPSTR  lpBuffer 
)

Definition at line 34 of file disk.c.

36 {
37  DWORD drive, count;
38  DWORD dwDriveMap;
39  LPSTR p;
40 
41  dwDriveMap = GetLogicalDrives();
42 
43  for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
44  {
45  if (dwDriveMap & (1<<drive))
46  count++;
47  }
48 
49 
50  if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
51 
52  p = lpBuffer;
53 
54  for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
55  if (dwDriveMap & (1<<drive))
56  {
57  *p++ = 'A' + (UCHAR)drive;
58  *p++ = ':';
59  *p++ = '\\';
60  *p++ = '\0';
61  }
62  *p = '\0';
63 
64  return (count * 4);
65 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
char * LPSTR
Definition: xmlstorage.h:182
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD nBufferLength
Definition: winbase.h:3028
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char UCHAR
Definition: xmlstorage.h:181
DWORD WINAPI GetLogicalDrives(VOID)
Definition: disk.c:110
static char drive[2]
Definition: batch.c:28
#define MAX_DOS_DRIVES
Definition: disk.c:26
GLfloat GLfloat p
Definition: glext.h:8902

◆ GetLogicalDriveStringsW()

DWORD WINAPI GetLogicalDriveStringsW ( IN DWORD  nBufferLength,
IN LPWSTR  lpBuffer 
)

Definition at line 73 of file disk.c.

75 {
76  DWORD drive, count;
77  DWORD dwDriveMap;
78  LPWSTR p;
79 
80  dwDriveMap = GetLogicalDrives();
81 
82  for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
83  {
84  if (dwDriveMap & (1<<drive))
85  count++;
86  }
87 
88  if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
89 
90  p = lpBuffer;
91  for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
92  if (dwDriveMap & (1<<drive))
93  {
94  *p++ = (WCHAR)('A' + drive);
95  *p++ = (WCHAR)':';
96  *p++ = (WCHAR)'\\';
97  *p++ = (WCHAR)'\0';
98  }
99  *p = (WCHAR)'\0';
100 
101  return (count * 4);
102 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD nBufferLength
Definition: winbase.h:3028
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI GetLogicalDrives(VOID)
Definition: disk.c:110
static char drive[2]
Definition: batch.c:28
#define MAX_DOS_DRIVES
Definition: disk.c:26
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by ConvertNtPathToWin32Path(), create_drive_bar(), GetInstallSourceWin32(), msi_dialog_vcl_add_drives(), msi_dialog_vsc_add_drives(), and SetupCreateDiskSpaceListW().