mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
dll: fuse: reimplement ReadDirectory
This commit is contained in:
parent
41605a3d5a
commit
f97ef5704f
@ -1403,6 +1403,8 @@ NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPat
|
|||||||
return FspPosixMapPosixToWindowsPathEx(PosixPath, PWindowsPath, TRUE);
|
return FspPosixMapPosixToWindowsPathEx(PosixPath, PWindowsPath, TRUE);
|
||||||
}
|
}
|
||||||
FSP_API VOID FspPosixDeletePath(void *Path);
|
FSP_API VOID FspPosixDeletePath(void *Path);
|
||||||
|
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size);
|
||||||
|
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Path Handling
|
* Path Handling
|
||||||
|
@ -390,3 +390,15 @@ FSP_API VOID FspFileSystemDeleteDirectoryBuffer(PVOID *PDirBuffer)
|
|||||||
*PDirBuffer = 0;
|
*PDirBuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||||
|
PUINT8 *PBuffer, PULONG *PIndex, PULONG PCount)
|
||||||
|
{
|
||||||
|
/* assume that FspFileSystemAcquireDirectoryBuffer has been called */
|
||||||
|
|
||||||
|
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer;
|
||||||
|
|
||||||
|
*PBuffer = DirBuffer->Buffer;
|
||||||
|
*PIndex = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark);
|
||||||
|
*PCount = (DirBuffer->Capacity - DirBuffer->HiMark) / sizeof(ULONG);
|
||||||
|
}
|
||||||
|
@ -882,7 +882,6 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
filedesc->OpenFlags = fi.flags;
|
filedesc->OpenFlags = fi.flags;
|
||||||
filedesc->FileHandle = fi.fh;
|
filedesc->FileHandle = fi.fh;
|
||||||
filedesc->DirBuffer = 0;
|
filedesc->DirBuffer = 0;
|
||||||
filedesc->DirBufferSize = 0;
|
|
||||||
contexthdr->PosixPath = 0;
|
contexthdr->PosixPath = 0;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
@ -1000,7 +999,6 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
filedesc->OpenFlags = fi.flags;
|
filedesc->OpenFlags = fi.flags;
|
||||||
filedesc->FileHandle = fi.fh;
|
filedesc->FileHandle = fi.fh;
|
||||||
filedesc->DirBuffer = 0;
|
filedesc->DirBuffer = 0;
|
||||||
filedesc->DirBufferSize = 0;
|
|
||||||
contexthdr->PosixPath = 0;
|
contexthdr->PosixPath = 0;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
@ -1113,7 +1111,7 @@ static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
f->ops.release(filedesc->PosixPath, &fi);
|
f->ops.release(filedesc->PosixPath, &fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemFree(filedesc->DirBuffer);
|
FspFileSystemDeleteDirectoryBuffer(&filedesc->DirBuffer);
|
||||||
MemFree(filedesc->PosixPath);
|
MemFree(filedesc->PosixPath);
|
||||||
MemFree(filedesc);
|
MemFree(filedesc);
|
||||||
}
|
}
|
||||||
@ -1603,186 +1601,92 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
|
static int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
|
||||||
const struct fuse_stat *stbuf, fuse_off_t off)
|
const struct fuse_stat *stbuf, fuse_off_t off)
|
||||||
{
|
{
|
||||||
struct fuse_dirhandle *dh = buf;
|
struct fuse_dirhandle *dh = buf;
|
||||||
struct fsp_fuse_dirinfo *di;
|
struct fsp_fuse_file_desc *filedesc = dh->filedesc;
|
||||||
ULONG len, xfersize;
|
|
||||||
|
|
||||||
len = lstrlenA(name);
|
|
||||||
if (len > 255)
|
|
||||||
len = 255;
|
|
||||||
|
|
||||||
di = (PVOID)((PUINT8)dh->Buffer + dh->BytesTransferred);
|
|
||||||
xfersize = FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(struct fsp_fuse_dirinfo) + len + 1);
|
|
||||||
|
|
||||||
if ((PUINT8)di + xfersize > (PUINT8)dh->Buffer + dh->Length)
|
|
||||||
{
|
|
||||||
PVOID Buffer;
|
|
||||||
ULONG Length = dh->Length;
|
|
||||||
|
|
||||||
if (0 == Length)
|
|
||||||
Length = 16 * 1024;
|
|
||||||
else if (Length < 16 * 1024 * 1024)
|
|
||||||
Length *= 2;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
Buffer = MemAlloc(Length);
|
|
||||||
if (0 == Buffer)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
memcpy(Buffer, dh->Buffer, dh->BytesTransferred);
|
|
||||||
MemFree(dh->Buffer);
|
|
||||||
|
|
||||||
dh->Buffer = Buffer;
|
|
||||||
dh->Length = Length;
|
|
||||||
|
|
||||||
di = (PVOID)((PUINT8)dh->Buffer + dh->BytesTransferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
dh->BytesTransferred += xfersize;
|
|
||||||
dh->NonZeroOffset = dh->NonZeroOffset || 0 != off;
|
|
||||||
|
|
||||||
di->Size = (UINT16)(sizeof(struct fsp_fuse_dirinfo) + len + 1);
|
|
||||||
di->FileInfoValid = FALSE;
|
|
||||||
di->NextOffset = 0 != off ? off : dh->BytesTransferred;
|
|
||||||
memcpy(di->PosixNameBuf, name, len);
|
|
||||||
di->PosixNameBuf[len] = '\0';
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fsp_fuse_intf_AddDirInfoOld(fuse_dirh_t dh, const char *name,
|
|
||||||
int type, fuse_ino_t ino)
|
|
||||||
{
|
|
||||||
return fsp_fuse_intf_AddDirInfo(dh, name, 0, 0) ? -ENOMEM : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
PVOID FileContext, PWSTR Pattern, PWSTR Marker,
|
|
||||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
|
||||||
{
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
#if 0
|
|
||||||
struct fuse *f = FileSystem->UserContext;
|
|
||||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
|
||||||
struct fuse_file_info fi;
|
|
||||||
struct fuse_dirhandle dh;
|
|
||||||
struct fsp_fuse_dirinfo *di;
|
|
||||||
PUINT8 diend;
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
FSP_FSCTL_DIR_INFO V;
|
FSP_FSCTL_DIR_INFO V;
|
||||||
UINT8 B[sizeof(FSP_FSCTL_DIR_INFO) + 255 * sizeof(WCHAR)];
|
UINT8 B[sizeof(FSP_FSCTL_DIR_INFO) + 255 * sizeof(WCHAR)];
|
||||||
} DirInfoBuf;
|
} DirInfoBuf;
|
||||||
FSP_FSCTL_DIR_INFO *DirInfo = &DirInfoBuf.V;
|
FSP_FSCTL_DIR_INFO *DirInfo = &DirInfoBuf.V;
|
||||||
UINT32 Uid, Gid, Mode;
|
ULONG SizeA, SizeW;
|
||||||
char *PosixPath = 0, *PosixName, *PosixPathEnd, SavedPathChar;
|
|
||||||
PWSTR FileName = 0;
|
|
||||||
ULONG Size;
|
|
||||||
int err;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
if (!filedesc->IsDirectory)
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
memset(&dh, 0, sizeof dh);
|
|
||||||
|
|
||||||
if (0 == filedesc->DirBuffer)
|
|
||||||
{
|
|
||||||
if (0 != f->ops.readdir)
|
|
||||||
{
|
|
||||||
memset(&fi, 0, sizeof fi);
|
|
||||||
fi.flags = filedesc->OpenFlags;
|
|
||||||
fi.fh = filedesc->FileHandle;
|
|
||||||
|
|
||||||
err = f->ops.readdir(filedesc->PosixPath, &dh, fsp_fuse_intf_AddDirInfo, Offset, &fi);
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
}
|
|
||||||
else if (0 != f->ops.getdir)
|
|
||||||
{
|
|
||||||
err = f->ops.getdir(filedesc->PosixPath, &dh, fsp_fuse_intf_AddDirInfoOld);
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Result = STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (0 == dh.BytesTransferred)
|
|
||||||
{
|
|
||||||
/* EOF */
|
|
||||||
*PBytesTransferred = 0;
|
|
||||||
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
|
|
||||||
goto success;
|
|
||||||
}
|
|
||||||
else if (dh.NonZeroOffset)
|
|
||||||
{
|
|
||||||
di = (PVOID)((PUINT8)dh.Buffer + 0);
|
|
||||||
diend = (PUINT8)dh.Buffer + dh.BytesTransferred;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
di = (PVOID)((PUINT8)dh.Buffer + Offset);
|
|
||||||
diend = (PUINT8)dh.Buffer + dh.BytesTransferred;
|
|
||||||
filedesc->DirBuffer = dh.Buffer;
|
|
||||||
filedesc->DirBufferSize = dh.BytesTransferred;
|
|
||||||
dh.Buffer = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
di = (PVOID)((PUINT8)filedesc->DirBuffer + Offset);
|
|
||||||
diend = (PUINT8)filedesc->DirBuffer + filedesc->DirBufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;
|
|
||||||
(PUINT8)di + sizeof(di->Size) <= diend;
|
|
||||||
di = (PVOID)((PUINT8)di + FSP_FSCTL_DEFAULT_ALIGN_UP(di->Size)))
|
|
||||||
{
|
|
||||||
if (sizeof(struct fsp_fuse_dirinfo) > di->Size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ('/' == filedesc->PosixPath[0] && '\0' == filedesc->PosixPath[1])
|
if ('/' == filedesc->PosixPath[0] && '\0' == filedesc->PosixPath[1])
|
||||||
{
|
{
|
||||||
/* if this is the root directory do not add the dot entries */
|
/* if this is the root directory do not add the dot entries */
|
||||||
|
|
||||||
if ('.' == di->PosixNameBuf[0] && ('\0' == di->PosixNameBuf[1] ||
|
if ('.' == name[0] && ('\0' == name[1] ||
|
||||||
('.' == di->PosixNameBuf[1] && '\0' == di->PosixNameBuf[2])))
|
('.' == name[1] && '\0' == name[2])))
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!di->FileInfoValid)
|
SizeA = lstrlenA(name);
|
||||||
{
|
if (SizeA > 255)
|
||||||
if (0 == PosixPath)
|
/* ignore bad filenames; should we return error code? */
|
||||||
{
|
return 0;
|
||||||
Size = lstrlenA(filedesc->PosixPath);
|
|
||||||
PosixPath = MemAlloc(Size + 1 + 255 + 1);
|
SizeW = MultiByteToWideChar(CP_UTF8, 0, name, SizeA, DirInfo->FileNameBuf, 255);
|
||||||
|
if (0 == SizeW)
|
||||||
|
/* ignore bad filenames; should we return error code? */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(DirInfo, 0, sizeof *DirInfo);
|
||||||
|
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + SizeW * sizeof(WCHAR));
|
||||||
|
|
||||||
|
return !FspFileSystemFillDirectoryBuffer(&filedesc->DirBuffer, DirInfo, &dh->Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fsp_fuse_intf_AddDirInfoOld(fuse_dirh_t dh, const char *name,
|
||||||
|
int type, fuse_ino_t ino)
|
||||||
|
{
|
||||||
|
return fsp_fuse_intf_AddDirInfo(dh, name, 0, 0) ? -ENOMEM : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fsp_fuse_intf_FixDirInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
struct fsp_fuse_file_desc *filedesc)
|
||||||
|
{
|
||||||
|
char *PosixPath = 0, *PosixName, *PosixPathEnd, SavedPathChar;
|
||||||
|
ULONG SizeA, SizeW;
|
||||||
|
PUINT8 Buffer;
|
||||||
|
PULONG Index, IndexEnd;
|
||||||
|
ULONG Count;
|
||||||
|
FSP_FSCTL_DIR_INFO *DirInfo;
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
SizeA = lstrlenA(filedesc->PosixPath);
|
||||||
|
PosixPath = MemAlloc(SizeA + 1 + 255 + 1);
|
||||||
if (0 == PosixPath)
|
if (0 == PosixPath)
|
||||||
{
|
{
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(PosixPath, filedesc->PosixPath, Size);
|
memcpy(PosixPath, filedesc->PosixPath, SizeA);
|
||||||
if (1 < Size)
|
if (1 < SizeA)
|
||||||
/* if not root */
|
/* if not root */
|
||||||
PosixPath[Size++] = '/';
|
PosixPath[SizeA++] = '/';
|
||||||
PosixPath[Size] = '\0';
|
PosixPath[SizeA] = '\0';
|
||||||
PosixName = PosixPath + Size;
|
PosixName = PosixPath + SizeA;
|
||||||
}
|
|
||||||
|
|
||||||
if ('.' == di->PosixNameBuf[0] && '\0' == di->PosixNameBuf[1])
|
FspFileSystemPeekInDirectoryBuffer(&filedesc->DirBuffer, &Buffer, &Index, &Count);
|
||||||
|
|
||||||
|
for (IndexEnd = Index + Count; IndexEnd > Index; Index++)
|
||||||
|
{
|
||||||
|
DirInfo = (FSP_FSCTL_DIR_INFO *)(Buffer + *Index);
|
||||||
|
SizeW = (DirInfo->Size - sizeof *DirInfo) / sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (1 == SizeW && L'.' == DirInfo->FileNameBuf[0])
|
||||||
{
|
{
|
||||||
PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 1 : PosixName;
|
PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 1 : PosixName;
|
||||||
SavedPathChar = *PosixPathEnd;
|
SavedPathChar = *PosixPathEnd;
|
||||||
*PosixPathEnd = '\0';
|
*PosixPathEnd = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ('.' == di->PosixNameBuf[0] && '.' == di->PosixNameBuf[1] && '\0' == di->PosixNameBuf[2])
|
if (2 == SizeW && L'.' == DirInfo->FileNameBuf[0] && L'.' == DirInfo->FileNameBuf[1])
|
||||||
{
|
{
|
||||||
PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 2 : PosixName;
|
PosixPathEnd = 1 < PosixName - PosixPath ? PosixName - 2 : PosixName;
|
||||||
while (PosixPath < PosixPathEnd && '/' != *PosixPathEnd)
|
while (PosixPath < PosixPathEnd && '/' != *PosixPathEnd)
|
||||||
@ -1795,57 +1699,86 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
PosixPathEnd = 0;
|
PosixPathEnd = 0;
|
||||||
Size = lstrlenA(di->PosixNameBuf);
|
SizeA = WideCharToMultiByte(CP_UTF8, 0, DirInfo->FileNameBuf, SizeW, PosixName, 255, 0, 0);
|
||||||
if (Size > 255)
|
if (0 == SizeA)
|
||||||
Size = 255;
|
{
|
||||||
memcpy(PosixName, di->PosixNameBuf, Size);
|
/* this should never happen because we just converted using MultiByteToWideChar */
|
||||||
PosixName[Size] = '\0';
|
Result = STATUS_OBJECT_NAME_INVALID;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
PosixName[SizeA] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, 0,
|
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, 0,
|
||||||
&Uid, &Gid, &Mode, &di->FileInfo);
|
&Uid, &Gid, &Mode, &DirInfo->FileInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (0 != PosixPathEnd)
|
if (0 != PosixPathEnd)
|
||||||
*PosixPathEnd = SavedPathChar;
|
*PosixPathEnd = SavedPathChar;
|
||||||
|
|
||||||
di->FileInfoValid = TRUE;
|
FspPosixDecodeWindowsPath(DirInfo->FileNameBuf, SizeW);
|
||||||
}
|
|
||||||
memcpy(&DirInfo->FileInfo, &di->FileInfo, sizeof di->FileInfo);
|
|
||||||
|
|
||||||
Result = FspPosixMapPosixToWindowsPath(di->PosixNameBuf, &FileName);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
Size = lstrlenW(FileName);
|
|
||||||
if (Size > 255)
|
|
||||||
Size = 255;
|
|
||||||
Size *= sizeof(WCHAR);
|
|
||||||
memcpy(DirInfo->FileNameBuf, FileName, Size);
|
|
||||||
|
|
||||||
FspPosixDeletePath(FileName);
|
|
||||||
|
|
||||||
memset(DirInfo->Padding, 0, sizeof DirInfo->Padding);
|
|
||||||
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + Size);
|
|
||||||
DirInfo->NextOffset = di->NextOffset;
|
|
||||||
|
|
||||||
if (!FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((PUINT8)di + sizeof(di->Size) > diend)
|
|
||||||
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
|
|
||||||
|
|
||||||
success:
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
MemFree(PosixPath);
|
MemFree(PosixPath);
|
||||||
MemFree(dh.Buffer);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileNode, PWSTR Pattern, PWSTR Marker,
|
||||||
|
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||||
|
struct fuse_dirhandle dh;
|
||||||
|
struct fuse_file_info fi;
|
||||||
|
int err;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (FspFileSystemAcquireDirectoryBuffer(&filedesc->DirBuffer, 0 == Marker, &Result))
|
||||||
|
{
|
||||||
|
memset(&dh, 0, sizeof dh);
|
||||||
|
dh.filedesc = filedesc;
|
||||||
|
dh.Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (0 != f->ops.readdir)
|
||||||
|
{
|
||||||
|
memset(&fi, 0, sizeof fi);
|
||||||
|
fi.flags = filedesc->OpenFlags;
|
||||||
|
fi.fh = filedesc->FileHandle;
|
||||||
|
|
||||||
|
err = f->ops.readdir(filedesc->PosixPath, &dh, fsp_fuse_intf_AddDirInfo, 0, &fi);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else if (0 != f->ops.getdir)
|
||||||
|
{
|
||||||
|
err = f->ops.getdir(filedesc->PosixPath, &dh, fsp_fuse_intf_AddDirInfoOld);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
Result = dh.Result;
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
Result = fsp_fuse_intf_FixDirInfo(FileSystem, filedesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFileSystemReleaseDirectoryBuffer(&filedesc->DirBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
FspFileSystemReadDirectoryBuffer(&filedesc->DirBuffer,
|
||||||
|
Marker, Buffer, Length, PBytesTransferred);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
@ -62,27 +62,15 @@ struct fsp_fuse_file_desc
|
|||||||
int OpenFlags;
|
int OpenFlags;
|
||||||
UINT64 FileHandle;
|
UINT64 FileHandle;
|
||||||
PVOID DirBuffer;
|
PVOID DirBuffer;
|
||||||
ULONG DirBufferSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fuse_dirhandle
|
struct fuse_dirhandle
|
||||||
{
|
{
|
||||||
PVOID Buffer;
|
struct fsp_fuse_file_desc *filedesc;
|
||||||
ULONG Length;
|
NTSTATUS Result;
|
||||||
ULONG BytesTransferred;
|
|
||||||
BOOLEAN NonZeroOffset;
|
|
||||||
BOOLEAN DotFiles, HasChild;
|
BOOLEAN DotFiles, HasChild;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fsp_fuse_dirinfo
|
|
||||||
{
|
|
||||||
UINT16 Size;
|
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
|
||||||
BOOLEAN FileInfoValid;
|
|
||||||
UINT64 NextOffset;
|
|
||||||
char PosixNameBuf[]; /* includes term-0 (unlike FSP_FSCTL_DIR_INFO) */
|
|
||||||
};
|
|
||||||
|
|
||||||
NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS fsp_fuse_op_enter(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 fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
@ -51,6 +51,9 @@ NTSTATUS FspEventLogUnregister(VOID);
|
|||||||
|
|
||||||
PWSTR FspDiagIdent(VOID);
|
PWSTR FspDiagIdent(VOID);
|
||||||
|
|
||||||
|
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||||
|
PUINT8 *PBuffer, PULONG *PIndex, PULONG PCount);
|
||||||
|
|
||||||
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
|
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
|
||||||
|
|
||||||
static inline ULONG FspPathSuffixIndex(PWSTR FileName)
|
static inline ULONG FspPathSuffixIndex(PWSTR FileName)
|
||||||
|
@ -923,3 +923,30 @@ FSP_API VOID FspPosixDeletePath(void *Path)
|
|||||||
{
|
{
|
||||||
MemFree(Path);
|
MemFree(Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
|
||||||
|
{
|
||||||
|
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
|
||||||
|
{
|
||||||
|
WCHAR c = *p;
|
||||||
|
|
||||||
|
if (L'\\' == c)
|
||||||
|
*p = L'/';
|
||||||
|
/* encode characters in the Unicode private use area: U+F0XX -> XX */
|
||||||
|
else if (0xf000 <= c && c <= 0xf0ff)
|
||||||
|
*p &= ~0xf000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size)
|
||||||
|
{
|
||||||
|
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
|
||||||
|
{
|
||||||
|
WCHAR c = *p;
|
||||||
|
|
||||||
|
if (L'/' == c)
|
||||||
|
*p = L'\\';
|
||||||
|
else if (128 > c && (FspPosixInvalidPathChars[c >> 5] & (0x80000000 >> (c & 0x1f))))
|
||||||
|
*p |= 0xf000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user