mirror of
https://github.com/reactos/reactos.git
synced 2024-10-07 01:44:21 +00:00
[KERNEL32] [FORMATTING]: Separate volume.c into disk.c, volume.c, and mountpt.c. Format function headers appropriately. No code change.
svn path=/trunk/; revision=59638
This commit is contained in:
parent
d81cd01efc
commit
53d4f6c6a3
|
@ -47,6 +47,7 @@ list(APPEND SOURCE
|
||||||
client/file/delete.c
|
client/file/delete.c
|
||||||
client/file/deviceio.c
|
client/file/deviceio.c
|
||||||
client/file/dir.c
|
client/file/dir.c
|
||||||
|
client/file/disk.c
|
||||||
client/file/fileinfo.c
|
client/file/fileinfo.c
|
||||||
client/file/filemap.c
|
client/file/filemap.c
|
||||||
client/file/filename.c
|
client/file/filename.c
|
||||||
|
@ -57,6 +58,7 @@ list(APPEND SOURCE
|
||||||
client/file/lock.c
|
client/file/lock.c
|
||||||
client/file/mailslot.c
|
client/file/mailslot.c
|
||||||
client/file/move.c
|
client/file/move.c
|
||||||
|
client/file/mntpoint.c
|
||||||
client/file/npipe.c
|
client/file/npipe.c
|
||||||
client/file/rw.c
|
client/file/rw.c
|
||||||
client/file/tape.c
|
client/file/tape.c
|
||||||
|
|
424
reactos/dll/win32/kernel32/client/file/disk.c
Normal file
424
reactos/dll/win32/kernel32/client/file/disk.c
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/kernel32/file/disk.c
|
||||||
|
* PURPOSE: Disk and Drive functions
|
||||||
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||||
|
* Erik Bos, Alexandre Julliard :
|
||||||
|
* GetLogicalDriveStringsA,
|
||||||
|
* GetLogicalDriveStringsW, GetLogicalDrives
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 01/11/98
|
||||||
|
*/
|
||||||
|
//WINE copyright notice:
|
||||||
|
/*
|
||||||
|
* DOS drives handling functions
|
||||||
|
*
|
||||||
|
* Copyright 1993 Erik Bos
|
||||||
|
* Copyright 1996 Alexandre Julliard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <k32.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
DEBUG_CHANNEL(kernel32file);
|
||||||
|
|
||||||
|
#define MAX_DOS_DRIVES 26
|
||||||
|
HANDLE WINAPI InternalOpenDirW(IN LPCWSTR DirName, IN BOOLEAN Write);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
/* Synced to Wine-2008/12/28 */
|
||||||
|
DWORD
|
||||||
|
WINAPI
|
||||||
|
GetLogicalDriveStringsA(IN DWORD nBufferLength,
|
||||||
|
IN LPSTR lpBuffer)
|
||||||
|
{
|
||||||
|
DWORD drive, count;
|
||||||
|
DWORD dwDriveMap;
|
||||||
|
LPSTR p;
|
||||||
|
|
||||||
|
dwDriveMap = GetLogicalDrives();
|
||||||
|
|
||||||
|
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
{
|
||||||
|
if (dwDriveMap & (1<<drive))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
|
||||||
|
|
||||||
|
p = lpBuffer;
|
||||||
|
|
||||||
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (dwDriveMap & (1<<drive))
|
||||||
|
{
|
||||||
|
*p++ = 'A' + (UCHAR)drive;
|
||||||
|
*p++ = ':';
|
||||||
|
*p++ = '\\';
|
||||||
|
*p++ = '\0';
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return (count * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
/* Synced to Wine-2008/12/28 */
|
||||||
|
DWORD
|
||||||
|
WINAPI
|
||||||
|
GetLogicalDriveStringsW(IN DWORD nBufferLength,
|
||||||
|
IN LPWSTR lpBuffer)
|
||||||
|
{
|
||||||
|
DWORD drive, count;
|
||||||
|
DWORD dwDriveMap;
|
||||||
|
LPWSTR p;
|
||||||
|
|
||||||
|
dwDriveMap = GetLogicalDrives();
|
||||||
|
|
||||||
|
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
{
|
||||||
|
if (dwDriveMap & (1<<drive))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
|
||||||
|
|
||||||
|
p = lpBuffer;
|
||||||
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
|
if (dwDriveMap & (1<<drive))
|
||||||
|
{
|
||||||
|
*p++ = (WCHAR)('A' + drive);
|
||||||
|
*p++ = (WCHAR)':';
|
||||||
|
*p++ = (WCHAR)'\\';
|
||||||
|
*p++ = (WCHAR)'\0';
|
||||||
|
}
|
||||||
|
*p = (WCHAR)'\0';
|
||||||
|
|
||||||
|
return (count * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
/* Synced to Wine-? */
|
||||||
|
DWORD
|
||||||
|
WINAPI
|
||||||
|
GetLogicalDrives(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PROCESS_DEVICEMAP_INFORMATION ProcessDeviceMapInfo;
|
||||||
|
|
||||||
|
/* Get the Device Map for this Process */
|
||||||
|
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
||||||
|
ProcessDeviceMap,
|
||||||
|
&ProcessDeviceMapInfo,
|
||||||
|
sizeof(ProcessDeviceMapInfo),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Return the Drive Map */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessDeviceMapInfo.Query.DriveMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
GetDiskFreeSpaceA(IN LPCSTR lpRootPathName,
|
||||||
|
OUT LPDWORD lpSectorsPerCluster,
|
||||||
|
OUT LPDWORD lpBytesPerSector,
|
||||||
|
OUT LPDWORD lpNumberOfFreeClusters,
|
||||||
|
OUT LPDWORD lpTotalNumberOfClusters)
|
||||||
|
{
|
||||||
|
PWCHAR RootPathNameW=NULL;
|
||||||
|
|
||||||
|
if (lpRootPathName)
|
||||||
|
{
|
||||||
|
if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetDiskFreeSpaceW (RootPathNameW,
|
||||||
|
lpSectorsPerCluster,
|
||||||
|
lpBytesPerSector,
|
||||||
|
lpNumberOfFreeClusters,
|
||||||
|
lpTotalNumberOfClusters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
GetDiskFreeSpaceW(IN LPCWSTR lpRootPathName,
|
||||||
|
OUT LPDWORD lpSectorsPerCluster,
|
||||||
|
OUT LPDWORD lpBytesPerSector,
|
||||||
|
OUT LPDWORD lpNumberOfFreeClusters,
|
||||||
|
OUT LPDWORD lpTotalNumberOfClusters)
|
||||||
|
{
|
||||||
|
FILE_FS_SIZE_INFORMATION FileFsSize;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
WCHAR RootPathName[MAX_PATH];
|
||||||
|
HANDLE hFile;
|
||||||
|
NTSTATUS errCode;
|
||||||
|
|
||||||
|
if (lpRootPathName)
|
||||||
|
{
|
||||||
|
wcsncpy (RootPathName, lpRootPathName, 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetCurrentDirectoryW (MAX_PATH, RootPathName);
|
||||||
|
}
|
||||||
|
RootPathName[3] = 0;
|
||||||
|
|
||||||
|
hFile = InternalOpenDirW(RootPathName, FALSE);
|
||||||
|
if (INVALID_HANDLE_VALUE == hFile)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
errCode = NtQueryVolumeInformationFile(hFile,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&FileFsSize,
|
||||||
|
sizeof(FILE_FS_SIZE_INFORMATION),
|
||||||
|
FileFsSizeInformation);
|
||||||
|
if (!NT_SUCCESS(errCode))
|
||||||
|
{
|
||||||
|
CloseHandle(hFile);
|
||||||
|
BaseSetLastNTError (errCode);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpSectorsPerCluster)
|
||||||
|
*lpSectorsPerCluster = FileFsSize.SectorsPerAllocationUnit;
|
||||||
|
if (lpBytesPerSector)
|
||||||
|
*lpBytesPerSector = FileFsSize.BytesPerSector;
|
||||||
|
if (lpNumberOfFreeClusters)
|
||||||
|
*lpNumberOfFreeClusters = FileFsSize.AvailableAllocationUnits.u.LowPart;
|
||||||
|
if (lpTotalNumberOfClusters)
|
||||||
|
*lpTotalNumberOfClusters = FileFsSize.TotalAllocationUnits.u.LowPart;
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
GetDiskFreeSpaceExA(IN LPCSTR lpDirectoryName OPTIONAL,
|
||||||
|
OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller,
|
||||||
|
OUT PULARGE_INTEGER lpTotalNumberOfBytes,
|
||||||
|
OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
|
||||||
|
{
|
||||||
|
PWCHAR DirectoryNameW=NULL;
|
||||||
|
|
||||||
|
if (lpDirectoryName)
|
||||||
|
{
|
||||||
|
if (!(DirectoryNameW = FilenameA2W(lpDirectoryName, FALSE)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetDiskFreeSpaceExW (DirectoryNameW ,
|
||||||
|
lpFreeBytesAvailableToCaller,
|
||||||
|
lpTotalNumberOfBytes,
|
||||||
|
lpTotalNumberOfFreeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
GetDiskFreeSpaceExW(IN LPCWSTR lpDirectoryName OPTIONAL,
|
||||||
|
OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller,
|
||||||
|
OUT PULARGE_INTEGER lpTotalNumberOfBytes,
|
||||||
|
OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
FILE_FS_SIZE_INFORMATION FsSize;
|
||||||
|
FILE_FS_FULL_SIZE_INFORMATION FsFullSize;
|
||||||
|
} FsInfo;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
ULARGE_INTEGER BytesPerCluster;
|
||||||
|
HANDLE hFile;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (lpDirectoryName == NULL)
|
||||||
|
lpDirectoryName = L"\\";
|
||||||
|
|
||||||
|
hFile = InternalOpenDirW(lpDirectoryName, FALSE);
|
||||||
|
if (INVALID_HANDLE_VALUE == hFile)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpFreeBytesAvailableToCaller != NULL || lpTotalNumberOfBytes != NULL)
|
||||||
|
{
|
||||||
|
/* To get the free space available to the user associated with the
|
||||||
|
current thread, try FileFsFullSizeInformation. If this is not
|
||||||
|
supported by the file system, fall back to FileFsSize */
|
||||||
|
|
||||||
|
Status = NtQueryVolumeInformationFile(hFile,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&FsInfo.FsFullSize,
|
||||||
|
sizeof(FsInfo.FsFullSize),
|
||||||
|
FileFsFullSizeInformation);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Close the handle before returning data
|
||||||
|
to avoid a handle leak in case of a fault! */
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
BytesPerCluster.QuadPart =
|
||||||
|
FsInfo.FsFullSize.BytesPerSector * FsInfo.FsFullSize.SectorsPerAllocationUnit;
|
||||||
|
|
||||||
|
if (lpFreeBytesAvailableToCaller != NULL)
|
||||||
|
{
|
||||||
|
lpFreeBytesAvailableToCaller->QuadPart =
|
||||||
|
BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpTotalNumberOfBytes != NULL)
|
||||||
|
{
|
||||||
|
lpTotalNumberOfBytes->QuadPart =
|
||||||
|
BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpTotalNumberOfFreeBytes != NULL)
|
||||||
|
{
|
||||||
|
lpTotalNumberOfFreeBytes->QuadPart =
|
||||||
|
BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtQueryVolumeInformationFile(hFile,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&FsInfo.FsSize,
|
||||||
|
sizeof(FsInfo.FsSize),
|
||||||
|
FileFsSizeInformation);
|
||||||
|
|
||||||
|
/* Close the handle before returning data
|
||||||
|
to avoid a handle leak in case of a fault! */
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError (Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BytesPerCluster.QuadPart =
|
||||||
|
FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit;
|
||||||
|
|
||||||
|
if (lpFreeBytesAvailableToCaller)
|
||||||
|
{
|
||||||
|
lpFreeBytesAvailableToCaller->QuadPart =
|
||||||
|
BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpTotalNumberOfBytes)
|
||||||
|
{
|
||||||
|
lpTotalNumberOfBytes->QuadPart =
|
||||||
|
BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpTotalNumberOfFreeBytes)
|
||||||
|
{
|
||||||
|
lpTotalNumberOfFreeBytes->QuadPart =
|
||||||
|
BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
UINT
|
||||||
|
WINAPI
|
||||||
|
GetDriveTypeA(IN LPCSTR lpRootPathName)
|
||||||
|
{
|
||||||
|
PWCHAR RootPathNameW;
|
||||||
|
|
||||||
|
if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
|
||||||
|
return DRIVE_UNKNOWN;
|
||||||
|
|
||||||
|
return GetDriveTypeW(RootPathNameW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
UINT
|
||||||
|
WINAPI
|
||||||
|
GetDriveTypeW(IN LPCWSTR lpRootPathName)
|
||||||
|
{
|
||||||
|
FILE_FS_DEVICE_INFORMATION FileFsDevice;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
|
||||||
|
HANDLE hFile;
|
||||||
|
NTSTATUS errCode;
|
||||||
|
|
||||||
|
hFile = InternalOpenDirW(lpRootPathName, FALSE);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
return DRIVE_NO_ROOT_DIR; /* According to WINE regression tests */
|
||||||
|
}
|
||||||
|
|
||||||
|
errCode = NtQueryVolumeInformationFile (hFile,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&FileFsDevice,
|
||||||
|
sizeof(FILE_FS_DEVICE_INFORMATION),
|
||||||
|
FileFsDeviceInformation);
|
||||||
|
if (!NT_SUCCESS(errCode))
|
||||||
|
{
|
||||||
|
CloseHandle(hFile);
|
||||||
|
BaseSetLastNTError (errCode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
switch (FileFsDevice.DeviceType)
|
||||||
|
{
|
||||||
|
case FILE_DEVICE_CD_ROM:
|
||||||
|
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
|
||||||
|
return DRIVE_CDROM;
|
||||||
|
case FILE_DEVICE_VIRTUAL_DISK:
|
||||||
|
return DRIVE_RAMDISK;
|
||||||
|
case FILE_DEVICE_NETWORK_FILE_SYSTEM:
|
||||||
|
return DRIVE_REMOTE;
|
||||||
|
case FILE_DEVICE_DISK:
|
||||||
|
case FILE_DEVICE_DISK_FILE_SYSTEM:
|
||||||
|
if (FileFsDevice.Characteristics & FILE_REMOTE_DEVICE)
|
||||||
|
return DRIVE_REMOTE;
|
||||||
|
if (FileFsDevice.Characteristics & FILE_REMOVABLE_MEDIA)
|
||||||
|
return DRIVE_REMOVABLE;
|
||||||
|
return DRIVE_FIXED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR("Returning DRIVE_UNKNOWN for device type %d\n", FileFsDevice.DeviceType);
|
||||||
|
|
||||||
|
return DRIVE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
394
reactos/dll/win32/kernel32/client/file/mntpoint.c
Normal file
394
reactos/dll/win32/kernel32/client/file/mntpoint.c
Normal file
|
@ -0,0 +1,394 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/kernel32/file/mntpoint.c
|
||||||
|
* PURPOSE: File volume mount point functions
|
||||||
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||||
|
* Erik Bos, Alexandre Julliard :
|
||||||
|
* GetLogicalDriveStringsA,
|
||||||
|
* GetLogicalDriveStringsW, GetLogicalDrives
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 01/11/98
|
||||||
|
*/
|
||||||
|
//WINE copyright notice:
|
||||||
|
/*
|
||||||
|
* DOS drives handling functions
|
||||||
|
*
|
||||||
|
* Copyright 1993 Erik Bos
|
||||||
|
* Copyright 1996 Alexandre Julliard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <k32.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
DEBUG_CHANNEL(kernel32file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GetVolumeNameForVolumeMountPointW
|
||||||
|
* @implemented
|
||||||
|
*
|
||||||
|
* Return an unique volume name for a drive root or mount point.
|
||||||
|
*
|
||||||
|
* @param VolumeMountPoint
|
||||||
|
* Pointer to string that contains either root drive name or
|
||||||
|
* mount point name.
|
||||||
|
* @param VolumeName
|
||||||
|
* Pointer to buffer that is filled with resulting unique
|
||||||
|
* volume name on success.
|
||||||
|
* @param VolumeNameLength
|
||||||
|
* Size of VolumeName buffer in TCHARs.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* TRUE when the function succeeds and the VolumeName buffer is filled,
|
||||||
|
* FALSE otherwise.
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint,
|
||||||
|
OUT LPWSTR VolumeName,
|
||||||
|
IN DWORD VolumeNameLength)
|
||||||
|
{
|
||||||
|
UNICODE_STRING NtFileName;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
IO_STATUS_BLOCK Iosb;
|
||||||
|
ULONG BufferLength;
|
||||||
|
PMOUNTDEV_NAME MountDevName;
|
||||||
|
PMOUNTMGR_MOUNT_POINT MountPoint;
|
||||||
|
ULONG MountPointSize;
|
||||||
|
PMOUNTMGR_MOUNT_POINTS MountPoints;
|
||||||
|
ULONG Index;
|
||||||
|
PUCHAR SymbolicLinkName;
|
||||||
|
BOOL Result;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (!VolumeMountPoint || !VolumeMountPoint[0])
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First step is to convert the passed volume mount point name to
|
||||||
|
* an NT acceptable name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!RtlDosPathNameToNtPathName_U(VolumeMountPoint, &NtFileName, NULL, NULL))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NtFileName.Length > sizeof(WCHAR) &&
|
||||||
|
NtFileName.Buffer[(NtFileName.Length / sizeof(WCHAR)) - 1] == '\\')
|
||||||
|
{
|
||||||
|
NtFileName.Length -= sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query mount point device name which we will later use for determining
|
||||||
|
* the volume name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL);
|
||||||
|
Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes, &Iosb,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
RtlFreeUnicodeString(&NtFileName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferLength = sizeof(MOUNTDEV_NAME) + 50 * sizeof(WCHAR);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MountDevName = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
|
||||||
|
if (MountDevName == NULL)
|
||||||
|
{
|
||||||
|
NtClose(FileHandle);
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb,
|
||||||
|
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||||
|
NULL, 0, MountDevName, BufferLength);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, MountDevName);
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
BufferLength = sizeof(MOUNTDEV_NAME) + MountDevName->NameLength;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NtClose(FileHandle);
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!NT_SUCCESS(Status));
|
||||||
|
|
||||||
|
NtClose(FileHandle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the mount point information from mount manager.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MountPointSize = MountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT);
|
||||||
|
MountPoint = RtlAllocateHeap(GetProcessHeap(), 0, MountPointSize);
|
||||||
|
if (MountPoint == NULL)
|
||||||
|
{
|
||||||
|
RtlFreeHeap(GetProcessHeap(), 0, MountDevName);
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT));
|
||||||
|
MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
|
||||||
|
MountPoint->DeviceNameLength = MountDevName->NameLength;
|
||||||
|
RtlCopyMemory(MountPoint + 1, MountDevName->Name, MountDevName->NameLength);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountDevName);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&NtFileName, L"\\??\\MountPointManager");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL);
|
||||||
|
Status = NtOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes,
|
||||||
|
&Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferLength = sizeof(MOUNTMGR_MOUNT_POINTS);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
|
||||||
|
if (MountPoints == NULL)
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb,
|
||||||
|
IOCTL_MOUNTMGR_QUERY_POINTS,
|
||||||
|
MountPoint, MountPointSize,
|
||||||
|
MountPoints, BufferLength);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
BufferLength = MountPoints->Size;
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!NT_SUCCESS(Status));
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we've gathered info about all mount points mapped to our device, so
|
||||||
|
* select the correct one and copy it into the output buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (Index = 0; Index < MountPoints->NumberOfMountPoints; Index++)
|
||||||
|
{
|
||||||
|
MountPoint = MountPoints->MountPoints + Index;
|
||||||
|
SymbolicLinkName = (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\"
|
||||||
|
* (with the last slash being optional) style symbolic links.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (MountPoint->SymbolicLinkNameLength == 48 * sizeof(WCHAR) ||
|
||||||
|
(MountPoint->SymbolicLinkNameLength == 49 * sizeof(WCHAR) &&
|
||||||
|
SymbolicLinkName[48] == L'\\'))
|
||||||
|
{
|
||||||
|
if (RtlCompareMemory(SymbolicLinkName, L"\\??\\Volume{",
|
||||||
|
11 * sizeof(WCHAR)) == 11 * sizeof(WCHAR) &&
|
||||||
|
SymbolicLinkName[19] == L'-' && SymbolicLinkName[24] == L'-' &&
|
||||||
|
SymbolicLinkName[29] == L'-' && SymbolicLinkName[34] == L'-' &&
|
||||||
|
SymbolicLinkName[47] == L'}')
|
||||||
|
{
|
||||||
|
if (VolumeNameLength >= MountPoint->SymbolicLinkNameLength / sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
RtlCopyMemory(VolumeName,
|
||||||
|
(PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset,
|
||||||
|
MountPoint->SymbolicLinkNameLength);
|
||||||
|
VolumeName[1] = L'\\';
|
||||||
|
Result = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||||
|
Result = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented (Wine 13 sep 2008)
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
|
||||||
|
IN LPSTR lpszVolumeName,
|
||||||
|
IN DWORD cchBufferLength)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
WCHAR volumeW[50], *pathW = NULL;
|
||||||
|
DWORD len = min( sizeof(volumeW) / sizeof(WCHAR), cchBufferLength );
|
||||||
|
|
||||||
|
TRACE("(%s, %p, %x)\n", debugstr_a(lpszVolumeMountPoint), lpszVolumeName, cchBufferLength);
|
||||||
|
|
||||||
|
if (!lpszVolumeMountPoint || !(pathW = FilenameA2W( lpszVolumeMountPoint, TRUE )))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len )))
|
||||||
|
FilenameW2A_N( lpszVolumeName, len, volumeW, -1 );
|
||||||
|
|
||||||
|
RtlFreeHeap( RtlGetProcessHeap(), 0, pathW );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
SetVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint,
|
||||||
|
IN LPCWSTR lpszVolumeName)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
SetVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
|
||||||
|
IN LPCSTR lpszVolumeName)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
DeleteVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
DeleteVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
HANDLE
|
||||||
|
WINAPI
|
||||||
|
FindFirstVolumeMountPointW(IN LPCWSTR lpszRootPathName,
|
||||||
|
IN LPWSTR lpszVolumeMountPoint,
|
||||||
|
IN DWORD cchBufferLength)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
HANDLE
|
||||||
|
WINAPI
|
||||||
|
FindFirstVolumeMountPointA(IN LPCSTR lpszRootPathName,
|
||||||
|
IN LPSTR lpszVolumeMountPoint,
|
||||||
|
IN DWORD cchBufferLength)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
FindNextVolumeMountPointA(IN HANDLE hFindVolumeMountPoint,
|
||||||
|
IN LPSTR lpszVolumeMountPoint,
|
||||||
|
DWORD cchBufferLength)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
FindNextVolumeMountPointW(IN HANDLE hFindVolumeMountPoint,
|
||||||
|
IN LPWSTR lpszVolumeMountPoint,
|
||||||
|
DWORD cchBufferLength)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
WINAPI
|
||||||
|
FindVolumeMountPointClose(IN HANDLE hFindVolumeMountPoint)
|
||||||
|
{
|
||||||
|
STUB;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue