mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	wslinux support: ATOMIC_CREATE_ECP_CONTEXT
This commit is contained in:
		| @@ -29,7 +29,7 @@ static NTSTATUS FspFsvolCreate( | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); | ||||
| static NTSTATUS FspFsvolCreateNoLock( | ||||
|     PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, | ||||
|     BOOLEAN MainFileOpen); | ||||
|     BOOLEAN MainFileOpen, PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp); | ||||
| FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; | ||||
| FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; | ||||
| static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, | ||||
| @@ -144,6 +144,7 @@ static NTSTATUS FspFsvolCreate( | ||||
|     PECP_LIST ExtraCreateParameters; | ||||
|     PVOID ExtraCreateParameter; | ||||
|     BOOLEAN MainFileOpen = FALSE; | ||||
|     PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp = 0; | ||||
|  | ||||
|     /* | ||||
|      * Check if the IRP has ECP's. | ||||
| @@ -219,6 +220,21 @@ static NTSTATUS FspFsvolCreate( | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|         if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures) | ||||
|         { | ||||
|             // {4720bd83-52ac-4104-a130-d1ec6a8cc8e5} | ||||
|             static const GUID FspAtomicCreateEcpGuid = | ||||
|                 { 0x4720bd83, 0x52ac, 0x4104, { 0xa1, 0x30, 0xd1, 0xec, 0x6a, 0x8c, 0xc8, 0xe5 } }; | ||||
|  | ||||
|             ExtraCreateParameter = 0; | ||||
|             AtomicCreateEcp = | ||||
|                 NT_SUCCESS(FsRtlFindExtraCreateParameter(ExtraCreateParameters, | ||||
|                     &FspAtomicCreateEcpGuid, &ExtraCreateParameter, 0)) && | ||||
|                 0 != ExtraCreateParameter && | ||||
|                 !FsRtlIsEcpFromUserMode(ExtraCreateParameter) ? | ||||
|                     ExtraCreateParameter : 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (!MainFileOpen) | ||||
| @@ -226,7 +242,8 @@ static NTSTATUS FspFsvolCreate( | ||||
|         FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject); | ||||
|         try | ||||
|         { | ||||
|             Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, FALSE); | ||||
|             Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, | ||||
|                 MainFileOpen, AtomicCreateEcp); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
| @@ -235,14 +252,15 @@ static NTSTATUS FspFsvolCreate( | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|         Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, TRUE); | ||||
|         Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, | ||||
|             MainFileOpen, AtomicCreateEcp); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspFsvolCreateNoLock( | ||||
|     PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, | ||||
|     BOOLEAN MainFileOpen) | ||||
|     BOOLEAN MainFileOpen, PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
| @@ -279,6 +297,8 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|     USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; | ||||
|     PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; | ||||
|     ULONG EaLength = IrpSp->Parameters.Create.EaLength; | ||||
|     PVOID ExtraBuffer = 0; | ||||
|     ULONG ExtraLength = 0; | ||||
|     ULONG Flags = IrpSp->Flags; | ||||
|     KPROCESSOR_MODE RequestorMode = | ||||
|         FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; | ||||
| @@ -292,6 +312,7 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|     BOOLEAN HasRestorePrivilege = | ||||
|         BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE); | ||||
|     BOOLEAN HasTrailingBackslash = FALSE; | ||||
|     BOOLEAN EaIsReparsePoint = FALSE; | ||||
|     FSP_FILE_NODE *FileNode, *RelatedFileNode; | ||||
|     FSP_FILE_DESC *FileDesc; | ||||
|     UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 }; | ||||
| @@ -302,6 +323,36 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|     if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID)) | ||||
|         return STATUS_NOT_IMPLEMENTED; | ||||
|  | ||||
|     /* is there an AtomicCreateEcp attached? */ | ||||
|     if (0 != AtomicCreateEcp) | ||||
|     { | ||||
|         if ((FILE_CREATE != CreateDisposition && FILE_OPEN_IF != CreateDisposition) || | ||||
|             0 != EaBuffer || | ||||
|             RTL_SIZEOF_THROUGH_FIELD(FSP_ATOMIC_CREATE_ECP_CONTEXT, ReparseBuffer) > | ||||
|                 AtomicCreateEcp->Size || | ||||
|             /* !!!: revisit: FlagOn*/ | ||||
|             !FlagOn(AtomicCreateEcp->InFlags, | ||||
|                 ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT | | ||||
|                 ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED)) | ||||
|             return STATUS_INVALID_PARAMETER; /* docs do not say what to return on failure! */ | ||||
|  | ||||
|         if (FlagOn(AtomicCreateEcp->InFlags, | ||||
|             ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED)) | ||||
|         { | ||||
|             Result = FsRtlValidateReparsePointBuffer(AtomicCreateEcp->ReparseBufferLength, | ||||
|                 AtomicCreateEcp->ReparseBuffer); | ||||
|             if (!NT_SUCCESS(Result)) | ||||
|                 return Result; | ||||
|  | ||||
|             /* mark that we satisfied the reparse point request, although we may fail it later! */ | ||||
|             AtomicCreateEcp->OutFlags = ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET; | ||||
|  | ||||
|             ExtraBuffer = AtomicCreateEcp->ReparseBuffer; | ||||
|             ExtraLength = AtomicCreateEcp->ReparseBufferLength; | ||||
|             EaIsReparsePoint = TRUE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* was an EA buffer specified? */ | ||||
|     if (0 != EaBuffer) | ||||
|     { | ||||
| @@ -318,6 +369,9 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|             EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information); | ||||
|         if (!NT_SUCCESS(Result)) | ||||
|             return Result; | ||||
|  | ||||
|         ExtraBuffer = EaBuffer; | ||||
|         ExtraLength = EaLength; | ||||
|     } | ||||
|  | ||||
|     /* cannot open a paging file */ | ||||
| @@ -555,9 +609,9 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|         SecurityDescriptorSize = 0; | ||||
|         FileAttributes = 0; | ||||
|  | ||||
|         /* cannot set EA on named stream */ | ||||
|         EaBuffer = 0; | ||||
|         EaLength = 0; | ||||
|         /* cannot set extra buffer on named stream */ | ||||
|         ExtraBuffer = 0; | ||||
|         ExtraLength = 0; | ||||
|  | ||||
|         /* remember the main file node */ | ||||
|         ASSERT(0 == FileNode->MainFileNode); | ||||
| @@ -577,8 +631,8 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|  | ||||
|     /* create the user-mode file system request */ | ||||
|     Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, | ||||
|         0 != EaBuffer ? | ||||
|             FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + EaLength : SecurityDescriptorSize, | ||||
|         0 != ExtraBuffer ? | ||||
|             FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + ExtraLength : SecurityDescriptorSize, | ||||
|         FspFsvolCreateRequestFini, &Request); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|     { | ||||
| @@ -616,10 +670,10 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|     Request->Req.Create.DesiredAccess = DesiredAccess; | ||||
|     Request->Req.Create.GrantedAccess = GrantedAccess; | ||||
|     Request->Req.Create.ShareAccess = ShareAccess; | ||||
|     Request->Req.Create.Ea.Offset = 0 != EaBuffer ? | ||||
|     Request->Req.Create.Ea.Offset = 0 != ExtraBuffer ? | ||||
|         (0 != Request->Req.Create.SecurityDescriptor.Offset ? | ||||
|             NEXTOFS(Request->Req.Create.SecurityDescriptor) : NEXTOFS(Request->FileName)) : 0; | ||||
|     Request->Req.Create.Ea.Size = 0 != EaBuffer ? (UINT16)EaLength : 0; | ||||
|     Request->Req.Create.Ea.Size = 0 != ExtraBuffer ? (UINT16)ExtraLength : 0; | ||||
|     Request->Req.Create.UserMode = UserMode == RequestorMode; | ||||
|     Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; | ||||
|     Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege; | ||||
| @@ -628,10 +682,10 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|     Request->Req.Create.CaseSensitive = CaseSensitive; | ||||
|     Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash; | ||||
|     Request->Req.Create.NamedStream = MainFileName.Length; | ||||
| #undef NEXTOFS | ||||
|  | ||||
|     Request->Req.Create.AcceptsSecurityDescriptor = 0 == Request->Req.Create.NamedStream && | ||||
|         !!FsvolDeviceExtension->VolumeParams.AllowOpenInKernelMode; | ||||
|     Request->Req.Create.EaIsReparsePoint = EaIsReparsePoint; | ||||
| #undef NEXTOFS | ||||
|  | ||||
|     ASSERT( | ||||
|         0 == StreamPart.Length && 0 == MainFileName.Length || | ||||
| @@ -642,10 +696,10 @@ static NTSTATUS FspFsvolCreateNoLock( | ||||
|         RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, | ||||
|             SecurityDescriptor, SecurityDescriptorSize); | ||||
|  | ||||
|     /* copy the EA buffer (if any) into the request */ | ||||
|     if (0 != EaBuffer) | ||||
|     /* copy the extra buffer (if any) into the request */ | ||||
|     if (0 != ExtraBuffer) | ||||
|         RtlCopyMemory(Request->Buffer + Request->Req.Create.Ea.Offset, | ||||
|             EaBuffer, EaLength); | ||||
|             ExtraBuffer, ExtraLength); | ||||
|  | ||||
|     /* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */ | ||||
|     if (Request->Req.Create.OpenTargetDirectory) | ||||
|   | ||||
| @@ -1678,4 +1678,39 @@ typedef struct | ||||
|     ULONG LxDeviceIdMajor; | ||||
|     ULONG LxDeviceIdMinor; | ||||
| } FSP_FILE_STAT_LX_INFORMATION, *PFSP_FILE_STAT_LX_INFORMATION; | ||||
|  | ||||
| /* ATOMIC_CREATE_ECP_CONTEXT is missing on some WDK's */ | ||||
| #define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED   0x0002 | ||||
| #define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET        0x0002 | ||||
| #define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT               0x0100 | ||||
| typedef struct | ||||
| { | ||||
|     LARGE_INTEGER CreationTime; | ||||
|     LARGE_INTEGER LastAccessTime; | ||||
|     LARGE_INTEGER LastWriteTime; | ||||
|     LARGE_INTEGER ChangeTime; | ||||
| } FSP_FILE_TIMESTAMPS, *PFSP_FILE_TIMESTAMPS; | ||||
| typedef struct | ||||
| { | ||||
|     USHORT Size; | ||||
|     USHORT InFlags; | ||||
|     USHORT OutFlags; | ||||
|     USHORT ReparseBufferLength; | ||||
|     PREPARSE_DATA_BUFFER ReparseBuffer; | ||||
|     LONGLONG FileSize; | ||||
|     LONGLONG ValidDataLength; | ||||
|     PFSP_FILE_TIMESTAMPS FileTimestamps; | ||||
|     ULONG FileAttributes; | ||||
|     ULONG UsnSourceInfo; | ||||
|     USN Usn; | ||||
|     ULONG SuppressFileAttributeInheritanceMask; | ||||
|     ULONG InOpFlags; | ||||
|     ULONG OutOpFlags; | ||||
|     ULONG InGenFlags; | ||||
|     ULONG OutGenFlags; | ||||
|     ULONG CaseSensitiveFlagsMask; | ||||
|     ULONG InCaseSensitiveFlags; | ||||
|     ULONG OutCaseSensitiveFlags; | ||||
| } FSP_ATOMIC_CREATE_ECP_CONTEXT, *PFSP_ATOMIC_CREATE_ECP_CONTEXT; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -981,10 +981,16 @@ static NTSTATUS FspFsvolQueryInformation( | ||||
|         Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0); | ||||
|         break; | ||||
|     case 68/*FileStatInformation*/: | ||||
|         Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, 0); | ||||
|         if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures) | ||||
|             Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, 0); | ||||
|         else | ||||
|             Result = STATUS_INVALID_PARAMETER; | ||||
|         break; | ||||
|     case 70/*FileStatLxInformation*/: | ||||
|         Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, 0); | ||||
|         if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures) | ||||
|             Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, 0); | ||||
|         else | ||||
|             Result = STATUS_INVALID_PARAMETER; | ||||
|         break; | ||||
|     default: | ||||
|         Result = STATUS_INVALID_PARAMETER; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user