mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 09:22:57 -05:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
551ed341a7 | |||
52ffb47fee | |||
c208e0ecbd | |||
87389f010b | |||
c32b1c19c2 | |||
8ce6836674 |
@ -19,7 +19,7 @@
|
||||
|
||||
<MyCanonicalVersion>1.10</MyCanonicalVersion>
|
||||
|
||||
<MyProductVersion>2022 Beta4</MyProductVersion>
|
||||
<MyProductVersion>2022 Beta5</MyProductVersion>
|
||||
<MyProductStage>Beta</MyProductStage>
|
||||
|
||||
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||
@ -39,7 +39,7 @@
|
||||
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601;MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(IsKernelModeToolset)'=='true'">
|
||||
|
@ -110,6 +110,7 @@
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
|
||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||
<ImportLibrary>$(OutDir)$(TargetName)$(TargetExt).lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@ -124,6 +125,7 @@
|
||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
||||
<ImportLibrary>$(OutDir)$(TargetName)$(TargetExt).lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@ -137,6 +139,7 @@
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
|
||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||
<ImportLibrary>$(OutDir)$(TargetName)$(TargetExt).lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -151,6 +154,7 @@
|
||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
||||
<ImportLibrary>$(OutDir)$(TargetName)$(TargetExt).lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
@ -114,7 +114,7 @@ static BOOLEAN FspFileSystemSearchDirectoryBuffer(FSP_FILE_SYSTEM_DIRECTORY_BUFF
|
||||
}
|
||||
}
|
||||
|
||||
*PIndexNum = Lo;
|
||||
*PIndexNum = Hi;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
PVOID DirInfoBuffer;
|
||||
ULONG DirInfoSize;
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||
BOOLEAN PassQueryDirectoryPattern, PatternIsFileName;
|
||||
BOOLEAN PassQueryDirectoryPattern, PatternIsWild, PatternIsFileName;
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
@ -520,6 +520,14 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* if the pattern does not contain wildcards and we already returned a result, bail now! */
|
||||
PatternIsWild = FsRtlDoesNameContainWildCards(&FileDesc->DirectoryPattern);
|
||||
if (!PatternIsWild && FileDesc->DirectoryHasSuchFile)
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
return STATUS_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
/* see if the required information is still in the cache and valid! */
|
||||
if (FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize))
|
||||
{
|
||||
@ -545,19 +553,10 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
|
||||
/* special handling when pattern is filename */
|
||||
PatternIsFileName = FsvolDeviceExtension->VolumeParams.PassQueryDirectoryFileName &&
|
||||
!FsRtlDoesNameContainWildCards(&FileDesc->DirectoryPattern);
|
||||
!PatternIsWild;
|
||||
PassQueryDirectoryPattern = PatternIsFileName ||
|
||||
(FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern &&
|
||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer);
|
||||
if (PatternIsFileName &&
|
||||
0 != FileDesc->DirectoryMarker.Buffer &&
|
||||
0 == FspFileNameCompare(&FileDesc->DirectoryPattern, &FileDesc->DirectoryMarker,
|
||||
!FileDesc->CaseSensitive, 0))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
return !FileDesc->DirectoryHasSuchFile ?
|
||||
STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
/* probe and lock the user buffer */
|
||||
Result = FspLockUserBuffer(Irp, Length, IoWriteAccess);
|
||||
|
@ -1497,6 +1497,7 @@ typedef struct
|
||||
DidSetFileAttributes:1, DidSetReparsePoint:1, DidSetSecurity:1,
|
||||
DidSetCreationTime:1, DidSetLastAccessTime:1, DidSetLastWriteTime:1, DidSetChangeTime:1,
|
||||
DirectoryHasSuchFile:1;
|
||||
NTSTATUS DispositionStatus;
|
||||
UNICODE_STRING DirectoryPattern;
|
||||
UNICODE_STRING DirectoryMarker;
|
||||
UINT64 DirInfo;
|
||||
|
@ -83,6 +83,8 @@ static NTSTATUS FspFsvolSetDispositionInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspFsvolSetDispositionInformationSuccess(
|
||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||
static NTSTATUS FspFsvolSetDispositionInformationFailure(
|
||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||
static NTSTATUS FspFsvolSetRenameInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspFsvolSetRenameInformationSuccess(
|
||||
@ -125,6 +127,7 @@ FAST_IO_QUERY_OPEN FspFastIoQueryOpen;
|
||||
#pragma alloc_text(PAGE, FspFsvolSetPositionInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetDispositionInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetDispositionInformationSuccess)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetDispositionInformationFailure)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetRenameInformation)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetRenameInformationSuccess)
|
||||
#pragma alloc_text(PAGE, FspFsvolSetInformation)
|
||||
@ -1567,6 +1570,27 @@ retry:
|
||||
else
|
||||
DispositionFlags = FILE_DISPOSITION_DO_NOT_DELETE;
|
||||
|
||||
/*
|
||||
* DeleteFileW and RemoveDirectoryW in recent versions of Windows 10 have been changed to
|
||||
* perform a FileDispositionInformationEx with POSIX semantics and if that fails to retry
|
||||
* with FileDispositionInformation. Unfortunately this is done even for legitimate error
|
||||
* codes such as STATUS_DIRECTORY_NOT_EMPTY.
|
||||
*
|
||||
* This means that user mode file systems have to do unnecessary CanDelete checks even when
|
||||
* they support FileDispositionInformationEx. The extra check incurs extra context switches,
|
||||
* and in some cases it may also be costly to compute (e.g. FUSE).
|
||||
*
|
||||
* We optimize this away by storing the status of the last CanDelete check in the FileDesc
|
||||
* and then continue returning the same status code for all checks for the same FileDesc.
|
||||
*/
|
||||
if (FILE_DISPOSITION_DELETE == (DispositionFlags & ~FILE_DISPOSITION_POSIX_SEMANTICS) &&
|
||||
STATUS_SUCCESS != FileDesc->DispositionStatus)
|
||||
{
|
||||
Result = FileDesc->DispositionStatus;
|
||||
goto unlock_exit;
|
||||
}
|
||||
FileDesc->DispositionStatus = STATUS_SUCCESS;
|
||||
|
||||
Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, 0,
|
||||
FspFsvolSetInformationRequestFini, &Request);
|
||||
if (!NT_SUCCESS(Result))
|
||||
@ -1629,6 +1653,44 @@ static NTSTATUS FspFsvolSetDispositionInformationSuccess(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolSetDispositionInformationFailure(
|
||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||
UINT32 DispositionFlags = Request->Req.SetInformation.Info.DispositionEx.Flags;
|
||||
|
||||
/*
|
||||
* DeleteFileW and RemoveDirectoryW in recent versions of Windows 10 have been changed to
|
||||
* perform a FileDispositionInformationEx with POSIX semantics and if that fails to retry
|
||||
* with FileDispositionInformation. Unfortunately this is done even for legitimate error
|
||||
* codes such as STATUS_DIRECTORY_NOT_EMPTY.
|
||||
*
|
||||
* This means that user mode file systems have to do unnecessary CanDelete checks even when
|
||||
* they support FileDispositionInformationEx. The extra check incurs extra context switches,
|
||||
* and in some cases it may also be costly to compute (e.g. FUSE).
|
||||
*
|
||||
* We optimize this away by storing the status of the last CanDelete check in the FileDesc
|
||||
* and then continue returning the same status code for all checks for the same FileDesc.
|
||||
*/
|
||||
switch (Response->IoStatus.Status)
|
||||
{
|
||||
case STATUS_ACCESS_DENIED:
|
||||
case STATUS_DIRECTORY_NOT_EMPTY:
|
||||
case STATUS_CANNOT_DELETE:
|
||||
if (FILE_DISPOSITION_DELETE == (DispositionFlags & ~FILE_DISPOSITION_POSIX_SEMANTICS))
|
||||
FileDesc->DispositionStatus = Response->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
return Response->IoStatus.Status;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolSetRenameInformation(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -2095,15 +2157,23 @@ NTSTATUS FspFsvolSetInformationComplete(
|
||||
{
|
||||
FSP_ENTER_IOC(PAGED_CODE());
|
||||
|
||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
|
||||
|
||||
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||
{
|
||||
/* special case FileDispositionInformation */
|
||||
switch (FileInformationClass)
|
||||
{
|
||||
case FileDispositionInformation:
|
||||
case FileDispositionInformationEx:
|
||||
FSP_RETURN(Result = FspFsvolSetDispositionInformationFailure(Irp, Response));
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Result = Response->IoStatus.Status;
|
||||
FSP_RETURN();
|
||||
}
|
||||
|
||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
|
||||
|
||||
/* special case FileDispositionInformation/FileRenameInformation */
|
||||
switch (FileInformationClass)
|
||||
{
|
||||
|
@ -889,6 +889,10 @@ if X%5==XNOEXCL (
|
||||
-reparse* -stream* %~5
|
||||
)
|
||||
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
|
||||
echo net use L: /delete
|
||||
net use L: /delete
|
||||
|
@ -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)
|
||||
{
|
||||
if (OptExternal)
|
||||
@ -384,4 +472,5 @@ void dirbuf_tests(void)
|
||||
TEST(dirbuf_empty_test);
|
||||
TEST(dirbuf_dots_test);
|
||||
TEST(dirbuf_fill_test);
|
||||
TEST(dirbuf_boundary_test);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
if (WinFspDiskTests)
|
||||
@ -645,6 +732,8 @@ void dirnotify_test(void)
|
||||
void dirctl_tests(void)
|
||||
{
|
||||
TEST(querydir_test);
|
||||
if (!OptShareName)
|
||||
TEST_OPT(querydir_single_test);
|
||||
TEST(querydir_expire_cache_test);
|
||||
if (!OptShareName)
|
||||
TEST(querydir_buffer_overflow_test);
|
||||
|
@ -50,7 +50,7 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
|
||||
else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2])
|
||||
P = FileNameBuf + 2;
|
||||
else
|
||||
ABORT("unknown filename format");
|
||||
P = FileNameBuf;
|
||||
|
||||
for (EndP = P + wcslen(P); EndP > P; P++)
|
||||
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])
|
||||
ABORT("--mountpoint not supported with NTFS");
|
||||
else
|
||||
ABORT("unknown filename format");
|
||||
P = FileNameBuf;
|
||||
|
||||
L1 = wcslen(P) + 1;
|
||||
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 */
|
||||
P = FileNameBuf + 2;
|
||||
else
|
||||
ABORT("unknown filename format");
|
||||
P = FileNameBuf;
|
||||
|
||||
L1 = wcslen(P) + 1;
|
||||
L2 = wcslen(OptShareComputer);
|
||||
|
Reference in New Issue
Block a user