mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys,dll: MountUseMountmgrFromFSD
This commit is contained in:
parent
d7450d740e
commit
a731f0e5d8
@ -75,6 +75,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\service.c" />
|
<ClCompile Include="..\..\src\dll\service.c" />
|
||||||
<ClCompile Include="..\..\src\dll\util.c" />
|
<ClCompile Include="..\..\src\dll\util.c" />
|
||||||
<ClCompile Include="..\..\src\dll\wksid.c" />
|
<ClCompile Include="..\..\src\dll\wksid.c" />
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -175,6 +175,9 @@
|
|||||||
<ClCompile Include="..\..\src\dll\debug.c">
|
<ClCompile Include="..\..\src\dll\debug.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
||||||
|
<Filter>Source\shared\ku</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\dll\library.def">
|
<None Include="..\..\src\dll\library.def">
|
||||||
|
@ -228,6 +228,7 @@
|
|||||||
<FilesToPackage Include="$(TargetPath)" />
|
<FilesToPackage Include="$(TargetPath)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\uuid5.c" />
|
<ClCompile Include="..\..\src\shared\ku\uuid5.c" />
|
||||||
<ClCompile Include="..\..\src\sys\cleanup.c" />
|
<ClCompile Include="..\..\src\sys\cleanup.c" />
|
||||||
|
@ -131,6 +131,9 @@
|
|||||||
<ClCompile Include="..\..\src\sys\devtimer.c">
|
<ClCompile Include="..\..\src\sys\devtimer.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
||||||
|
<Filter>Source\shared\ku</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -91,6 +91,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
|||||||
/* fsctl device codes */
|
/* fsctl device codes */
|
||||||
#define FSP_FSCTL_MOUNTDEV \
|
#define FSP_FSCTL_MOUNTDEV \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define FSP_FSCTL_MOUNTMGR \
|
||||||
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'm', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_VOLUME_NAME \
|
#define FSP_FSCTL_VOLUME_NAME \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_VOLUME_LIST \
|
#define FSP_FSCTL_VOLUME_LIST \
|
||||||
@ -679,6 +681,8 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
|||||||
PHANDLE PVolumeHandle);
|
PHANDLE PVolumeHandle);
|
||||||
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
||||||
BOOLEAN Persistent, GUID *UniqueId);
|
BOOLEAN Persistent, GUID *UniqueId);
|
||||||
|
FSP_API NTSTATUS FspFsctlUseMountmgr(HANDLE VolumeHandle,
|
||||||
|
PWSTR MountPoint);
|
||||||
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
||||||
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
||||||
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
||||||
|
@ -130,6 +130,22 @@ FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlUseMountmgr(HANDLE VolumeHandle,
|
||||||
|
PWSTR MountPoint)
|
||||||
|
{
|
||||||
|
DWORD Bytes;
|
||||||
|
|
||||||
|
Bytes = 0 != MountPoint ? lstrlenW(MountPoint) * sizeof(WCHAR) : 0;
|
||||||
|
|
||||||
|
if (!DeviceIoControl(VolumeHandle,
|
||||||
|
FSP_FSCTL_MOUNTMGR,
|
||||||
|
MountPoint, Bytes, 0, 0,
|
||||||
|
&Bytes, 0))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
||||||
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
||||||
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
||||||
|
@ -73,6 +73,15 @@ NTSTATUS FspEventLogUnregister(VOID);
|
|||||||
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
|
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
|
||||||
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
|
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
|
||||||
ULONG FspLdapConnect(PWSTR HostName, PVOID *PLdap);
|
ULONG FspLdapConnect(PWSTR HostName, PVOID *PLdap);
|
||||||
VOID FspLdapClose(PVOID Ldap);
|
VOID FspLdapClose(PVOID Ldap);
|
||||||
ULONG FspLdapGetValue(PVOID Ldap, PWSTR Base, ULONG Scope, PWSTR Filter, PWSTR Attribute,
|
ULONG FspLdapGetValue(PVOID Ldap, PWSTR Base, ULONG Scope, PWSTR Filter, PWSTR Attribute,
|
||||||
|
448
src/dll/mount.c
448
src/dll/mount.c
@ -31,6 +31,7 @@ static NTSTATUS (NTAPI *FspNtClose)(
|
|||||||
HANDLE Handle);
|
HANDLE Handle);
|
||||||
static BOOLEAN FspMountDoNotUseLauncherValue;
|
static BOOLEAN FspMountDoNotUseLauncherValue;
|
||||||
static BOOLEAN FspMountBroadcastDriveChangeValue;
|
static BOOLEAN FspMountBroadcastDriveChangeValue;
|
||||||
|
static BOOLEAN FspMountUseMountmgrFromFSDValue;
|
||||||
|
|
||||||
static VOID FspMountInitializeFromRegistry(VOID)
|
static VOID FspMountInitializeFromRegistry(VOID)
|
||||||
{
|
{
|
||||||
@ -53,6 +54,14 @@ static VOID FspMountInitializeFromRegistry(VOID)
|
|||||||
RRF_RT_REG_DWORD, 0, &Value, &Size);
|
RRF_RT_REG_DWORD, 0, &Value, &Size);
|
||||||
if (ERROR_SUCCESS == Result)
|
if (ERROR_SUCCESS == Result)
|
||||||
FspMountBroadcastDriveChangeValue = !!Value;
|
FspMountBroadcastDriveChangeValue = !!Value;
|
||||||
|
|
||||||
|
Value = 0;
|
||||||
|
Size = sizeof Value;
|
||||||
|
Result = RegGetValueW(HKEY_LOCAL_MACHINE, L"" FSP_FSCTL_PRODUCT_FULL_REGKEY,
|
||||||
|
L"MountUseMountmgrFromFSD",
|
||||||
|
RRF_RT_REG_DWORD, 0, &Value, &Size);
|
||||||
|
if (ERROR_SUCCESS == Result)
|
||||||
|
FspMountUseMountmgrFromFSDValue = !!Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI FspMountInitialize(
|
static BOOL WINAPI FspMountInitialize(
|
||||||
@ -80,301 +89,40 @@ static BOOL WINAPI FspMountInitialize(
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
|
|
||||||
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength)
|
|
||||||
{
|
|
||||||
HANDLE MgrHandle = INVALID_HANDLE_VALUE;
|
|
||||||
DWORD Bytes = 0;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
if (0 == POutputBufferLength)
|
|
||||||
POutputBufferLength = &Bytes;
|
|
||||||
|
|
||||||
MgrHandle = CreateFileW(L"\\\\.\\MountPointManager",
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
0,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
if (INVALID_HANDLE_VALUE == MgrHandle)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeviceIoControl(MgrHandle,
|
|
||||||
IoControlCode,
|
|
||||||
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength,
|
|
||||||
&Bytes, 0))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
*POutputBufferLength = Bytes;
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
if (INVALID_HANDLE_VALUE != MgrHandle)
|
|
||||||
CloseHandle(MgrHandle);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspMountmgrMakeMountdev(HANDLE VolumeHandle, PWSTR VolumeName, GUID *UniqueId)
|
|
||||||
{
|
|
||||||
/* mountmgr.h */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
Disabled = 0,
|
|
||||||
Enabled,
|
|
||||||
} MOUNTMGR_AUTO_MOUNT_STATE;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MOUNTMGR_AUTO_MOUNT_STATE CurrentState;
|
|
||||||
} MOUNTMGR_QUERY_AUTO_MOUNT;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MOUNTMGR_AUTO_MOUNT_STATE NewState;
|
|
||||||
} MOUNTMGR_SET_AUTO_MOUNT;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USHORT DeviceNameLength;
|
|
||||||
WCHAR DeviceName[1];
|
|
||||||
} MOUNTMGR_TARGET_NAME;
|
|
||||||
|
|
||||||
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
|
||||||
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
|
||||||
MOUNTMGR_TARGET_NAME *TargetName = 0;
|
|
||||||
ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
/* transform our volume into one that can be used by the MountManager */
|
|
||||||
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, UniqueId);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
|
||||||
QueryAutoMountSize = sizeof QueryAutoMount;
|
|
||||||
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeNameSize;
|
|
||||||
|
|
||||||
TargetName = MemAlloc(TargetNameSize);
|
|
||||||
if (0 == TargetName)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* query the current AutoMount value and save it */
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT */
|
|
||||||
0, 0, &QueryAutoMount, &QueryAutoMountSize);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/* disable AutoMount */
|
|
||||||
SetAutoMount.NewState = 0;
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
|
||||||
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/* announce volume arrival */
|
|
||||||
memset(TargetName, 0, sizeof *TargetName);
|
|
||||||
TargetName->DeviceNameLength = (USHORT)VolumeNameSize;
|
|
||||||
memcpy(TargetName->DeviceName,
|
|
||||||
VolumeName, TargetName->DeviceNameLength);
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 11, METHOD_BUFFERED, FILE_READ_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION */
|
|
||||||
TargetName, TargetNameSize, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/* reset the AutoMount value to the saved one */
|
|
||||||
SetAutoMount.NewState = QueryAutoMount.CurrentState;
|
|
||||||
FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
|
||||||
&SetAutoMount, sizeof SetAutoMount, 0, 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))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
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 */
|
|
||||||
memset(CreatePointInput, 0, sizeof *CreatePointInput);
|
|
||||||
CreatePointInput->SymbolicLinkNameOffset = sizeof *CreatePointInput;
|
|
||||||
CreatePointInput->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
|
||||||
CreatePointInput->DeviceNameOffset =
|
|
||||||
CreatePointInput->SymbolicLinkNameOffset + CreatePointInput->SymbolicLinkNameLength;
|
|
||||||
CreatePointInput->DeviceNameLength = (USHORT)VolumeNameSize;
|
|
||||||
memcpy((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset,
|
|
||||||
L"\\DosDevices\\X:", CreatePointInput->SymbolicLinkNameLength);
|
|
||||||
((PWCHAR)((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset))[12] =
|
|
||||||
MountPoint[4] & ~0x20;
|
|
||||||
/* convert to uppercase */
|
|
||||||
memcpy((PUINT8)CreatePointInput + CreatePointInput->DeviceNameOffset,
|
|
||||||
VolumeName, CreatePointInput->DeviceNameLength);
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_CREATE_POINT */
|
|
||||||
CreatePointInput, CreatePointInputSize, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
FspMountmgrDeleteRegistry(&UniqueId);
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
MemFree(CreatePointInput);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspMountSet_Directory(PWSTR VolumeName, PWSTR MountPoint,
|
static NTSTATUS FspMountSet_Directory(PWSTR VolumeName, PWSTR MountPoint,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle);
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle);
|
||||||
static NTSTATUS FspMountRemove_Directory(HANDLE MountHandle);
|
static NTSTATUS FspMountRemove_Directory(HANDLE MountHandle);
|
||||||
|
|
||||||
|
static NTSTATUS FspMountSet_MountmgrDrive(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint)
|
||||||
|
{
|
||||||
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
|
/* use MountManager from FSD and exit */
|
||||||
|
return FspFsctlUseMountmgr(VolumeHandle, MountPoint + 4);
|
||||||
|
|
||||||
|
GUID UniqueId;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* transform our volume into one that can be used by the MountManager */
|
||||||
|
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, &UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* use the MountManager to create the drive */
|
||||||
|
UNICODE_STRING UVolumeName, UMountPoint;
|
||||||
|
UVolumeName.Length = UVolumeName.MaximumLength = (USHORT)(lstrlenW(VolumeName) * sizeof(WCHAR));
|
||||||
|
UVolumeName.Buffer = VolumeName;
|
||||||
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
Result = FspMountmgrCreateDrive(&UVolumeName, &UniqueId, &UMountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountSet_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint,
|
static NTSTATUS FspMountSet_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
|
||||||
{
|
{
|
||||||
@ -384,20 +132,33 @@ static NTSTATUS FspMountSet_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeN
|
|||||||
|
|
||||||
*PMountHandle = 0;
|
*PMountHandle = 0;
|
||||||
|
|
||||||
|
/* create the directory mount point */
|
||||||
Result = FspMountSet_Directory(VolumeName, MountPoint + 4, SecurityDescriptor, &MountHandle);
|
Result = FspMountSet_Directory(VolumeName, MountPoint + 4, SecurityDescriptor, &MountHandle);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = FspMountmgrMakeMountdev(VolumeHandle, VolumeName, &UniqueId);
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
|
{
|
||||||
|
/* use MountManager from FSD and exit */
|
||||||
|
Result = FspFsctlUseMountmgr(VolumeHandle, MountPoint + 4);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* transform our volume into one that can be used by the MountManager */
|
||||||
|
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, &UniqueId);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = FspMountmgrNotify(VolumeName, MountPoint + 4, TRUE);
|
/* notify the MountManager about the created directory mount point */
|
||||||
|
UNICODE_STRING UVolumeName, UMountPoint;
|
||||||
|
UVolumeName.Length = UVolumeName.MaximumLength = (USHORT)(lstrlenW(VolumeName) * sizeof(WCHAR));
|
||||||
|
UVolumeName.Buffer = VolumeName;
|
||||||
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
Result = FspMountmgrNotifyCreateDirectory(&UVolumeName, &UniqueId, &UMountPoint);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
FspMountmgrDeleteRegistry(&UniqueId);
|
|
||||||
|
|
||||||
*PMountHandle = MountHandle;
|
*PMountHandle = MountHandle;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
@ -409,79 +170,39 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountRemove_MountmgrDrive(PWSTR MountPoint)
|
static NTSTATUS FspMountRemove_MountmgrDrive(HANDLE VolumeHandle, PWSTR MountPoint)
|
||||||
{
|
{
|
||||||
/* mountmgr.h */
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
typedef struct
|
/* use MountManager from FSD and exit */
|
||||||
{
|
return FspFsctlUseMountmgr(VolumeHandle, 0);
|
||||||
ULONG SymbolicLinkNameOffset;
|
|
||||||
USHORT SymbolicLinkNameLength;
|
|
||||||
USHORT Reserved1;
|
|
||||||
ULONG UniqueIdOffset;
|
|
||||||
USHORT UniqueIdLength;
|
|
||||||
USHORT Reserved2;
|
|
||||||
ULONG DeviceNameOffset;
|
|
||||||
USHORT DeviceNameLength;
|
|
||||||
USHORT Reserved3;
|
|
||||||
} MOUNTMGR_MOUNT_POINT;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ULONG Size;
|
|
||||||
ULONG NumberOfMountPoints;
|
|
||||||
MOUNTMGR_MOUNT_POINT MountPoints[1];
|
|
||||||
} MOUNTMGR_MOUNT_POINTS;
|
|
||||||
|
|
||||||
MOUNTMGR_MOUNT_POINT *Input = 0;
|
/* use the MountManager to delete the drive */
|
||||||
MOUNTMGR_MOUNT_POINTS *Output = 0;
|
UNICODE_STRING UMountPoint;
|
||||||
ULONG InputSize, OutputSize;
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
NTSTATUS Result;
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
return FspMountmgrDeleteDrive(&UMountPoint);
|
||||||
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
|
||||||
OutputSize = 4096;
|
|
||||||
|
|
||||||
Input = MemAlloc(InputSize);
|
|
||||||
if (0 == Input)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Output = MemAlloc(OutputSize);
|
|
||||||
if (0 == Output)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(Input, 0, sizeof *Input);
|
|
||||||
Input->SymbolicLinkNameOffset = sizeof *Input;
|
|
||||||
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
|
||||||
memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset,
|
|
||||||
L"\\DosDevices\\X:", Input->SymbolicLinkNameLength);
|
|
||||||
((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20;
|
|
||||||
/* convert to uppercase */
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_DELETE_POINTS */
|
|
||||||
Input, InputSize, Output, &OutputSize);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
MemFree(Output);
|
|
||||||
MemFree(Input);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountRemove_MountmgrDirectory(PWSTR VolumeName, PWSTR MountPoint, HANDLE MountHandle)
|
static NTSTATUS FspMountRemove_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint,
|
||||||
|
HANDLE MountHandle)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
FspMountmgrNotify(VolumeName, MountPoint + 4, FALSE);
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
|
/* use MountManager from FSD, but do not exit; additional processing is required below */
|
||||||
|
FspFsctlUseMountmgr(VolumeHandle, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* notify the MountManager about the deleted directory mount point */
|
||||||
|
UNICODE_STRING UVolumeName, UMountPoint;
|
||||||
|
UVolumeName.Length = UVolumeName.MaximumLength = (USHORT)(lstrlenW(VolumeName) * sizeof(WCHAR));
|
||||||
|
UVolumeName.Buffer = VolumeName;
|
||||||
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
FspMountmgrNotifyDeleteDirectory(&UVolumeName, &UMountPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete the directory mount point */
|
||||||
Result = FspMountRemove_Directory(MountHandle);
|
Result = FspMountRemove_Directory(MountHandle);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -889,9 +610,10 @@ FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
|
|||||||
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
||||||
|
|
||||||
if (FspPathIsMountmgrDrive(Desc->MountPoint))
|
if (FspPathIsMountmgrDrive(Desc->MountPoint))
|
||||||
return FspMountRemove_MountmgrDrive(Desc->MountPoint);
|
return FspMountRemove_MountmgrDrive(Desc->VolumeHandle, Desc->MountPoint);
|
||||||
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
||||||
return FspMountRemove_MountmgrDirectory(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
|
return FspMountRemove_MountmgrDirectory(Desc->VolumeHandle, 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
|
||||||
|
599
src/shared/ku/mountmgr.c
Normal file
599
src/shared/ku/mountmgr.c
Normal file
@ -0,0 +1,599 @@
|
|||||||
|
/**
|
||||||
|
* @file shared/ku/mountmgr.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2022 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this software
|
||||||
|
* in accordance with the commercial license agreement provided in
|
||||||
|
* conjunction with the software. The terms and conditions of any such
|
||||||
|
* commercial license agreement shall govern, supersede, and render
|
||||||
|
* ineffective any application of the GPLv3 license to this software,
|
||||||
|
* notwithstanding of any reference thereto in the software or
|
||||||
|
* associated repository.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <shared/ku/library.h>
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4459) /* declaration of 'identifier' hides global declaration */
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
|
||||||
|
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength);
|
||||||
|
static NTSTATUS FspMountmgrNotifyVolumeArrival(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId);
|
||||||
|
static NTSTATUS FspMountmgrNotifyMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint, BOOLEAN Created);
|
||||||
|
static NTSTATUS FspMountmgrCreateMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
static NTSTATUS FspMountmgrDeleteMountPoint(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
static VOID FspMountmgrDeleteRegistry(
|
||||||
|
GUID *UniqueId);
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
|
||||||
|
#if defined(_KERNEL_MODE)
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrControl)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyVolumeArrival)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyMountPoint)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrCreateMountPoint)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrDeleteMountPoint)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrCreateDrive)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrDeleteDrive)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyCreateDirectory)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyDeleteDirectory)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
|
||||||
|
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength)
|
||||||
|
{
|
||||||
|
#if defined(_KERNEL_MODE)
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
HANDLE MgrHandle = 0;
|
||||||
|
ULONG Bytes = 0;
|
||||||
|
|
||||||
|
if (0 == POutputBufferLength)
|
||||||
|
POutputBufferLength = &Bytes;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\MountPointManager");
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&ObjectAttributes,
|
||||||
|
&DeviceName,
|
||||||
|
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
||||||
|
0/*RootDirectory*/,
|
||||||
|
0);
|
||||||
|
|
||||||
|
IoStatus.Status = ZwOpenFile(
|
||||||
|
&MgrHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatus,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_ALERT);
|
||||||
|
if (!NT_SUCCESS(IoStatus.Status))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
IoStatus.Status = ZwDeviceIoControlFile(
|
||||||
|
MgrHandle,
|
||||||
|
0, 0, 0,
|
||||||
|
&IoStatus,
|
||||||
|
IoControlCode,
|
||||||
|
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength);
|
||||||
|
if (!NT_SUCCESS(IoStatus.Status))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
*POutputBufferLength = (ULONG)IoStatus.Information;
|
||||||
|
IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != MgrHandle)
|
||||||
|
ZwClose(MgrHandle);
|
||||||
|
|
||||||
|
return IoStatus.Status;
|
||||||
|
#else
|
||||||
|
HANDLE MgrHandle = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD Bytes = 0;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 == POutputBufferLength)
|
||||||
|
POutputBufferLength = &Bytes;
|
||||||
|
|
||||||
|
MgrHandle = CreateFileW(L"\\\\.\\MountPointManager",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
0,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE == MgrHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(MgrHandle,
|
||||||
|
IoControlCode,
|
||||||
|
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength,
|
||||||
|
&Bytes, 0))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*POutputBufferLength = Bytes;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != MgrHandle)
|
||||||
|
CloseHandle(MgrHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrNotifyVolumeArrival(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Disabled = 0,
|
||||||
|
Enabled,
|
||||||
|
} MOUNTMGR_AUTO_MOUNT_STATE;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MOUNTMGR_AUTO_MOUNT_STATE CurrentState;
|
||||||
|
} MOUNTMGR_QUERY_AUTO_MOUNT;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MOUNTMGR_AUTO_MOUNT_STATE NewState;
|
||||||
|
} MOUNTMGR_SET_AUTO_MOUNT;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
WCHAR DeviceName[1];
|
||||||
|
} MOUNTMGR_TARGET_NAME;
|
||||||
|
|
||||||
|
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
||||||
|
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
||||||
|
MOUNTMGR_TARGET_NAME *TargetName = 0;
|
||||||
|
ULONG QueryAutoMountSize, TargetNameSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
QueryAutoMountSize = sizeof QueryAutoMount;
|
||||||
|
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeName->Length;
|
||||||
|
|
||||||
|
TargetName = MemAlloc(TargetNameSize);
|
||||||
|
if (0 == TargetName)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query the current AutoMount value and save it */
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT */
|
||||||
|
0, 0, &QueryAutoMount, &QueryAutoMountSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* disable AutoMount */
|
||||||
|
SetAutoMount.NewState = 0;
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
||||||
|
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* announce volume arrival */
|
||||||
|
memset(TargetName, 0, sizeof *TargetName);
|
||||||
|
TargetName->DeviceNameLength = VolumeName->Length;
|
||||||
|
memcpy(TargetName->DeviceName, VolumeName->Buffer, VolumeName->Length);
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 11, METHOD_BUFFERED, FILE_READ_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION */
|
||||||
|
TargetName, TargetNameSize, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* reset the AutoMount value to the saved one */
|
||||||
|
SetAutoMount.NewState = QueryAutoMount.CurrentState;
|
||||||
|
FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
||||||
|
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(TargetName);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrNotifyMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint, BOOLEAN Created)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT SourceVolumeNameOffset;
|
||||||
|
USHORT SourceVolumeNameLength;
|
||||||
|
USHORT TargetVolumeNameOffset;
|
||||||
|
USHORT TargetVolumeNameLength;
|
||||||
|
} MOUNTMGR_VOLUME_MOUNT_POINT;
|
||||||
|
|
||||||
|
MOUNTMGR_VOLUME_MOUNT_POINT *VolumeMountPoint = 0;
|
||||||
|
ULONG VolumeMountPointSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
VolumeMountPointSize = sizeof *VolumeMountPoint +
|
||||||
|
sizeof L"\\DosDevices\\" - sizeof(WCHAR) + MountPoint->Length + VolumeName->Length;
|
||||||
|
|
||||||
|
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) + MountPoint->Length);
|
||||||
|
VolumeMountPoint->TargetVolumeNameOffset =
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset + VolumeMountPoint->SourceVolumeNameLength;
|
||||||
|
VolumeMountPoint->TargetVolumeNameLength = VolumeName->Length;
|
||||||
|
memcpy((PUINT8)VolumeMountPoint + VolumeMountPoint->SourceVolumeNameOffset,
|
||||||
|
L"\\DosDevices\\", sizeof L"\\DosDevices\\" - sizeof(WCHAR));
|
||||||
|
memcpy((PUINT8)VolumeMountPoint +
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset + (sizeof L"\\DosDevices\\" - sizeof(WCHAR)),
|
||||||
|
MountPoint->Buffer, MountPoint->Length);
|
||||||
|
memcpy((PUINT8)VolumeMountPoint + VolumeMountPoint->TargetVolumeNameOffset,
|
||||||
|
VolumeName->Buffer, VolumeName->Length);
|
||||||
|
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))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(VolumeMountPoint);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrCreateMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT SymbolicLinkNameOffset;
|
||||||
|
USHORT SymbolicLinkNameLength;
|
||||||
|
USHORT DeviceNameOffset;
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
} MOUNTMGR_CREATE_POINT_INPUT;
|
||||||
|
|
||||||
|
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
|
||||||
|
ULONG CreatePointInputSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
CreatePointInputSize = sizeof *CreatePointInput +
|
||||||
|
sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeName->Length;
|
||||||
|
|
||||||
|
CreatePointInput = MemAlloc(CreatePointInputSize);
|
||||||
|
if (0 == CreatePointInput)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create mount point */
|
||||||
|
memset(CreatePointInput, 0, sizeof *CreatePointInput);
|
||||||
|
CreatePointInput->SymbolicLinkNameOffset = sizeof *CreatePointInput;
|
||||||
|
CreatePointInput->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||||
|
CreatePointInput->DeviceNameOffset =
|
||||||
|
CreatePointInput->SymbolicLinkNameOffset + CreatePointInput->SymbolicLinkNameLength;
|
||||||
|
CreatePointInput->DeviceNameLength = VolumeName->Length;
|
||||||
|
memcpy((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset,
|
||||||
|
L"\\DosDevices\\X:", CreatePointInput->SymbolicLinkNameLength);
|
||||||
|
((PWCHAR)((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset))[12] =
|
||||||
|
MountPoint->Buffer[0] & ~0x20;
|
||||||
|
/* convert to uppercase */
|
||||||
|
memcpy((PUINT8)CreatePointInput + CreatePointInput->DeviceNameOffset,
|
||||||
|
VolumeName->Buffer, VolumeName->Length);
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_CREATE_POINT */
|
||||||
|
CreatePointInput, CreatePointInputSize, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(CreatePointInput);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrDeleteMountPoint(
|
||||||
|
PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG SymbolicLinkNameOffset;
|
||||||
|
USHORT SymbolicLinkNameLength;
|
||||||
|
USHORT Reserved1;
|
||||||
|
ULONG UniqueIdOffset;
|
||||||
|
USHORT UniqueIdLength;
|
||||||
|
USHORT Reserved2;
|
||||||
|
ULONG DeviceNameOffset;
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
USHORT Reserved3;
|
||||||
|
} MOUNTMGR_MOUNT_POINT;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG Size;
|
||||||
|
ULONG NumberOfMountPoints;
|
||||||
|
MOUNTMGR_MOUNT_POINT MountPoints[1];
|
||||||
|
} MOUNTMGR_MOUNT_POINTS;
|
||||||
|
|
||||||
|
MOUNTMGR_MOUNT_POINT *Input = 0;
|
||||||
|
MOUNTMGR_MOUNT_POINTS *Output = 0;
|
||||||
|
ULONG InputSize, OutputSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||||
|
OutputSize = 4096;
|
||||||
|
|
||||||
|
Input = MemAlloc(InputSize);
|
||||||
|
if (0 == Input)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Output = MemAlloc(OutputSize);
|
||||||
|
if (0 == Output)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete mount point */
|
||||||
|
memset(Input, 0, sizeof *Input);
|
||||||
|
Input->SymbolicLinkNameOffset = sizeof *Input;
|
||||||
|
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||||
|
memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset,
|
||||||
|
L"\\DosDevices\\X:", Input->SymbolicLinkNameLength);
|
||||||
|
((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] =
|
||||||
|
MountPoint->Buffer[0] & ~0x20;
|
||||||
|
/* convert to uppercase */
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_DELETE_POINTS */
|
||||||
|
Input, InputSize, Output, &OutputSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(Output);
|
||||||
|
MemFree(Input);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspMountmgrDeleteRegistry(GUID *UniqueId)
|
||||||
|
{
|
||||||
|
#if defined(_KERNEL_MODE)
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
UNICODE_STRING Path;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE Handle = 0;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
KEY_VALUE_FULL_INFORMATION V;
|
||||||
|
UINT8 B[FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + 255 + sizeof *UniqueId];
|
||||||
|
} FullInformation;
|
||||||
|
ULONG FullInformationLength;
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\System\\MountedDevices");
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&ObjectAttributes,
|
||||||
|
&Path,
|
||||||
|
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
||||||
|
0/*RootDirectory*/,
|
||||||
|
0);
|
||||||
|
|
||||||
|
Result = ZwOpenKey(&Handle, KEY_QUERY_VALUE, &ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
for (ULONG I = 0;; I++)
|
||||||
|
{
|
||||||
|
Result = ZwEnumerateValueKey(Handle,
|
||||||
|
I, KeyValueFullInformation, &FullInformation,
|
||||||
|
sizeof FullInformation, &FullInformationLength);
|
||||||
|
if (STATUS_NO_MORE_ENTRIES == Result)
|
||||||
|
break;
|
||||||
|
else if (!NT_SUCCESS(Result))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (REG_BINARY == FullInformation.V.Type &&
|
||||||
|
sizeof *UniqueId == FullInformation.V.DataLength &&
|
||||||
|
InlineIsEqualGUID((GUID *)((PUINT8)&FullInformation.V + FullInformation.V.DataOffset),
|
||||||
|
UniqueId))
|
||||||
|
{
|
||||||
|
ValueName.Length = ValueName.MaximumLength = (USHORT)FullInformation.V.NameLength;
|
||||||
|
ValueName.Buffer = FullInformation.V.Name;
|
||||||
|
Result = ZwDeleteValueKey(Handle, &ValueName);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
|
||||||
|
I = (ULONG)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZwClose(Handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
HKEY RegKey;
|
||||||
|
LONG RegResult;
|
||||||
|
WCHAR RegValueName[MAX_PATH];
|
||||||
|
UINT8 RegValueData[sizeof *UniqueId];
|
||||||
|
DWORD RegValueNameSize, RegValueDataSize;
|
||||||
|
DWORD RegType;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* notify the MountManager about the new volume */
|
||||||
|
Result = FspMountmgrNotifyVolumeArrival(VolumeName, UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* use the MountManager to create the drive */
|
||||||
|
Result = FspMountmgrCreateMountPoint(VolumeName, MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* HACK: delete the MountManager registry entries */
|
||||||
|
FspMountmgrDeleteRegistry(UniqueId);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* use the MountManager to delete the drive */
|
||||||
|
Result = FspMountmgrDeleteMountPoint(MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* notify the MountManager about the new volume */
|
||||||
|
Result = FspMountmgrNotifyVolumeArrival(VolumeName, UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* notify the MountManager about the created directory mount point */
|
||||||
|
Result = FspMountmgrNotifyMountPoint(VolumeName, MountPoint, TRUE);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* HACK: delete the MountManager registry entries */
|
||||||
|
FspMountmgrDeleteRegistry(UniqueId);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* notify the MountManager about the deleted directory mount point */
|
||||||
|
return FspMountmgrNotifyMountPoint(VolumeName, MountPoint, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
@ -59,6 +59,8 @@ VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I
|
|||||||
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
||||||
|
static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||||
|
static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||||
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject);
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||||
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject);
|
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
@ -84,6 +86,8 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvrtDeviceInit)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvrtDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspFsmupDeviceInit)
|
#pragma alloc_text(PAGE, FspFsmupDeviceInit)
|
||||||
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
||||||
@ -171,7 +175,7 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject)
|
|||||||
Result = FspFsvolDeviceInit(DeviceObject);
|
Result = FspFsvolDeviceInit(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
Result = STATUS_SUCCESS;
|
Result = FspFsvrtDeviceInit(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsmupDeviceExtensionKind:
|
case FspFsmupDeviceExtensionKind:
|
||||||
Result = FspFsmupDeviceInit(DeviceObject);
|
Result = FspFsmupDeviceInit(DeviceObject);
|
||||||
@ -202,6 +206,7 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject)
|
|||||||
FspFsvolDeviceFini(DeviceObject);
|
FspFsvolDeviceFini(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
|
FspFsvrtDeviceFini(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsmupDeviceExtensionKind:
|
case FspFsmupDeviceExtensionKind:
|
||||||
FspFsmupDeviceFini(DeviceObject);
|
FspFsmupDeviceFini(DeviceObject);
|
||||||
@ -848,6 +853,27 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject)
|
|||||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
ExInitializeFastMutex(&FsvrtDeviceExtension->MountMutex);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
if (0 != FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
FspFree(FsvrtDeviceExtension->MountPoint.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -1232,13 +1232,18 @@ typedef struct
|
|||||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
/* read-only after creation (and insertion in the ContextTable) */
|
||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
UINT16 SectorSize;
|
UINT16 SectorSize;
|
||||||
LONG IsMountdev;
|
|
||||||
BOOLEAN Persistent;
|
|
||||||
GUID UniqueId;
|
|
||||||
UNICODE_STRING VolumeName;
|
UNICODE_STRING VolumeName;
|
||||||
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
||||||
|
FAST_MUTEX MountMutex;
|
||||||
|
/* interlocked access */
|
||||||
|
LONG IsMountdev;
|
||||||
|
/* protected under MountMutex */
|
||||||
|
BOOLEAN Persistent;
|
||||||
|
GUID UniqueId;
|
||||||
|
UNICODE_STRING MountPoint;
|
||||||
} FSP_FSVRT_DEVICE_EXTENSION;
|
} FSP_FSVRT_DEVICE_EXTENSION;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -1435,6 +1440,18 @@ BOOLEAN FspFsvolDeviceVolumePrefixInString(PDEVICE_OBJECT DeviceObject, PUNICODE
|
|||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
|
VOID FspFsvrtDeviceLockMount(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
ExAcquireFastMutexUnsafe(&FsvrtDeviceExtension->MountMutex);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
VOID FspFsvrtDeviceUnlockMount(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
ExReleaseFastMutexUnsafe(&FsvrtDeviceExtension->MountMutex);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
VOID FspFsmupDeviceLockPrefixTable(PDEVICE_OBJECT DeviceObject)
|
VOID FspFsmupDeviceLockPrefixTable(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(DeviceObject);
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(DeviceObject);
|
||||||
@ -1524,6 +1541,16 @@ NTSTATUS FspMountdevMake(
|
|||||||
VOID FspMountdevFini(
|
VOID FspMountdevFini(
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject);
|
PDEVICE_OBJECT FsvrtDeviceObject);
|
||||||
|
|
||||||
|
/* mountmgr */
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
|
||||||
/* fsmup */
|
/* fsmup */
|
||||||
NTSTATUS FspMupRegister(
|
NTSTATUS FspMupRegister(
|
||||||
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
||||||
@ -1543,6 +1570,8 @@ NTSTATUS FspVolumeMount(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeMakeMountdev(
|
NTSTATUS FspVolumeMakeMountdev(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspVolumeUseMountmgr(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetNameList(
|
NTSTATUS FspVolumeGetNameList(
|
||||||
|
@ -81,6 +81,10 @@ static NTSTATUS FspFsctlFileSystemControl(
|
|||||||
if (0 != IrpSp->FileObject->FsContext2)
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
Result = FspVolumeMakeMountdev(FsctlDeviceObject, Irp, IrpSp);
|
Result = FspVolumeMakeMountdev(FsctlDeviceObject, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
case FSP_FSCTL_MOUNTMGR:
|
||||||
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
|
Result = FspVolumeUseMountmgr(FsctlDeviceObject, Irp, IrpSp);
|
||||||
|
break;
|
||||||
case FSP_FSCTL_VOLUME_NAME:
|
case FSP_FSCTL_VOLUME_NAME:
|
||||||
if (0 != IrpSp->FileObject->FsContext2)
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
Result = FspVolumeGetName(FsctlDeviceObject, Irp, IrpSp);
|
Result = FspVolumeGetName(FsctlDeviceObject, Irp, IrpSp);
|
||||||
|
@ -138,7 +138,7 @@ NTSTATUS FspMountdevMake(
|
|||||||
* be mounted using the MountManager.
|
* be mounted using the MountManager.
|
||||||
*
|
*
|
||||||
* This function requires protection against concurrency. In general this
|
* This function requires protection against concurrency. In general this
|
||||||
* is achieved by acquiring the GlobalDeviceLock.
|
* is achieved by the caller acquiring the MountMutex.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -178,11 +178,6 @@ NTSTATUS FspMountdevMake(
|
|||||||
|
|
||||||
/* initialize the fsvrt device extension */
|
/* initialize the fsvrt device extension */
|
||||||
RtlCopyMemory(&FsvrtDeviceExtension->UniqueId, &Guid, sizeof Guid);
|
RtlCopyMemory(&FsvrtDeviceExtension->UniqueId, &Guid, sizeof Guid);
|
||||||
RtlInitEmptyUnicodeString(&FsvrtDeviceExtension->VolumeName,
|
|
||||||
FsvrtDeviceExtension->VolumeNameBuf, sizeof FsvrtDeviceExtension->VolumeNameBuf);
|
|
||||||
RtlCopyUnicodeString(&FsvrtDeviceExtension->VolumeName, &FsvolDeviceExtension->VolumeName);
|
|
||||||
|
|
||||||
/* mark the fsvrt device as initialized */
|
|
||||||
InterlockedIncrement(&FspFsvrtDeviceExtension(FsvrtDeviceObject)->IsMountdev);
|
InterlockedIncrement(&FspFsvrtDeviceExtension(FsvrtDeviceObject)->IsMountdev);
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
155
src/sys/volume.c
155
src/sys/volume.c
@ -38,6 +38,8 @@ static NTSTATUS FspVolumeMountNoLock(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeMakeMountdev(
|
NTSTATUS FspVolumeMakeMountdev(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspVolumeUseMountmgr(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetNameList(
|
NTSTATUS FspVolumeGetNameList(
|
||||||
@ -76,6 +78,7 @@ NTSTATUS FspVolumeWork(
|
|||||||
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
||||||
#pragma alloc_text(PAGE, FspVolumeMakeMountdev)
|
#pragma alloc_text(PAGE, FspVolumeMakeMountdev)
|
||||||
|
#pragma alloc_text(PAGE, FspVolumeUseMountmgr)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetName)
|
#pragma alloc_text(PAGE, FspVolumeGetName)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
||||||
@ -316,8 +319,12 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
{
|
{
|
||||||
if (0 != FsvrtDeviceObject)
|
if (0 != FsvrtDeviceObject)
|
||||||
{
|
{
|
||||||
FspFsvrtDeviceExtension(FsvrtDeviceObject)->SectorSize =
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
FsvolDeviceExtension->VolumeParams.SectorSize;
|
FsvrtDeviceExtension->SectorSize = FsvolDeviceExtension->VolumeParams.SectorSize;
|
||||||
|
RtlInitEmptyUnicodeString(&FsvrtDeviceExtension->VolumeName,
|
||||||
|
FsvrtDeviceExtension->VolumeNameBuf, sizeof FsvrtDeviceExtension->VolumeNameBuf);
|
||||||
|
RtlCopyUnicodeString(&FsvrtDeviceExtension->VolumeName, &FsvolDeviceExtension->VolumeName);
|
||||||
|
|
||||||
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -638,7 +645,7 @@ NTSTATUS FspVolumeMakeMountdev(
|
|||||||
if (sizeof(GUID) > OutputBufferLength)
|
if (sizeof(GUID) > OutputBufferLength)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
FspDeviceGlobalLock();
|
FspFsvrtDeviceLockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -654,7 +661,147 @@ NTSTATUS FspVolumeMakeMountdev(
|
|||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
FspDeviceGlobalUnlock();
|
FspFsvrtDeviceUnlockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspVolumeUseMountmgr(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
|
||||||
|
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
|
||||||
|
ASSERT(FSP_FSCTL_MOUNTMGR == IrpSp->Parameters.FileSystemControl.FsControlCode);
|
||||||
|
ASSERT(0 != IrpSp->FileObject->FsContext2);
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
|
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 == FsvrtDeviceObject)
|
||||||
|
return STATUS_INVALID_PARAMETER; /* cannot only use fsvrt with mount manager */
|
||||||
|
if (1024 * sizeof(WCHAR) < InputBufferLength)
|
||||||
|
return STATUS_INVALID_PARAMETER; /* disallow very long paths */
|
||||||
|
|
||||||
|
FspFsvrtDeviceLockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
|
if (0 < InputBufferLength)
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
|
PWCHAR MountPointBuf = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
UNICODE_STRING RegPath;
|
||||||
|
UNICODE_STRING RegName;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
KEY_VALUE_PARTIAL_INFORMATION V;
|
||||||
|
UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(ULONG)];
|
||||||
|
} RegValue;
|
||||||
|
ULONG RegLength;
|
||||||
|
BOOLEAN Persistent = FALSE;
|
||||||
|
|
||||||
|
if (!(
|
||||||
|
2 * sizeof(WCHAR) <= InputBufferLength &&
|
||||||
|
(
|
||||||
|
(L'A' <= MountPointBuf[0] && MountPointBuf[0] <= L'Z') ||
|
||||||
|
(L'a' <= MountPointBuf[0] && MountPointBuf[0] <= L'z')
|
||||||
|
) &&
|
||||||
|
L':' == MountPointBuf[1]
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&RegPath, L"" FSP_REGKEY);
|
||||||
|
RtlInitUnicodeString(&RegName, L"MountUseMountmgrFromFSD");
|
||||||
|
RegLength = sizeof RegValue;
|
||||||
|
Result = FspRegistryGetValue(&RegPath, &RegName, &RegValue.V, &RegLength);
|
||||||
|
if (!NT_SUCCESS(Result) || REG_DWORD != RegValue.V.Type || 1 != *(PULONG)&RegValue.V.Data)
|
||||||
|
{
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (STATUS_TOO_LATE != Result)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
FsvrtDeviceExtension->MountPoint.Buffer = FspAllocNonPaged(InputBufferLength);
|
||||||
|
if (0 == FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
FsvrtDeviceExtension->MountPoint.Length =
|
||||||
|
FsvrtDeviceExtension->MountPoint.MaximumLength = (USHORT)InputBufferLength;
|
||||||
|
RtlCopyMemory(FsvrtDeviceExtension->MountPoint.Buffer, MountPointBuf, InputBufferLength);
|
||||||
|
|
||||||
|
if (2 * sizeof(WCHAR) == FsvrtDeviceExtension->MountPoint.Length)
|
||||||
|
Result = FspMountmgrCreateDrive(
|
||||||
|
&FsvrtDeviceExtension->VolumeName,
|
||||||
|
&FsvrtDeviceExtension->UniqueId,
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
else
|
||||||
|
Result = FspMountmgrNotifyCreateDirectory(
|
||||||
|
&FsvrtDeviceExtension->VolumeName,
|
||||||
|
&FsvrtDeviceExtension->UniqueId,
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFree(FsvrtDeviceExtension->MountPoint.Buffer);
|
||||||
|
FsvrtDeviceExtension->MountPoint.Buffer = 0;
|
||||||
|
FsvrtDeviceExtension->MountPoint.Length =
|
||||||
|
FsvrtDeviceExtension->MountPoint.MaximumLength = 0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
|
|
||||||
|
if (0 == FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (2 * sizeof(WCHAR) == FsvrtDeviceExtension->MountPoint.Length)
|
||||||
|
Result = FspMountmgrDeleteDrive(
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
else
|
||||||
|
Result = FspMountmgrNotifyDeleteDirectory(
|
||||||
|
&FsvrtDeviceExtension->VolumeName,
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
/* ignore Result */
|
||||||
|
|
||||||
|
FspFree(FsvrtDeviceExtension->MountPoint.Buffer);
|
||||||
|
FsvrtDeviceExtension->MountPoint.Buffer = 0;
|
||||||
|
FsvrtDeviceExtension->MountPoint.Length =
|
||||||
|
FsvrtDeviceExtension->MountPoint.MaximumLength = 0;
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
FspFsvrtDeviceUnlockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user