dll: FspFileSystemSearchDirectoryBuffer: fix #351

This commit is contained in:
Bill Zissimopoulos 2021-12-03 14:47:19 +00:00
parent 8ba8d31e50
commit 8ce6836674
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
5 changed files with 186 additions and 4 deletions

View File

@ -114,7 +114,7 @@ static BOOLEAN FspFileSystemSearchDirectoryBuffer(FSP_FILE_SYSTEM_DIRECTORY_BUFF
} }
} }
*PIndexNum = Lo; *PIndexNum = Hi;
return FALSE; return FALSE;
} }

View File

@ -889,6 +889,10 @@ if X%5==XNOEXCL (
-reparse* -stream* %~5 -reparse* -stream* %~5
) )
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1 if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
"%ProjRoot%\build\VStudio\build\%Configuration%\%4.exe" ^
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
+querydir_single_test
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
popd popd
echo net use L: /delete echo net use L: /delete
net use L: /delete net use L: /delete

View File

@ -376,6 +376,94 @@ static void dirbuf_fill_test(void)
} }
} }
static void dirbuf_boundary_dotest(PWSTR Marker, ULONG ExpectI, ULONG ExpectN, ...)
{
PVOID DirBuffer = 0;
NTSTATUS Result;
BOOLEAN Success;
union
{
UINT8 B[sizeof(FSP_FSCTL_DIR_INFO) + MAX_PATH * sizeof(WCHAR)];
FSP_FSCTL_DIR_INFO D;
} DirInfoBuf;
FSP_FSCTL_DIR_INFO *DirInfo = &DirInfoBuf.D, *DirInfoEnd;
UINT8 Buffer[1024];
ULONG Length, BytesTransferred;
WCHAR CurrFileName[MAX_PATH];
ULONG N;
PWSTR Name;
va_list Names0, Names1;
va_start(Names0, ExpectN);
va_copy(Names1, Names0);
Length = sizeof Buffer;
Result = STATUS_UNSUCCESSFUL;
Success = FspFileSystemAcquireDirectoryBuffer(&DirBuffer, FALSE, &Result);
ASSERT(Success);
ASSERT(STATUS_SUCCESS == Result);
while (0 != (Name = va_arg(Names0, PWSTR)))
{
memset(&DirInfoBuf, 0, sizeof DirInfoBuf);
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + wcslen(Name) * sizeof(WCHAR));
wcscpy_s(DirInfo->FileNameBuf, MAX_PATH, Name);
Success = FspFileSystemFillDirectoryBuffer(&DirBuffer, DirInfo, &Result);
ASSERT(Success);
ASSERT(STATUS_SUCCESS == Result);
}
FspFileSystemReleaseDirectoryBuffer(&DirBuffer);
BytesTransferred = 0;
FspFileSystemReadDirectoryBuffer(&DirBuffer, Marker, Buffer, Length, &BytesTransferred);
for (N = 0; ExpectI > N; N++)
va_arg(Names1, PWSTR);
for (N = 0,
DirInfo = (PVOID)Buffer, DirInfoEnd = (PVOID)(Buffer + BytesTransferred);
DirInfoEnd > DirInfo && 0 != DirInfo->Size;
DirInfo = (PVOID)((PUINT8)DirInfo + FSP_FSCTL_DEFAULT_ALIGN_UP(DirInfo->Size)), N++)
{
memcpy(CurrFileName, DirInfo->FileNameBuf, DirInfo->Size - sizeof *DirInfo);
CurrFileName[(DirInfo->Size - sizeof *DirInfo) / sizeof(WCHAR)] = L'\0';
Name = va_arg(Names1, PWSTR);
ASSERT(0 == wcscmp(CurrFileName, Name));
}
ASSERT(ExpectN == N);
FspFileSystemDeleteDirectoryBuffer(&DirBuffer);
va_end(Names1);
va_end(Names0);
}
static void dirbuf_boundary_test(void)
{
dirbuf_boundary_dotest(L"A", 0, 0, 0);
dirbuf_boundary_dotest(L"A", 0, 1, L"B", 0);
dirbuf_boundary_dotest(L"B", 0, 0, L"B", 0);
dirbuf_boundary_dotest(L"C", 0, 0, L"B", 0);
dirbuf_boundary_dotest(L"A", 0, 2, L"B", L"D", 0);
dirbuf_boundary_dotest(L"B", 1, 1, L"B", L"D", 0);
dirbuf_boundary_dotest(L"C", 1, 1, L"B", L"D", 0);
dirbuf_boundary_dotest(L"D", 0, 0, L"B", L"D", 0);
dirbuf_boundary_dotest(L"E", 0, 0, L"B", L"D", 0);
dirbuf_boundary_dotest(L"A", 0, 3, L"B", L"D", L"F", 0);
dirbuf_boundary_dotest(L"B", 1, 2, L"B", L"D", L"F", 0);
dirbuf_boundary_dotest(L"C", 1, 2, L"B", L"D", L"F", 0);
dirbuf_boundary_dotest(L"D", 2, 1, L"B", L"D", L"F", 0);
dirbuf_boundary_dotest(L"E", 2, 1, L"B", L"D", L"F", 0);
dirbuf_boundary_dotest(L"F", 0, 0, L"B", L"D", L"F", 0);
dirbuf_boundary_dotest(L"G", 0, 0, L"B", L"D", L"F", 0);
}
void dirbuf_tests(void) void dirbuf_tests(void)
{ {
if (OptExternal) if (OptExternal)
@ -384,4 +472,5 @@ void dirbuf_tests(void)
TEST(dirbuf_empty_test); TEST(dirbuf_empty_test);
TEST(dirbuf_dots_test); TEST(dirbuf_dots_test);
TEST(dirbuf_fill_test); TEST(dirbuf_fill_test);
TEST(dirbuf_boundary_test);
} }

