mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
dll: fuseintf: Create implementation
This commit is contained in:
parent
bc777f2d91
commit
c74f34eaf0
@ -298,7 +298,145 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
||||||
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 fuse_context *context = fsp_fuse_get_context(0);
|
||||||
|
struct fsp_fuse_context_header *contexthdr =
|
||||||
|
(PVOID)((PUINT8)context - sizeof *contexthdr);
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
FSP_FSCTL_FILE_INFO FileInfoBuf;
|
||||||
|
struct fsp_fuse_file_desc *filedesc = 0;
|
||||||
|
struct fuse_file_info fi;
|
||||||
|
BOOLEAN Opened = FALSE;
|
||||||
|
int err;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
filedesc = MemAlloc(sizeof *filedesc);
|
||||||
|
if (0 == filedesc)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uid = context->uid;
|
||||||
|
Gid = context->gid;
|
||||||
|
Mode = 0777;
|
||||||
|
if (0 != SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = FspPosixMapSecurityDescriptorToPermissions(SecurityDescriptor,
|
||||||
|
&Uid, &Gid, &Mode);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
Mode &= ~context->umask;
|
||||||
|
|
||||||
|
memset(&fi, 0, sizeof fi);
|
||||||
|
|
||||||
|
if (CreateOptions & FILE_DIRECTORY_FILE)
|
||||||
|
{
|
||||||
|
if (0 != f->ops.mkdir)
|
||||||
|
{
|
||||||
|
err = f->ops.mkdir(contexthdr->PosixPath, Mode);
|
||||||
|
if (0 != err)
|
||||||
|
{
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.create)
|
||||||
|
{
|
||||||
|
err = f->ops.create(contexthdr->PosixPath, Mode, &fi);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else if (0 != f->ops.mknod && 0 != f->ops.open)
|
||||||
|
{
|
||||||
|
err = f->ops.mknod(contexthdr->PosixPath, Mode, 0);
|
||||||
|
if (0 != err)
|
||||||
|
{
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
fi.flags = O_RDWR;
|
||||||
|
err = f->ops.open(contexthdr->PosixPath, &fi);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Opened = TRUE;
|
||||||
|
|
||||||
|
if (Uid != context->uid || Gid != context->gid)
|
||||||
|
if (0 != f->ops.chown)
|
||||||
|
{
|
||||||
|
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
|
||||||
|
if (0 != err)
|
||||||
|
{
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Result = fsp_fuse_intf_GetFileInfoByPath(FileSystem, contexthdr->PosixPath,
|
||||||
|
&Uid, &Gid, &Mode, &FileInfoBuf);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
*PFileNode = 0;
|
||||||
|
memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf);
|
||||||
|
|
||||||
|
filedesc->PosixPath = contexthdr->PosixPath;
|
||||||
|
filedesc->IsDirectory = !!(FileInfoBuf.FileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
filedesc->OpenFlags = fi.flags;
|
||||||
|
filedesc->FileHandle = fi.fh;
|
||||||
|
contexthdr->PosixPath = 0;
|
||||||
|
contexthdr->Response->Rsp.Create.Opened.UserContext2 = (UINT64)(UINT_PTR)filedesc;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (Opened)
|
||||||
|
{
|
||||||
|
if (CreateOptions & FILE_DIRECTORY_FILE)
|
||||||
|
{
|
||||||
|
if (0 != f->ops.releasedir)
|
||||||
|
f->ops.releasedir(filedesc->PosixPath, &fi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (0 != f->ops.release)
|
||||||
|
f->ops.release(filedesc->PosixPath, &fi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MemFree(filedesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user