mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: dirctl: support directory marker as FUSE style next offset
This commit is contained in:
parent
847eab3da4
commit
5110b3c5a1
@ -96,7 +96,7 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR),
|
|||||||
|
|
||||||
/* marshalling */
|
/* marshalling */
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4200) /* zero-sized array in struct/union */
|
#pragma warning(disable:4200 4201) /* zero-sized array in struct/union; nameless struct/union */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FspFsctlTransactReservedKind = 0,
|
FspFsctlTransactReservedKind = 0,
|
||||||
@ -175,7 +175,8 @@ enum
|
|||||||
UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\
|
UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\
|
||||||
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
|
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
|
||||||
UINT32 WslFeatures:1; /* support features required for WSLinux */\
|
UINT32 WslFeatures:1; /* support features required for WSLinux */\
|
||||||
UINT32 KmReservedFlags:5;\
|
UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\
|
||||||
|
UINT32 KmReservedFlags:4;\
|
||||||
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
|
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
|
||||||
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
|
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
|
||||||
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
|
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
|
||||||
@ -242,8 +243,12 @@ typedef struct
|
|||||||
{
|
{
|
||||||
UINT16 Size;
|
UINT16 Size;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
UINT8 Padding[24];
|
union
|
||||||
/* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */
|
{
|
||||||
|
UINT64 NextOffset;
|
||||||
|
UINT8 Padding[24];
|
||||||
|
/* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
WCHAR FileNameBuf[];
|
WCHAR FileNameBuf[];
|
||||||
} FSP_FSCTL_DIR_INFO;
|
} FSP_FSCTL_DIR_INFO;
|
||||||
FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO),
|
FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO),
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||||
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
||||||
|
PUINT64 DirectoryMarkerAsNextOffset,
|
||||||
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
|
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
|
||||||
BOOLEAN ReturnEaSize,
|
BOOLEAN ReturnEaSize,
|
||||||
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
|
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
|
||||||
@ -88,6 +89,7 @@ enum
|
|||||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||||
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
||||||
|
PUINT64 DirectoryMarkerAsNextOffset,
|
||||||
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
|
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
|
||||||
BOOLEAN ReturnEaSize,
|
BOOLEAN ReturnEaSize,
|
||||||
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
|
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
|
||||||
@ -130,6 +132,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
|||||||
PVOID PrevDestBuf = 0;
|
PVOID PrevDestBuf = 0;
|
||||||
ULONG BaseInfoLen, CopyLength;
|
ULONG BaseInfoLen, CopyLength;
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
|
UINT64 DirectoryNextOffset;
|
||||||
|
|
||||||
*PDestLen = 0;
|
*PDestLen = 0;
|
||||||
|
|
||||||
@ -176,12 +179,21 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
|||||||
FileName.MaximumLength = (USHORT)(DirInfoSize - sizeof(FSP_FSCTL_DIR_INFO));
|
FileName.MaximumLength = (USHORT)(DirInfoSize - sizeof(FSP_FSCTL_DIR_INFO));
|
||||||
FileName.Buffer = DirInfo->FileNameBuf;
|
FileName.Buffer = DirInfo->FileNameBuf;
|
||||||
|
|
||||||
|
DirectoryNextOffset = DirInfo->NextOffset;
|
||||||
|
|
||||||
if (0 != DirectoryMarker && 0 != DirectoryMarker->Buffer &&
|
if (0 != DirectoryMarker && 0 != DirectoryMarker->Buffer &&
|
||||||
!DirectoryMarkerFound)
|
!DirectoryMarkerFound)
|
||||||
{
|
{
|
||||||
DirectoryMarkerFound = 0 == FspFileNameCompare(
|
if (0 == DirectoryMarkerAsNextOffset)
|
||||||
&FileName, DirectoryMarker, CaseInsensitive, 0);
|
{
|
||||||
continue;
|
DirectoryMarkerFound = 0 == FspFileNameCompare(
|
||||||
|
&FileName, DirectoryMarker, CaseInsensitive, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(sizeof(UINT64) == DirectoryMarker->Length);
|
||||||
|
DirectoryMarkerFound = DirectoryNextOffset == *(PUINT64)DirectoryMarker->Buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */
|
/* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */
|
||||||
@ -272,8 +284,16 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryMarkerOut->Length = DirectoryMarkerOut->MaximumLength = FileName.Length;
|
if (0 == DirectoryMarkerAsNextOffset)
|
||||||
DirectoryMarkerOut->Buffer = (PVOID)((PUINT8)DestBuf + BaseInfoLen);
|
{
|
||||||
|
DirectoryMarkerOut->Length = DirectoryMarkerOut->MaximumLength = FileName.Length;
|
||||||
|
DirectoryMarkerOut->Buffer = (PVOID)((PUINT8)DestBuf + BaseInfoLen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DirectoryMarkerOut->Length = DirectoryMarkerOut->MaximumLength = sizeof(UINT64);
|
||||||
|
DirectoryMarkerOut->Buffer = (PVOID)DirectoryMarkerAsNextOffset;
|
||||||
|
}
|
||||||
|
|
||||||
DestBuf = (PVOID)((PUINT8)DestBuf +
|
DestBuf = (PVOID)((PUINT8)DestBuf +
|
||||||
FSP_FSCTL_ALIGN_UP(BaseInfoLen + CopyLength, sizeof(LONGLONG)));
|
FSP_FSCTL_ALIGN_UP(BaseInfoLen + CopyLength, sizeof(LONGLONG)));
|
||||||
@ -283,7 +303,15 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
|||||||
Loop = FALSE;
|
Loop = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*DirectoryMarkerOut = FileName;
|
{
|
||||||
|
if (0 == DirectoryMarkerAsNextOffset)
|
||||||
|
*DirectoryMarkerOut = FileName;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DirectoryMarkerOut->Length = DirectoryMarkerOut->MaximumLength = sizeof(UINT64);
|
||||||
|
DirectoryMarkerOut->Buffer = (PVOID)DirectoryMarkerAsNextOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
except (EXCEPTION_EXECUTE_HANDLER)
|
except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
@ -323,9 +351,12 @@ static NTSTATUS FspFsvolQueryDirectoryCopyCache(
|
|||||||
FileDesc->DirInfo = FileNode->NonPaged->DirInfo;
|
FileDesc->DirInfo = FileNode->NonPaged->DirInfo;
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
||||||
|
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
|
||||||
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
|
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
|
||||||
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
||||||
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
||||||
|
UINT64 DirectoryMarkerAsNextOffset = 0;
|
||||||
PUINT8 DirInfoBgn = (PUINT8)DirInfo;
|
PUINT8 DirInfoBgn = (PUINT8)DirInfo;
|
||||||
PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize;
|
PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize;
|
||||||
|
|
||||||
@ -334,8 +365,10 @@ static NTSTATUS FspFsvolQueryDirectoryCopyCache(
|
|||||||
|
|
||||||
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
|
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
|
||||||
0 != FileDesc->DirInfoCacheHint ? 0 : &FileDesc->DirectoryMarker, &DirectoryMarker,
|
0 != FileDesc->DirInfoCacheHint ? 0 : &FileDesc->DirectoryMarker, &DirectoryMarker,
|
||||||
|
FsvolDeviceExtension->VolumeParams.DirectoryMarkerAsNextOffset ?
|
||||||
|
&DirectoryMarkerAsNextOffset : 0,
|
||||||
FileInformationClass, ReturnSingleEntry,
|
FileInformationClass, ReturnSingleEntry,
|
||||||
!!FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes,
|
!!FsvolDeviceExtension->VolumeParams.ExtendedAttributes,
|
||||||
&DirInfo, DirInfoSize,
|
&DirInfo, DirInfoSize,
|
||||||
DestBuf, PDestLen);
|
DestBuf, PDestLen);
|
||||||
|
|
||||||
@ -366,10 +399,13 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
FSP_FILE_NODE *FileNode = FileDesc->FileNode;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
||||||
|
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
|
||||||
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
|
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
|
||||||
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
||||||
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
||||||
FSP_FILE_NODE *FileNode = FileDesc->FileNode;
|
UINT64 DirectoryMarkerAsNextOffset = 0;
|
||||||
|
|
||||||
FSP_FSCTL_STATIC_ASSERT(
|
FSP_FSCTL_STATIC_ASSERT(
|
||||||
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) >=
|
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) >=
|
||||||
@ -378,8 +414,10 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
|
|||||||
|
|
||||||
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
|
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
|
||||||
0, &DirectoryMarker,
|
0, &DirectoryMarker,
|
||||||
|
FsvolDeviceExtension->VolumeParams.DirectoryMarkerAsNextOffset ?
|
||||||
|
&DirectoryMarkerAsNextOffset : 0,
|
||||||
FileInformationClass, ReturnSingleEntry,
|
FileInformationClass, ReturnSingleEntry,
|
||||||
!!FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes,
|
!!FsvolDeviceExtension->VolumeParams.ExtendedAttributes,
|
||||||
&DirInfo, DirInfoSize,
|
&DirInfo, DirInfoSize,
|
||||||
DestBuf, PDestLen);
|
DestBuf, PDestLen);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user