[*] Fix FS Watcher under Windows XP -> Windows 7

This commit is contained in:
Reece Wilson 2023-07-28 14:09:23 +01:00
parent 4a5cb3c168
commit 7fa0a52e2c
3 changed files with 79 additions and 17 deletions

View File

@ -86,7 +86,8 @@ namespace Aurora
ADD_GET_PROC(Nt, RtlWaitOnAddress)
ADD_GET_PROC(Nt, ZwSetTimerResolution)
ADD_GET_PROC(Nt, NtQueryInformationProcess)
ADD_GET_PROC(Nt, NtNotifyChangeDirectoryFile)
ADD_GET_PROC_BI(Kernel32, KernelBase, VirtualAlloc2)
ADD_GET_PROC_BI(Kernel32, KernelBase, MapViewOfFile3)
ADD_GET_PROC_BI(Kernel32, KernelBase, UnmapViewOfFile2)

View File

@ -127,6 +127,18 @@ namespace Aurora
);
#endif
inline NTSTATUS(__stdcall *pNtNotifyChangeDirectoryFile)(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID Buffer,
ULONG BufferSize,
ULONG CompletionFilter,
BOOLEAN WatchTree
);
inline BOOL(__stdcall *pGetSystemCpuSetInformation)(
PSYSTEM_CPU_SET_INFORMATION Information,
ULONG BufferLength,

View File

@ -45,8 +45,12 @@ namespace Aurora::IO::FS
NTWatcher *parent;
AuString strBaseDir;
HANDLE hFileHandle {INVALID_HANDLE_VALUE};
bool bWin7Mode {};
AuSPtr<Loop::LSEvent> pWin7Event {};
AuUInt32 dwReferences {};
UCHAR buffer[8000];
IO_STATUS_BLOCK ioStatusBlock;
~NTWatchObject()
{
Cancel();
@ -372,26 +376,62 @@ namespace Aurora::IO::FS
bool firstTime = !this->ntOverlapped.hEvent;
this->ntOverlapped.hEvent = (HANDLE)this->parent->ntEvent_->GetHandle();
REQUEST_OPLOCK_INPUT_BUFFER input
if (AuSwInfo::IsWindows8OrGreater())
{
REQUEST_OPLOCK_CURRENT_VERSION,
sizeof(REQUEST_OPLOCK_INPUT_BUFFER),
OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE,
firstTime ? REQUEST_OPLOCK_INPUT_FLAG_REQUEST : REQUEST_OPLOCK_INPUT_FLAG_ACK,
};
REQUEST_OPLOCK_INPUT_BUFFER input
{
REQUEST_OPLOCK_CURRENT_VERSION,
sizeof(REQUEST_OPLOCK_INPUT_BUFFER),
OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE,
firstTime ? REQUEST_OPLOCK_INPUT_FLAG_REQUEST : REQUEST_OPLOCK_INPUT_FLAG_ACK,
};
DWORD bytesReturned;
if (DeviceIoControl(this->hFileHandle, FSCTL_REQUEST_OPLOCK, &input, sizeof(input), &whoAsked_, sizeof(whoAsked_), &bytesReturned, &this->ntOverlapped))
{
this->CheckBroken();
DWORD bytesReturned;
if (DeviceIoControl(this->hFileHandle, FSCTL_REQUEST_OPLOCK, &input, sizeof(input), &whoAsked_, sizeof(whoAsked_), &bytesReturned, &this->ntOverlapped))
{
this->CheckBroken();
}
else
{
if (GetLastError() != ERROR_IO_PENDING)
{
SysPushErrorIO();
return false;
}
}
}
else
else if (pNtNotifyChangeDirectoryFile)
{
if (GetLastError() != ERROR_IO_PENDING)
auto dwRet = pNtNotifyChangeDirectoryFile(this->hFileHandle,
this->ntOverlapped.hEvent,
NULL,
NULL,
&ioStatusBlock,
buffer,
sizeof(buffer),
//FILE_NOTIFY_CHANGE_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_LAST_ACCESS |
FILE_NOTIFY_CHANGE_CREATION,
FALSE);
this->bWin7Mode = true;
if (dwRet == STATUS_PENDING)
{
return true;
}
if (!NT_SUCCESS(dwRet))
{
SysPushErrorIO();
return false;
}
else
{
CheckBroken();
}
}
return true;
@ -401,7 +441,9 @@ namespace Aurora::IO::FS
{
DWORD bytesTransferred;
if (this->bBroken || GetOverlappedResult(this->hFileHandle, &this->ntOverlapped, &bytesTransferred, false))
if (this->bBroken ||
((this->bWin7Mode) ||
(!this->bWin7Mode && GetOverlappedResult(this->hFileHandle, &this->ntOverlapped, &bytesTransferred, false))))
{
bool bSuccess {true};
this->bBroken = true;
@ -423,11 +465,18 @@ namespace Aurora::IO::FS
bAnyTriggered = true;
}
if (this->whoAsked_.Flags & REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED)
if (this->bWin7Mode)
{
this->whoAsked_.Flags = 0;
bSuccess = ScheduleOnce();
}
else
{
if (this->whoAsked_.Flags & REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED)
{
this->whoAsked_.Flags = 0;
bSuccess = ScheduleOnce();
}
}
this->bBroken = false;
return bSuccess;