tst: winfsp-tests: add --fuse-external option

This commit is contained in:
Bill Zissimopoulos 2021-11-13 10:15:12 +00:00
parent d67a917c6f
commit ec3386c2b3
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
9 changed files with 136 additions and 29 deletions

View File

@ -1370,9 +1370,10 @@ void create_tests(void)
TEST(create_fileattr_test); TEST(create_fileattr_test);
TEST(create_readonlydir_test); TEST(create_readonlydir_test);
TEST(create_related_test); TEST(create_related_test);
TEST(create_allocation_test); if (!OptFuseExternal)
TEST(create_allocation_test);
TEST(create_sd_test); TEST(create_sd_test);
if (!OptNoTraverseToken && !OptShareName) if (!OptFuseExternal && !OptNoTraverseToken && !OptShareName)
TEST(create_notraverse_test); TEST(create_notraverse_test);
TEST(create_backup_test); TEST(create_backup_test);
TEST(create_restore_test); TEST(create_restore_test);

View File

@ -170,7 +170,11 @@ static NTSTATUS ea_check_ea_enumerate(
if (0 == strcmp(SingleEa->EaName, "BNAMETWO")) if (0 == strcmp(SingleEa->EaName, "BNAMETWO"))
{ {
ASSERT(FILE_NEED_EA == SingleEa->Flags); if (!OptFuseExternal)
{
/* FUSE has no concept of FILE_NEED_EA */
ASSERT(FILE_NEED_EA == SingleEa->Flags);
}
ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("BNAMETWO")); ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("BNAMETWO"));
ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("second")); ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("second"));
ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "second", SingleEa->EaValueLength)); ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "second", SingleEa->EaValueLength));
@ -720,12 +724,17 @@ static void ea_create_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
CloseHandle(FileHandle); CloseHandle(FileHandle);
Result = NtCreateFile(&FileHandle, if (!OptFuseExternal)
FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb, {
&LargeZero, FILE_ATTRIBUTE_NORMAL, 0, /* FUSE has no concept of FILE_NEED_EA */
FILE_OPEN, FILE_NO_EA_KNOWLEDGE,
0, 0); Result = NtCreateFile(&FileHandle,
ASSERT(STATUS_ACCESS_DENIED == Result); FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb,
&LargeZero, FILE_ATTRIBUTE_NORMAL, 0,
FILE_OPEN, FILE_NO_EA_KNOWLEDGE,
0, 0);
ASSERT(STATUS_ACCESS_DENIED == Result);
}
Result = NtCreateFile(&FileHandle, Result = NtCreateFile(&FileHandle,
FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb, FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb,

View File

@ -2213,10 +2213,11 @@ void query_winfsp_test(void)
void info_tests(void) void info_tests(void)
{ {
if (!OptShareName) if (!OptFuseExternal && !OptShareName)
TEST(getfileattr_test); TEST(getfileattr_test);
TEST(getfileinfo_test); TEST(getfileinfo_test);
TEST(getfileinfo_name_test); if (!OptFuseExternal)
TEST(getfileinfo_name_test);
TEST(setfileinfo_test); TEST(setfileinfo_test);
TEST(delete_test); TEST(delete_test);
TEST(delete_access_test); TEST(delete_access_test);

View File

@ -192,20 +192,25 @@ static void reparse_nfs_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, 0); 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle); ASSERT(INVALID_HANDLE_VALUE != Handle);
ReparseDataBuf.D.ReparseDataLength = 0; if (!OptFuseExternal)
{
/* FUSE cannot delete reparse points */
Success = DeviceIoControl(Handle, FSCTL_DELETE_REPARSE_POINT, ReparseDataBuf.D.ReparseDataLength = 0;
&ReparseDataBuf, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseDataBuf.D.ReparseDataLength,
0, 0,
&Bytes, 0);
ASSERT(Success);
Success = DeviceIoControl(Handle, FSCTL_GET_REPARSE_POINT, Success = DeviceIoControl(Handle, FSCTL_DELETE_REPARSE_POINT,
0, 0, &ReparseDataBuf, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseDataBuf.D.ReparseDataLength,
&ReparseDataBuf, sizeof ReparseDataBuf, 0, 0,
&Bytes, 0); &Bytes, 0);
ASSERT(!Success); ASSERT(Success);
ASSERT(ERROR_NOT_A_REPARSE_POINT == GetLastError());
Success = DeviceIoControl(Handle, FSCTL_GET_REPARSE_POINT,
0, 0,
&ReparseDataBuf, sizeof ReparseDataBuf,
&Bytes, 0);
ASSERT(!Success);
ASSERT(ERROR_NOT_A_REPARSE_POINT == GetLastError());
}
CloseHandle(Handle); CloseHandle(Handle);
@ -241,7 +246,7 @@ static void reparse_symlink_dotest0(ULONG Flags, PWSTR Prefix,
PUINT8 NameInfoBuf[sizeof(FILE_NAME_INFO) + MAX_PATH]; PUINT8 NameInfoBuf[sizeof(FILE_NAME_INFO) + MAX_PATH];
PFILE_NAME_INFO PNameInfo = (PVOID)NameInfoBuf; PFILE_NAME_INFO PNameInfo = (PVOID)NameInfoBuf;
Success = CreateSymbolicLinkW(LinkPath, TargetPath, 0); Success = BestEffortCreateSymbolicLinkW(LinkPath, TargetPath, 0);
if (Success) if (Success)
{ {
Handle = CreateFileW(FilePath, Handle = CreateFileW(FilePath,
@ -401,7 +406,7 @@ static BOOL my_symlink_fn(ULONG Flags, PWSTR Prefix, void *memfs, PWSTR LinkName
StringCbPrintfW(FilePath, sizeof FilePath, L"%s", StringCbPrintfW(FilePath, sizeof FilePath, L"%s",
FileName); FileName);
return CreateSymbolicLinkW(LinkPath, return BestEffortCreateSymbolicLinkW(LinkPath,
-1 == Flags && L'\\' == FileName[0] ? FilePath + 6 : FilePath, -1 == Flags && L'\\' == FileName[0] ? FilePath + 6 : FilePath,
SymlinkFlags); SymlinkFlags);
} }
@ -422,7 +427,57 @@ static BOOL my_namecheck_fn(ULONG Flags, PWSTR Prefix, void *memfs, PWSTR FileNa
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (INVALID_HANDLE_VALUE == Handle) if (INVALID_HANDLE_VALUE == Handle)
return FALSE; {
/*
* Prior to Windows 11 it used to be the case that NTFS open with FILE_FLAG_BACKUP_SEMANTICS
* did not care about SYMLINK/SYMLINKD difference!
*
* On Windows 11 this no longer appears to be true. In order to keep this test around, we perform
* an alternative name check in this case.
*/
if (-1 == Flags && (ERROR_ACCESS_DENIED == GetLastError() || ERROR_DIRECTORY == GetLastError()))
; /* Windows 11: if NTFS and appropriate error then ignore */
else
return FALSE;
Handle = CreateFileW(FilePath, 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);
if (INVALID_HANDLE_VALUE == Handle)
return FALSE;
union
{
REPARSE_DATA_BUFFER D;
UINT8 B[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
} ReparseDataBuf;
DWORD Bytes;
BOOL Success;
Success = DeviceIoControl(Handle, FSCTL_GET_REPARSE_POINT,
0, 0,
&ReparseDataBuf, sizeof ReparseDataBuf,
&Bytes, 0);
if (Success)
{
Success = Success &&
ReparseDataBuf.D.ReparseTag == IO_REPARSE_TAG_SYMLINK;
Success = Success &&
ReparseDataBuf.D.SymbolicLinkReparseBuffer.SubstituteNameLength ==
wcslen(ExpectedPath + 6) * sizeof(WCHAR);
Success = Success &&
0 == mywcscmp(
ExpectedPath + 6,
-1,
ReparseDataBuf.D.SymbolicLinkReparseBuffer.PathBuffer +
ReparseDataBuf.D.SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
ReparseDataBuf.D.SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR));
}
CloseHandle(Handle);
return Success;
}
if (GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf)) if (GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf))
{ {
@ -500,7 +555,11 @@ static void reparse_symlink_relative_dotest(ULONG Flags, PWSTR Prefix, ULONG Fil
my_failcheck(L"\\loop"); my_failcheck(L"\\loop");
ASSERT(ERROR_CANT_RESOLVE_FILENAME == GetLastError()); ASSERT(ERROR_CANT_RESOLVE_FILENAME == GetLastError());
/* NTFS open with FILE_FLAG_BACKUP_SEMANTICS does not care about SYMLINK/SYMLINKD difference! */ /*
* NTFS open with FILE_FLAG_BACKUP_SEMANTICS does not care about SYMLINK/SYMLINKD difference!
*
* UPDATE: Appears to no longer be true on Windows 11!
*/
my_namecheck(L"\\lf", L"\\1"); my_namecheck(L"\\lf", L"\\1");
my_namecheck(L"\\ld", L"\\1\\1.1\\1.1.1"); my_namecheck(L"\\ld", L"\\1\\1.1\\1.1.1");
@ -555,7 +614,8 @@ void reparse_symlink_relative_test(void)
void reparse_tests(void) void reparse_tests(void)
{ {
TEST(reparse_guid_test); if (!OptFuseExternal)
TEST(reparse_guid_test);
TEST(reparse_nfs_test); TEST(reparse_nfs_test);
TEST(reparse_symlink_test); TEST(reparse_symlink_test);
TEST(reparse_symlink_relative_test); TEST(reparse_symlink_relative_test);

View File

@ -333,6 +333,7 @@ void security_stress_meta_test(void)
void security_tests(void) void security_tests(void)
{ {
TEST(getsecurity_test); TEST(getsecurity_test);
TEST(setsecurity_test); if (!OptFuseExternal)
TEST(setsecurity_test);
TEST_OPT(security_stress_meta_test); TEST_OPT(security_stress_meta_test);
} }

View File

@ -2287,6 +2287,9 @@ void stream_dirnotify_test(void)
void stream_tests(void) void stream_tests(void)
{ {
if (OptFuseExternal)
return;
TEST(stream_create_test); TEST(stream_create_test);
if (!OptOplock) if (!OptOplock)
TEST(stream_create_overwrite_test); TEST(stream_create_overwrite_test);

View File

@ -34,6 +34,7 @@ int WinFspDiskTests = 1;
int WinFspNetTests = 1; int WinFspNetTests = 1;
BOOLEAN OptExternal = FALSE; BOOLEAN OptExternal = FALSE;
BOOLEAN OptFuseExternal = FALSE;
BOOLEAN OptResilient = FALSE; BOOLEAN OptResilient = FALSE;
BOOLEAN OptCaseInsensitiveCmp = FALSE; BOOLEAN OptCaseInsensitiveCmp = FALSE;
BOOLEAN OptCaseInsensitive = FALSE; BOOLEAN OptCaseInsensitive = FALSE;
@ -270,6 +271,15 @@ int main(int argc, char *argv[])
WinFspNetTests = 0; WinFspNetTests = 0;
rmarg(argv, argc, argi); rmarg(argv, argc, argi);
} }
else if (0 == strcmp("--fuse-external", a))
{
OptExternal = TRUE;
OptFuseExternal = TRUE;
NtfsTests = 1;
WinFspDiskTests = 0;
WinFspNetTests = 0;
rmarg(argv, argc, argi);
}
else if (0 == strcmp("--resilient", a)) else if (0 == strcmp("--resilient", a))
{ {
OptResilient = TRUE; OptResilient = TRUE;

View File

@ -132,6 +132,24 @@ BOOL WINAPI ResilientDeleteFileW(
BOOL WINAPI ResilientRemoveDirectoryW( BOOL WINAPI ResilientRemoveDirectoryW(
LPCWSTR lpPathName); LPCWSTR lpPathName);
static inline
BOOLEAN BestEffortCreateSymbolicLinkW(
PWSTR SymlinkFileName,
PWSTR TargetFileName,
DWORD Flags)
{
BOOLEAN Success = CreateSymbolicLinkW(
SymlinkFileName,
TargetFileName,
Flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
if (!Success && ERROR_INVALID_PARAMETER == GetLastError())
Success = CreateSymbolicLinkW(
SymlinkFileName,
TargetFileName,
Flags & ~SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
return Success;
}
typedef struct typedef struct
{ {
BOOLEAN Disposition; BOOLEAN Disposition;
@ -154,6 +172,7 @@ extern int WinFspDiskTests;
extern int WinFspNetTests; extern int WinFspNetTests;
extern BOOLEAN OptExternal; extern BOOLEAN OptExternal;
extern BOOLEAN OptFuseExternal;
extern BOOLEAN OptResilient; extern BOOLEAN OptResilient;
extern BOOLEAN OptCaseInsensitiveCmp; extern BOOLEAN OptCaseInsensitiveCmp;
extern BOOLEAN OptCaseInsensitive; extern BOOLEAN OptCaseInsensitive;

View File

@ -184,5 +184,8 @@ static void wsl_stat_test(void)
void wsl_tests(void) void wsl_tests(void)
{ {
if (OptFuseExternal)
return;
TEST_OPT(wsl_stat_test); TEST_OPT(wsl_stat_test);
} }