mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +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
4 changed files with 904 additions and 902 deletions
|
@ -47,6 +47,7 @@ list(APPEND SOURCE
|
|||
client/file/delete.c
|
||||
client/file/deviceio.c
|
||||
client/file/dir.c
|
||||
client/file/disk.c
|
||||
client/file/fileinfo.c
|
||||
client/file/filemap.c
|
||||
client/file/filename.c
|
||||
|
@ -57,6 +58,7 @@ list(APPEND SOURCE
|
|||
client/file/lock.c
|
||||
client/file/mailslot.c
|
||||
client/file/move.c
|
||||
client/file/mntpoint.c
|
||||
client/file/npipe.c
|
||||
client/file/rw.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