| 4 | #include "../ProgramLog/error/win32.hpp" |
| 5 | |
| 6 | void FolderWatcher::OverlappedCallback(DWORD error, DWORD, OVERLAPPED *overlapped) |
| 7 | { |
| 8 | // getting parent pointer by casting first child pointer needs standard layout. |
| 9 | static_assert(std::is_standard_layout_v<FolderWatcher> && offsetof(FolderWatcher, m_Overlapped) == 0); |
| 10 | |
| 11 | const auto that = reinterpret_cast<FolderWatcher *>(overlapped); |
| 12 | switch (error) |
| 13 | { |
| 14 | case ERROR_SUCCESS: |
| 15 | for (const auto &fileEntry : wil::create_next_entry_offset_iterator(reinterpret_cast<FILE_NOTIFY_INFORMATION *>(that->m_Buffer.get()))) |
| 16 | { |
| 17 | that->m_Callback(overlapped->hEvent, fileEntry.Action, { fileEntry.FileName, fileEntry.FileNameLength / 2 }); |
| 18 | } |
| 19 | |
| 20 | that->rearm(); |
| 21 | break; |
| 22 | |
| 23 | case ERROR_NOTIFY_ENUM_DIR: |
| 24 | that->m_Callback(overlapped->hEvent, 0, { }); |
| 25 | that->rearm(); |
| 26 | break; |
| 27 | |
| 28 | case ERROR_OPERATION_ABORTED: |
| 29 | break; |
| 30 | |
| 31 | default: |
| 32 | that->m_FolderHandle.reset(); |
| 33 | that->m_Buffer.reset(); |
| 34 | LastErrorHandle(spdlog::level::warn, L"Error occured while watching directory"); |
| 35 | break; |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | void FolderWatcher::rearm() |
| 40 | { |