mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: Mount Manager directory support
This commit is contained in:
parent
5251dcbce9
commit
d7450d740e
@ -126,6 +126,12 @@ static inline BOOLEAN FspPathIsMountmgrMountPoint(PWSTR FileName)
|
|||||||
) &&
|
) &&
|
||||||
L':' == FileName[5];
|
L':' == FileName[5];
|
||||||
}
|
}
|
||||||
|
static inline BOOLEAN FspPathIsMountmgrDrive(PWSTR FileName)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
FspPathIsMountmgrMountPoint(FileName) &&
|
||||||
|
L'\0' == FileName[6];
|
||||||
|
}
|
||||||
|
|
||||||
#define FSP_NEXT_EA(Ea, EaEnd) \
|
#define FSP_NEXT_EA(Ea, EaEnd) \
|
||||||
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))
|
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))
|
||||||
|
270
src/dll/mount.c
270
src/dll/mount.c
@ -122,12 +122,8 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint)
|
static NTSTATUS FspMountmgrMakeMountdev(HANDLE VolumeHandle, PWSTR VolumeName, GUID *UniqueId)
|
||||||
{
|
{
|
||||||
/* only support drives for now! (format: \\.\X:) */
|
|
||||||
if (L'\0' != MountPoint[6])
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* mountmgr.h */
|
/* mountmgr.h */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -147,38 +143,21 @@ static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWST
|
|||||||
USHORT DeviceNameLength;
|
USHORT DeviceNameLength;
|
||||||
WCHAR DeviceName[1];
|
WCHAR DeviceName[1];
|
||||||
} MOUNTMGR_TARGET_NAME;
|
} MOUNTMGR_TARGET_NAME;
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USHORT SymbolicLinkNameOffset;
|
|
||||||
USHORT SymbolicLinkNameLength;
|
|
||||||
USHORT DeviceNameOffset;
|
|
||||||
USHORT DeviceNameLength;
|
|
||||||
} MOUNTMGR_CREATE_POINT_INPUT;
|
|
||||||
|
|
||||||
GUID UniqueId;
|
|
||||||
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
||||||
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
||||||
MOUNTMGR_TARGET_NAME *TargetName = 0;
|
MOUNTMGR_TARGET_NAME *TargetName = 0;
|
||||||
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
|
ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize;
|
||||||
ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize, CreatePointInputSize;
|
|
||||||
HKEY RegKey;
|
|
||||||
LONG RegResult;
|
|
||||||
WCHAR RegValueName[MAX_PATH];
|
|
||||||
UINT8 RegValueData[sizeof UniqueId];
|
|
||||||
DWORD RegValueNameSize, RegValueDataSize;
|
|
||||||
DWORD RegType;
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
/* transform our volume into one that can be used by the MountManager */
|
/* transform our volume into one that can be used by the MountManager */
|
||||||
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, &UniqueId);
|
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, UniqueId);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
||||||
QueryAutoMountSize = sizeof QueryAutoMount;
|
QueryAutoMountSize = sizeof QueryAutoMount;
|
||||||
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeNameSize;
|
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeNameSize;
|
||||||
CreatePointInputSize = sizeof *CreatePointInput +
|
|
||||||
sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize;
|
|
||||||
|
|
||||||
TargetName = MemAlloc(TargetNameSize);
|
TargetName = MemAlloc(TargetNameSize);
|
||||||
if (0 == TargetName)
|
if (0 == TargetName)
|
||||||
@ -187,13 +166,6 @@ static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWST
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatePointInput = MemAlloc(CreatePointInputSize);
|
|
||||||
if (0 == CreatePointInput)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* query the current AutoMount value and save it */
|
/* query the current AutoMount value and save it */
|
||||||
Result = FspMountmgrControl(
|
Result = FspMountmgrControl(
|
||||||
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
|
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
|
||||||
@ -229,10 +201,145 @@ static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWST
|
|||||||
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
||||||
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
||||||
#if 0
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(TargetName);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrNotify(PWSTR VolumeName, PWSTR MountPoint, BOOLEAN Created)
|
||||||
|
{
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT SourceVolumeNameOffset;
|
||||||
|
USHORT SourceVolumeNameLength;
|
||||||
|
USHORT TargetVolumeNameOffset;
|
||||||
|
USHORT TargetVolumeNameLength;
|
||||||
|
} MOUNTMGR_VOLUME_MOUNT_POINT;
|
||||||
|
|
||||||
|
MOUNTMGR_VOLUME_MOUNT_POINT *VolumeMountPoint = 0;
|
||||||
|
ULONG VolumeNameSize, MountPointSize, VolumeMountPointSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
||||||
|
MountPointSize = lstrlenW(MountPoint) * sizeof(WCHAR);
|
||||||
|
VolumeMountPointSize = sizeof *VolumeMountPoint +
|
||||||
|
sizeof L"\\DosDevices\\" - sizeof(WCHAR) + MountPointSize + VolumeNameSize;
|
||||||
|
|
||||||
|
VolumeMountPoint = MemAlloc(VolumeMountPointSize);
|
||||||
|
if (0 == VolumeMountPoint)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notify volume mount point created/deleted */
|
||||||
|
memset(VolumeMountPoint, 0, sizeof *VolumeMountPoint);
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset = sizeof *VolumeMountPoint;
|
||||||
|
VolumeMountPoint->SourceVolumeNameLength = (USHORT)(
|
||||||
|
sizeof L"\\DosDevices\\" - sizeof(WCHAR) + MountPointSize);
|
||||||
|
VolumeMountPoint->TargetVolumeNameOffset =
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset + VolumeMountPoint->SourceVolumeNameLength;
|
||||||
|
VolumeMountPoint->TargetVolumeNameLength = (USHORT)VolumeNameSize;
|
||||||
|
memcpy((PUINT8)VolumeMountPoint + VolumeMountPoint->SourceVolumeNameOffset,
|
||||||
|
L"\\DosDevices\\", sizeof L"\\DosDevices\\" - sizeof(WCHAR));
|
||||||
|
memcpy((PUINT8)VolumeMountPoint +
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset + (sizeof L"\\DosDevices\\" - sizeof(WCHAR)),
|
||||||
|
MountPoint, MountPointSize);
|
||||||
|
memcpy((PUINT8)VolumeMountPoint + VolumeMountPoint->TargetVolumeNameOffset,
|
||||||
|
VolumeName, VolumeNameSize);
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
Created ?
|
||||||
|
CTL_CODE('m', 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) :
|
||||||
|
/* IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED */
|
||||||
|
CTL_CODE('m', 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED */
|
||||||
|
VolumeMountPoint, VolumeMountPointSize, 0, 0);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
#endif
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(VolumeMountPoint);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspMountmgrDeleteRegistry(GUID *UniqueId)
|
||||||
|
{
|
||||||
|
HKEY RegKey;
|
||||||
|
LONG RegResult;
|
||||||
|
WCHAR RegValueName[MAX_PATH];
|
||||||
|
UINT8 RegValueData[sizeof *UniqueId];
|
||||||
|
DWORD RegValueNameSize, RegValueDataSize;
|
||||||
|
DWORD RegType;
|
||||||
|
|
||||||
|
/* HACK: delete the MountManager registry entries */
|
||||||
|
RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\MountedDevices",
|
||||||
|
0, KEY_READ | KEY_WRITE, &RegKey);
|
||||||
|
if (ERROR_SUCCESS == RegResult)
|
||||||
|
{
|
||||||
|
for (DWORD I = 0;; I++)
|
||||||
|
{
|
||||||
|
RegValueNameSize = MAX_PATH;
|
||||||
|
RegValueDataSize = sizeof RegValueData;
|
||||||
|
RegResult = RegEnumValueW(RegKey,
|
||||||
|
I, RegValueName, &RegValueNameSize, 0, &RegType, RegValueData, &RegValueDataSize);
|
||||||
|
if (ERROR_NO_MORE_ITEMS == RegResult)
|
||||||
|
break;
|
||||||
|
else if (ERROR_SUCCESS != RegResult)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (REG_BINARY == RegType &&
|
||||||
|
sizeof RegValueData == RegValueDataSize &&
|
||||||
|
InlineIsEqualGUID((GUID *)&RegValueData, UniqueId))
|
||||||
|
{
|
||||||
|
RegResult = RegDeleteValueW(RegKey, RegValueName);
|
||||||
|
if (ERROR_SUCCESS == RegResult)
|
||||||
|
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
|
||||||
|
I = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountSet_MountmgrDrive(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint)
|
||||||
|
{
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT SymbolicLinkNameOffset;
|
||||||
|
USHORT SymbolicLinkNameLength;
|
||||||
|
USHORT DeviceNameOffset;
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
} MOUNTMGR_CREATE_POINT_INPUT;
|
||||||
|
|
||||||
|
GUID UniqueId;
|
||||||
|
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
|
||||||
|
ULONG VolumeNameSize, CreatePointInputSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspMountmgrMakeMountdev(VolumeHandle, VolumeName, &UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
||||||
|
CreatePointInputSize = sizeof *CreatePointInput +
|
||||||
|
sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize;
|
||||||
|
|
||||||
|
CreatePointInput = MemAlloc(CreatePointInputSize);
|
||||||
|
if (0 == CreatePointInput)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* create mount point */
|
/* create mount point */
|
||||||
memset(CreatePointInput, 0, sizeof *CreatePointInput);
|
memset(CreatePointInput, 0, sizeof *CreatePointInput);
|
||||||
@ -255,46 +362,54 @@ static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWST
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/* HACK: delete the MountManager registry entries */
|
FspMountmgrDeleteRegistry(&UniqueId);
|
||||||
RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\MountedDevices",
|
|
||||||
0, KEY_READ | KEY_WRITE, &RegKey);
|
|
||||||
if (ERROR_SUCCESS == RegResult)
|
|
||||||
{
|
|
||||||
for (DWORD I = 0;; I++)
|
|
||||||
{
|
|
||||||
RegValueNameSize = MAX_PATH;
|
|
||||||
RegValueDataSize = sizeof RegValueData;
|
|
||||||
RegResult = RegEnumValueW(RegKey,
|
|
||||||
I, RegValueName, &RegValueNameSize, 0, &RegType, RegValueData, &RegValueDataSize);
|
|
||||||
if (ERROR_NO_MORE_ITEMS == RegResult)
|
|
||||||
break;
|
|
||||||
else if (ERROR_SUCCESS != RegResult)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (REG_BINARY == RegType &&
|
|
||||||
sizeof RegValueData == RegValueDataSize &&
|
|
||||||
InlineIsEqualGUID((GUID *)&RegValueData, &UniqueId))
|
|
||||||
{
|
|
||||||
RegResult = RegDeleteValueW(RegKey, RegValueName);
|
|
||||||
if (ERROR_SUCCESS == RegResult)
|
|
||||||
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
|
|
||||||
I = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(RegKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
MemFree(CreatePointInput);
|
MemFree(CreatePointInput);
|
||||||
MemFree(TargetName);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountRemove_Mountmgr(PWSTR MountPoint)
|
static NTSTATUS FspMountSet_Directory(PWSTR VolumeName, PWSTR MountPoint,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle);
|
||||||
|
static NTSTATUS FspMountRemove_Directory(HANDLE MountHandle);
|
||||||
|
static NTSTATUS FspMountSet_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
|
||||||
|
{
|
||||||
|
GUID UniqueId;
|
||||||
|
HANDLE MountHandle = INVALID_HANDLE_VALUE;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PMountHandle = 0;
|
||||||
|
|
||||||
|
Result = FspMountSet_Directory(VolumeName, MountPoint + 4, SecurityDescriptor, &MountHandle);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspMountmgrMakeMountdev(VolumeHandle, VolumeName, &UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspMountmgrNotify(VolumeName, MountPoint + 4, TRUE);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
FspMountmgrDeleteRegistry(&UniqueId);
|
||||||
|
|
||||||
|
*PMountHandle = MountHandle;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result) && INVALID_HANDLE_VALUE != MountHandle)
|
||||||
|
FspMountRemove_Directory(MountHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountRemove_MountmgrDrive(PWSTR MountPoint)
|
||||||
{
|
{
|
||||||
/* mountmgr.h */
|
/* mountmgr.h */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -361,6 +476,22 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountRemove_MountmgrDirectory(PWSTR VolumeName, PWSTR MountPoint, HANDLE MountHandle)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
FspMountmgrNotify(VolumeName, MountPoint + 4, FALSE);
|
||||||
|
|
||||||
|
Result = FspMountRemove_Directory(MountHandle);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspLauncherDefineDosDevice(
|
static NTSTATUS FspLauncherDefineDosDevice(
|
||||||
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
|
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
|
||||||
{
|
{
|
||||||
@ -740,8 +871,11 @@ FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc)
|
|||||||
Desc->MountPoint[0] = L'*';
|
Desc->MountPoint[0] = L'*';
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
|
else if (FspPathIsMountmgrDrive(Desc->MountPoint))
|
||||||
|
return FspMountSet_MountmgrDrive(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint);
|
||||||
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
||||||
return FspMountSet_Mountmgr(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint);
|
return FspMountSet_MountmgrDirectory(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint,
|
||||||
|
Desc->Security, &Desc->MountHandle);
|
||||||
else if (FspPathIsDrive(Desc->MountPoint))
|
else if (FspPathIsDrive(Desc->MountPoint))
|
||||||
return FspMountSet_Drive(Desc->VolumeName, Desc->MountPoint,
|
return FspMountSet_Drive(Desc->VolumeName, Desc->MountPoint,
|
||||||
&Desc->MountHandle);
|
&Desc->MountHandle);
|
||||||
@ -754,8 +888,10 @@ FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
|
|||||||
{
|
{
|
||||||
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
||||||
|
|
||||||
if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
if (FspPathIsMountmgrDrive(Desc->MountPoint))
|
||||||
return FspMountRemove_Mountmgr(Desc->MountPoint);
|
return FspMountRemove_MountmgrDrive(Desc->MountPoint);
|
||||||
|
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
||||||
|
return FspMountRemove_MountmgrDirectory(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
|
||||||
else if (FspPathIsDrive(Desc->MountPoint))
|
else if (FspPathIsDrive(Desc->MountPoint))
|
||||||
return FspMountRemove_Drive(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
|
return FspMountRemove_Drive(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user