From 4655926d03a8df9b9b9ffb2a5c19fd8908b14943 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Fri, 6 Sep 2019 14:24:00 -0700 Subject: [PATCH] sys, dll: mount manager support --- inc/winfsp/fsctl.h | 2 +- src/dll/fs.c | 39 ++++++++++++++- src/dll/fsctl.c | 4 +- src/sys/device.c | 21 +------- src/sys/driver.h | 2 + src/sys/mountdev.c | 37 +++++++++++++- src/sys/util.c | 60 +++++++++++++++++++++++ src/sys/volume.c | 85 ++++++++++++++++++++++++++------- tst/winfsp-tests/volpath-test.c | 19 ++++++-- 9 files changed, 223 insertions(+), 46 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index c21c9dd6..0aedf2b3 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -601,7 +601,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize, PHANDLE PVolumeHandle); FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle, - BOOLEAN Persistent); + BOOLEAN Persistent, GUID *UniqueId); FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, PVOID ResponseBuf, SIZE_T ResponseBufSize, PVOID RequestBuf, SIZE_T *PRequestBufSize, diff --git a/src/dll/fs.c b/src/dll/fs.c index 347eddeb..8e717dc4 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -455,12 +455,19 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu USHORT DeviceNameLength; } MOUNTMGR_CREATE_POINT_INPUT; + GUID UniqueId; MOUNTMGR_CREATE_POINT_INPUT *Input = 0; ULONG VolumeNameSize, InputSize; + HKEY RegKey; + LONG RegResult; + WCHAR RegValueName[MAX_PATH]; + UINT8 RegValueData[sizeof UniqueId]; + DWORD RegValueNameSize, RegValueDataSize; + DWORD RegType; NTSTATUS Result; /* 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)) goto exit; @@ -493,6 +500,36 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu if (!NT_SUCCESS(Result)) 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; exit: diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index cbfe248f..442b4d94 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -108,13 +108,13 @@ exit: } FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle, - BOOLEAN Persistent) + BOOLEAN Persistent, GUID *UniqueId) { DWORD Bytes; if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_MOUNTDEV, - &Persistent, sizeof Persistent, 0, 0, + &Persistent, sizeof Persistent, UniqueId, sizeof *UniqueId, &Bytes, 0)) return FspNtStatusFromWin32(GetLastError()); diff --git a/src/sys/device.c b/src/sys/device.c index 817f9053..952187e6 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -67,8 +67,6 @@ VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo); VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject); -static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject); -static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject); static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject); static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject); NTSTATUS FspDeviceCopyList( @@ -102,8 +100,6 @@ VOID FspDeviceDeleteAll(VOID); #pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName) #pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName) #pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName) -#pragma alloc_text(PAGE, FspFsvrtDeviceInit) -#pragma alloc_text(PAGE, FspFsvrtDeviceFini) #pragma alloc_text(PAGE, FspFsmupDeviceInit) #pragma alloc_text(PAGE, FspFsmupDeviceFini) #pragma alloc_text(PAGE, FspDeviceCopyList) @@ -191,7 +187,7 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject) Result = FspFsvolDeviceInit(DeviceObject); break; case FspFsvrtDeviceExtensionKind: - Result = FspFsvrtDeviceInit(DeviceObject); + Result = STATUS_SUCCESS; break; case FspFsmupDeviceExtensionKind: Result = FspFsmupDeviceInit(DeviceObject); @@ -222,7 +218,6 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject) FspFsvolDeviceFini(DeviceObject); break; case FspFsvrtDeviceExtensionKind: - FspFsvrtDeviceFini(DeviceObject); break; case FspFsmupDeviceExtensionKind: FspFsmupDeviceFini(DeviceObject); @@ -950,20 +945,6 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject) 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) { PAGED_CODE(); diff --git a/src/sys/driver.h b/src/sys/driver.h index 8e704392..01c02bf5 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -514,6 +514,8 @@ NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileO NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength, 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 FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags); diff --git a/src/sys/mountdev.c b/src/sys/mountdev.c index f85d2f4b..0c9dc241 100644 --- a/src/sys/mountdev.c +++ b/src/sys/mountdev.c @@ -154,7 +154,7 @@ NTSTATUS FspMountdevMake( if (0 != InterlockedCompareExchange(&FsvrtDeviceExtension->IsMountdev, 0, 0)) return Persistent == FsvrtDeviceExtension->Persistent ? - STATUS_SUCCESS : STATUS_ACCESS_DENIED; + STATUS_TOO_LATE : STATUS_ACCESS_DENIED; FsvrtDeviceExtension->Persistent = Persistent; @@ -188,4 +188,39 @@ exit: VOID FspMountdevFini( 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); } diff --git a/src/sys/util.c b/src/sys/util.c index dc981026..c3218b81 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -35,6 +35,8 @@ NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileO NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength, PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength); +NTSTATUS FspSendMountmgrDeviceControlIrp(ULONG IoControlCode, + PVOID SystemBuffer, ULONG InputBufferLength, PULONG POutputBufferLength); static NTSTATUS FspSendIrpCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0); 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, FspSendQuerySecurityIrp) #pragma alloc_text(PAGE, FspSendQueryEaIrp) +#pragma alloc_text(PAGE, FspSendMountmgrDeviceControlIrp) #pragma alloc_text(PAGE, FspBufferUserBuffer) #pragma alloc_text(PAGE, FspLockUserBuffer) #pragma alloc_text(PAGE, FspMapLockedPagesInUserMode) @@ -444,6 +447,63 @@ NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, 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( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0) { diff --git a/src/sys/volume.c b/src/sys/volume.c index 9359e4b2..d1b02ea2 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -36,8 +36,6 @@ static NTSTATUS FspVolumeMountNoLock( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeMakeMountdev( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); -NTSTATUS FspVolumeMakeMountdevNoLock( - PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeGetName( PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); NTSTATUS FspVolumeGetNameList( @@ -62,7 +60,6 @@ NTSTATUS FspVolumeWork( // ! #pragma alloc_text(PAGE, FspVolumeMount) // ! #pragma alloc_text(PAGE, FspVolumeMountNoLock) #pragma alloc_text(PAGE, FspVolumeMakeMountdev) -#pragma alloc_text(PAGE, FspVolumeMakeMountdevNoLock) #pragma alloc_text(PAGE, FspVolumeGetName) #pragma alloc_text(PAGE, FspVolumeGetNameList) #pragma alloc_text(PAGE, FspVolumeGetNameListNoLock) @@ -327,10 +324,22 @@ VOID FspVolumeDelete( // !PAGED_CODE(); PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; FSP_FILE_NODE **FileNodes; ULONG FileNodeCount, Index; 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); FspDeviceGlobalLock(); @@ -554,18 +563,6 @@ NTSTATUS FspVolumeMakeMountdev( { 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_MN_USER_FS_REQUEST == IrpSp->MinorFunction); ASSERT(FSP_FSCTL_MOUNTDEV == IrpSp->Parameters.FileSystemControl.FsControlCode); @@ -575,13 +572,65 @@ NTSTATUS FspVolumeMakeMountdevNoLock( FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; - PVOID InputBuffer = Irp->AssociatedIrp.SystemBuffer; - BOOLEAN Persistent = 0 < InputBufferLength ? !!*(PBOOLEAN)InputBuffer : FALSE; + ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; + 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) 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( diff --git a/tst/winfsp-tests/volpath-test.c b/tst/winfsp-tests/volpath-test.c index 5aafb2d5..a1aac8a5 100644 --- a/tst/winfsp-tests/volpath-test.c +++ b/tst/winfsp-tests/volpath-test.c @@ -104,7 +104,7 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint) HANDLE Handle; BOOLEAN Success, VolumePathNameSuccess[8]; WCHAR FilePath[MAX_PATH]; - WCHAR VolumePathName[MAX_PATH]; + WCHAR VolumePathName[MAX_PATH], VolumeName[MAX_PATH]; Result = FspFileSystemSetMountPoint(MemfsFileSystem(memfs), MountPoint); 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)); VolumePathNameSuccess[0] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH); + VolumePathNameSuccess[4] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); VolumePathNameSuccess[1] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH); + VolumePathNameSuccess[5] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); VolumePathNameSuccess[2] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH); + VolumePathNameSuccess[6] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2", 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); ASSERT(Success); + FspFileSystemRemoveMountPoint(MemfsFileSystem(memfs)); + memfs_stop(memfs); - ASSERT(VolumePathNameSuccess[0] == VolumePathNameSuccess[1]); - ASSERT(VolumePathNameSuccess[1] == VolumePathNameSuccess[2]); + ASSERT(VolumePathNameSuccess[0]); + ASSERT(VolumePathNameSuccess[1]); + ASSERT(VolumePathNameSuccess[2]); + + if (MemfsNet != Flags) + { + ASSERT(VolumePathNameSuccess[4]); + ASSERT(VolumePathNameSuccess[5]); + ASSERT(VolumePathNameSuccess[6]); + } } static void volpath_mount_test(void)