sys: FspFsvolFileSystemControlReparsePoint: improve computation of TargetOnFileSystem field when MUP is being used

This commit is contained in:
Bill Zissimopoulos 2016-09-12 15:11:45 -07:00
parent 30f2807e2b
commit be8c29114a
3 changed files with 59 additions and 17 deletions

View File

@ -45,6 +45,7 @@
#define FSP_ALLOC_INTERNAL_TAG 'IpsF' #define FSP_ALLOC_INTERNAL_TAG 'IpsF'
#define FSP_ALLOC_EXTERNAL_TAG 'XpsF' #define FSP_ALLOC_EXTERNAL_TAG 'XpsF'
#define FSP_IO_INCREMENT IO_NETWORK_INCREMENT #define FSP_IO_INCREMENT IO_NETWORK_INCREMENT
#define FSP_VOLUME_PREFIX_CASE_INS TRUE
/* debug */ /* debug */
#if DBG #if DBG
@ -427,8 +428,8 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize);
BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams); BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams);
VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PDEVICE_OBJECT *PDeviceObject); PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
@ -820,7 +821,8 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
static inline static inline
BOOLEAN FspFsvolDeviceVolumePrefixInString(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING String) BOOLEAN FspFsvolDeviceVolumePrefixInString(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING String)
{ {
return RtlPrefixUnicodeString(&FspFsvolDeviceExtension(DeviceObject)->VolumePrefix, String, TRUE); return RtlPrefixUnicodeString(&FspFsvolDeviceExtension(DeviceObject)->VolumePrefix, String,
FSP_VOLUME_PREFIX_CASE_INS);
} }
NTSTATUS FspDeviceCopyList( NTSTATUS FspDeviceCopyList(
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);

View File

@ -150,19 +150,62 @@ static NTSTATUS FspFsvolFileSystemControlReparsePoint(
{ {
UNICODE_STRING TargetObjectName; UNICODE_STRING TargetObjectName;
PDEVICE_OBJECT TargetDeviceObject; PDEVICE_OBJECT TargetDeviceObject;
PFILE_OBJECT TargetFileObject;
ULONG TargetFileNameIndex; ULONG TargetFileNameIndex;
ULONG32 TargetProviderId;
FSRTL_MUP_PROVIDER_INFO_LEVEL_1 ProviderInfo;
ULONG ProviderInfoSize;
TargetObjectName.Length = TargetObjectName.MaximumLength = ReparseTargetPathLength; TargetObjectName.Length = TargetObjectName.MaximumLength = ReparseTargetPathLength;
TargetObjectName.Buffer = ReparseTargetPath; TargetObjectName.Buffer = ReparseTargetPath;
Result = FspGetDeviceObjectByName(&TargetObjectName, FILE_READ_DATA, Result = FspGetDeviceObjectPointer(&TargetObjectName, FILE_READ_DATA,
&TargetFileNameIndex, &TargetDeviceObject); &TargetFileNameIndex, &TargetFileObject, &TargetDeviceObject);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto target_check_exit; goto target_check_exit;
TargetOnFileSystem = IoGetRelatedDeviceObject(FileObject) == TargetDeviceObject ? if (TargetFileNameIndex < ReparseTargetPathLength &&
(UINT16)TargetFileNameIndex : 0; IoGetRelatedDeviceObject(FileObject) == TargetDeviceObject)
ObDereferenceObject(TargetDeviceObject); {
if (0 == FsvolDeviceExtension->VolumePrefix.Length)
TargetOnFileSystem = (UINT16)TargetFileNameIndex;
else
{
ProviderInfoSize = sizeof ProviderInfo;
Result = FsRtlMupGetProviderInfoFromFileObject(TargetFileObject, 1,
&ProviderInfo, &ProviderInfoSize);
if (NT_SUCCESS(Result))
{
TargetProviderId = ProviderInfo.ProviderId;
ProviderInfoSize = sizeof ProviderInfo;
Result = FsRtlMupGetProviderInfoFromFileObject(FileObject, 1,
&ProviderInfo, &ProviderInfoSize);
if (!NT_SUCCESS(Result))
goto target_check_exit;
if (ProviderInfo.ProviderId == TargetProviderId)
TargetOnFileSystem = (UINT16)TargetFileNameIndex;
}
else
{
TargetObjectName.Length = TargetObjectName.MaximumLength =
FsvolDeviceExtension->VolumePrefix.Length;
TargetObjectName.Buffer = ReparseTargetPath +
TargetFileNameIndex / sizeof(WCHAR);
TargetFileNameIndex += FsvolDeviceExtension->VolumePrefix.Length;
if (TargetFileNameIndex < ReparseTargetPathLength &&
RtlEqualUnicodeString(&FsvolDeviceExtension->VolumePrefix,
&TargetObjectName,
FSP_VOLUME_PREFIX_CASE_INS))
TargetOnFileSystem = (UINT16)TargetFileNameIndex;
}
}
}
ObDereferenceObject(TargetFileObject);
target_check_exit: target_check_exit:
; ;

View File

@ -20,8 +20,8 @@
BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams); BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams);
VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PDEVICE_OBJECT *PDeviceObject); PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
static NTSTATUS FspSendSetInformationIrpCompletion( static NTSTATUS FspSendSetInformationIrpCompletion(
@ -90,7 +90,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#pragma alloc_text(PAGE, FspUnicodePathIsValid) #pragma alloc_text(PAGE, FspUnicodePathIsValid)
#pragma alloc_text(PAGE, FspUnicodePathSuffix) #pragma alloc_text(PAGE, FspUnicodePathSuffix)
#pragma alloc_text(PAGE, FspCreateGuid) #pragma alloc_text(PAGE, FspCreateGuid)
#pragma alloc_text(PAGE, FspGetDeviceObjectByName) #pragma alloc_text(PAGE, FspGetDeviceObjectPointer)
#pragma alloc_text(PAGE, FspSendSetInformationIrp) #pragma alloc_text(PAGE, FspSendSetInformationIrp)
#pragma alloc_text(PAGE, FspBufferUserBuffer) #pragma alloc_text(PAGE, FspBufferUserBuffer)
#pragma alloc_text(PAGE, FspLockUserBuffer) #pragma alloc_text(PAGE, FspLockUserBuffer)
@ -246,13 +246,12 @@ NTSTATUS FspCreateGuid(GUID *Guid)
return Result; return Result;
} }
NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PDEVICE_OBJECT *PDeviceObject) PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject)
{ {
PAGED_CODE(); PAGED_CODE();
UNICODE_STRING PartialName; UNICODE_STRING PartialName;
PFILE_OBJECT FileObject;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle; HANDLE Handle;
NTSTATUS Result; NTSTATUS Result;
@ -271,12 +270,10 @@ NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK Desire
L'\\' != PartialName.Buffer[PartialName.Length / sizeof(WCHAR)]) L'\\' != PartialName.Buffer[PartialName.Length / sizeof(WCHAR)])
PartialName.Length += sizeof(WCHAR); PartialName.Length += sizeof(WCHAR);
Result = IoGetDeviceObjectPointer(&PartialName, DesiredAccess, &FileObject, PDeviceObject); Result = IoGetDeviceObjectPointer(&PartialName, DesiredAccess, PFileObject, PDeviceObject);
if (NT_SUCCESS(Result)) if (NT_SUCCESS(Result))
{ {
*PFileNameIndex = PartialName.Length; *PFileNameIndex = PartialName.Length;
ObReferenceObject(*PDeviceObject);
ObDereferenceObject(FileObject);
break; break;
} }