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
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 */