From 23b49564889275931ee898e61a9c12f915fc3388 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 7 Dec 2015 11:54:02 -0800 Subject: [PATCH] sys: IRP_MJ_CREATE --- inc/winfsp/fsctl.h | 27 ++++++++++++++++----------- src/sys/create.c | 20 ++++++++++++++------ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 4edf323f..c9b3f543 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -96,7 +96,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.} */ - FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */ + 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.} */ @@ -104,8 +104,8 @@ typedef struct UINT16 Ea; /* reserved; not currently implemented */ UINT16 EaSize; /* reserved; not currently implemented */ UINT32 UserMode:1; /* request originated in user mode */ - UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ - UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */ + UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ + UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */ UINT32 CaseSensitive:1; /* filename comparisons should be case-sensitive */ } Create; struct @@ -135,16 +135,21 @@ typedef struct } IoStatus; union { - struct + union { - 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) */ - union + /* IoStatus.Status == STATUS_SUCCESS */ + struct { - FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for existing files */ - FSP_FSCTL_TRANSACT_BUF ReparseFileName; /* file name to use for STATUS_REPARSE */ - } Buf; + UINT64 UserContext; /* open file user context (unique file id) */ + UINT64 UserContext2; /* kernel file object user context (only low 32 bits valid) */ + UINT32 FileAttributes; /* FILE_ATTRIBUTE_{NORMAL,DIRECTORY,etc.} */ + FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor */ + } Opened; + /* IoStatus.Status == STATUS_REPARSE */ + struct + { + FSP_FSCTL_TRANSACT_BUF FileName; /* file name to use for STATUS_REPARSE */ + } Reparse; } Create; } Rsp; FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[]; diff --git a/src/sys/create.c b/src/sys/create.c index 8fe60269..6c691cee 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -116,6 +116,14 @@ static NTSTATUS FspFsvolCreate( goto exit; } + /* impossible create options set? */ + if (FlagOn(CreateOptions, FILE_NON_DIRECTORY_FILE) && + FlagOn(CreateOptions, FILE_DIRECTORY_FILE)) + { + Result = STATUS_INVALID_PARAMETER; + goto exit; + } + /* check security descriptor validity */ if (0 != SecurityDescriptor) { @@ -392,9 +400,9 @@ VOID FspFsvolCreateComplete( if (STATUS_REPARSE == Result) { ReparseFileName.Buffer = - (PVOID)(Response->Buffer + Response->Rsp.Create.Buf.ReparseFileName.Offset); + (PVOID)(Response->Buffer + Response->Rsp.Create.Reparse.FileName.Offset); ReparseFileName.Length = ReparseFileName.MaximumLength = - Response->Rsp.Create.Buf.ReparseFileName.Size; + Response->Rsp.Create.Reparse.FileName.Size; Result = STATUS_ACCESS_DENIED; if (IO_REPARSE == Response->IoStatus.Information) @@ -439,8 +447,8 @@ VOID FspFsvolCreateComplete( } SecurityDescriptor = - (PVOID)(Response->Buffer + Response->Rsp.Create.Buf.SecurityDescriptor.Offset); - SecurityDescriptorSize = Response->Rsp.Create.Buf.SecurityDescriptor.Size; + (PVOID)(Response->Buffer + Response->Rsp.Create.Opened.SecurityDescriptor.Offset); + SecurityDescriptorSize = Response->Rsp.Create.Opened.SecurityDescriptor.Size; /* are we doing access checks? */ if (FsvrtDeviceExtension->VolumeParams.NoSystemAccessCheck && @@ -485,8 +493,8 @@ VOID FspFsvolCreateComplete( } /* record the user-mode file system contexts */ - FsContext->UserContext = Response->Rsp.Create.UserContext; - FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.UserContext2; + FsContext->UserContext = Response->Rsp.Create.Opened.UserContext; + FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.Opened.UserContext2; /* * The following must be done under the file system volume device Resource,