mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 09:22:57 -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