https://git.reactos.org/?p=reactos.git;a=commitdiff;h=be1155f294ea1c4d551a3…
commit be1155f294ea1c4d551a34411d48389e510d4082
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sun Oct 22 22:25:03 2017 +0200
[ATL] Initial implementation of CAtlExeModuleT.
CORE-13908
---
sdk/lib/atl/atlbase.h | 189 +++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 181 insertions(+), 8 deletions(-)
diff --git a/sdk/lib/atl/atlbase.h b/sdk/lib/atl/atlbase.h
index 21d6d252b5..5d6c874bb6 100644
--- a/sdk/lib/atl/atlbase.h
+++ b/sdk/lib/atl/atlbase.h
@@ -190,15 +190,18 @@ struct _ATL_REGMAP_ENTRY
LPCOLESTR szData;
};
-HRESULT __stdcall AtlWinModuleInit(_ATL_WIN_MODULE *pWinModule);
-HRESULT __stdcall AtlWinModuleTerm(_ATL_WIN_MODULE *pWinModule, HINSTANCE hInst);
-HRESULT __stdcall AtlInternalQueryInterface(void *pThis, const _ATL_INTMAP_ENTRY
*pEntries, REFIID iid, void **ppvObject);
-void __stdcall AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pWinModule,
_AtlCreateWndData *pData, void *pObject);
-void *__stdcall AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *pWinModule);
-HRESULT __stdcall AtlComModuleGetClassObject(_ATL_COM_MODULE *pComModule, REFCLSID
rclsid, REFIID riid, LPVOID *ppv);
+HRESULT WINAPI AtlWinModuleInit(_ATL_WIN_MODULE *pWinModule);
+HRESULT WINAPI AtlWinModuleTerm(_ATL_WIN_MODULE *pWinModule, HINSTANCE hInst);
+HRESULT WINAPI AtlInternalQueryInterface(void *pThis, const _ATL_INTMAP_ENTRY *pEntries,
REFIID iid, void **ppvObject);
+void WINAPI AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pWinModule, _AtlCreateWndData
*pData, void *pObject);
+void *WINAPI AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *pWinModule);
+HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pComModule, REFCLSID rclsid,
REFIID riid, LPVOID *ppv);
-HRESULT __stdcall AtlComModuleRegisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib,
const CLSID *clsid);
-HRESULT __stdcall AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib,
const CLSID *clsid);
+HRESULT WINAPI AtlComModuleRegisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const
CLSID *clsid);
+HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const
CLSID *clsid);
+
+HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context,
DWORD flags);
+HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module);
template<class TLock>
@@ -662,6 +665,127 @@ public:
}
};
+
+template <class T>
+class CAtlExeModuleT : public CAtlModuleT<T>
+{
+public:
+ DWORD m_dwMainThreadID;
+ //DWORD m_dwTimeOut;
+ //DWORD m_dwPause;
+ //bool m_bDelayShutdown;
+
+ CAtlExeModuleT()
+ :m_dwMainThreadID(::GetCurrentThreadId())
+ {
+ }
+
+ ~CAtlExeModuleT()
+ {
+ }
+
+ int WinMain(int nShowCmd)
+ {
+ HRESULT hr = T::InitializeCom();
+ if (FAILED(hr))
+ return hr;
+
+ T* pThis = static_cast<T*>(this);
+
+ LPCTSTR lpCommandLine = GetCommandLine();
+ if (pThis->ParseCommandLine(lpCommandLine, &hr))
+ {
+ hr = pThis->Run(nShowCmd);
+ }
+
+ T::UninitializeCom();
+ return hr;
+ }
+
+
+ HRESULT Run(int nShowCmd = SW_HIDE)
+ {
+ HRESULT hr = S_OK;
+
+ T* pThis = static_cast<T*>(this);
+ hr = pThis->PreMessageLoop(nShowCmd);
+
+ if (hr == S_OK)
+ {
+ pThis->RunMessageLoop();
+ hr = pThis->PostMessageLoop();
+ }
+
+ return hr;
+ }
+
+ LONG Lock()
+ {
+ return CoAddRefServerProcess();
+ }
+
+ LONG Unlock()
+ {
+ LONG lRet = CoReleaseServerProcess();
+ if (lRet == 0)
+ {
+ ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
+ }
+ return lRet;
+ }
+
+ bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode)
+ {
+ // unimplemented!
+ return true;
+ }
+
+ HRESULT PreMessageLoop(int nShowCmd)
+ {
+ T* pThis = static_cast<T*>(this);
+ return pThis->RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
+ }
+
+ void RunMessageLoop()
+ {
+ MSG msg;
+ while (GetMessage(&msg, 0, 0, 0) > 0)
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ HRESULT PostMessageLoop()
+ {
+ T* pThis = static_cast<T*>(this);
+ return pThis->RevokeClassObjects();
+ }
+
+ HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags)
+ {
+ return AtlComModuleRegisterClassObjects(&_AtlComModule, dwClsContext,
dwFlags);
+ }
+
+ HRESULT RevokeClassObjects()
+ {
+ return AtlComModuleRevokeClassObjects(&_AtlComModule);
+ }
+
+ static HRESULT InitializeCom()
+ {
+ return ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ }
+
+ static void UninitializeCom()
+ {
+ ::CoUninitialize();
+ }
+
+};
+
+
+
class CComModule : public CAtlModuleT<CComModule>
{
public:
@@ -1685,6 +1809,55 @@ inline HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE
*mod, BOOL bU
}
+// Adapted from dll/win32/atl/atl.c
+inline HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD
context, DWORD flags)
+{
+ _ATL_OBJMAP_ENTRY **iter;
+ IUnknown* unk = NULL;
+ HRESULT hr;
+
+ if (!module)
+ return E_INVALIDARG;
+
+ for (iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast;
iter++)
+ {
+ if (!(*iter)->pfnGetClassObject)
+ continue;
+
+ hr = (*iter)->pfnGetClassObject((void*)(*iter)->pfnCreateInstance,
IID_IUnknown, (void**)&unk);
+ if (FAILED(hr))
+ return hr;
+
+ hr = CoRegisterClassObject(*(*iter)->pclsid, unk, context, flags,
&(*iter)->dwRegister);
+ unk->Release();
+ if (FAILED(hr))
+ return hr;
+ }
+
+ return S_OK;
+}
+
+
+// Adapted from dll/win32/atl/atl.c
+inline HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
+{
+ _ATL_OBJMAP_ENTRY **iter;
+ HRESULT hr;
+
+ if (!module)
+ return E_INVALIDARG;
+
+ for (iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast;
iter++)
+ {
+ hr = CoRevokeClassObject((*iter)->dwRegister);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ return S_OK;
+}
+
+
}; // namespace ATL
#ifndef _ATL_NO_AUTOMATIC_NAMESPACE