From ca8a02bd9d061794d7669fb7f9cd39a84b786bae Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 3 Dec 2015 16:59:31 -0800 Subject: [PATCH] sys: IRP_MJ_CREATE --- inc/winfsp/fsctl.h | 75 +++++++++++++++++++++++++++++++++++++++------- src/sys/create.c | 34 +++++++++++++++------ src/sys/fileobj.c | 2 +- src/sys/iop.c | 2 +- 4 files changed, 91 insertions(+), 22 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 17506e6b..e14bac8a 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -21,8 +21,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = /* alignment macros */ #define FSP_FSCTL_ALIGN_UP(x, s) (((x) + ((s) - 1L)) & ~((s) - 1L)) -#define FSP_FSCTL_DEFAULT_ALIGNMENT (16) -#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(16)) +#define FSP_FSCTL_DEFAULT_ALIGNMENT (8) +#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(8)) /* fsctl device codes */ #define FSP_FSCTL_CREATE \ @@ -47,44 +47,97 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = /* marshalling */ #pragma warning(push) #pragma warning(disable:4200) /* zero-sized array in struct/union */ +enum +{ + FspFsctlTransactUnknownKind = 0, + FspFsctlTransactCreateKind = 'C', + FspFsctlTransactCloseKind = 'c', + FspFsctlTransactReadKind = 'R', + FspFsctlTransactWriteKind = 'W', + FspFsctlTransactQueryInformationKind = 'I', + FspFsctlTransactSetInformationKind = 'i', + FspFsctlTransactQueryEaKind = 'E', + FspFsctlTransactSetEaKind = 'e', + FspFsctlTransactFlushBuffersKind = 'F', + FspFsctlTransactQueryVolumeInformationKind = 'V', + FspFsctlTransactSetVolumeInformationKind = 'v', + FspFsctlTransactDirectoryControlKind = 'D', + FspFsctlTransactFileSystemControlKind = 'K', + FspFsctlTransactDeviceControlKind = 'k', + FspFsctlTransactShutdownKind = 'd', + FspFsctlTransactLockControlKind = 'L', + FspFsctlTransactCleanupKind = 'l', + FspFsctlTransactQuerySecurityKind = 'S', + FspFsctlTransactSetSecurityKind = 's', +}; typedef struct { UINT16 Version; UINT16 SectorSize; UINT32 SerialNumber; - BOOLEAN EaSupported; /* supports extended attributes (unimplemented; set to 0) */ - BOOLEAN FileNameRequired; /* FileName required for all operations (not just Create) */ + UINT32 EaSupported:1; /* supports extended attributes (unimplemented; set to 0) */ + UINT32 FileNameRequired:1; /* FileName required for all operations (not just Create) */ + UINT32 NoAccessCheck:1; /* if set the user-mode flie system performs access checks */ } FSP_FSCTL_VOLUME_PARAMS; typedef struct { UINT16 Version; UINT16 Size; + UINT32 Kind; UINT64 Hint; - UINT8 Kind; union { struct { - UINT8 Placeholder; + 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.} */ + UINT64 AllocationSize; /* initial allocation size */ + UINT64 SecurityDescriptor; /* (PSECURITY_DESCRIPTOR); security to apply to new files */ + UINT64 EaBuffer; /* (PVOID); reserved; not currently implemented */ + UINT32 EaLength; /* (PVOID); reserved; not currently implemented */ + UINT64 AccessToken; /* (HANDLE); request access token; sent if NoAccessCheck is 0 */ + UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ + UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ + UINT32 UserMode:1; /* request originated in user mode */ + UINT32 HasTraversePrivilege:1; + /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ + UINT32 OpenTargetDirectory:1; + /* open target directory and report FILE_{EXISTS,DOES_NOT_EXIST} */ + UINT32 CaseSensitive:1; /* filename comparisons should be case-sensitive */ } Create; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } Cleanup; + struct + { + UINT64 UserContext; + UINT64 UserContext2; + } Close; } Req; - WCHAR FileName[]; + FSP_FSCTL_DECLSPEC_ALIGN WCHAR FileName[]; } FSP_FSCTL_TRANSACT_REQ; typedef struct { UINT16 Version; UINT16 Size; + UINT32 Kind; UINT64 Hint; struct { - UINT32 Status; UINT64 Information; + UINT32 Status; } IoStatus; - UINT8 Kind; union { - UINT8 Placeholder; // !!!: REMOVE - } Req; + struct + { + UINT64 UserContext; /* user context attached to an open file (unique file id) */ + UINT64 UserContext2; /* user context attached to a kernel file object */ + } Create; + } Rsp; } FSP_FSCTL_TRANSACT_RSP; #pragma warning(pop) static inline FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactProduceRequest( diff --git a/src/sys/create.c b/src/sys/create.c index 5c67c092..aa884490 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -57,17 +57,17 @@ static NTSTATUS FspFsvolCreate( PFILE_OBJECT RelatedFileObject = FileObject->RelatedFileObject; UNICODE_STRING FileName = FileObject->FileName; ULONG Flags = IrpSp->Flags; - //KPROCESSOR_MODE RequestorMode = FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; - //PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; - //ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; - //USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; - //ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; + KPROCESSOR_MODE RequestorMode = FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; + PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; + ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; + USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; + ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; ULONG CreateOptions = IrpSp->Parameters.Create.Options & 0xffffff; - //USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes; - //LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; + USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes; + LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; //ULONG EaLength = IrpSp->Parameters.Create.EaLength; - //BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); + BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); BOOLEAN HasTrailingBackslash = FALSE; FSP_FILE_CONTEXT *FsContext = 0; FSP_FSCTL_TRANSACT_REQ *Request; @@ -173,7 +173,23 @@ static NTSTATUS FspFsvolCreate( return Result; } - /* !!!: populate the request */ + /* populate the Create request */ + Request->Kind = FspFsctlTransactCreateKind; + Request->Req.Create.CreateDisposition = CreateDisposition; + Request->Req.Create.CreateOptions = CreateOptions; + Request->Req.Create.FileAttributes = FileAttributes; + Request->Req.Create.AllocationSize = AllocationSize.QuadPart; + Request->Req.Create.SecurityDescriptor = 0; + Request->Req.Create.EaBuffer = 0; + Request->Req.Create.EaLength = 0; + Request->Req.Create.AccessToken = 0; + Request->Req.Create.DesiredAccess = DesiredAccess; + Request->Req.Create.ShareAccess = ShareAccess; + Request->Req.Create.DesiredAccess = DesiredAccess; + Request->Req.Create.UserMode = UserMode == RequestorMode; + Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; + Request->Req.Create.CaseSensitive = BooleanFlagOn(Flags, SL_CASE_SENSITIVE); + Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY); /* * Post the IRP to our Ioq; we do this here instead of at FSP_LEAVE_MJ time, diff --git a/src/sys/fileobj.c b/src/sys/fileobj.c index 3dae540f..cc13d875 100644 --- a/src/sys/fileobj.c +++ b/src/sys/fileobj.c @@ -38,7 +38,7 @@ NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext) ExInitializeResourceLite(&NonPaged->PagingIoResource); ExInitializeFastMutex(&NonPaged->HeaderFastMutex); - RtlZeroMemory(FsContext, sizeof *FsContext); + RtlZeroMemory(FsContext, sizeof *FsContext + ExtraSize); FsContext->Header.NodeTypeCode = 'F'; FsContext->Header.NodeByteSize = sizeof *FsContext; FsContext->Header.IsFastIoPossible = FastIoIsQuestionable; diff --git a/src/sys/iop.c b/src/sys/iop.c index fae3ac9f..4e498795 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -30,7 +30,7 @@ NTSTATUS FspIopCreateRequest( if (0 == Request) return STATUS_INSUFFICIENT_RESOURCES; - RtlZeroMemory(Request, sizeof *Request); + RtlZeroMemory(Request, sizeof *Request + ExtraSize); Request->Size = (UINT16)(sizeof *Request + ExtraSize); Request->Hint = (UINT_PTR)Irp; if (0 != FileName)