|  | 
| 1 |  | -namespace YY::Thunks | 
|  | 1 | + | 
|  | 2 | + | 
|  | 3 | +#if defined(YY_Thunks_Implemented) && (YY_Thunks_Target < __WindowsNT6) | 
|  | 4 | +namespace YY::Thunks::Fallback | 
|  | 5 | +{ | 
|  | 6 | +    static NTSTATUS NTAPI NtCancelIoFileEx( | 
|  | 7 | +        HANDLE _hHandle, | 
|  | 8 | +        IO_STATUS_BLOCK* _pIo, | 
|  | 9 | +        IO_STATUS_BLOCK* _pIoStatus | 
|  | 10 | +        ) | 
|  | 11 | +    { | 
|  | 12 | +        // NtCancelIoFile无法模拟特定的IO取消工作,因此需要取消特定IO时立即失败处理 | 
|  | 13 | +        if (_pIo != nullptr) | 
|  | 14 | +        { | 
|  | 15 | +            // Not supported | 
|  | 16 | +            return STATUS_NOT_FOUND; | 
|  | 17 | +        } | 
|  | 18 | + | 
|  | 19 | +    #ifndef __USING_NTDLL_LIB | 
|  | 20 | +        const auto NtCancelIoFile = try_get_NtCancelIoFile(); | 
|  | 21 | +        if (!NtCancelIoFile) | 
|  | 22 | +        { | 
|  | 23 | +            // 正常来说不应该走到这里 | 
|  | 24 | +            return STATUS_NOT_SUPPORTED; | 
|  | 25 | +        } | 
|  | 26 | +    #endif | 
|  | 27 | + | 
|  | 28 | +        auto _Status = NtCancelIoFile(_hHandle, _pIoStatus); | 
|  | 29 | +        if (_Status < 0) | 
|  | 30 | +            return _Status; | 
|  | 31 | + | 
|  | 32 | +        internal::StringBuffer<char> _Buffer; | 
|  | 33 | +        auto _pProcessInfo = internal::GetCurrentProcessInfo(_Buffer); | 
|  | 34 | +        if (!_pProcessInfo) | 
|  | 35 | +            return _Status; | 
|  | 36 | + | 
|  | 37 | +        const auto _uCurrentThreadId = GetCurrentThreadId(); | 
|  | 38 | +        for (ULONG i = 0; i != _pProcessInfo->ThreadCount; ++i) | 
|  | 39 | +        { | 
|  | 40 | +            auto& _Thread = _pProcessInfo->Threads[i]; | 
|  | 41 | + | 
|  | 42 | +            if (_uCurrentThreadId == static_cast<DWORD>(reinterpret_cast<UINT_PTR>(_Thread.ClientId.UniqueThread))) | 
|  | 43 | +                continue; | 
|  | 44 | + | 
|  | 45 | +            auto _hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, static_cast<DWORD>(reinterpret_cast<UINT_PTR>(_Thread.ClientId.UniqueThread))); | 
|  | 46 | +            if (!_hThread) | 
|  | 47 | +                continue; | 
|  | 48 | + | 
|  | 49 | +            QueueUserAPC( | 
|  | 50 | +                [](ULONG_PTR _hHandle) | 
|  | 51 | +                { | 
|  | 52 | +    #ifndef __USING_NTDLL_LIB | 
|  | 53 | +                    const auto NtCancelIoFile = try_get_NtCancelIoFile(); | 
|  | 54 | +    #endif | 
|  | 55 | +                    IO_STATUS_BLOCK _IoStatus; | 
|  | 56 | +                    // 故意不判断空指针,NtCancelIoFileEx开头已经判断过了。 | 
|  | 57 | +                    // 如果真的崩溃,那么说明内存被改坏了。 | 
|  | 58 | +                    NtCancelIoFile(reinterpret_cast<HANDLE>(_hHandle), &_IoStatus); | 
|  | 59 | +                }, _hThread, (ULONG_PTR)_hHandle); | 
|  | 60 | +            CloseHandle(_hThread); | 
|  | 61 | +        } | 
|  | 62 | + | 
|  | 63 | +        return _Status; | 
|  | 64 | +    } | 
|  | 65 | +} | 
|  | 66 | +#endif | 
|  | 67 | + | 
|  | 68 | + | 
|  | 69 | +namespace YY::Thunks | 
| 2 | 70 | { | 
| 3 | 71 | #if (YY_Thunks_Target < __WindowsNT6) | 
| 4 | 72 | 
 | 
|  | 
| 10 | 78 |     NTSTATUS, | 
| 11 | 79 |     NTAPI, | 
| 12 | 80 |     NtCancelIoFileEx, | 
| 13 |  | -        HANDLE handle, | 
| 14 |  | -        IO_STATUS_BLOCK* io, | 
| 15 |  | -        IO_STATUS_BLOCK* io_status | 
|  | 81 | +        HANDLE _hHandle, | 
|  | 82 | +        IO_STATUS_BLOCK* _pIo, | 
|  | 83 | +        IO_STATUS_BLOCK* _pIoStatus | 
| 16 | 84 |         ) | 
| 17 | 85 |     { | 
| 18 | 86 |         if (const auto _pfnNtCancelIoFileEx = try_get_NtCancelIoFileEx()) | 
| 19 | 87 |         { | 
| 20 |  | -            return _pfnNtCancelIoFileEx(handle, io, io_status); | 
|  | 88 | +            return _pfnNtCancelIoFileEx(_hHandle, _pIo, _pIoStatus); | 
| 21 | 89 |         } | 
| 22 | 90 | 
 | 
| 23 |  | -#ifndef __USING_NTDLL_LIB | 
| 24 |  | -        const auto NtCancelIoFile = try_get_NtCancelIoFile(); | 
| 25 |  | -        if(!NtCancelIoFile) | 
| 26 |  | -        { | 
| 27 |  | -            // 正常来说不应该走到这里 | 
| 28 |  | -            return STATUS_NOT_SUPPORTED; | 
| 29 |  | -        } | 
| 30 |  | -#endif | 
| 31 |  | -        // 最坏打算,清除所有的调用 | 
| 32 |  | -        return NtCancelIoFile(handle, io_status);     | 
|  | 91 | +        return Fallback::NtCancelIoFileEx(_hHandle, _pIo, _pIoStatus); | 
| 33 | 92 |     } | 
| 34 | 93 | #endif | 
| 35 | 94 | 
 | 
|  | 
0 commit comments