mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-07 20:42:09 -05:00
grand EaSize patch; passes winfsp-tests and ifstest
This commit is contained in:
parent
b619dbfe97
commit
732e6cc38c
@ -230,8 +230,6 @@ typedef struct
|
|||||||
PWSTR NormalizedName;
|
PWSTR NormalizedName;
|
||||||
UINT16 NormalizedNameSize;
|
UINT16 NormalizedNameSize;
|
||||||
} FSP_FSCTL_OPEN_FILE_INFO;
|
} FSP_FSCTL_OPEN_FILE_INFO;
|
||||||
FSP_FSCTL_STATIC_ASSERT(88 == sizeof(FSP_FSCTL_OPEN_FILE_INFO),
|
|
||||||
"sizeof(FSP_FSCTL_OPEN_FILE_INFO) must be exactly 88.");
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT16 Size;
|
UINT16 Size;
|
||||||
@ -505,6 +503,7 @@ typedef struct
|
|||||||
} QueryEa;
|
} QueryEa;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
FSP_FSCTL_TRANSACT_BUF Ea; /* Size==0 means no extended atttributed returned */
|
FSP_FSCTL_TRANSACT_BUF Ea; /* Size==0 means no extended atttributed returned */
|
||||||
} SetEa;
|
} SetEa;
|
||||||
struct
|
struct
|
||||||
|
@ -1023,6 +1023,9 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
* Extended attributes buffer.
|
* Extended attributes buffer.
|
||||||
* @param EaLength
|
* @param EaLength
|
||||||
* Extended attributes buffer length.
|
* Extended attributes buffer length.
|
||||||
|
* @param FileInfo [out]
|
||||||
|
* Pointer to a structure that will receive the file information on successful return
|
||||||
|
* from this call. This information includes file attributes, file times, etc.
|
||||||
* @return
|
* @return
|
||||||
* STATUS_SUCCESS or error code.
|
* STATUS_SUCCESS or error code.
|
||||||
* @see
|
* @see
|
||||||
@ -1030,7 +1033,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
*/
|
*/
|
||||||
NTSTATUS (*SetEa)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*SetEa)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext,
|
PVOID FileContext,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength);
|
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
|
||||||
|
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This ensures that this interface will always contain 64 function pointers.
|
* This ensures that this interface will always contain 64 function pointers.
|
||||||
@ -1624,6 +1628,20 @@ FSP_API NTSTATUS FspFileSystemEnumerateEa(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
*/
|
*/
|
||||||
FSP_API BOOLEAN FspFileSystemAddEa(PFILE_FULL_EA_INFORMATION SingleEa,
|
FSP_API BOOLEAN FspFileSystemAddEa(PFILE_FULL_EA_INFORMATION SingleEa,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred);
|
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred);
|
||||||
|
/**
|
||||||
|
* Get extended attribute "packed" size. This computation matches what NTFS reports.
|
||||||
|
*
|
||||||
|
* @param SingleEa
|
||||||
|
* The extended attribute to get the size for.
|
||||||
|
* @return
|
||||||
|
* The packed size of the extended attribute.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
UINT32 FspFileSystemGetEaPackedSize(PFILE_FULL_EA_INFORMATION SingleEa)
|
||||||
|
{
|
||||||
|
/* magic computations are courtesy of NTFS */
|
||||||
|
return 5 + SingleEa->EaNameLength + SingleEa->EaValueLength;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Directory buffering
|
* Directory buffering
|
||||||
|
@ -1208,12 +1208,22 @@ FSP_API NTSTATUS FspFileSystemOpQueryEa(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_API NTSTATUS FspFileSystemOpSetEa(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpSetEa(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
|
|
||||||
if (0 == FileSystem->Interface->SetEa)
|
if (0 == FileSystem->Interface->SetEa)
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
return FileSystem->Interface->SetEa(FileSystem,
|
memset(&FileInfo, 0, sizeof FileInfo);
|
||||||
|
Result = FileSystem->Interface->SetEa(FileSystem,
|
||||||
(PVOID)ValOfFileContext(Request->Req.SetEa),
|
(PVOID)ValOfFileContext(Request->Req.SetEa),
|
||||||
(PVOID)Request->Buffer, Request->Req.SetEa.Ea.Size);
|
(PVOID)Request->Buffer, Request->Req.SetEa.Ea.Size,
|
||||||
|
&FileInfo);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
memcpy(&Response->Rsp.SetEa.FileInfo, &FileInfo, sizeof FileInfo);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
@ -2289,16 +2289,29 @@ static NTSTATUS fsp_fuse_intf_SetEaEntry(
|
|||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileDesc,
|
PVOID FileDesc,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
|
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
|
||||||
|
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
struct fsp_fuse_file_desc *filedesc = FileDesc;
|
struct fsp_fuse_file_desc *filedesc = FileDesc;
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
struct fuse_file_info fi;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == f->ops.setxattr || 0 == f->ops.removexattr)
|
if (0 == f->ops.setxattr || 0 == f->ops.removexattr)
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
return FspFileSystemEnumerateEa(FileSystem,
|
Result = FspFileSystemEnumerateEa(FileSystem,
|
||||||
fsp_fuse_intf_SetEaEntry, filedesc->PosixPath, Ea, EaLength);
|
fsp_fuse_intf_SetEaEntry, filedesc->PosixPath, Ea, EaLength);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
memset(&fi, 0, sizeof fi);
|
||||||
|
fi.flags = filedesc->OpenFlags;
|
||||||
|
fi.fh = filedesc->FileHandle;
|
||||||
|
|
||||||
|
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||||
|
&Uid, &Gid, &Mode, FileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
||||||
|
@ -1161,14 +1161,21 @@ namespace Fsp
|
|||||||
Object FileNode,
|
Object FileNode,
|
||||||
Object FileDesc,
|
Object FileDesc,
|
||||||
IntPtr Ea,
|
IntPtr Ea,
|
||||||
UInt32 EaLength)
|
UInt32 EaLength,
|
||||||
|
out FileInfo FileInfo)
|
||||||
{
|
{
|
||||||
return Api.FspFileSystemEnumerateEa(
|
Int32 Result;
|
||||||
|
Result = SetEaEntries(
|
||||||
FileNode,
|
FileNode,
|
||||||
FileDesc,
|
FileDesc,
|
||||||
this.SetEaEntry,
|
|
||||||
Ea,
|
Ea,
|
||||||
EaLength);
|
EaLength);
|
||||||
|
if (0 > Result)
|
||||||
|
{
|
||||||
|
FileInfo = default(FileInfo);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
return GetFileInfo(FileNode, FileDesc, out FileInfo);
|
||||||
}
|
}
|
||||||
public virtual Int32 SetEaEntry(
|
public virtual Int32 SetEaEntry(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -1445,12 +1452,25 @@ namespace Fsp
|
|||||||
return self.ExceptionHandler(ex);
|
return self.ExceptionHandler(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public Int32 SetEaEntries(
|
||||||
|
Object FileNode,
|
||||||
|
Object FileDesc,
|
||||||
|
IntPtr Ea,
|
||||||
|
UInt32 EaLength)
|
||||||
|
{
|
||||||
|
return Api.FspFileSystemEnumerateEa(
|
||||||
|
FileNode,
|
||||||
|
FileDesc,
|
||||||
|
this.SetEaEntry,
|
||||||
|
Ea,
|
||||||
|
EaLength);
|
||||||
|
}
|
||||||
public static UInt32 GetEaEntrySize(
|
public static UInt32 GetEaEntrySize(
|
||||||
String EaName,
|
String EaName,
|
||||||
Byte[] EaValue,
|
Byte[] EaValue,
|
||||||
Boolean NeedEa)
|
Boolean NeedEa)
|
||||||
{
|
{
|
||||||
return FullEaInformation.Size(EaName, EaValue, NeedEa);
|
return FullEaInformation.PackedSize(EaName, EaValue, NeedEa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,7 +1122,8 @@ namespace Fsp
|
|||||||
IntPtr FileSystemPtr,
|
IntPtr FileSystemPtr,
|
||||||
ref FullContext FullContext,
|
ref FullContext FullContext,
|
||||||
IntPtr Ea,
|
IntPtr Ea,
|
||||||
UInt32 EaLength)
|
UInt32 EaLength,
|
||||||
|
out FileInfo FileInfo)
|
||||||
{
|
{
|
||||||
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
|
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
|
||||||
try
|
try
|
||||||
@ -1133,10 +1134,12 @@ namespace Fsp
|
|||||||
FileNode,
|
FileNode,
|
||||||
FileDesc,
|
FileDesc,
|
||||||
Ea,
|
Ea,
|
||||||
EaLength);
|
EaLength,
|
||||||
|
out FileInfo);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
FileInfo = default(FileInfo);
|
||||||
return ExceptionHandler(FileSystem, ex);
|
return ExceptionHandler(FileSystem, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,8 +283,6 @@ namespace Fsp.Interop
|
|||||||
* This should really be:
|
* This should really be:
|
||||||
* FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX - FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName)
|
* FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX - FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName)
|
||||||
*/
|
*/
|
||||||
internal static int EaNameOffset =
|
|
||||||
(int)Marshal.OffsetOf(typeof(FullEaInformation), "EaName");
|
|
||||||
|
|
||||||
internal UInt32 NextEntryOffset;
|
internal UInt32 NextEntryOffset;
|
||||||
internal Byte Flags;
|
internal Byte Flags;
|
||||||
@ -313,13 +311,14 @@ namespace Fsp.Interop
|
|||||||
P[I + J] = Value[J];
|
P[I + J] = Value[J];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal static UInt32 Size(String Name, Byte[] Value, Boolean NeedEa)
|
internal static UInt32 PackedSize(String Name, Byte[] Value, Boolean NeedEa)
|
||||||
{
|
{
|
||||||
int NameLength = 254 < Name.Length ? 254 : Name.Length;
|
int NameLength = 254 < Name.Length ? 254 : Name.Length;
|
||||||
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
|
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
|
||||||
EaNameSize - Name.Length - 1 : Value.Length;
|
EaNameSize - Name.Length - 1 : Value.Length;
|
||||||
|
|
||||||
return (UInt32)((EaNameOffset + NameLength + 1 + ValueLength + 3) & ~3);
|
/* magic computations are courtesy of NTFS */
|
||||||
|
return (UInt32)(5 + NameLength + ValueLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +565,8 @@ namespace Fsp.Interop
|
|||||||
IntPtr FileSystem,
|
IntPtr FileSystem,
|
||||||
ref FullContext FullContext,
|
ref FullContext FullContext,
|
||||||
IntPtr Ea,
|
IntPtr Ea,
|
||||||
UInt32 EaLength);
|
UInt32 EaLength,
|
||||||
|
out FileInfo FileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int Size = IntPtr.Size * 64;
|
internal static int Size = IntPtr.Size * 64;
|
||||||
|
@ -1285,6 +1285,7 @@ typedef struct FSP_FILE_NODE
|
|||||||
UINT64 LastAccessTime;
|
UINT64 LastAccessTime;
|
||||||
UINT64 LastWriteTime;
|
UINT64 LastWriteTime;
|
||||||
UINT64 ChangeTime;
|
UINT64 ChangeTime;
|
||||||
|
UINT32 EaSize;
|
||||||
ULONG FileInfoChangeNumber;
|
ULONG FileInfoChangeNumber;
|
||||||
UINT64 Security;
|
UINT64 Security;
|
||||||
ULONG SecurityChangeNumber;
|
ULONG SecurityChangeNumber;
|
||||||
|
16
src/sys/ea.c
16
src/sys/ea.c
@ -578,9 +578,11 @@ NTSTATUS FspFsvolSetEaComplete(
|
|||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
BOOLEAN Valid;
|
BOOLEAN EaValid;
|
||||||
|
|
||||||
Valid = FALSE;
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetEa.FileInfo, FALSE);
|
||||||
|
|
||||||
|
EaValid = FALSE;
|
||||||
if (0 < Response->Rsp.SetEa.Ea.Size &&
|
if (0 < Response->Rsp.SetEa.Ea.Size &&
|
||||||
Response->Buffer + Response->Rsp.SetEa.Ea.Size <=
|
Response->Buffer + Response->Rsp.SetEa.Ea.Size <=
|
||||||
(PUINT8)Response + Response->Size)
|
(PUINT8)Response + Response->Size)
|
||||||
@ -589,19 +591,17 @@ NTSTATUS FspFsvolSetEaComplete(
|
|||||||
(PVOID)Response->Buffer, /* FspEaBufferFromFileSystemValidate may alter the buffer! */
|
(PVOID)Response->Buffer, /* FspEaBufferFromFileSystemValidate may alter the buffer! */
|
||||||
Response->Rsp.SetEa.Ea.Size,
|
Response->Rsp.SetEa.Ea.Size,
|
||||||
(PULONG)&Irp->IoStatus.Information);
|
(PULONG)&Irp->IoStatus.Information);
|
||||||
Valid = NT_SUCCESS(Result);
|
EaValid = NT_SUCCESS(Result);
|
||||||
}
|
}
|
||||||
|
if (EaValid)
|
||||||
/* if the EA buffer that we got back is valid */
|
|
||||||
if (Valid)
|
|
||||||
{
|
{
|
||||||
/* update the cached EA */
|
/* if the EA buffer that we got back is valid, update the cached EA */
|
||||||
FspFileNodeSetEa(FileNode,
|
FspFileNodeSetEa(FileNode,
|
||||||
Response->Buffer, Response->Rsp.SetEa.Ea.Size);
|
Response->Buffer, Response->Rsp.SetEa.Ea.Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* invalidate the cached EA */
|
/* if the EA buffer that we got back is not valid, invalidate the cached EA */
|
||||||
FspFileNodeSetEa(FileNode, 0, 0);
|
FspFileNodeSetEa(FileNode, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1631,6 +1631,7 @@ VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileIn
|
|||||||
FileInfo->LastAccessTime = FileNode->LastAccessTime;
|
FileInfo->LastAccessTime = FileNode->LastAccessTime;
|
||||||
FileInfo->LastWriteTime = FileNode->LastWriteTime;
|
FileInfo->LastWriteTime = FileNode->LastWriteTime;
|
||||||
FileInfo->ChangeTime = FileNode->ChangeTime;
|
FileInfo->ChangeTime = FileNode->ChangeTime;
|
||||||
|
FileInfo->EaSize = FileNode->EaSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
@ -1778,6 +1779,7 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
|||||||
MainFileNode->LastAccessTime = FileInfo->LastAccessTime;
|
MainFileNode->LastAccessTime = FileInfo->LastAccessTime;
|
||||||
MainFileNode->LastWriteTime = FileInfo->LastWriteTime;
|
MainFileNode->LastWriteTime = FileInfo->LastWriteTime;
|
||||||
MainFileNode->ChangeTime = FileInfo->ChangeTime;
|
MainFileNode->ChangeTime = FileInfo->ChangeTime;
|
||||||
|
MainFileNode->EaSize = FileInfo->EaSize;
|
||||||
|
|
||||||
if (0 != CcFileObject)
|
if (0 != CcFileObject)
|
||||||
{
|
{
|
||||||
|
@ -179,6 +179,9 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject,
|
|||||||
Info->EaInformation.EaSize =
|
Info->EaInformation.EaSize =
|
||||||
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes ?
|
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes ?
|
||||||
FileInfo->EaSize : 0;
|
FileInfo->EaSize : 0;
|
||||||
|
/* magic computations are courtesy of NTFS */
|
||||||
|
if (0 != Info->EaInformation.EaSize)
|
||||||
|
Info->EaInformation.EaSize += 4;
|
||||||
|
|
||||||
Info->PositionInformation.CurrentByteOffset = FileObject->CurrentByteOffset;
|
Info->PositionInformation.CurrentByteOffset = FileObject->CurrentByteOffset;
|
||||||
|
|
||||||
@ -258,6 +261,9 @@ static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject,
|
|||||||
Info->EaSize =
|
Info->EaSize =
|
||||||
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes ?
|
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes ?
|
||||||
FileInfo->EaSize : 0;
|
FileInfo->EaSize : 0;
|
||||||
|
/* magic computations are courtesy of NTFS */
|
||||||
|
if (0 != Info->EaSize)
|
||||||
|
Info->EaSize += 4;
|
||||||
|
|
||||||
*PBuffer = (PVOID)(Info + 1);
|
*PBuffer = (PVOID)(Info + 1);
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ namespace memfs
|
|||||||
FileNode.FileSecurity = SecurityDescriptor;
|
FileNode.FileSecurity = SecurityDescriptor;
|
||||||
if (IntPtr.Zero != Ea)
|
if (IntPtr.Zero != Ea)
|
||||||
{
|
{
|
||||||
Result = SetEa(FileNode, null, Ea, EaLength);
|
Result = SetEaEntries(FileNode, null, Ea, EaLength);
|
||||||
if (0 > Result)
|
if (0 > Result)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -469,7 +469,7 @@ namespace memfs
|
|||||||
}
|
}
|
||||||
if (IntPtr.Zero != Ea)
|
if (IntPtr.Zero != Ea)
|
||||||
{
|
{
|
||||||
Result = SetEa(FileNode, null, Ea, EaLength);
|
Result = SetEaEntries(FileNode, null, Ea, EaLength);
|
||||||
if (0 > Result)
|
if (0 > Result)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -1121,6 +1121,11 @@ namespace memfs
|
|||||||
SortedDictionary<String, EaValueData> EaMap = FileNode.GetEaMap(true);
|
SortedDictionary<String, EaValueData> EaMap = FileNode.GetEaMap(true);
|
||||||
EaValueData Data;
|
EaValueData Data;
|
||||||
UInt32 EaSizePlus = 0, EaSizeMinus = 0;
|
UInt32 EaSizePlus = 0, EaSizeMinus = 0;
|
||||||
|
if (EaMap.TryGetValue(EaName, out Data))
|
||||||
|
{
|
||||||
|
EaSizeMinus = GetEaEntrySize(EaName, Data.EaValue, Data.NeedEa);
|
||||||
|
EaMap.Remove(EaName);
|
||||||
|
}
|
||||||
if (null != EaValue)
|
if (null != EaValue)
|
||||||
{
|
{
|
||||||
Data.EaValue = EaValue;
|
Data.EaValue = EaValue;
|
||||||
@ -1128,11 +1133,6 @@ namespace memfs
|
|||||||
EaMap[EaName] = Data;
|
EaMap[EaName] = Data;
|
||||||
EaSizePlus = GetEaEntrySize(EaName, EaValue, NeedEa);
|
EaSizePlus = GetEaEntrySize(EaName, EaValue, NeedEa);
|
||||||
}
|
}
|
||||||
else if (EaMap.TryGetValue(EaName, out Data))
|
|
||||||
{
|
|
||||||
EaSizeMinus = GetEaEntrySize(EaName, Data.EaValue, Data.NeedEa);
|
|
||||||
EaMap.Remove(EaName);
|
|
||||||
}
|
|
||||||
FileNode.FileInfo.EaSize = FileNode.FileInfo.EaSize + EaSizePlus - EaSizeMinus;
|
FileNode.FileInfo.EaSize = FileNode.FileInfo.EaSize + EaSizePlus - EaSizeMinus;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -458,13 +458,15 @@ NTSTATUS MemfsFileNodeSetEa(
|
|||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
memcpy(FileNodeEa, Ea, EaSizePlus);
|
memcpy(FileNodeEa, Ea, EaSizePlus);
|
||||||
FileNodeEa->NextEntryOffset = 0;
|
FileNodeEa->NextEntryOffset = 0;
|
||||||
|
|
||||||
|
EaSizePlus = FspFileSystemGetEaPackedSize(Ea);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = EaMap->find(Ea->EaName);
|
p = EaMap->find(Ea->EaName);
|
||||||
if (p != EaMap->end())
|
if (p != EaMap->end())
|
||||||
{
|
{
|
||||||
EaSizeMinus = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
|
EaSizeMinus = FspFileSystemGetEaPackedSize(Ea);
|
||||||
p->second->EaNameLength + 1 + p->second->EaValueLength;
|
|
||||||
free(p->second);
|
free(p->second);
|
||||||
EaMap->erase(p);
|
EaMap->erase(p);
|
||||||
}
|
}
|
||||||
@ -482,9 +484,7 @@ NTSTATUS MemfsFileNodeSetEa(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileNode->FileInfo.EaSize = FileNode->FileInfo.EaSize
|
FileNode->FileInfo.EaSize = FileNode->FileInfo.EaSize + EaSizePlus - EaSizeMinus;
|
||||||
+ FSP_FSCTL_ALIGN_UP(EaSizePlus, sizeof(ULONG))
|
|
||||||
- FSP_FSCTL_ALIGN_UP(EaSizeMinus, sizeof(ULONG));
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2167,10 +2167,20 @@ static NTSTATUS GetEa(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS SetEa(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS SetEa(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileNode,
|
PVOID FileNode0,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
|
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
|
||||||
|
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
return FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode, Ea, EaLength);
|
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode, Ea, EaLength);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
MemfsFileNodeGetFileInfo(FileNode, FileInfo);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user