From 1f0942a1009e397e75141ab328600a35bf7348b4 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 5 Dec 2015 13:10:45 -0800 Subject: [PATCH] sys: IRP_MJ_CREATE --- inc/winfsp/fsctl.h | 16 ++++++++++++---- src/sys/create.c | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 55c7805b..3a1d9f7f 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -78,6 +78,11 @@ typedef struct UINT32 NoSystemAccessCheck:1; /* if set the user-mode flie system performs access checks */ } FSP_FSCTL_VOLUME_PARAMS; typedef struct +{ + UINT16 Offset; + UINT16 Size; +} FSP_FSCTL_TRANSACT_BUF; +typedef struct { UINT16 Version; UINT16 Size; @@ -90,8 +95,7 @@ typedef struct UINT32 CreateDisposition; /* FILE_{SUPERSEDE,CREATE,OPEN,OPEN_IF,OVERWRITE,OVERWRITE_IF} */ UINT32 CreateOptions; /* FILE_{DIRECTORY_FILE,NON_DIRECTORY_FILE,etc.} */ UINT32 FileAttributes; /* FILE_ATTRIBUTE_{NORMAL,DIRECTORY,etc.} */ - UINT16 SecurityDescriptor; /* security descriptor for new files (offset within Buffer) */ - UINT16 SecurityDescriptorSize; /* security descriptor size */ + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */ UINT64 AllocationSize; /* initial allocation size */ UINT64 AccessToken; /* (HANDLE); request access token; sent if NoAccessCheck is 0 */ UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ @@ -114,6 +118,7 @@ typedef struct UINT64 UserContext2; } Close; } Req; + FSP_FSCTL_TRANSACT_BUF FileName; FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; } FSP_FSCTL_TRANSACT_REQ; typedef struct @@ -134,8 +139,11 @@ typedef struct UINT64 UserContext; /* user context attached to an open file (unique file id) */ UINT64 UserContext2; /* user context attached to a kernel file object */ /* (only low 32 bits valid in 32-bit mode) */ - UINT16 SecurityDescriptor; /* security descriptor for existing files (offset within Buffer) */ - UINT16 SecurityDescriptorSize; /* security descriptor size */ + union + { + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for existing files */ + FSP_FSCTL_TRANSACT_BUF ReparseFileName; /* file name to use for STATUS_REPARSE */ + } Buf; } Create; } Rsp; FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; diff --git a/src/sys/create.c b/src/sys/create.c index 80d28570..b1721406 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -241,12 +241,14 @@ static NTSTATUS FspFsvolCreate( /* populate the Create request */ Request->Kind = FspFsctlTransactCreateKind; + Request->FileName.Offset = 0; + Request->FileName.Size = FsContext->FileName.Length + sizeof(WCHAR); Request->Req.Create.CreateDisposition = CreateDisposition; Request->Req.Create.CreateOptions = CreateOptions; Request->Req.Create.FileAttributes = FileAttributes; - Request->Req.Create.SecurityDescriptor = 0 == SecurityDescriptor ? 0 : - FSP_FSCTL_DEFAULT_ALIGN_UP(FsContext->FileName.Length + sizeof(WCHAR)); - Request->Req.Create.SecurityDescriptorSize = (UINT16)SecurityDescriptorSize; + Request->Req.Create.SecurityDescriptor.Offset = 0 == SecurityDescriptorSize ? 0 : + FSP_FSCTL_DEFAULT_ALIGN_UP(Request->FileName.Size); + Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize; Request->Req.Create.AllocationSize = AllocationSize.QuadPart; Request->Req.Create.AccessToken = 0; Request->Req.Create.DesiredAccess = DesiredAccess; @@ -262,7 +264,7 @@ static NTSTATUS FspFsvolCreate( if (IsAbsoluteSecurityDescriptor) { Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, - Request->Buffer + Request->Req.Create.SecurityDescriptor, &SecurityDescriptorSize); + Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, &SecurityDescriptorSize); if (!NT_SUCCESS(Result)) { FspFileContextDelete(FsContext); @@ -272,7 +274,7 @@ static NTSTATUS FspFsvolCreate( } } else if (IsSelfRelativeSecurityDescriptor) - RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor, + RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, SecurityDescriptor, SecurityDescriptorSize); /* @@ -351,8 +353,8 @@ VOID FspFsvolCreateComplete( PFILE_OBJECT FileObject = IrpSp->FileObject; PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; PSECURITY_DESCRIPTOR SecurityDescriptor = - (PVOID)(Response->Buffer + Response->Rsp.Create.SecurityDescriptor); - ULONG SecurityDescriptorSize = Response->Rsp.Create.SecurityDescriptorSize; + (PVOID)(Response->Buffer + Response->Rsp.Create.Buf.SecurityDescriptor.Offset); + ULONG SecurityDescriptorSize = Response->Rsp.Create.Buf.SecurityDescriptor.Size; ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; ULONG Flags = IrpSp->Flags; @@ -367,6 +369,27 @@ VOID FspFsvolCreateComplete( { FspFileContextDelete(FileObject->FsContext); FileObject->FsContext = 0; + + Irp->IoStatus.Information = Response->IoStatus.Information; + Result = Response->IoStatus.Status; + FSP_RETURN(); + } + + /* special case STATUS_REPARSE */ + if (STATUS_REPARSE == Result) + { + if (IO_REPARSE != Response->IoStatus.Information && + IO_REMOUNT != Response->IoStatus.Information) + { + FspFileContextDelete(FileObject->FsContext); + FileObject->FsContext = 0; + FSP_RETURN(Result = STATUS_ACCESS_DENIED); + } + + if (IO_REPARSE != Response->IoStatus.Information) + { + } + Irp->IoStatus.Information = Response->IoStatus.Information; Result = Response->IoStatus.Status; FSP_RETURN();