tst: winfsp-tests: add --notify option

This commit is contained in:
Bill Zissimopoulos 2020-10-10 14:30:14 -07:00
parent e54c2288f7
commit 1bb0580a6a
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
5 changed files with 123 additions and 8 deletions

View File

@ -21,6 +21,7 @@
#define WINFSP_TESTS_NO_HOOKS
#include "winfsp-tests.h"
#include <winfsp/winfsp.h>
#define FILENAMEBUF_SIZE 1024
@ -107,6 +108,75 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
}
}
typedef struct
{
HANDLE VolumeHandle;
FSP_FSCTL_NOTIFY_INFO *NotifyInfo;
} MAYBE_NOTIFY_DATA;
static DWORD WINAPI MaybeNotifyRoutine(PVOID Context)
{
MAYBE_NOTIFY_DATA *NotifyData = Context;
/*
* The supplied VolumeHandle may be invalid or refer to the wrong object.
* This is ok because:
*
* - If the VolumeHandle is invalid, Windows will catch it and will fail the operation.
* - If the VolumeHandle refers to the wrong object, the FspFsctlNotify "should" fail
* because of an unknown DeviceIoControl code.
* - If the VolumeHandle refers to the wrong file system, it is still ok if we send an
* extraneous notify.
*/
FspFsctlNotify(NotifyData->VolumeHandle,
NotifyData->NotifyInfo, NotifyData->NotifyInfo->Size);
HeapFree(GetProcessHeap(), 0, NotifyData->NotifyInfo);
HeapFree(GetProcessHeap(), 0, NotifyData);
return 0;
}
static VOID MaybeNotify(PWSTR FileName, ULONG Filter, ULONG Action)
{
static WCHAR DevicePrefix[] =
L"\\\\?\\GLOBALROOT\\Device\\Volume{01234567-0123-0123-0101-010101010101}";
static WCHAR MemfsSharePrefix[] =
L"\\\\memfs\\share";
MAYBE_NOTIFY_DATA *NotifyData;
FSP_FSCTL_NOTIFY_INFO *NotifyInfo;
size_t L;
if (!OptNotify || OptExternal || 0 == memfs_handle)
return;
if (0 == wcsncmp(FileName, DevicePrefix, wcschr(DevicePrefix, L'{') - DevicePrefix))
FileName += wcslen(DevicePrefix);
else if (0 == mywcscmp(
FileName, (int)wcslen(MemfsSharePrefix), MemfsSharePrefix, (int)wcslen(MemfsSharePrefix)))
FileName += wcslen(MemfsSharePrefix);
else
return;
L = wcslen(FileName);
NotifyData = HeapAlloc(GetProcessHeap(), 0, sizeof *NotifyData);
NotifyInfo = HeapAlloc(GetProcessHeap(), 0, sizeof *NotifyInfo + L * sizeof(WCHAR));
if (0 == NotifyData || 0 == NotifyInfo)
ABORT("cannot malloc notify data");
NotifyInfo->Size = (UINT16)(sizeof *NotifyInfo + L * sizeof(WCHAR));
NotifyInfo->Filter = Filter;
NotifyInfo->Action = Action;
memcpy(NotifyInfo->FileNameBuf, FileName, L * sizeof(WCHAR));
NotifyData->VolumeHandle = memfs_handle;
NotifyData->NotifyInfo = NotifyInfo;
if (!QueueUserWorkItem(MaybeNotifyRoutine, NotifyData, 0))
ABORT("cannot queue notify data");
}
typedef struct
{
HANDLE File;
@ -210,6 +280,9 @@ HANDLE WINAPI HookCreateFileW(
PrepareFileName(lpFileName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeRequestOplock(FileNameBuf);
MaybeAdjustTraversePrivilege(FALSE);
@ -241,6 +314,9 @@ BOOL WINAPI HookSetFileAttributesW(
PrepareFileName(lpFileName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Success = SetFileAttributesW(FileNameBuf, dwFileAttributes);
MaybeAdjustTraversePrivilege(TRUE);
@ -256,6 +332,9 @@ BOOL WINAPI HookCreateDirectoryW(
PrepareFileName(lpPathName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Success = CreateDirectoryW(FileNameBuf, lpSecurityAttributes);
MaybeAdjustTraversePrivilege(TRUE);
@ -270,6 +349,9 @@ BOOL WINAPI HookDeleteFileW(
PrepareFileName(lpFileName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeRequestOplock(FileNameBuf);
MaybeAdjustTraversePrivilege(FALSE);
@ -287,6 +369,9 @@ BOOL WINAPI HookRemoveDirectoryW(
PrepareFileName(lpPathName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Success = (OptResilient ? ResilientRemoveDirectoryW : RemoveDirectoryW)(
FileNameBuf);
@ -306,6 +391,13 @@ BOOL WINAPI HookMoveFileExW(
PrepareFileName(lpExistingFileName, OldFileNameBuf);
PrepareFileName(lpNewFileName, NewFileNameBuf);
MaybeNotify(OldFileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
if (OptCaseInsensitive ?
_wcsicmp(OldFileNameBuf, NewFileNameBuf) : wcscmp(OldFileNameBuf, NewFileNameBuf))
MaybeNotify(NewFileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeRequestOplock(OldFileNameBuf);
if (OptCaseInsensitive ?
_wcsicmp(OldFileNameBuf, NewFileNameBuf) : wcscmp(OldFileNameBuf, NewFileNameBuf))
@ -326,6 +418,9 @@ HANDLE WINAPI HookFindFirstFileW(
PrepareFileName(lpFileName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Handle = FindFirstFileW(FileNameBuf, lpFindFileData);
MaybeAdjustTraversePrivilege(TRUE);
@ -343,6 +438,9 @@ HANDLE WINAPI HookFindFirstStreamW(
PrepareFileName(lpFileName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Handle = FindFirstStreamW(FileNameBuf, InfoLevel, lpFindStreamData, dwFlags);
MaybeAdjustTraversePrivilege(TRUE);
@ -426,6 +524,9 @@ BOOL WINAPI HookSetCurrentDirectoryW(
PrepareFileName(lpPathName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Success = SetCurrentDirectoryW(FileNameBuf);
MaybeAdjustTraversePrivilege(TRUE);
@ -449,6 +550,9 @@ BOOL WINAPI HookCreateProcessW(
PrepareFileName(lpApplicationName, FileNameBuf);
MaybeNotify(FileNameBuf,
FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_ACTION_MODIFIED);
MaybeAdjustTraversePrivilege(FALSE);
Success = CreateProcessW(FileNameBuf,
lpCommandLine, /* we should probably change this as well */

View File

@ -27,6 +27,7 @@
#include "winfsp-tests.h"
int memfs_running;
HANDLE memfs_handle;
void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout)
{
@ -66,6 +67,7 @@ void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout)
ASSERT(NT_SUCCESS(Result));
memfs_running = 1;
memfs_handle = MemfsFileSystem(Memfs)->VolumeHandle;
return Memfs;
}
@ -77,6 +79,7 @@ void *memfs_start(ULONG Flags)
void memfs_stop(void *data)
{
memfs_handle = 0;
memfs_running = 0;
if (0 == data)

View File

@ -342,12 +342,12 @@ void notify_open_change_test(void)
void notify_tests(void)
{
if (!OptExternal)
{
TEST(notify_abandon_test);
TEST(notify_abandon_rename_test);
TEST(notify_timeout_test);
TEST(notify_change_test);
TEST(notify_open_change_test);
}
if (OptExternal || OptNotify)
return;
TEST(notify_abandon_test);
TEST(notify_abandon_rename_test);
TEST(notify_timeout_test);
TEST(notify_change_test);
TEST(notify_open_change_test);
}

View File

@ -38,6 +38,7 @@ BOOLEAN OptCaseInsensitiveCmp = FALSE;
BOOLEAN OptCaseInsensitive = FALSE;
BOOLEAN OptCaseRandomize = FALSE;
BOOLEAN OptFlushAndPurgeOnCleanup = FALSE;
BOOLEAN OptNotify = FALSE;
WCHAR OptOplock = 0;
WCHAR OptMountPointBuf[MAX_PATH], *OptMountPoint;
WCHAR OptShareNameBuf[MAX_PATH], *OptShareName, *OptShareTarget;
@ -259,6 +260,11 @@ int main(int argc, char *argv[])
OptFlushAndPurgeOnCleanup = TRUE;
rmarg(argv, argc, argi);
}
else if (0 == strcmp("--notify", a))
{
OptNotify = TRUE;
rmarg(argv, argc, argi);
}
else if (0 == strcmp("--oplock=batch", a))
{
OptOplock = 'B';

View File

@ -159,6 +159,7 @@ extern BOOLEAN OptCaseInsensitiveCmp;
extern BOOLEAN OptCaseInsensitive;
extern BOOLEAN OptCaseRandomize;
extern BOOLEAN OptFlushAndPurgeOnCleanup;
extern BOOLEAN OptNotify;
extern WCHAR OptOplock;
extern WCHAR OptMountPointBuf[], *OptMountPoint;
extern WCHAR OptShareNameBuf[], *OptShareName, *OptShareTarget;
@ -168,3 +169,4 @@ extern HANDLE OptNoTraverseToken;
extern LUID OptNoTraverseLuid;
extern int memfs_running;
extern HANDLE memfs_handle;