mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
sys, dll: mount manager support
This commit is contained in:
parent
565caebe4c
commit
4655926d03
@ -601,7 +601,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
|||||||
PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize,
|
PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize,
|
||||||
PHANDLE PVolumeHandle);
|
PHANDLE PVolumeHandle);
|
||||||
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
||||||
BOOLEAN Persistent);
|
BOOLEAN Persistent, GUID *UniqueId);
|
||||||
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,
|
||||||
|
39
src/dll/fs.c
39
src/dll/fs.c
@ -455,12 +455,19 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu
|
|||||||
USHORT DeviceNameLength;
|
USHORT DeviceNameLength;
|
||||||
} MOUNTMGR_CREATE_POINT_INPUT;
|
} MOUNTMGR_CREATE_POINT_INPUT;
|
||||||
|
|
||||||
|
GUID UniqueId;
|
||||||
MOUNTMGR_CREATE_POINT_INPUT *Input = 0;
|
MOUNTMGR_CREATE_POINT_INPUT *Input = 0;
|
||||||
ULONG VolumeNameSize, InputSize;
|
ULONG VolumeNameSize, InputSize;
|
||||||
|
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);
|
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, &UniqueId);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
@ -493,6 +500,36 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -108,13 +108,13 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
||||||
BOOLEAN Persistent)
|
BOOLEAN Persistent, GUID *UniqueId)
|
||||||
{
|
{
|
||||||
DWORD Bytes;
|
DWORD Bytes;
|
||||||
|
|
||||||
if (!DeviceIoControl(VolumeHandle,
|
if (!DeviceIoControl(VolumeHandle,
|
||||||
FSP_FSCTL_MOUNTDEV,
|
FSP_FSCTL_MOUNTDEV,
|
||||||
&Persistent, sizeof Persistent, 0, 0,
|
&Persistent, sizeof Persistent, UniqueId, sizeof *UniqueId,
|
||||||
&Bytes, 0))
|
&Bytes, 0))
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
@ -67,8 +67,6 @@ 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(
|
||||||
@ -102,8 +100,6 @@ 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)
|
||||||
@ -191,7 +187,7 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject)
|
|||||||
Result = FspFsvolDeviceInit(DeviceObject);
|
Result = FspFsvolDeviceInit(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
Result = FspFsvrtDeviceInit(DeviceObject);
|
Result = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
case FspFsmupDeviceExtensionKind:
|
case FspFsmupDeviceExtensionKind:
|
||||||
Result = FspFsmupDeviceInit(DeviceObject);
|
Result = FspFsmupDeviceInit(DeviceObject);
|
||||||
@ -222,7 +218,6 @@ 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);
|
||||||
@ -950,20 +945,6 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject)
|
|||||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FspMountdevFini(DeviceObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -514,6 +514,8 @@ NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileO
|
|||||||
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||||
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
|
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
|
||||||
|
NTSTATUS FspSendMountmgrDeviceControlIrp(ULONG IoControlCode,
|
||||||
|
PVOID SystemBuffer, ULONG InputBufferLength, PULONG POutputBufferLength);
|
||||||
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||||
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||||
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags);
|
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags);
|
||||||
|
@ -154,7 +154,7 @@ NTSTATUS FspMountdevMake(
|
|||||||
|
|
||||||
if (0 != InterlockedCompareExchange(&FsvrtDeviceExtension->IsMountdev, 0, 0))
|
if (0 != InterlockedCompareExchange(&FsvrtDeviceExtension->IsMountdev, 0, 0))
|
||||||
return Persistent == FsvrtDeviceExtension->Persistent ?
|
return Persistent == FsvrtDeviceExtension->Persistent ?
|
||||||
STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
STATUS_TOO_LATE : STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
FsvrtDeviceExtension->Persistent = Persistent;
|
FsvrtDeviceExtension->Persistent = Persistent;
|
||||||
|
|
||||||
@ -188,4 +188,39 @@ exit:
|
|||||||
VOID FspMountdevFini(
|
VOID FspMountdevFini(
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject)
|
PDEVICE_OBJECT FsvrtDeviceObject)
|
||||||
{
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
|
PVOID Buffer = 0;
|
||||||
|
ULONG Length = 4096;
|
||||||
|
MOUNTMGR_MOUNT_POINT *MountPoint;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 == InterlockedCompareExchange(&FsvrtDeviceExtension->IsMountdev, 0, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (FsvrtDeviceExtension->Persistent)
|
||||||
|
/* if the mountdev is marked as persistent do not purge the MountManager */
|
||||||
|
return;
|
||||||
|
|
||||||
|
Buffer = FspAllocNonPaged(Length);
|
||||||
|
if (0 == Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MountPoint = Buffer;
|
||||||
|
RtlZeroMemory(MountPoint, sizeof *MountPoint);
|
||||||
|
MountPoint->UniqueIdOffset = sizeof(MOUNTMGR_MOUNT_POINT);
|
||||||
|
MountPoint->UniqueIdLength = sizeof FsvrtDeviceExtension->UniqueId;
|
||||||
|
RtlCopyMemory((PUINT8)MountPoint + MountPoint->UniqueIdOffset,
|
||||||
|
&FsvrtDeviceExtension->UniqueId, MountPoint->UniqueIdLength);
|
||||||
|
|
||||||
|
Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_DELETE_POINTS,
|
||||||
|
Buffer, MountPoint->UniqueIdOffset + MountPoint->UniqueIdLength, &Length);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != Buffer)
|
||||||
|
FspFree(Buffer);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileO
|
|||||||
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
||||||
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
|
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
|
||||||
|
NTSTATUS FspSendMountmgrDeviceControlIrp(ULONG IoControlCode,
|
||||||
|
PVOID SystemBuffer, ULONG InputBufferLength, PULONG POutputBufferLength);
|
||||||
static NTSTATUS FspSendIrpCompletion(
|
static NTSTATUS FspSendIrpCompletion(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0);
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0);
|
||||||
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
|
||||||
@ -136,6 +138,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
|||||||
#pragma alloc_text(PAGE, FspSendSetInformationIrp)
|
#pragma alloc_text(PAGE, FspSendSetInformationIrp)
|
||||||
#pragma alloc_text(PAGE, FspSendQuerySecurityIrp)
|
#pragma alloc_text(PAGE, FspSendQuerySecurityIrp)
|
||||||
#pragma alloc_text(PAGE, FspSendQueryEaIrp)
|
#pragma alloc_text(PAGE, FspSendQueryEaIrp)
|
||||||
|
#pragma alloc_text(PAGE, FspSendMountmgrDeviceControlIrp)
|
||||||
#pragma alloc_text(PAGE, FspBufferUserBuffer)
|
#pragma alloc_text(PAGE, FspBufferUserBuffer)
|
||||||
#pragma alloc_text(PAGE, FspLockUserBuffer)
|
#pragma alloc_text(PAGE, FspLockUserBuffer)
|
||||||
#pragma alloc_text(PAGE, FspMapLockedPagesInUserMode)
|
#pragma alloc_text(PAGE, FspMapLockedPagesInUserMode)
|
||||||
@ -444,6 +447,63 @@ NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
|
|||||||
return Context.IoStatus.Status;
|
return Context.IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspSendMountmgrDeviceControlIrp(ULONG IoControlCode,
|
||||||
|
PVOID SystemBuffer, ULONG InputBufferLength, PULONG POutputBufferLength)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(METHOD_BUFFERED == (IoControlCode & 3));
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PIRP Irp;
|
||||||
|
PIO_STACK_LOCATION IrpSp;
|
||||||
|
FSP_SEND_IRP_CONTEXT Context;
|
||||||
|
ULONG OutputBufferLength = 0;
|
||||||
|
|
||||||
|
if (0 == POutputBufferLength)
|
||||||
|
POutputBufferLength = &OutputBufferLength;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&DeviceName, MOUNTMGR_DEVICE_NAME);
|
||||||
|
Result = IoGetDeviceObjectPointer(&DeviceName, FILE_READ_ATTRIBUTES,
|
||||||
|
&FileObject, &DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (0 == Irp)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||||
|
Irp->RequestorMode = KernelMode;
|
||||||
|
Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
|
||||||
|
IrpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
|
||||||
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength = *POutputBufferLength;
|
||||||
|
IrpSp->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
|
||||||
|
IrpSp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
|
||||||
|
|
||||||
|
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
|
||||||
|
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
Result = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (STATUS_PENDING == Result)
|
||||||
|
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
|
||||||
|
|
||||||
|
*POutputBufferLength = (ULONG)Context.IoStatus.Information;
|
||||||
|
Result = Context.IoStatus.Status;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != FileObject)
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspSendIrpCompletion(
|
static NTSTATUS FspSendIrpCompletion(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0)
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0)
|
||||||
{
|
{
|
||||||
|
@ -36,8 +36,6 @@ 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 FspVolumeMakeMountdevNoLock(
|
|
||||||
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(
|
||||||
@ -62,7 +60,6 @@ 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, FspVolumeMakeMountdevNoLock)
|
|
||||||
#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)
|
||||||
@ -327,10 +324,22 @@ VOID FspVolumeDelete(
|
|||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
FSP_FILE_NODE **FileNodes;
|
FSP_FILE_NODE **FileNodes;
|
||||||
ULONG FileNodeCount, Index;
|
ULONG FileNodeCount, Index;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have an fsvrt that is a mountdev, finalize it now! Finalizing a mountdev
|
||||||
|
* involves interaction with the MountManager, which tries to open our devices.
|
||||||
|
* So if we delay this interaction and we do it during final fsvrt teardown (i.e.
|
||||||
|
* FspDeviceDelete time) we will fail such opens with STATUS_CANCELLED, which will
|
||||||
|
* confuse the MountManager.
|
||||||
|
*/
|
||||||
|
if (0 != FsvrtDeviceObject)
|
||||||
|
FspMountdevFini(FsvrtDeviceObject);
|
||||||
|
|
||||||
FspDeviceReference(FsvolDeviceObject);
|
FspDeviceReference(FsvolDeviceObject);
|
||||||
|
|
||||||
FspDeviceGlobalLock();
|
FspDeviceGlobalLock();
|
||||||
@ -554,18 +563,6 @@ NTSTATUS FspVolumeMakeMountdev(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
FspDeviceGlobalLock();
|
|
||||||
Result = FspVolumeMakeMountdevNoLock(FsctlDeviceObject, Irp, IrpSp);
|
|
||||||
FspDeviceGlobalUnlock();
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspVolumeMakeMountdevNoLock(
|
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
|
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
|
||||||
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
|
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
|
||||||
ASSERT(FSP_FSCTL_MOUNTDEV == IrpSp->Parameters.FileSystemControl.FsControlCode);
|
ASSERT(FSP_FSCTL_MOUNTDEV == IrpSp->Parameters.FileSystemControl.FsControlCode);
|
||||||
@ -575,13 +572,65 @@ NTSTATUS FspVolumeMakeMountdevNoLock(
|
|||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
||||||
PVOID InputBuffer = Irp->AssociatedIrp.SystemBuffer;
|
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
||||||
BOOLEAN Persistent = 0 < InputBufferLength ? !!*(PBOOLEAN)InputBuffer : FALSE;
|
BOOLEAN Persistent = 0 < InputBufferLength ? !!*(PBOOLEAN)Irp->AssociatedIrp.SystemBuffer : FALSE;
|
||||||
|
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
||||||
|
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
MOUNTMGR_TARGET_NAME V;
|
||||||
|
UINT8 B[FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + FSP_FSCTL_VOLUME_NAME_SIZEMAX];
|
||||||
|
} TargetName;
|
||||||
|
ULONG Length;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == FsvrtDeviceObject)
|
if (0 == FsvrtDeviceObject)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
if (sizeof(GUID) > OutputBufferLength)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
return FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
FspDeviceGlobalLock();
|
||||||
|
|
||||||
|
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
Length = sizeof QueryAutoMount;
|
||||||
|
Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT,
|
||||||
|
&QueryAutoMount, 0, &Length);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
SetAutoMount.NewState = 0;
|
||||||
|
Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_SET_AUTO_MOUNT,
|
||||||
|
&SetAutoMount, sizeof SetAutoMount, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
TargetName.V.DeviceNameLength = FsvolDeviceExtension->VolumeName.Length;
|
||||||
|
RtlCopyMemory(TargetName.V.DeviceName,
|
||||||
|
FsvolDeviceExtension->VolumeName.Buffer, FsvolDeviceExtension->VolumeName.Length);
|
||||||
|
Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
|
||||||
|
&TargetName.V, FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + TargetName.V.DeviceNameLength, 0);
|
||||||
|
|
||||||
|
SetAutoMount.NewState = QueryAutoMount.CurrentState;
|
||||||
|
FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_SET_AUTO_MOUNT,
|
||||||
|
&SetAutoMount, sizeof SetAutoMount, 0);
|
||||||
|
}
|
||||||
|
else if (STATUS_TOO_LATE == Result)
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||||
|
&FspFsvrtDeviceExtension(FsvrtDeviceObject)->UniqueId, sizeof(GUID));
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = sizeof(GUID);
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
FspDeviceGlobalUnlock();
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
|
@ -104,7 +104,7 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
BOOLEAN Success, VolumePathNameSuccess[8];
|
BOOLEAN Success, VolumePathNameSuccess[8];
|
||||||
WCHAR FilePath[MAX_PATH];
|
WCHAR FilePath[MAX_PATH];
|
||||||
WCHAR VolumePathName[MAX_PATH];
|
WCHAR VolumePathName[MAX_PATH], VolumeName[MAX_PATH];
|
||||||
|
|
||||||
Result = FspFileSystemSetMountPoint(MemfsFileSystem(memfs), MountPoint);
|
Result = FspFileSystemSetMountPoint(MemfsFileSystem(memfs), MountPoint);
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
@ -129,16 +129,19 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
VolumePathNameSuccess[0] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH);
|
VolumePathNameSuccess[0] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH);
|
||||||
|
VolumePathNameSuccess[4] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
VolumePathNameSuccess[1] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH);
|
VolumePathNameSuccess[1] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH);
|
||||||
|
VolumePathNameSuccess[5] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
VolumePathNameSuccess[2] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH);
|
VolumePathNameSuccess[2] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH);
|
||||||
|
VolumePathNameSuccess[6] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
@ -152,10 +155,20 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
Success = RemoveDirectoryW(FilePath);
|
Success = RemoveDirectoryW(FilePath);
|
||||||
ASSERT(Success);
|
ASSERT(Success);
|
||||||
|
|
||||||
|
FspFileSystemRemoveMountPoint(MemfsFileSystem(memfs));
|
||||||
|
|
||||||
memfs_stop(memfs);
|
memfs_stop(memfs);
|
||||||
|
|
||||||
ASSERT(VolumePathNameSuccess[0] == VolumePathNameSuccess[1]);
|
ASSERT(VolumePathNameSuccess[0]);
|
||||||
ASSERT(VolumePathNameSuccess[1] == VolumePathNameSuccess[2]);
|
ASSERT(VolumePathNameSuccess[1]);
|
||||||
|
ASSERT(VolumePathNameSuccess[2]);
|
||||||
|
|
||||||
|
if (MemfsNet != Flags)
|
||||||
|
{
|
||||||
|
ASSERT(VolumePathNameSuccess[4]);
|
||||||
|
ASSERT(VolumePathNameSuccess[5]);
|
||||||
|
ASSERT(VolumePathNameSuccess[6]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void volpath_mount_test(void)
|
static void volpath_mount_test(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user