[*] Fix FS Watcher under Windows XP -> Windows 7
This commit is contained in:
parent
4a5cb3c168
commit
7fa0a52e2c
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user