View File

@ -269,6 +269,93 @@ void querydir_test(void)
} }
} }
static void querydir_single_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout, ULONG SleepTimeout)
{
void *memfs = memfs_start_ex(Flags, FileInfoTimeout);
HANDLE Handle;
BOOL Success;
WCHAR CurrentDirectory[MAX_PATH], FileName[MAX_PATH];
WIN32_FIND_DATAW FindData;
StringCbPrintfW(FileName, sizeof FileName, L"%s%s\\",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
Success = GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
ASSERT(Success);
Success = SetCurrentDirectoryW(FileName);
ASSERT(Success);
for (ULONG Index = 0; 1000 > Index; Index++)
{
StringCbPrintfW(FileName, sizeof FileName, L"xxxxxxx-file%lu", Index);
Handle = CreateFileW(FileName,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
Success = CloseHandle(Handle);
ASSERT(Success);
}
Handle = FindFirstFileW(L"*", &FindData);
ASSERT(INVALID_HANDLE_VALUE != Handle);
do
{
} while (FindNextFileW(Handle, &FindData));
Success = FindClose(Handle);
ASSERT(Success);
for (ULONG Index = 0; 1000 > Index; Index++)
{
StringCbPrintfW(FileName, sizeof FileName, L"xxxxxxx-file%lu", Index);
Handle = FindFirstFileW(FileName, &FindData);
ASSERT(INVALID_HANDLE_VALUE != Handle);
do
{
} while (FindNextFileW(Handle, &FindData));
Success = FindClose(Handle);
ASSERT(Success);
}
for (ULONG Index = 0; 1000 > Index; Index++)
{
StringCbPrintfW(FileName, sizeof FileName, L"xxxxxxx-file%lu", Index);
Success = DeleteFileW(FileName);
ASSERT(Success);
}
Success = RealSetCurrentDirectoryW(CurrentDirectory);
ASSERT(Success);
memfs_stop(memfs);
}
void querydir_single_test(void)
{
if (OptShareName)
return;
if (NtfsTests)
{
WCHAR DirBuf[MAX_PATH];
GetTestDirectory(DirBuf);
querydir_single_dotest(-1, DirBuf, 0, 0);
}
if (WinFspDiskTests)
{
querydir_single_dotest(MemfsDisk, 0, 0, 0);
querydir_single_dotest(MemfsDisk, 0, 1000, 0);
}
if (WinFspNetTests)
{
querydir_single_dotest(MemfsNet, L"\\\\memfs\\share", 0, 0);
querydir_single_dotest(MemfsNet, L"\\\\memfs\\share", 1000, 0);
}
}
void querydir_expire_cache_test(void) void querydir_expire_cache_test(void)
{ {
if (WinFspDiskTests) if (WinFspDiskTests)
@ -645,6 +732,8 @@ void dirnotify_test(void)
void dirctl_tests(void) void dirctl_tests(void)
{ {
TEST(querydir_test); TEST(querydir_test);
if (!OptShareName)
TEST_OPT(querydir_single_test);
TEST(querydir_expire_cache_test); TEST(querydir_expire_cache_test);
if (!OptShareName) if (!OptShareName)
TEST(querydir_buffer_overflow_test); TEST(querydir_buffer_overflow_test);

View File

@ -50,7 +50,7 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2]) else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2])
P = FileNameBuf + 2; P = FileNameBuf + 2;
else else
ABORT("unknown filename format"); P = FileNameBuf;
for (EndP = P + wcslen(P); EndP > P; P++) for (EndP = P + wcslen(P); EndP > P; P++)
if (testalpha(*P) && myrand() <= (TogglePercent) * 0x7fff / 100) if (testalpha(*P) && myrand() <= (TogglePercent) * 0x7fff / 100)
@ -71,7 +71,7 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2]) else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2])
ABORT("--mountpoint not supported with NTFS"); ABORT("--mountpoint not supported with NTFS");
else else
ABORT("unknown filename format"); P = FileNameBuf;
L1 = wcslen(P) + 1; L1 = wcslen(P) + 1;
L2 = wcslen(OptMountPoint); L2 = wcslen(OptMountPoint);
@ -96,7 +96,7 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
/* NTFS testing can only been done when the whole drive is being shared */ /* NTFS testing can only been done when the whole drive is being shared */
P = FileNameBuf + 2; P = FileNameBuf + 2;
else else
ABORT("unknown filename format"); P = FileNameBuf;
L1 = wcslen(P) + 1; L1 = wcslen(P) + 1;
L2 = wcslen(OptShareComputer); L2 = wcslen(OptShareComputer);