mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
dll: fuse: implementation checkpoint
This commit is contained in:
parent
afc498ba6e
commit
9d42c625cc
@ -141,10 +141,10 @@ VOID fsp_fuse_finalize_thread(VOID)
|
|||||||
context = TlsGetValue(fsp_fuse_tlskey);
|
context = TlsGetValue(fsp_fuse_tlskey);
|
||||||
if (0 != context)
|
if (0 != context)
|
||||||
{
|
{
|
||||||
struct fsp_fuse_context_header *context_header =
|
struct fsp_fuse_context_header *contexthdr =
|
||||||
(PVOID)((PUINT8)context - sizeof *context_header);
|
(PVOID)((PUINT8)context - sizeof *contexthdr);
|
||||||
|
|
||||||
MemFree(context_header);
|
MemFree(contexthdr);
|
||||||
TlsSetValue(fsp_fuse_tlskey, 0);
|
TlsSetValue(fsp_fuse_tlskey, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,7 +256,8 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
}
|
}
|
||||||
context->fuse = f;
|
context->fuse = f;
|
||||||
context->private_data = f->data;
|
context->private_data = f->data;
|
||||||
context->uid = context->gid = -1;
|
context->uid = -1;
|
||||||
|
context->gid = -1;
|
||||||
|
|
||||||
memset(&conn, 0, sizeof conn);
|
memset(&conn, 0, sizeof conn);
|
||||||
conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */
|
conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */
|
||||||
@ -613,14 +614,14 @@ FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *rese
|
|||||||
context = TlsGetValue(fsp_fuse_tlskey);
|
context = TlsGetValue(fsp_fuse_tlskey);
|
||||||
if (0 == context)
|
if (0 == context)
|
||||||
{
|
{
|
||||||
struct fsp_fuse_context_header *context_header;
|
struct fsp_fuse_context_header *contexthdr;
|
||||||
|
|
||||||
context_header = MemAlloc(sizeof *context_header + sizeof *context);
|
contexthdr = MemAlloc(sizeof *contexthdr + sizeof *context);
|
||||||
if (0 == context_header)
|
if (0 == contexthdr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(context_header, 0, sizeof *context_header + sizeof *context);
|
memset(contexthdr, 0, sizeof *contexthdr + sizeof *context);
|
||||||
context = (PVOID)context_header->ContextBuf;
|
context = (PVOID)contexthdr->ContextBuf;
|
||||||
context->pid = -1;
|
context->pid = -1;
|
||||||
|
|
||||||
TlsSetValue(fsp_fuse_tlskey, context);
|
TlsSetValue(fsp_fuse_tlskey, context);
|
||||||
|
@ -21,7 +21,7 @@ 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)
|
||||||
{
|
{
|
||||||
struct fuse_context *context;
|
struct fuse_context *context;
|
||||||
struct fsp_fuse_context_header *context_header;
|
struct fsp_fuse_context_header *contexthdr;
|
||||||
char *PosixPath = 0;
|
char *PosixPath = 0;
|
||||||
UINT32 Uid = -1, Gid = -1;
|
UINT32 Uid = -1, Gid = -1;
|
||||||
PWSTR FileName = 0;
|
PWSTR FileName = 0;
|
||||||
@ -129,13 +129,14 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
context->fuse = FileSystem->UserContext;
|
context->fuse = FileSystem->UserContext;
|
||||||
|
context->private_data = context->fuse->data;
|
||||||
context->uid = Uid;
|
context->uid = Uid;
|
||||||
context->gid = Gid;
|
context->gid = Gid;
|
||||||
|
|
||||||
context_header = (PVOID)((PUINT8)context - sizeof *context_header);
|
contexthdr = (PVOID)((PUINT8)context - sizeof *contexthdr);
|
||||||
context_header->Request = Request;
|
contexthdr->Request = Request;
|
||||||
context_header->Response = Response;
|
contexthdr->Response = Response;
|
||||||
context_header->PosixPath = PosixPath;
|
contexthdr->PosixPath = PosixPath;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
@ -156,19 +157,18 @@ NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
struct fuse_context *context;
|
struct fuse_context *context;
|
||||||
struct fsp_fuse_context_header *context_header;
|
struct fsp_fuse_context_header *contexthdr;
|
||||||
|
|
||||||
context = fsp_fuse_get_context(0);
|
context = fsp_fuse_get_context(0);
|
||||||
context->fuse = 0;
|
context->fuse = 0;
|
||||||
|
context->private_data = 0;
|
||||||
context->uid = -1;
|
context->uid = -1;
|
||||||
context->gid = -1;
|
context->gid = -1;
|
||||||
|
|
||||||
context_header = (PVOID)((PUINT8)context - sizeof *context_header);
|
contexthdr = (PVOID)((PUINT8)context - sizeof *contexthdr);
|
||||||
if (0 != context_header->PosixPath)
|
if (0 != contexthdr->PosixPath)
|
||||||
FspPosixDeletePath(context_header->PosixPath);
|
FspPosixDeletePath(contexthdr->PosixPath);
|
||||||
context_header->Request = 0;
|
memset(contexthdr, 0, sizeof *contexthdr);
|
||||||
context_header->Response = 0;
|
|
||||||
context_header->PosixPath = 0;
|
|
||||||
|
|
||||||
FspFileSystemOpLeave(FileSystem, Request, Response);
|
FspFileSystemOpLeave(FileSystem, Request, Response);
|
||||||
|
|
||||||
@ -190,41 +190,74 @@ static NTSTATUS fsp_fuse_intf_SetVolumeLabel(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fsp_fuse_intf_GetFileInfoByPath(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
const char *PosixPath,
|
||||||
|
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode,
|
||||||
|
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
|
{
|
||||||
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
UINT64 AllocationUnit;
|
||||||
|
struct fuse_stat stbuf;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (0 == f->ops.getattr)
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
|
err = f->ops.getattr(PosixPath, (void *)&stbuf);
|
||||||
|
if (0 != err)
|
||||||
|
return fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
|
||||||
|
*PUid = stbuf.st_uid;
|
||||||
|
*PGid = stbuf.st_gid;
|
||||||
|
*PMode = stbuf.st_mode;
|
||||||
|
|
||||||
|
AllocationUnit = f->VolumeParams.SectorSize * f->VolumeParams.SectorsPerAllocationUnit;
|
||||||
|
FileInfo->FileAttributes = (stbuf.st_mode & 0040000) ? FILE_ATTRIBUTE_DIRECTORY : 0;
|
||||||
|
FileInfo->ReparseTag = 0;
|
||||||
|
FileInfo->AllocationSize =
|
||||||
|
(stbuf.st_size + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
||||||
|
FileInfo->FileSize = stbuf.st_size;
|
||||||
|
FileInfo->CreationTime =
|
||||||
|
Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 +
|
||||||
|
stbuf.st_birthtim.tv_nsec / 100;
|
||||||
|
FileInfo->LastAccessTime =
|
||||||
|
Int32x32To64(stbuf.st_atim.tv_sec, 10000000) + 116444736000000000 +
|
||||||
|
stbuf.st_atim.tv_nsec / 100;
|
||||||
|
FileInfo->LastWriteTime =
|
||||||
|
Int32x32To64(stbuf.st_mtim.tv_sec, 10000000) + 116444736000000000 +
|
||||||
|
stbuf.st_mtim.tv_nsec / 100;
|
||||||
|
FileInfo->ChangeTime =
|
||||||
|
Int32x32To64(stbuf.st_ctim.tv_sec, 10000000) + 116444736000000000 +
|
||||||
|
stbuf.st_ctim.tv_nsec / 100;
|
||||||
|
FileInfo->IndexNumber = stbuf.st_ino;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PWSTR FileName, PUINT32 PFileAttributes,
|
PWSTR FileName, PUINT32 PFileAttributes,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptorBuf, SIZE_T *PSecurityDescriptorSize)
|
PSECURITY_DESCRIPTOR SecurityDescriptorBuf, SIZE_T *PSecurityDescriptorSize)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
char *PosixPath = 0;
|
char *PosixPath = 0;
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
SIZE_T SecurityDescriptorSize;
|
SIZE_T SecurityDescriptorSize;
|
||||||
struct fuse_stat stbuf;
|
|
||||||
int err;
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == f->ops.getattr)
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
Result = FspPosixMapWindowsToPosixPath(FileName, &PosixPath);
|
Result = FspPosixMapWindowsToPosixPath(FileName, &PosixPath);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
memset(&stbuf, 0, sizeof stbuf);
|
Result = fsp_fuse_intf_GetFileInfoByPath(FileSystem, PosixPath, &Uid, &Gid, &Mode, &FileInfo);
|
||||||
err = f->ops.getattr(PosixPath, (void *)&stbuf);
|
if (!NT_SUCCESS(Result))
|
||||||
if (0 != err)
|
|
||||||
{
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != PFileAttributes)
|
|
||||||
*PFileAttributes = (stbuf.st_mode & 0040000) ?
|
|
||||||
FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
|
|
||||||
|
|
||||||
if (0 != PSecurityDescriptorSize)
|
if (0 != PSecurityDescriptorSize)
|
||||||
{
|
{
|
||||||
Result = FspPosixMapPermissionsToSecurityDescriptor(
|
Result = FspPosixMapPermissionsToSecurityDescriptor(Uid, Gid, Mode, &SecurityDescriptor);
|
||||||
stbuf.st_uid, stbuf.st_gid, stbuf.st_mode, &SecurityDescriptor);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
@ -242,6 +275,9 @@ static NTSTATUS fsp_fuse_intf_GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
memcpy(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize);
|
memcpy(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 != PFileAttributes)
|
||||||
|
*PFileAttributes = FileInfo.FileAttributes;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@ -269,7 +305,66 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PWSTR FileName, BOOLEAN CaseSensitive, UINT32 CreateOptions,
|
PWSTR FileName, BOOLEAN CaseSensitive, UINT32 CreateOptions,
|
||||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
struct fsp_fuse_context_header *contexthdr = fsp_fuse_context_header();
|
||||||
|
struct fsp_fuse_file_desc *filedesc;
|
||||||
|
struct fuse_file_info fi;
|
||||||
|
int err;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
filedesc = MemAlloc(sizeof *filedesc);
|
||||||
|
if (0 == filedesc)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
memset(&fi, 0, sizeof fi);
|
||||||
|
fi.flags = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (contexthdr->FileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
if (0 != f->ops.opendir)
|
||||||
|
{
|
||||||
|
err = f->ops.opendir(contexthdr->PosixPath, &fi);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (0 != f->ops.open)
|
||||||
|
{
|
||||||
|
err = f->ops.open(contexthdr->PosixPath, &fi);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache
|
||||||
|
* WinFsp does not currently support disabling the cache manager
|
||||||
|
* for an individual file although it should not be hard to add
|
||||||
|
* if required.
|
||||||
|
*
|
||||||
|
* Ignore fuse_file_info::nonseekable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
*PFileNode = 0;
|
||||||
|
//memcpy(FileInfo, &contexthdr->FileInfo, sizeof *FileInfo);
|
||||||
|
|
||||||
|
filedesc->PosixPath = contexthdr->PosixPath;
|
||||||
|
filedesc->FileHandle = fi.fh;
|
||||||
|
contexthdr->PosixPath = 0;
|
||||||
|
contexthdr->Response->Rsp.Create.Opened.UserContext2 = (UINT64)(UINT_PTR)filedesc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MemFree(filedesc);
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
@ -45,6 +45,19 @@ struct fsp_fuse_context_header
|
|||||||
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ContextBuf[];
|
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ContextBuf[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fsp_fuse_file_desc
|
||||||
|
{
|
||||||
|
char *PosixPath;
|
||||||
|
UINT64 FileHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline
|
||||||
|
struct fsp_fuse_context_header *fsp_fuse_context_header(VOID)
|
||||||
|
{
|
||||||
|
struct fuse_context *context = fsp_fuse_get_context(0);
|
||||||
|
return (PVOID)((PUINT8)context - sizeof(struct fsp_fuse_context_header));
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user