mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-07 20:42:09 -05:00
dll: fuse: FSP_FUSE_CAP_DELETE_ACCESS
This commit is contained in:
parent
73359d682b
commit
52dd6f7478
@ -79,7 +79,7 @@ struct fuse_operations
|
|||||||
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
|
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
|
||||||
/* S */ void *(*init)(struct fuse_conn_info *conn);
|
/* S */ void *(*init)(struct fuse_conn_info *conn);
|
||||||
/* S */ void (*destroy)(void *data);
|
/* S */ void (*destroy)(void *data);
|
||||||
/* _ */ int (*access)(const char *path, int mask);
|
/* S */ int (*access)(const char *path, int mask);
|
||||||
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
|
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
|
||||||
/* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
|
/* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
/* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
|
/* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
|
||||||
|
@ -54,6 +54,7 @@ extern "C" {
|
|||||||
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
|
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
|
||||||
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
|
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
|
||||||
#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */
|
#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */
|
||||||
|
#define FSP_FUSE_CAP_DELETE_ACCESS (1 << 24) /* file system supports access with DELETE_OK */
|
||||||
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
|
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
|
||||||
|
|
||||||
#define FUSE_IOCTL_COMPAT (1 << 0)
|
#define FUSE_IOCTL_COMPAT (1 << 0)
|
||||||
@ -79,6 +80,9 @@ extern "C" {
|
|||||||
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
|
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* delete access */
|
||||||
|
#define FSP_FUSE_DELETE_OK 0x40000000
|
||||||
|
|
||||||
/* notify extension */
|
/* notify extension */
|
||||||
#define FSP_FUSE_NOTIFY_MKDIR 0x0001
|
#define FSP_FUSE_NOTIFY_MKDIR 0x0001
|
||||||
#define FSP_FUSE_NOTIFY_RMDIR 0x0002
|
#define FSP_FUSE_NOTIFY_RMDIR 0x0002
|
||||||
|
@ -991,6 +991,19 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
int err;
|
int err;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 != (CreateOptions & FILE_DELETE_ON_CLOSE) &&
|
||||||
|
0 != (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) && 0 != f->ops.access)
|
||||||
|
{
|
||||||
|
err = f->ops.access(contexthdr->PosixPath, FSP_FUSE_DELETE_OK);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
||||||
|
{
|
||||||
|
if (STATUS_ACCESS_DENIED == Result)
|
||||||
|
Result = STATUS_CANNOT_DELETE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, 0,
|
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, 0,
|
||||||
&Uid, &Gid, &Mode, &FileInfoBuf);
|
&Uid, &Gid, &Mode, &FileInfoBuf);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -1583,49 +1596,63 @@ static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
static NTSTATUS fsp_fuse_intf_Delete(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_Delete(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileDesc, PWSTR FileName, ULONG Flags)
|
PVOID FileDesc, PWSTR FileName, ULONG Flags)
|
||||||
{
|
{
|
||||||
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
struct fsp_fuse_file_desc *filedesc = FileDesc;
|
||||||
|
int err;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
switch (Flags)
|
switch (Flags)
|
||||||
{
|
{
|
||||||
case FILE_DISPOSITION_DO_NOT_DELETE:
|
case FILE_DISPOSITION_DO_NOT_DELETE:
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
case FILE_DISPOSITION_DELETE:
|
case FILE_DISPOSITION_DELETE:
|
||||||
return fsp_fuse_intf_CanDelete(FileSystem, FileDesc, FileName);
|
Result = STATUS_SUCCESS;
|
||||||
|
if (0 != (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) && 0 != f->ops.access)
|
||||||
|
{
|
||||||
|
err = f->ops.access(filedesc->PosixPath, FSP_FUSE_DELETE_OK);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (STATUS_INVALID_DEVICE_REQUEST == Result)
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
Result = fsp_fuse_intf_CanDelete(FileSystem, FileDesc, FileName);
|
||||||
|
|
||||||
|
/* when doing unlink/rmdir convert EPERM/EACCES to STATUS_CANNOT_DELETE */
|
||||||
|
if (STATUS_ACCESS_DENIED == Result)
|
||||||
|
Result = STATUS_CANNOT_DELETE;
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
|
||||||
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
|
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
|
||||||
case -1:
|
case -1:
|
||||||
|
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
if (0 != f->ops.rmdir)
|
||||||
struct fsp_fuse_file_desc *filedesc = FileDesc;
|
|
||||||
int err;
|
|
||||||
NTSTATUS Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
|
|
||||||
{
|
{
|
||||||
if (0 != f->ops.rmdir)
|
err = f->ops.rmdir(filedesc->PosixPath);
|
||||||
{
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
err = f->ops.rmdir(filedesc->PosixPath);
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Result = STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
if (0 != f->ops.unlink)
|
|
||||||
{
|
|
||||||
err = f->ops.unlink(filedesc->PosixPath);
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Result = STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* when doing unlink/rmdir convert EPERM/EACCES to STATUS_CANNOT_DELETE */
|
|
||||||
if (STATUS_ACCESS_DENIED == Result)
|
|
||||||
Result = STATUS_CANNOT_DELETE;
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (0 != f->ops.unlink)
|
||||||
|
{
|
||||||
|
err = f->ops.unlink(filedesc->PosixPath);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when doing unlink/rmdir convert EPERM/EACCES to STATUS_CANNOT_DELETE */
|
||||||
|
if (STATUS_ACCESS_DENIED == Result)
|
||||||
|
Result = STATUS_CANNOT_DELETE;
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -88,6 +88,7 @@ static NTSTATUS fsp_fuse_loop_start(struct fuse *f)
|
|||||||
FSP_FUSE_CAP_READDIR_PLUS |
|
FSP_FUSE_CAP_READDIR_PLUS |
|
||||||
FSP_FUSE_CAP_READ_ONLY |
|
FSP_FUSE_CAP_READ_ONLY |
|
||||||
FSP_FUSE_CAP_STAT_EX |
|
FSP_FUSE_CAP_STAT_EX |
|
||||||
|
FSP_FUSE_CAP_DELETE_ACCESS |
|
||||||
FSP_FUSE_CAP_CASE_INSENSITIVE;
|
FSP_FUSE_CAP_CASE_INSENSITIVE;
|
||||||
if (0 != f->ops.init)
|
if (0 != f->ops.init)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user