mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
dll: fuseintf: ReadDirectory implementation
This commit is contained in:
parent
240bdfeb39
commit
009728e2b7
@ -718,13 +718,15 @@ struct fuse_dirhandle
|
|||||||
{
|
{
|
||||||
FSP_FILE_SYSTEM *FileSystem;
|
FSP_FILE_SYSTEM *FileSystem;
|
||||||
char *PosixPath, *PosixName;
|
char *PosixPath, *PosixName;
|
||||||
|
PVOID OriginalBuffer;
|
||||||
|
ULONG OriginalLength;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
ULONG BytesTransferred;
|
ULONG BytesTransferred;
|
||||||
};
|
};
|
||||||
|
|
||||||
int fsp_fuse_intf_AddDirInfoCommon(void *buf, const char *name,
|
int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
|
||||||
const struct fuse_stat *stbuf, fuse_off_t off, BOOLEAN GrowBuffer)
|
const struct fuse_stat *stbuf, fuse_off_t off)
|
||||||
{
|
{
|
||||||
struct fuse_dirhandle *dh = buf;
|
struct fuse_dirhandle *dh = buf;
|
||||||
UINT32 Uid, Gid, Mode;
|
UINT32 Uid, Gid, Mode;
|
||||||
@ -789,7 +791,33 @@ int fsp_fuse_intf_AddDirInfoCommon(void *buf, const char *name,
|
|||||||
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + Size);
|
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + Size);
|
||||||
DirInfo->NextOffset = off;
|
DirInfo->NextOffset = off;
|
||||||
|
|
||||||
if (GrowBuffer)
|
/*
|
||||||
|
* FUSE readdir documentation quote:
|
||||||
|
*
|
||||||
|
* The filesystem may choose between two modes of operation:
|
||||||
|
*
|
||||||
|
* 1) The readdir implementation ignores the offset parameter, and
|
||||||
|
* passes zero to the filler function's offset. The filler
|
||||||
|
* function will not return '1' (unless an error happens), so the
|
||||||
|
* whole directory is read in a single readdir operation. This
|
||||||
|
* works just like the old getdir() method.
|
||||||
|
*
|
||||||
|
* 2) The readdir implementation keeps track of the offsets of the
|
||||||
|
* directory entries. It uses the offset parameter and always
|
||||||
|
* passes non-zero offset to the filler function. When the buffer
|
||||||
|
* is full (or an error happens) the filler function will return
|
||||||
|
* '1'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (0 != off)
|
||||||
|
{
|
||||||
|
if (0 == dh->Buffer)
|
||||||
|
{
|
||||||
|
dh->Buffer = dh->OriginalBuffer;
|
||||||
|
dh->Length = dh->OriginalLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dh->OriginalBuffer != dh->Buffer)
|
||||||
{
|
{
|
||||||
DirInfo->NextOffset = dh->BytesTransferred + FSP_FSCTL_DEFAULT_ALIGN_UP(DirInfo->Size);
|
DirInfo->NextOffset = dh->BytesTransferred + FSP_FSCTL_DEFAULT_ALIGN_UP(DirInfo->Size);
|
||||||
|
|
||||||
@ -816,16 +844,10 @@ int fsp_fuse_intf_AddDirInfoCommon(void *buf, const char *name,
|
|||||||
return ! FspFileSystemAddDirInfo(DirInfo, dh->Buffer, dh->Length, &dh->BytesTransferred);
|
return ! FspFileSystemAddDirInfo(DirInfo, dh->Buffer, dh->Length, &dh->BytesTransferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
|
|
||||||
const struct fuse_stat *stbuf, fuse_off_t off)
|
|
||||||
{
|
|
||||||
return fsp_fuse_intf_AddDirInfoCommon(buf, name, stbuf, off, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fsp_fuse_intf_AddDirInfoOld(fuse_dirh_t dh, const char *name,
|
int fsp_fuse_intf_AddDirInfoOld(fuse_dirh_t dh, const char *name,
|
||||||
int type, fuse_ino_t ino)
|
int type, fuse_ino_t ino)
|
||||||
{
|
{
|
||||||
return fsp_fuse_intf_AddDirInfoCommon(dh, name, 0, 0, TRUE) ? -ENOMEM : 0;
|
return fsp_fuse_intf_AddDirInfo(dh, name, 0, 0) ? -ENOMEM : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||||
@ -863,6 +885,9 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
dh.PosixPath[Size++] = '/';
|
dh.PosixPath[Size++] = '/';
|
||||||
dh.PosixName = dh.PosixPath + Size;
|
dh.PosixName = dh.PosixPath + Size;
|
||||||
|
|
||||||
|
dh.OriginalBuffer = Buffer;
|
||||||
|
dh.OriginalLength = Length;
|
||||||
|
|
||||||
if (0 != f->ops.readdir)
|
if (0 != f->ops.readdir)
|
||||||
{
|
{
|
||||||
memset(&fi, 0, sizeof fi);
|
memset(&fi, 0, sizeof fi);
|
||||||
@ -885,8 +910,25 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
|
if (dh.OriginalBuffer == dh.Buffer)
|
||||||
|
{
|
||||||
|
*PBytesTransferred = dh.BytesTransferred;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == dh.Buffer)
|
||||||
|
{
|
||||||
|
*PBytesTransferred = dh.BytesTransferred;
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
filedesc->DirBuffer = dh.Buffer;
|
filedesc->DirBuffer = dh.Buffer;
|
||||||
filedesc->DirBufferSize = dh.BytesTransferred;
|
filedesc->DirBufferSize = dh.BytesTransferred;
|
||||||
|
/* fall through! */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user