dll: fuse: implementation checkpoint

This commit is contained in:
Bill Zissimopoulos 2016-06-09 15:40:34 -07:00
parent afc498ba6e
commit 9d42c625cc
3 changed files with 148 additions and 39 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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,