mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
wslinux support: ATOMIC_CREATE_ECP_CONTEXT
This commit is contained in:
parent
195f3bf92d
commit
c01402443d
@ -168,7 +168,8 @@ enum
|
||||
/* additional kernel-mode flags */\
|
||||
UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\
|
||||
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
|
||||
UINT32 KmReservedFlags:6;\
|
||||
UINT32 WslFeatures:1; /* support features required for WSLinux */\
|
||||
UINT32 KmReservedFlags:5;\
|
||||
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
|
||||
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
|
||||
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
|
||||
@ -277,7 +278,7 @@ typedef struct
|
||||
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
|
||||
FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */
|
||||
FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes or reparse point buffer */
|
||||
UINT32 UserMode:1; /* request originated in user mode */
|
||||
UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */
|
||||
UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */
|
||||
@ -286,6 +287,7 @@ typedef struct
|
||||
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
||||
UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */
|
||||
UINT32 AcceptsSecurityDescriptor:1;
|
||||
UINT32 EaIsReparsePoint:1; /* Ea buffer is reparse point */
|
||||
UINT32 ReservedFlags:24;
|
||||
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
|
||||
} Create;
|
||||
|
@ -912,7 +912,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
/**
|
||||
* Create new file or directory.
|
||||
*
|
||||
* This function works like Create, except that it also accepts EA (extended attributes).
|
||||
* This function works like Create, except that it also accepts an extra buffer that
|
||||
* may contain extended attributes or a reparse point.
|
||||
*
|
||||
* NOTE: If both Create and CreateEx are defined, CreateEx takes precedence.
|
||||
*
|
||||
@ -941,10 +942,12 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* Windows GetSecurityDescriptorLength API. Will be NULL for named streams.
|
||||
* @param AllocationSize
|
||||
* Allocation size for the newly created file.
|
||||
* @param Ea
|
||||
* Extended attributes buffer.
|
||||
* @param EaLength
|
||||
* Extended attributes buffer length.
|
||||
* @param ExtraBuffer
|
||||
* Extended attributes or reparse point buffer.
|
||||
* @param ExtraLength
|
||||
* Extended attributes or reparse point buffer length.
|
||||
* @param ExtraBufferIsReparsePoint
|
||||
* FALSE: extra buffer is extended attributes; TRUE: extra buffer is reparse point.
|
||||
* @param PFileContext [out]
|
||||
* Pointer that will receive the file context on successful return from this call.
|
||||
* @param FileInfo [out]
|
||||
@ -956,7 +959,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem,
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
|
||||
PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
|
||||
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Overwrite a file.
|
||||
|
@ -443,6 +443,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||
0 != Request->Req.Create.Ea.Size ?
|
||||
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
|
||||
Request->Req.Create.Ea.Size,
|
||||
Request->Req.Create.EaIsReparsePoint,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
else
|
||||
Result = FileSystem->Interface->Create(FileSystem,
|
||||
@ -590,6 +591,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
||||
0 != Request->Req.Create.Ea.Size ?
|
||||
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
|
||||
Request->Req.Create.Ea.Size,
|
||||
Request->Req.Create.EaIsReparsePoint,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
else
|
||||
Result = FileSystem->Interface->Create(FileSystem,
|
||||
@ -724,6 +726,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
||||
0 != Request->Req.Create.Ea.Size ?
|
||||
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
|
||||
Request->Req.Create.Ea.Size,
|
||||
Request->Req.Create.EaIsReparsePoint,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
else
|
||||
Result = FileSystem->Interface->Create(FileSystem,
|
||||
|
@ -752,7 +752,7 @@ exit:
|
||||
static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
|
||||
PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
|
||||
PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -766,12 +766,21 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
int err;
|
||||
NTSTATUS Result;
|
||||
|
||||
if (0 != Ea)
|
||||
if (0 != ExtraBuffer)
|
||||
{
|
||||
if (0 == f->ops.listxattr || 0 == f->ops.getxattr ||
|
||||
0 == f->ops.setxattr || 0 == f->ops.removexattr)
|
||||
if (!ExtraBufferIsReparsePoint)
|
||||
{
|
||||
Result = STATUS_EAS_NOT_SUPPORTED;
|
||||
if (0 == f->ops.listxattr || 0 == f->ops.getxattr ||
|
||||
0 == f->ops.setxattr || 0 == f->ops.removexattr)
|
||||
{
|
||||
Result = STATUS_EAS_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* !!!: revisit */
|
||||
Result = STATUS_INVALID_PARAMETER;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@ -889,12 +898,21 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (0 != Ea)
|
||||
if (0 != ExtraBuffer)
|
||||
{
|
||||
Result = FspFileSystemEnumerateEa(FileSystem,
|
||||
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, Ea, EaLength);
|
||||
if (!NT_SUCCESS(Result))
|
||||
if (!ExtraBufferIsReparsePoint)
|
||||
{
|
||||
Result = FspFileSystemEnumerateEa(FileSystem,
|
||||
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, ExtraBuffer, ExtraLength);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* !!!: revisit: WslFeatures, GetFileInfoFunnel, GetReparsePointEx, SetReparsePoint */
|
||||
Result = STATUS_INVALID_PARAMETER;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
|
||||
|
@ -1085,8 +1085,9 @@ namespace Fsp
|
||||
UInt32 FileAttributes,
|
||||
Byte[] SecurityDescriptor,
|
||||
UInt64 AllocationSize,
|
||||
IntPtr Ea,
|
||||
UInt32 EaLength,
|
||||
IntPtr ExtraBuffer,
|
||||
UInt32 ExtraLength,
|
||||
Boolean ExtraBufferIsReparsePoint,
|
||||
out Object FileNode,
|
||||
out Object FileDesc,
|
||||
out FileInfo FileInfo,
|
||||
@ -1391,6 +1392,16 @@ namespace Fsp
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Makes a byte array that contains a reparse point.
|
||||
/// </summary>
|
||||
/// <returns>The reparse point byte array.</returns>
|
||||
public static Byte[] MakeReparsePoint(
|
||||
IntPtr Buffer,
|
||||
UInt32 Size)
|
||||
{
|
||||
return Api.MakeReparsePoint(Buffer, (UIntPtr)Size);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the reparse tag from reparse data.
|
||||
/// </summary>
|
||||
/// <param name="ReparseData">
|
||||
|
@ -221,6 +221,11 @@ namespace Fsp
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 0); }
|
||||
}
|
||||
public Boolean WslFeatures
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.WslFeatures); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.WslFeatures : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the prefix for a network file system.
|
||||
/// </summary>
|
||||
@ -472,8 +477,9 @@ namespace Fsp
|
||||
UInt32 FileAttributes,
|
||||
IntPtr SecurityDescriptor,
|
||||
UInt64 AllocationSize,
|
||||
IntPtr Ea,
|
||||
UInt32 EaLength,
|
||||
IntPtr ExtraBuffer,
|
||||
UInt32 ExtraLength,
|
||||
Boolean ExtraBufferIsReparsePoint,
|
||||
ref FullContext FullContext,
|
||||
ref OpenFileInfo OpenFileInfo)
|
||||
{
|
||||
@ -490,8 +496,9 @@ namespace Fsp
|
||||
FileAttributes,
|
||||
Api.MakeSecurityDescriptor(SecurityDescriptor),
|
||||
AllocationSize,
|
||||
Ea,
|
||||
EaLength,
|
||||
ExtraBuffer,
|
||||
ExtraLength,
|
||||
ExtraBufferIsReparsePoint,
|
||||
out FileNode,
|
||||
out FileDesc,
|
||||
out OpenFileInfo.FileInfo,
|
||||
|
@ -53,6 +53,7 @@ namespace Fsp.Interop
|
||||
internal const UInt32 UmFileContextIsFullContext = 0x00020000;
|
||||
internal const UInt32 AllowOpenInKernelMode = 0x01000000;
|
||||
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
|
||||
internal const UInt32 WslFeatures = 0x04000000;
|
||||
internal const int PrefixSize = 192;
|
||||
internal const int FileSystemNameSize = 16;
|
||||
|
||||
@ -557,8 +558,9 @@ namespace Fsp.Interop
|
||||
UInt32 FileAttributes,
|
||||
IntPtr SecurityDescriptor,
|
||||
UInt64 AllocationSize,
|
||||
IntPtr Ea,
|
||||
UInt32 EaLength,
|
||||
IntPtr ExtraBuffer,
|
||||
UInt32 ExtraLength,
|
||||
[MarshalAs(UnmanagedType.U1)] Boolean ExtraBufferIsReparsePoint,
|
||||
ref FullContext FullContext,
|
||||
ref OpenFileInfo OpenFileInfo);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
|
@ -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;
|
||||
|
@ -274,6 +274,7 @@ namespace memfs
|
||||
Host.PostCleanupWhenModifiedOnly = true;
|
||||
Host.PassQueryDirectoryFileName = true;
|
||||
Host.ExtendedAttributes = true;
|
||||
Host.WslFeatures = true;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -331,8 +332,9 @@ namespace memfs
|
||||
UInt32 FileAttributes,
|
||||
Byte[] SecurityDescriptor,
|
||||
UInt64 AllocationSize,
|
||||
IntPtr Ea,
|
||||
UInt32 EaLength,
|
||||
IntPtr ExtraBuffer,
|
||||
UInt32 ExtraLength,
|
||||
Boolean ExtraBufferIsReparsePoint,
|
||||
out Object FileNode0,
|
||||
out Object FileDesc,
|
||||
out FileInfo FileInfo,
|
||||
@ -369,11 +371,21 @@ namespace memfs
|
||||
FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ?
|
||||
FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive;
|
||||
FileNode.FileSecurity = SecurityDescriptor;
|
||||
if (IntPtr.Zero != Ea)
|
||||
if (IntPtr.Zero != ExtraBuffer)
|
||||
{
|
||||
Result = SetEaEntries(FileNode, null, Ea, EaLength);
|
||||
if (0 > Result)
|
||||
return Result;
|
||||
if (!ExtraBufferIsReparsePoint)
|
||||
{
|
||||
Result = SetEaEntries(FileNode, null, ExtraBuffer, ExtraLength);
|
||||
if (0 > Result)
|
||||
return Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte[] ReparseData = MakeReparsePoint(ExtraBuffer, ExtraLength);
|
||||
FileNode.FileInfo.FileAttributes |= (UInt32)System.IO.FileAttributes.ReparsePoint;
|
||||
FileNode.FileInfo.ReparseTag = GetReparseTag(ReparseData);
|
||||
FileNode.ReparseData = ReparseData;
|
||||
}
|
||||
}
|
||||
if (0 != AllocationSize)
|
||||
{
|
||||
|
@ -70,6 +70,11 @@ FSP_FSCTL_STATIC_ASSERT(MEMFS_MAX_PATH > MAX_PATH,
|
||||
#define MEMFS_EA
|
||||
|
||||
/*
|
||||
* Define the MEMFS_WSL macro to include WSLinux support.
|
||||
*/
|
||||
#define MEMFS_WSL
|
||||
|
||||
/*
|
||||
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
|
||||
* a check for the Write buffer to ensure that it is read-only.
|
||||
*
|
||||
@ -1047,8 +1052,8 @@ static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
|
||||
static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
||||
#if defined(MEMFS_EA)
|
||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
|
||||
#if defined(MEMFS_EA) || defined(MEMFS_WSL)
|
||||
PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
|
||||
#endif
|
||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
@ -1129,15 +1134,43 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
memcpy(FileNode->FileSecurity, SecurityDescriptor, FileNode->FileSecuritySize);
|
||||
}
|
||||
|
||||
#if defined(MEMFS_EA)
|
||||
if (0 != Ea)
|
||||
#if defined(MEMFS_EA) || defined(MEMFS_WSL)
|
||||
if (0 != ExtraBuffer)
|
||||
{
|
||||
Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode, Ea, EaLength);
|
||||
if (!NT_SUCCESS(Result))
|
||||
#if defined(MEMFS_EA)
|
||||
if (!ExtraBufferIsReparsePoint)
|
||||
{
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
return Result;
|
||||
Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode,
|
||||
(PFILE_FULL_EA_INFORMATION)ExtraBuffer, ExtraLength);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(MEMFS_WSL)
|
||||
if (ExtraBufferIsReparsePoint)
|
||||
{
|
||||
#if defined(MEMFS_REPARSE_POINTS)
|
||||
FileNode->ReparseDataSize = ExtraLength;
|
||||
FileNode->ReparseData = malloc(ExtraLength);
|
||||
if (0 == FileNode->ReparseData && 0 != ExtraLength)
|
||||
{
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
FileNode->FileInfo.FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
FileNode->FileInfo.ReparseTag = *(PULONG)ExtraBuffer;
|
||||
/* the first field in a reparse buffer is the reparse tag */
|
||||
memcpy(FileNode->ReparseData, ExtraBuffer, ExtraLength);
|
||||
#else
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2189,7 +2222,7 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||
GetVolumeInfo,
|
||||
SetVolumeLabel,
|
||||
GetSecurityByName,
|
||||
#if defined(MEMFS_EA)
|
||||
#if defined(MEMFS_EA) || defined(MEMFS_WSL)
|
||||
0,
|
||||
#else
|
||||
Create,
|
||||
@ -2240,8 +2273,10 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||
0,
|
||||
#endif
|
||||
0,
|
||||
#if defined(MEMFS_EA)
|
||||
#if defined(MEMFS_EA) || defined(MEMFS_WSL)
|
||||
Create,
|
||||
#endif
|
||||
#if defined(MEMFS_EA)
|
||||
Overwrite,
|
||||
GetEa,
|
||||
SetEa
|
||||
@ -2347,6 +2382,9 @@ NTSTATUS MemfsCreateFunnel(
|
||||
#endif
|
||||
#if defined(MEMFS_EA)
|
||||
VolumeParams.ExtendedAttributes = 1;
|
||||
#endif
|
||||
#if defined(MEMFS_WSL)
|
||||
VolumeParams.WslFeatures = 1;
|
||||
#endif
|
||||
VolumeParams.AllowOpenInKernelMode = 1;
|
||||
if (0 != VolumePrefix)
|
||||
|
Loading…
x
Reference in New Issue
Block a user