dll: FspFileSystemPreflight

This commit is contained in:
Bill Zissimopoulos 2017-01-16 14:54:10 -08:00
parent c6ae62f301
commit 7764663386
5 changed files with 120 additions and 34 deletions

View File

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

View File

@ -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.
* *

View File

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

View File

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

View File

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