mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: FspFileSystemPreflight
This commit is contained in:
parent
c6ae62f301
commit
7764663386
@ -113,8 +113,8 @@
|
|||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\sys\driver.inf.in">
|
<CustomBuild Include="..\..\src\sys\driver.inf.in">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</None>
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -845,6 +845,20 @@ typedef struct _FSP_FILE_SYSTEM_OPERATION_CONTEXT
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
FSP_FSCTL_TRANSACT_RSP *Response;
|
FSP_FSCTL_TRANSACT_RSP *Response;
|
||||||
} FSP_FILE_SYSTEM_OPERATION_CONTEXT;
|
} FSP_FILE_SYSTEM_OPERATION_CONTEXT;
|
||||||
|
/**
|
||||||
|
* Check whether creating a file system object is possible.
|
||||||
|
*
|
||||||
|
* @param DevicePath
|
||||||
|
* The name of the control device for this file system. This must be either
|
||||||
|
* FSP_FSCTL_DISK_DEVICE_NAME or FSP_FSCTL_NET_DEVICE_NAME.
|
||||||
|
* @param MountPoint
|
||||||
|
* The mount point for the new file system. A value of NULL means that the file system should
|
||||||
|
* use the next available drive letter counting downwards from Z: as its mount point.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS or error code.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath,
|
||||||
|
PWSTR MountPoint);
|
||||||
/**
|
/**
|
||||||
* Create a file system object.
|
* Create a file system object.
|
||||||
*
|
*
|
||||||
|
37
src/dll/fs.c
37
src/dll/fs.c
@ -72,6 +72,43 @@ VOID FspFileSystemFinalize(BOOLEAN Dynamic)
|
|||||||
TlsFree(FspFileSystemTlsKey);
|
TlsFree(FspFileSystemTlsKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath,
|
||||||
|
PWSTR MountPoint)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
WCHAR TargetPath[MAX_PATH];
|
||||||
|
HANDLE DirHandle;
|
||||||
|
|
||||||
|
Result = FspFsctlPreflight(DevicePath);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
if (0 == MountPoint)
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FspPathIsDrive(MountPoint))
|
||||||
|
Result = QueryDosDeviceW(MountPoint, TargetPath, MAX_PATH) ?
|
||||||
|
STATUS_OBJECT_NAME_COLLISION : STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DirHandle = CreateFileW(MountPoint,
|
||||||
|
FILE_READ_ATTRIBUTES,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
0,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
||||||
|
0);
|
||||||
|
Result = INVALID_HANDLE_VALUE != DirHandle || ERROR_FILE_NOT_FOUND != GetLastError() ?
|
||||||
|
STATUS_OBJECT_NAME_COLLISION : STATUS_SUCCESS;
|
||||||
|
if (INVALID_HANDLE_VALUE != DirHandle)
|
||||||
|
CloseHandle(DirHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||||
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
||||||
const FSP_FILE_SYSTEM_INTERFACE *Interface,
|
const FSP_FILE_SYSTEM_INTERFACE *Interface,
|
||||||
|
@ -230,36 +230,6 @@ 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] & ~0x20) - '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)
|
||||||
{
|
{
|
||||||
struct fuse *f = Service->UserContext;
|
struct fuse *f = Service->UserContext;
|
||||||
@ -380,7 +350,7 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
FspFileSystemSetOperationGuardStrategy(f->FileSystem, f->OpGuardStrategy);
|
FspFileSystemSetOperationGuardStrategy(f->FileSystem, f->OpGuardStrategy);
|
||||||
FspFileSystemSetDebugLog(f->FileSystem, f->DebugLog);
|
FspFileSystemSetDebugLog(f->FileSystem, f->DebugLog);
|
||||||
|
|
||||||
if (L'\0' != f->MountPoint)
|
if (0 != f->MountPoint)
|
||||||
{
|
{
|
||||||
Result = FspFileSystemSetMountPoint(f->FileSystem,
|
Result = FspFileSystemSetMountPoint(f->FileSystem,
|
||||||
L'*' == f->MountPoint[0] && L'\0' == f->MountPoint[1] ? 0 : f->MountPoint);
|
L'*' == f->MountPoint[0] && L'\0' == f->MountPoint[1] ? 0 : f->MountPoint);
|
||||||
@ -548,7 +518,9 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
|||||||
goto fail;
|
goto fail;
|
||||||
memcpy(f->MountPoint, ch->MountPoint, Size);
|
memcpy(f->MountPoint, ch->MountPoint, Size);
|
||||||
|
|
||||||
Result = fsp_fuse_preflight(f);
|
Result = FspFileSystemPreflight(
|
||||||
|
f->VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME,
|
||||||
|
'*' != f->MountPoint[0] || '\0' != f->MountPoint[1] ? f->MountPoint : 0);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
switch (Result)
|
switch (Result)
|
||||||
|
@ -272,6 +272,68 @@ void mount_volume_transact_test(void)
|
|||||||
mount_volume_transact_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
mount_volume_transact_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mount_preflight_dotest(PWSTR DeviceName)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
WCHAR MountPoint[MAX_PATH];
|
||||||
|
WCHAR DirBuf[MAX_PATH];
|
||||||
|
DWORD Drives;
|
||||||
|
WCHAR Drive;
|
||||||
|
BOOL Success;
|
||||||
|
|
||||||
|
MountPoint[0] = L'C';
|
||||||
|
MountPoint[1] = L':';
|
||||||
|
MountPoint[2] = L'\0';
|
||||||
|
|
||||||
|
GetTestDirectory(DirBuf);
|
||||||
|
|
||||||
|
Drives = GetLogicalDrives();
|
||||||
|
ASSERT(0 != Drives);
|
||||||
|
|
||||||
|
Result = FspFileSystemPreflight(DeviceName, 0);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
|
||||||
|
for (Drive = 'Z'; 'A' <= Drive; Drive--)
|
||||||
|
if (0 == (Drives & (1 << (Drive - 'A'))))
|
||||||
|
break;
|
||||||
|
ASSERT('A' <= Drive);
|
||||||
|
|
||||||
|
MountPoint[0] = Drive;
|
||||||
|
Result = FspFileSystemPreflight(DeviceName, MountPoint);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
|
||||||
|
for (Drive = 'Z'; 'A' <= Drive; Drive--)
|
||||||
|
if (0 != (Drives & (1 << (Drive - 'A'))))
|
||||||
|
break;
|
||||||
|
ASSERT('A' <= Drive);
|
||||||
|
|
||||||
|
MountPoint[0] = Drive;
|
||||||
|
Result = FspFileSystemPreflight(DeviceName, MountPoint);
|
||||||
|
ASSERT(STATUS_OBJECT_NAME_COLLISION == Result);
|
||||||
|
|
||||||
|
StringCbPrintfW(MountPoint, sizeof MountPoint, L"%s\\dir1", DirBuf);
|
||||||
|
|
||||||
|
Result = FspFileSystemPreflight(DeviceName, MountPoint);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
|
||||||
|
Success = CreateDirectoryW(MountPoint, 0);
|
||||||
|
ASSERT(Success);
|
||||||
|
|
||||||
|
Result = FspFileSystemPreflight(DeviceName, MountPoint);
|
||||||
|
ASSERT(STATUS_OBJECT_NAME_COLLISION == Result);
|
||||||
|
|
||||||
|
Success = RemoveDirectoryW(MountPoint);
|
||||||
|
ASSERT(Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mount_preflight_test(void)
|
||||||
|
{
|
||||||
|
if (WinFspDiskTests)
|
||||||
|
mount_preflight_dotest(L"WinFsp.Disk");
|
||||||
|
if (WinFspNetTests)
|
||||||
|
mount_preflight_dotest(L"WinFsp.Net");
|
||||||
|
}
|
||||||
|
|
||||||
void mount_tests(void)
|
void mount_tests(void)
|
||||||
{
|
{
|
||||||
if (NtfsTests || OptOplock)
|
if (NtfsTests || OptOplock)
|
||||||
@ -282,4 +344,5 @@ void mount_tests(void)
|
|||||||
TEST_OPT(mount_create_volume_test);
|
TEST_OPT(mount_create_volume_test);
|
||||||
TEST_OPT(mount_volume_cancel_test);
|
TEST_OPT(mount_volume_cancel_test);
|
||||||
TEST_OPT(mount_volume_transact_test);
|
TEST_OPT(mount_volume_transact_test);
|
||||||
|
TEST_OPT(mount_preflight_test);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user