mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
dll: fsctl, fuse: preflight check
This commit is contained in:
parent
7fef1b87f6
commit
9b93c766c3
@ -422,6 +422,7 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
|||||||
FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle);
|
FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle);
|
||||||
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
||||||
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize);
|
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize);
|
||||||
|
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -193,6 +193,23 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
SIZE_T VolumeListSize;
|
||||||
|
|
||||||
|
Result = FspFsctlStartService();
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
VolumeListSize = 0;
|
||||||
|
Result = FspFsctlGetVolumeList(DevicePath, 0, &VolumeListSize);
|
||||||
|
if (!NT_SUCCESS(Result) && STATUS_BUFFER_TOO_SMALL != Result)
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsctlStartService(VOID)
|
static NTSTATUS FspFsctlStartService(VOID)
|
||||||
{
|
{
|
||||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
#include <dll/fuse/library.h>
|
#include <dll/fuse/library.h>
|
||||||
|
|
||||||
|
#define FSP_FUSE_SECTORSIZE_MIN 512
|
||||||
|
#define FSP_FUSE_SECTORSIZE_MAX 4096
|
||||||
|
|
||||||
struct fuse_chan
|
struct fuse_chan
|
||||||
{
|
{
|
||||||
PWSTR MountPoint;
|
PWSTR MountPoint;
|
||||||
@ -205,6 +208,36 @@ FSP_FUSE_API int fsp_fuse_is_lib_option(struct fsp_fuse_env *env,
|
|||||||
|
|
||||||
static void fsp_fuse_cleanup(struct fuse *f);
|
static void fsp_fuse_cleanup(struct fuse *f);
|
||||||
|
|
||||||
|
static NTSTATUS fsp_fuse_preflight(struct fuse *f)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFsctlPreflight(f->VolumeParams.Prefix[0] ?
|
||||||
|
L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
if (L'\0' != f->MountPoint)
|
||||||
|
{
|
||||||
|
if ((
|
||||||
|
(L'A' <= f->MountPoint[0] && f->MountPoint[0] <= L'Z') ||
|
||||||
|
(L'a' <= f->MountPoint[0] && f->MountPoint[0] <= L'z')
|
||||||
|
) &&
|
||||||
|
L':' == f->MountPoint[1] || L'\0' == f->MountPoint[2])
|
||||||
|
{
|
||||||
|
if (GetLogicalDrives() & (1 << (f->MountPoint[0] - 'A')))
|
||||||
|
return STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (L'*' == f->MountPoint[0] && L'\0' == f->MountPoint[1])
|
||||||
|
;
|
||||||
|
else
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
||||||
{
|
{
|
||||||
static FSP_FILE_SYSTEM_INTERFACE intf =
|
static FSP_FILE_SYSTEM_INTERFACE intf =
|
||||||
@ -247,10 +280,13 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
struct fuse_statvfs stbuf;
|
struct fuse_statvfs stbuf;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
err = f->ops.statfs("/", &stbuf);
|
err = f->ops.statfs("/", &stbuf);
|
||||||
if (0 != err)
|
if (0 != err)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (stbuf.f_bsize > FSP_FUSE_SECTORSIZE_MAX)
|
||||||
|
stbuf.f_bsize = FSP_FUSE_SECTORSIZE_MAX;
|
||||||
if (0 == f->VolumeParams.SectorSize)
|
if (0 == f->VolumeParams.SectorSize)
|
||||||
f->VolumeParams.SectorSize = (UINT16)stbuf.f_bsize;
|
f->VolumeParams.SectorSize = (UINT16)stbuf.f_bsize;
|
||||||
if (0 == f->VolumeParams.MaxComponentLength)
|
if (0 == f->VolumeParams.MaxComponentLength)
|
||||||
@ -261,21 +297,30 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
struct fuse_stat stbuf;
|
struct fuse_stat stbuf;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
err = f->ops.getattr("/", (void *)&stbuf);
|
err = f->ops.getattr("/", (void *)&stbuf);
|
||||||
if (0 != err)
|
if (0 != err)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (0 == f->VolumeParams.VolumeCreationTime)
|
if (0 == f->VolumeParams.VolumeCreationTime)
|
||||||
|
{
|
||||||
|
if (0 != stbuf.st_birthtim.tv_sec)
|
||||||
f->VolumeParams.VolumeCreationTime =
|
f->VolumeParams.VolumeCreationTime =
|
||||||
Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 +
|
Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 +
|
||||||
stbuf.st_birthtim.tv_nsec / 100;
|
stbuf.st_birthtim.tv_nsec / 100;
|
||||||
|
else
|
||||||
|
if (0 != stbuf.st_ctim.tv_sec)
|
||||||
|
f->VolumeParams.VolumeCreationTime =
|
||||||
|
Int32x32To64(stbuf.st_ctim.tv_sec, 10000000) + 116444736000000000 +
|
||||||
|
stbuf.st_ctim.tv_nsec / 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the FSD does not currently limit these VolumeParams fields; do so here! */
|
/* the FSD does not currently limit these VolumeParams fields; do so here! */
|
||||||
if (f->VolumeParams.SectorSize < 512)
|
if (f->VolumeParams.SectorSize < FSP_FUSE_SECTORSIZE_MIN)
|
||||||
f->VolumeParams.SectorSize = 512;
|
f->VolumeParams.SectorSize = FSP_FUSE_SECTORSIZE_MIN;
|
||||||
if (f->VolumeParams.SectorSize < 4096)
|
if (f->VolumeParams.SectorSize > FSP_FUSE_SECTORSIZE_MAX)
|
||||||
f->VolumeParams.SectorSize = 4096;
|
f->VolumeParams.SectorSize = FSP_FUSE_SECTORSIZE_MAX;
|
||||||
if (f->VolumeParams.MaxComponentLength > 255)
|
if (f->VolumeParams.MaxComponentLength > 255)
|
||||||
f->VolumeParams.MaxComponentLength = 255;
|
f->VolumeParams.MaxComponentLength = 255;
|
||||||
|
|
||||||
@ -441,6 +486,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
|||||||
struct fuse *f = 0;
|
struct fuse *f = 0;
|
||||||
struct fsp_fuse_core_opt_data opt_data;
|
struct fsp_fuse_core_opt_data opt_data;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
|
PWSTR ErrorMessage = L".";
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (opsize > sizeof(struct fuse_operations))
|
if (opsize > sizeof(struct fuse_operations))
|
||||||
@ -485,11 +531,41 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
|||||||
FspServiceAllowConsoleMode(f->Service);
|
FspServiceAllowConsoleMode(f->Service);
|
||||||
f->Service->UserContext = f;
|
f->Service->UserContext = f;
|
||||||
|
|
||||||
|
Result = fsp_fuse_preflight(f);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
switch (Result)
|
||||||
|
{
|
||||||
|
case STATUS_ACCESS_DENIED:
|
||||||
|
ErrorMessage = L": Access denied.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATUS_NO_SUCH_DEVICE:
|
||||||
|
ErrorMessage = L": FSD not found.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATUS_OBJECT_NAME_INVALID:
|
||||||
|
ErrorMessage = L": invalid mount point.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATUS_OBJECT_NAME_COLLISION:
|
||||||
|
ErrorMessage = L": mount point in use.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ErrorMessage = L": unspecified error.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
||||||
L"Cannot create " FSP_FUSE_LIBRARY_NAME " file system.");
|
L"Cannot create " FSP_FUSE_LIBRARY_NAME " file system%s",
|
||||||
|
ErrorMessage);
|
||||||
|
|
||||||
if (0 != f)
|
if (0 != f)
|
||||||
fsp_fuse_destroy(env, f);
|
fsp_fuse_destroy(env, f);
|
||||||
@ -500,8 +576,7 @@ fail:
|
|||||||
FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env,
|
FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env,
|
||||||
struct fuse *f)
|
struct fuse *f)
|
||||||
{
|
{
|
||||||
if (0 != f->FileSystem)
|
fsp_fuse_cleanup(f);
|
||||||
FspFileSystemDelete(f->FileSystem);
|
|
||||||
|
|
||||||
if (0 != f->Service)
|
if (0 != f->Service)
|
||||||
FspServiceDelete(f->Service);
|
FspServiceDelete(f->Service);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user