#if !defined(_FUSION_INC_ASYNCHELP_H_INCLUDED_) #define _FUSION_INC_ASYNCHELP_H_INCLUDED_ #pragma once class CAsyncContext : public OVERLAPPED { public: CAsyncContext() { } virtual ~CAsyncContext() { } // Public handler for async operations which are finished via an I/O completion port static VOID OnQueuedCompletion(HANDLE hCompletionPort, DWORD cbTransferred, ULONG_PTR ulCompletionKey, LPOVERLAPPED lpo) { CAsyncContext *pThis = reinterpret_cast(ulCompletionKey); INVOCATION_CONTEXT ic; ic.m_it = CAsyncContext::INVOCATION_CONTEXT::eCompletionPort; ic.m_dwErrorCode = ERROR_SUCCESS; ic.m_hCompletionPort = hCompletionPort; ic.m_lpo = lpo; ic.m_cbTransferred = cbTransferred; pThis->OnCompletion(ic); } // Public handler for async operations which are signalled via an APC. static VOID CALLBACK OnUserAPC(DWORD_PTR dwParam) { CAsyncContext *pThis = reinterpret_cast(dwParam); INVOCATION_CONTEXT ic; ic.m_it = CAsyncContext::INVOCATION_CONTEXT::eUserAPC; ic.m_dwErrorCode = ERROR_SUCCESS; pThis->OnCompletion(ic); } // Public handler for async operations which are signalled via a thread message static VOID OnThreadMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { CAsyncContext *pThis = reinterpret_cast(wParam); INVOCATION_CONTEXT ic; ic.m_it = CAsyncContext::INVOCATION_CONTEXT::eThreadMessage; ic.m_dwErrorCode = ERROR_SUCCESS; ic.m_uMsg = uMsg; ic.m_lParam = lParam; pThis->OnCompletion(ic); } // Public handler for async operations which are signalled via a window message static VOID OnWindowMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CAsyncContext *pThis = reinterpret_cast(wParam); INVOCATION_CONTEXT ic; ic.m_it = CAsyncContext::INVOCATION_CONTEXT::eWindowMessage; ic.m_dwErrorCode = ERROR_SUCCESS; ic.m_hwnd = hwnd; ic.m_uMsg = uMsg; ic.m_lParam = lParam; pThis->OnCompletion(ic); } // Public handler for async operations which are signalled via an overlapped completion routine // (e.g. ReadFileEx(), WriteFileEx()). static VOID CALLBACK OnOverlappedCompletion(DWORD dwErrorCode, DWORD cbTransferred, LPOVERLAPPED lpo) { CAsyncContext *pThis = static_cast(lpo); INVOCATION_CONTEXT ic; ic.m_it = CAsyncContext::INVOCATION_CONTEXT::eOverlappedCompletionRoutine; ic.m_lpo = lpo; ic.m_dwErrorCode = dwErrorCode; ic.m_cbTransferred = cbTransferred; pThis->OnCompletion(ic); } // Call this member function when an asynch I/O completes immediately VOID OnImmediateCompletion(DWORD dwErrorCode, DWORD cbTransferred) { INVOCATION_CONTEXT ic; ic.m_it = CAsyncContext::INVOCATION_CONTEXT::eDirectCall; ic.m_lpo = this; ic.m_dwErrorCode = dwErrorCode; ic.m_cbTransferred = cbTransferred; this->OnCompletion(ic); } protected: struct INVOCATION_CONTEXT { enum InvocationType { eCompletionPort, eUserAPC, eThreadMessage, eWindowMessage, eDirectCall, eOverlappedCompletionRoutine, } m_it; DWORD m_dwErrorCode; // Win32 error code - valid for all invocation types HANDLE m_hCompletionPort; // valid for: eCompletionPort LPOVERLAPPED m_lpo; // valid for: eCompletionPort, eOverlappedCompletionRoutine, eDirectCall DWORD m_cbTransferred; // valid for: eCompletionPort, eOverlappedCompletionRoutine, eDirectCall LPARAM m_lParam; // valid for: eThreadMessage, eWindowMessage HWND m_hwnd; // valid for: eWindowMessage UINT m_uMsg; // valid for: eThreadMessage, eWindowMessage }; // Derived classes override OnCompletion to do what's necessary. virtual VOID OnCompletion(const INVOCATION_CONTEXT &ric) = 0; }; #endif