sys: FspMainFileOpen, FspMainFileClose, FspMainFileOpenCheck

This commit is contained in:
Bill Zissimopoulos 2016-10-04 22:19:41 -07:00
parent 1d435269bd
commit 860e9db8a7
4 changed files with 245 additions and 144 deletions

View File

@ -24,7 +24,8 @@ static NTSTATUS FspFsvrtCreate(
static NTSTATUS FspFsvolCreate(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN MainFileOpen);
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
@ -109,23 +110,30 @@ static NTSTATUS FspFsvolCreate(
PAGED_CODE();
NTSTATUS Result = STATUS_SUCCESS;
BOOLEAN MainFileOpen = FspMainFileOpenCheck(Irp);
if (!MainFileOpen)
{
FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject);
try
{
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp);
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, FALSE);
}
finally
{
if (FSP_STATUS_IOQ_POST != Result)
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
}
}
else
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, TRUE);
return Result;
}
static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN MainFileOpen)
{
PAGED_CODE();
@ -220,7 +228,7 @@ static NTSTATUS FspFsvolCreateNoLock(
FsvolDeviceExtension->VolumeParams.NamedStreams ? &StreamPart : 0))
return STATUS_OBJECT_NAME_INVALID;
/* if we have a stream part */
/* if we have a stream part (even non-empty) */
if (0 != StreamPart.Buffer)
{
ASSERT(
@ -398,6 +406,9 @@ static NTSTATUS FspFsvolCreateNoLock(
/* remember the main file node */
FileNode->MainFileNode = FileDesc->MainFileObject->FsContext;
ASSERT(RtlEqualUnicodeString(&MainFileName, &FileNode->MainFileNode->FileName,
!CaseSensitive));
Result = STATUS_SUCCESS;
main_stream_exit:
@ -427,8 +438,11 @@ static NTSTATUS FspFsvolCreateNoLock(
FileDesc->FileNode = FileNode;
FileDesc->CaseSensitive = CaseSensitive;
FileDesc->HasTraversePrivilege = HasTraversePrivilege;
if (!MainFileOpen)
{
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
}
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
/* populate the Create request */
@ -798,6 +812,8 @@ NTSTATUS FspFsvolCreateComplete(
if (FileNode->IsDirectory)
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
PVOID RequestDeviceObjectValue = FspIopRequestContext(Request, RequestDeviceObject);
/* disassociate the FileDesc momentarily from the Request */
FspIopRequestContext(Request, RequestDeviceObject) = 0;
FspIopRequestContext(Request, RequestFileDesc) = 0;
@ -806,7 +822,7 @@ NTSTATUS FspFsvolCreateComplete(
Request->Kind = FspFsctlTransactOverwriteKind;
RtlZeroMemory(&Request->Req.Create, sizeof Request->Req.Create);
FspIopResetRequest(Request, FspFsvolCreateOverwriteRequestFini);
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
FspIopRequestContext(Request, RequestDeviceObject) = RequestDeviceObjectValue;
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
FspIopRequestContext(Request, RequestFileObject) = FileObject;
FspIopRequestContext(Request, RequestState) = (PVOID)RequestPending;
@ -889,7 +905,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
if (FspFsctlTransactCreateKind == Request->Kind)
{
PDEVICE_OBJECT FsvolDeviceObject = FspIopRequestContext(Request, RequestDeviceObject);
PVOID RequestDeviceObjectValue = FspIopRequestContext(Request, RequestDeviceObject);
/* disassociate the FileDesc momentarily from the Request */
Request = FspIrpRequest(Irp);
@ -899,7 +915,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
/* reset the Request and reassociate the FileDesc and FileObject with it */
Request->Kind = FspFsctlTransactReservedKind;
FspIopResetRequest(Request, FspFsvolCreateTryOpenRequestFini);
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
FspIopRequestContext(Request, RequestDeviceObject) = RequestDeviceObjectValue;
FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
FspIopRequestContext(Request, RequestFileObject) = FileObject;
FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage;

View File

@ -431,17 +431,6 @@ VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE
NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspMainFileOpen(
PDEVICE_OBJECT DeviceObject,
PUNICODE_STRING MainFileName, BOOLEAN CaseSensitive,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG FileAttributes,
ULONG Disposition,
PHANDLE PMainFileHandle,
PFILE_OBJECT *PMainFileObject);
NTSTATUS FspMainFileClose(
HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
@ -1034,6 +1023,39 @@ NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
PUNICODE_STRING FileName, BOOLEAN Reset);
NTSTATUS FspMainFileOpen(
PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING MainFileName, BOOLEAN CaseSensitive,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG FileAttributes,
ULONG Disposition,
PHANDLE PMainFileHandle,
PFILE_OBJECT *PMainFileObject);
NTSTATUS FspMainFileClose(
HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject);
static __forceinline
BOOLEAN FspMainFileOpenCheck(PIRP Irp)
{
extern const GUID FspMainFileOpenEcpGuid;
NTSTATUS Result;
PECP_LIST ExtraCreateParameters = 0;
PVOID ExtraCreateParameter = 0;
Result = FsRtlGetEcpListFromIrp(Irp, &ExtraCreateParameters);
if (!NT_SUCCESS(Result) || 0 == ExtraCreateParameters)
return FALSE;
Result = FsRtlFindExtraCreateParameter(ExtraCreateParameters,
&FspMainFileOpenEcpGuid, &ExtraCreateParameter, 0);
if (!NT_SUCCESS(Result) || 0 == ExtraCreateParameter)
return FALSE;
if (FsRtlIsEcpFromUserMode(ExtraCreateParameter))
return FALSE;
return TRUE;
}
#define FspFileNodeAcquireShared(N,F) FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F)
#define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F, FALSE)
#define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F)
@ -1069,6 +1091,7 @@ extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
extern ERESOURCE FspDeviceGlobalResource;
extern WCHAR FspFileDescDirectoryPatternMatchAll[];
extern const GUID FspMainFileOpenEcpGuid;
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
extern ULONG FspMvMdlMappingNoWrite;

View File

@ -70,6 +70,17 @@ NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
PUNICODE_STRING FileName, BOOLEAN Reset);
NTSTATUS FspMainFileOpen(
PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING MainFileName, BOOLEAN CaseSensitive,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG FileAttributes,
ULONG Disposition,
PHANDLE PMainFileHandle,
PFILE_OBJECT *PMainFileObject);
NTSTATUS FspMainFileClose(
HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFileNodeCopyList)
@ -112,6 +123,8 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
#pragma alloc_text(PAGE, FspFileDescCreate)
#pragma alloc_text(PAGE, FspFileDescDelete)
#pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern)
#pragma alloc_text(PAGE, FspMainFileOpen)
#pragma alloc_text(PAGE, FspMainFileClose)
#endif
#define FSP_FILE_NODE_GET_FLAGS() \
@ -1238,4 +1251,170 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
return STATUS_SUCCESS;
}
NTSTATUS FspMainFileOpen(
PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING MainFileName, BOOLEAN CaseSensitive,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG FileAttributes,
ULONG Disposition,
PHANDLE PMainFileHandle,
PFILE_OBJECT *PMainFileObject)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
UNICODE_STRING FullFileName = { 0 };
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
IO_DRIVER_CREATE_CONTEXT DriverCreateContext = { 0 };
PVOID ExtraCreateParameter;
HANDLE MainFileHandle;
PFILE_OBJECT MainFileObject;
/* assert that the supplied name is actually a main file name */
ASSERT(FspUnicodePathIsValid(MainFileName, 0));
*PMainFileHandle = 0;
*PMainFileObject = 0;
switch (Disposition)
{
case FILE_CREATE:
case FILE_OPEN_IF:
case FILE_OVERWRITE_IF:
Disposition = FILE_OPEN_IF;
break;
case FILE_OPEN:
case FILE_OVERWRITE:
case FILE_SUPERSEDE:
Disposition = FILE_OPEN;
break;
default:
IoStatus.Status = STATUS_INVALID_PARAMETER;
goto exit;
}
FullFileName.Length = 0;
FullFileName.MaximumLength =
FsvolDeviceExtension->VolumeName.Length +
FsvolDeviceExtension->VolumePrefix.Length +
MainFileName->Length;
FullFileName.Buffer = FspAlloc(FullFileName.MaximumLength);
if (0 == FullFileName.Buffer)
{
IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
RtlAppendUnicodeStringToString(&FullFileName, &FsvolDeviceExtension->VolumeName);
RtlAppendUnicodeStringToString(&FullFileName, &FsvolDeviceExtension->VolumePrefix);
RtlAppendUnicodeStringToString(&FullFileName, MainFileName);
InitializeObjectAttributes(
&ObjectAttributes,
&FullFileName,
OBJ_KERNEL_HANDLE | OBJ_FORCE_ACCESS_CHECK | (CaseSensitive ? 0 : OBJ_CASE_INSENSITIVE),
0/*RootDirectory*/,
SecurityDescriptor);
/* do not use SiloContext field as it is only available on Win10 v1607 and higher */
DriverCreateContext.Size =
FIELD_OFFSET(IO_DRIVER_CREATE_CONTEXT, TxnParameters) +
sizeof(((PIO_DRIVER_CREATE_CONTEXT)0)->TxnParameters);
DriverCreateContext.DeviceObjectHint = FsvolDeviceObject;
IoStatus.Status = FsRtlAllocateExtraCreateParameterList(0,
&DriverCreateContext.ExtraCreateParameter);
if (!NT_SUCCESS(IoStatus.Status))
goto exit;
IoStatus.Status = FsRtlAllocateExtraCreateParameter(&FspMainFileOpenEcpGuid,
sizeof(PVOID),
0/*Flags*/,
0/*CleanupCallback*/,
FSP_ALLOC_INTERNAL_TAG,
&ExtraCreateParameter);
if (!NT_SUCCESS(IoStatus.Status))
goto exit;
IoStatus.Status = FsRtlInsertExtraCreateParameter(DriverCreateContext.ExtraCreateParameter,
ExtraCreateParameter);
if (!NT_SUCCESS(IoStatus.Status))
{
FsRtlFreeExtraCreateParameter(ExtraCreateParameter);
goto exit;
}
IoStatus.Status = IoCreateFileEx(
&MainFileHandle,
FILE_READ_ATTRIBUTES,
&ObjectAttributes,
&IoStatus,
0/*AllocationSize*/,
FileAttributes,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
Disposition,
FILE_OPEN_REPARSE_POINT,
0/*EaBuffer*/,
0/*EaLength*/,
CreateFileTypeNone,
0/*InternalParameters*/,
IO_FORCE_ACCESS_CHECK,
&DriverCreateContext);
if (!NT_SUCCESS(IoStatus.Status))
goto exit;
IoStatus.Status = ObReferenceObjectByHandle(
MainFileHandle,
0/*DesiredAccess*/,
*IoFileObjectType,
KernelMode,
&MainFileObject,
0/*HandleInformation*/);
if (!NT_SUCCESS(IoStatus.Status))
{
ObCloseHandle(MainFileHandle, KernelMode);
goto exit;
}
*PMainFileHandle = MainFileHandle;
*PMainFileObject = MainFileObject;
IoStatus.Status = STATUS_SUCCESS;
exit:
if (0 != DriverCreateContext.ExtraCreateParameter)
FsRtlFreeExtraCreateParameterList(DriverCreateContext.ExtraCreateParameter);
if (0 != FullFileName.Buffer)
FspFree(FullFileName.Buffer);
return IoStatus.Status;
}
NTSTATUS FspMainFileClose(
HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject)
{
PAGED_CODE();
NTSTATUS Result = STATUS_SUCCESS;
if (0 != MainFileObject)
ObDereferenceObject(MainFileObject);
if (0 != MainFileHandle)
{
Result = ObCloseHandle(MainFileHandle, KernelMode);
if (!NT_SUCCESS(Result))
DEBUGLOG("ObCloseHandle() = %s", NtStatusSym(Result));
}
return Result;
}
WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*";
// {904862B4-EB3F-461E-ACB2-4DF2B3FC898B}
const GUID FspMainFileOpenEcpGuid =
{ 0x904862b4, 0xeb3f, 0x461e, { 0xac, 0xb2, 0x4d, 0xf2, 0xb3, 0xfc, 0x89, 0x8b } };

View File

@ -23,17 +23,6 @@ VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE
NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspMainFileOpen(
PDEVICE_OBJECT DeviceObject,
PUNICODE_STRING MainFileName, BOOLEAN CaseSensitive,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG FileAttributes,
ULONG Disposition,
PHANDLE PMainFileHandle,
PFILE_OBJECT *PMainFileObject);
NTSTATUS FspMainFileClose(
HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
static NTSTATUS FspSendSetInformationIrpCompletion(
@ -104,8 +93,6 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#pragma alloc_text(PAGE, FspUnicodePathSuffix)
#pragma alloc_text(PAGE, FspCreateGuid)
#pragma alloc_text(PAGE, FspGetDeviceObjectPointer)
#pragma alloc_text(PAGE, FspMainFileOpen)
#pragma alloc_text(PAGE, FspMainFileClose)
#pragma alloc_text(PAGE, FspSendSetInformationIrp)
#pragma alloc_text(PAGE, FspBufferUserBuffer)
#pragma alloc_text(PAGE, FspLockUserBuffer)
@ -386,110 +373,6 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
return Result;
}
NTSTATUS FspMainFileOpen(
PDEVICE_OBJECT DeviceObject,
PUNICODE_STRING MainFileName, BOOLEAN CaseSensitive,
PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG FileAttributes,
ULONG Disposition,
PHANDLE PMainFileHandle,
PFILE_OBJECT *PMainFileObject)
{
PAGED_CODE();
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
HANDLE MainFileHandle;
PFILE_OBJECT MainFileObject;
/* assert that the supplied name is actually a main file name */
ASSERT(FspUnicodePathIsValid(MainFileName, 0));
*PMainFileHandle = 0;
*PMainFileObject = 0;
switch (Disposition)
{
case FILE_CREATE:
case FILE_OPEN_IF:
case FILE_OVERWRITE_IF:
Disposition = FILE_OPEN_IF;
break;
case FILE_OPEN:
case FILE_OVERWRITE:
case FILE_SUPERSEDE:
Disposition = FILE_OPEN;
break;
default:
return STATUS_INVALID_PARAMETER;
}
InitializeObjectAttributes(
&ObjectAttributes,
MainFileName,
OBJ_KERNEL_HANDLE | OBJ_FORCE_ACCESS_CHECK | (CaseSensitive ? 0 : OBJ_CASE_INSENSITIVE),
0/*RootDirectory*/,
SecurityDescriptor);
IoStatus.Status = IoCreateFileSpecifyDeviceObjectHint(
&MainFileHandle,
FILE_READ_ATTRIBUTES,
&ObjectAttributes,
&IoStatus,
0/*AllocationSize*/,
FileAttributes,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
Disposition,
FILE_OPEN_REPARSE_POINT,
0/*EaBuffer*/,
0/*EaLength*/,
CreateFileTypeNone,
0/*InternalParameters*/,
IO_FORCE_ACCESS_CHECK,
DeviceObject);
if (!NT_SUCCESS(IoStatus.Status))
return IoStatus.Status;
IoStatus.Status = ObReferenceObjectByHandle(
MainFileHandle,
0/*DesiredAccess*/,
*IoFileObjectType,
KernelMode,
&MainFileObject,
0/*HandleInformation*/);
if (!NT_SUCCESS(IoStatus.Status))
{
ObCloseHandle(MainFileHandle, KernelMode);
return IoStatus.Status;
}
*PMainFileHandle = MainFileHandle;
*PMainFileObject = MainFileObject;
return STATUS_SUCCESS;
}
NTSTATUS FspMainFileClose(
HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject)
{
PAGED_CODE();
NTSTATUS Result = STATUS_SUCCESS;
if (0 != MainFileObject)
ObDereferenceObject(MainFileObject);
if (0 != MainFileHandle)
{
Result = ObCloseHandle(MainFileHandle, KernelMode);
if (!NT_SUCCESS(Result))
DEBUGLOG("ObCloseHandle() = %s", NtStatusSym(Result));
}
return Result;
}
typedef struct
{
IO_STATUS_BLOCK IoStatus;