mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-29 19:18:39 -05:00 
			
		
		
		
	sys: IRP_MJ_CREATE
This commit is contained in:
		| @@ -21,8 +21,9 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = | |||||||
|  |  | ||||||
| /* alignment macros */ | /* alignment macros */ | ||||||
| #define FSP_FSCTL_ALIGN_UP(x, s)        (((x) + ((s) - 1L)) & ~((s) - 1L)) | #define FSP_FSCTL_ALIGN_UP(x, s)        (((x) + ((s) - 1L)) & ~((s) - 1L)) | ||||||
| #define FSP_FSCTL_DEFAULT_ALIGNMENT     (8) | #define FSP_FSCTL_DEFAULT_ALIGNMENT     8 | ||||||
| #define FSP_FSCTL_DECLSPEC_ALIGN        __declspec(align(8)) | #define FSP_FSCTL_DEFAULT_ALIGN_UP(x)   FSP_FSCTL_ALIGN_UP(x, FSP_FSCTL_DEFAULT_ALIGNMENT) | ||||||
|  | #define FSP_FSCTL_DECLSPEC_ALIGN        __declspec(align(FSP_FSCTL_DEFAULT_ALIGNMENT)) | ||||||
|  |  | ||||||
| /* fsctl device codes */ | /* fsctl device codes */ | ||||||
| #define FSP_FSCTL_CREATE                \ | #define FSP_FSCTL_CREATE                \ | ||||||
| @@ -37,9 +38,7 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = | |||||||
| #define FSP_FSCTL_CREATE_BUFFER_SIZE    128 | #define FSP_FSCTL_CREATE_BUFFER_SIZE    128 | ||||||
| #define FSP_FSCTL_TRANSACT_BUFFER_SIZE  (16 * 1024) | #define FSP_FSCTL_TRANSACT_BUFFER_SIZE  (16 * 1024) | ||||||
|  |  | ||||||
| #define FSP_FSCTL_VOLUME_PARAMS_SIZE    \ | #define FSP_FSCTL_VOLUME_PARAMS_SIZE    FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_VOLUME_PARAMS)) | ||||||
|     FSP_FSCTL_ALIGN_UP(sizeof(FSP_FSCTL_VOLUME_PARAMS),\ |  | ||||||
|         FSP_FSCTL_DEFAULT_ALIGNMENT) |  | ||||||
| #define FSP_FSCTL_TRANSACT_REQ_SIZEMAX  (4 * 1024) | #define FSP_FSCTL_TRANSACT_REQ_SIZEMAX  (4 * 1024) | ||||||
| #define FSP_FSCTL_TRANSACT_RSP_SIZEMAX  (4 * 1024) | #define FSP_FSCTL_TRANSACT_RSP_SIZEMAX  (4 * 1024) | ||||||
|  |  | ||||||
| @@ -142,7 +141,7 @@ typedef struct | |||||||
| static inline FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactProduceRequest( | static inline FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactProduceRequest( | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request, SIZE_T RequestSize, PVOID RequestBufEnd) |     FSP_FSCTL_TRANSACT_REQ *Request, SIZE_T RequestSize, PVOID RequestBufEnd) | ||||||
| { | { | ||||||
|     PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_ALIGN_UP(RequestSize, FSP_FSCTL_DEFAULT_ALIGNMENT); |     PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(RequestSize); | ||||||
|     return NextRequest <= RequestBufEnd ? NextRequest : 0; |     return NextRequest <= RequestBufEnd ? NextRequest : 0; | ||||||
| } | } | ||||||
| static inline const FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactConsumeRequest( | static inline const FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactConsumeRequest( | ||||||
| @@ -151,13 +150,13 @@ static inline const FSP_FSCTL_TRANSACT_REQ *FspFsctlTransactConsumeRequest( | |||||||
|     if ((PUINT8)Request + sizeof(Request->Size) > (PUINT8)RequestBufEnd || |     if ((PUINT8)Request + sizeof(Request->Size) > (PUINT8)RequestBufEnd || | ||||||
|         sizeof(FSP_FSCTL_TRANSACT_REQ) > Request->Size) |         sizeof(FSP_FSCTL_TRANSACT_REQ) > Request->Size) | ||||||
|         return 0; |         return 0; | ||||||
|     PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_ALIGN_UP(Request->Size, FSP_FSCTL_DEFAULT_ALIGNMENT); |     PVOID NextRequest = (PUINT8)Request + FSP_FSCTL_DEFAULT_ALIGN_UP(Request->Size); | ||||||
|     return NextRequest <= RequestBufEnd ? NextRequest : 0; |     return NextRequest <= RequestBufEnd ? NextRequest : 0; | ||||||
| } | } | ||||||
| static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactProduceResponse( | static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactProduceResponse( | ||||||
|     FSP_FSCTL_TRANSACT_RSP *Response, SIZE_T ResponseSize, PVOID ResponseBufEnd) |     FSP_FSCTL_TRANSACT_RSP *Response, SIZE_T ResponseSize, PVOID ResponseBufEnd) | ||||||
| { | { | ||||||
|     PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_ALIGN_UP(ResponseSize, FSP_FSCTL_DEFAULT_ALIGNMENT); |     PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(ResponseSize); | ||||||
|     return NextResponse <= ResponseBufEnd ? NextResponse : 0; |     return NextResponse <= ResponseBufEnd ? NextResponse : 0; | ||||||
| } | } | ||||||
| static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( | static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( | ||||||
| @@ -166,7 +165,7 @@ static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( | |||||||
|     if ((PUINT8)Response + sizeof(Response->Size) > (PUINT8)ResponseBufEnd || |     if ((PUINT8)Response + sizeof(Response->Size) > (PUINT8)ResponseBufEnd || | ||||||
|         sizeof(FSP_FSCTL_TRANSACT_RSP) > Response->Size) |         sizeof(FSP_FSCTL_TRANSACT_RSP) > Response->Size) | ||||||
|         return 0; |         return 0; | ||||||
|     PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_ALIGN_UP(Response->Size, FSP_FSCTL_DEFAULT_ALIGNMENT); |     PVOID NextResponse = (PUINT8)Response + FSP_FSCTL_DEFAULT_ALIGN_UP(Response->Size); | ||||||
|     return NextResponse <= ResponseBufEnd ? NextResponse : 0; |     return NextResponse <= ResponseBufEnd ? NextResponse : 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,7 +60,8 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     KPROCESSOR_MODE RequestorMode = FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; |     KPROCESSOR_MODE RequestorMode = FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; | ||||||
|     PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; |     PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; | ||||||
|     ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; |     ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; | ||||||
|     //PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; |     PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; | ||||||
|  |     ULONG SecurityDescriptorSize = 0; | ||||||
|     USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; |     USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; | ||||||
|     ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; |     ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; | ||||||
|     ULONG CreateOptions = IrpSp->Parameters.Create.Options & 0xffffff; |     ULONG CreateOptions = IrpSp->Parameters.Create.Options & 0xffffff; | ||||||
| @@ -68,6 +69,8 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; |     LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; | ||||||
|     PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; |     PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; | ||||||
|     //ULONG EaLength = IrpSp->Parameters.Create.EaLength; |     //ULONG EaLength = IrpSp->Parameters.Create.EaLength; | ||||||
|  |     BOOLEAN IsAbsoluteSecurityDescriptor = FALSE; | ||||||
|  |     BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE; | ||||||
|     BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); |     BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); | ||||||
|     BOOLEAN HasTrailingBackslash = FALSE; |     BOOLEAN HasTrailingBackslash = FALSE; | ||||||
|     FSP_FILE_CONTEXT *FsContext = 0; |     FSP_FILE_CONTEXT *FsContext = 0; | ||||||
| @@ -89,6 +92,26 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     if (0 != EaBuffer && !FsvrtDeviceExtension->VolumeParams.EaSupported) |     if (0 != EaBuffer && !FsvrtDeviceExtension->VolumeParams.EaSupported) | ||||||
|         return STATUS_EAS_NOT_SUPPORTED; |         return STATUS_EAS_NOT_SUPPORTED; | ||||||
|  |  | ||||||
|  |     /* check security descriptor validity */ | ||||||
|  |     if (0 != SecurityDescriptor) | ||||||
|  |     { | ||||||
|  |         IsAbsoluteSecurityDescriptor = RtlValidSecurityDescriptor(SecurityDescriptor); | ||||||
|  |         if (IsAbsoluteSecurityDescriptor) | ||||||
|  |         { | ||||||
|  |             Result = RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize); | ||||||
|  |             if (STATUS_BUFFER_TOO_SMALL != Result) | ||||||
|  |                 return STATUS_INVALID_PARAMETER; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); | ||||||
|  |             IsSelfRelativeSecurityDescriptor = RtlValidRelativeSecurityDescriptor( | ||||||
|  |                 SecurityDescriptor, SecurityDescriptorSize, 0); | ||||||
|  |             if (!IsSelfRelativeSecurityDescriptor) | ||||||
|  |                 return STATUS_INVALID_PARAMETER; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /* according to fastfat, filenames that begin with two backslashes are ok */ |     /* according to fastfat, filenames that begin with two backslashes are ok */ | ||||||
|     if (sizeof(WCHAR) * 2 <= FileName.Length && |     if (sizeof(WCHAR) * 2 <= FileName.Length && | ||||||
|         L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) |         L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) | ||||||
| @@ -167,7 +190,7 @@ static NTSTATUS FspFsvolCreate( | |||||||
|      */ |      */ | ||||||
|  |  | ||||||
|     /* create the user-mode file system request */ |     /* create the user-mode file system request */ | ||||||
|     Result = FspIopCreateRequest(Irp, &FsContext->FileName, 0, &Request); |     Result = FspIopCreateRequest(Irp, &FsContext->FileName, SecurityDescriptorSize, &Request); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|     { |     { | ||||||
|         FspFileContextDelete(FsContext); |         FspFileContextDelete(FsContext); | ||||||
| @@ -179,8 +202,9 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     Request->Req.Create.CreateDisposition = CreateDisposition; |     Request->Req.Create.CreateDisposition = CreateDisposition; | ||||||
|     Request->Req.Create.CreateOptions = CreateOptions; |     Request->Req.Create.CreateOptions = CreateOptions; | ||||||
|     Request->Req.Create.FileAttributes = FileAttributes; |     Request->Req.Create.FileAttributes = FileAttributes; | ||||||
|     Request->Req.Create.SecurityDescriptor = 0; |     Request->Req.Create.SecurityDescriptor = 0 == SecurityDescriptor ? 0 : | ||||||
|     Request->Req.Create.SecurityDescriptorSize = 0; |         FSP_FSCTL_DEFAULT_ALIGN_UP(FsContext->FileName.Length + sizeof(WCHAR)); | ||||||
|  |     Request->Req.Create.SecurityDescriptorSize = (UINT16)SecurityDescriptorSize; | ||||||
|     Request->Req.Create.AllocationSize = AllocationSize.QuadPart; |     Request->Req.Create.AllocationSize = AllocationSize.QuadPart; | ||||||
|     Request->Req.Create.AccessToken = 0; |     Request->Req.Create.AccessToken = 0; | ||||||
|     Request->Req.Create.DesiredAccess = DesiredAccess; |     Request->Req.Create.DesiredAccess = DesiredAccess; | ||||||
|   | |||||||
| @@ -20,20 +20,22 @@ NTSTATUS FspIopCreateRequest( | |||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request; | ||||||
|  |  | ||||||
|     *PRequest = 0; |     *PRequest = 0; | ||||||
|  |  | ||||||
|     if (0 != FileName) |     if (0 != FileName) | ||||||
|         ExtraSize += FileName->Length + sizeof(WCHAR); |         ExtraSize += FSP_FSCTL_DEFAULT_ALIGN_UP(FileName->Length + sizeof(WCHAR)); | ||||||
|  |  | ||||||
|     if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) |     if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) | ||||||
|         return STATUS_INVALID_PARAMETER; |         return STATUS_INVALID_PARAMETER; | ||||||
|  |  | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request = ExAllocatePoolWithTag(PagedPool, |     Request = ExAllocatePoolWithTag(PagedPool, | ||||||
|         sizeof *Request + ExtraSize, FSP_TAG); |         sizeof *Request + ExtraSize, FSP_TAG); | ||||||
|     if (0 == Request) |     if (0 == Request) | ||||||
|         return STATUS_INSUFFICIENT_RESOURCES; |         return STATUS_INSUFFICIENT_RESOURCES; | ||||||
|  |  | ||||||
|     RtlZeroMemory(Request, sizeof *Request); |     RtlZeroMemory(Request, sizeof *Request + ExtraSize); | ||||||
|     Request->Size = (UINT16)(sizeof *Request + ExtraSize); |     Request->Size = (UINT16)(sizeof *Request + ExtraSize); | ||||||
|     Request->Hint = (UINT_PTR)Irp; |     Request->Hint = (UINT_PTR)Irp; | ||||||
|     if (0 != FileName) |     if (0 != FileName) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user