#ifndef __AGCModule_h__ #define __AGCModule_h__ ///////////////////////////////////////////////////////////////////////////// // AGCModule : Declaration of the CAGCModule class. // extern "C" const CLSID CLSID_AGCGlobal; #include <..\TCLib\AutoHandle.h> #ifdef AGC_MODULE /////////////////////////////////////////////////////////////////////////// // class CAGCModule { // Attributes public: IAGCGlobalPtr GetAGCGlobal() { HRESULT hr; if (NULL == m_spcf) { hr = _Module.GetClassObject(CLSID_AGCGlobal, IID_IClassFactory, (void**)&m_spcf); assert(SUCCEEDED(hr) && NULL != m_spcf); } IAGCGlobalPtr spGlobal; hr = m_spcf->CreateInstance(NULL, IID_IAGCGlobal, (void**)&spGlobal); assert(NULL != spGlobal); return spGlobal; } // Operations public: void TriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); void TriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); void TriggerContextEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); void TriggerContextEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCSTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); HRESULT MakeAGCEvent(AGCEventID idEvent, IAGCEvent** ppEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, long cArgTriplets, ...); HRESULT MakeAGCEvent(AGCEventID idEvent, IAGCEvent** ppEvent, LPCSTR pszContext, LPCSTR pszSubject, AGCUniqueID idSubject, long cArgTriplets, ...); // Implementation protected: void DoTriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, void* pvArgs) { bool bIsError = GetAGCGlobal()->GetEventSeverity(idEvent) == EVENTLOG_ERROR_TYPE; // Always trigger events with severity level of Error synchronously if (!bIsError) GetAGCGlobal()->TriggerEvent(hListeners, idEvent, pszContext, pszSubject, idSubject, idObject1, idObject2, cArgTriplets, pvArgs); else { GetAGCGlobal()->TriggerEventSynchronous(hListeners, idEvent, pszContext, pszSubject, idSubject, idObject1, idObject2, cArgTriplets, pvArgs); *(DWORD*)0 = 0; // make DrWatson happy //DebugBreak(); exit(EXIT_FAILURE); } } // Data Members protected: IClassFactoryPtr m_spcf; }; #else // AGC_MODULE #ifndef _assert_h_ #ifndef assert #define assert(x) while (false) {} #endif // !assert inline void debugf(const char* , ...) {} #endif // !_assert_h_ #ifndef RETURN_FAILED #define RETURN_FAILED(exp) \ { \ HRESULT _hr = exp; \ if (FAILED(_hr)) \ return _hr; \ } #endif // !RETURN_FAILED #ifndef sizeofArray /////////////////////////////////////////////////////////////////////////// // Counts the number of elements in a fixed-length array. // Parameters: x - The name of the array of which to compute the size. #define sizeofArray(x) (sizeof(x) / sizeof(x[0])) #endif // !sizeofArray /////////////////////////////////////////////////////////////////////////// // class CAGCModule { // Construction public: CAGCModule(); // Attributes public: IAGCGlobal* GetAGCGlobal(); _ATL_REGMAP_ENTRY* GetRegMapEntries(); void SetDebugBreakOnErrors(bool bBreak); bool GetDebugBreakOnErrors() const; // Operations public: HRESULT Init(); void Term(); bool IsRegistered(); HRESULT Register(); // Operations public: void TriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); void TriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); void TriggerContextEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); void TriggerContextEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCSTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...); HRESULT MakeAGCEvent(AGCEventID idEvent, IAGCEvent** ppEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, long cArgTriplets, ...); HRESULT MakeAGCEvent(AGCEventID idEvent, IAGCEvent** ppEvent, LPCSTR pszContext, LPCSTR pszSubject, AGCUniqueID idSubject, long cArgTriplets, ...); // Implementation protected: void DoTriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, void* pvArgs); // Data Members protected: IAGCGlobalPtr m_spGlobal; bool m_bDebugBreakOnErrors; }; /////////////////////////////////////////////////////////////////////////// // Construction inline CAGCModule::CAGCModule() : m_bDebugBreakOnErrors(true) { } /////////////////////////////////////////////////////////////////////////// // Attributes inline IAGCGlobal* CAGCModule::GetAGCGlobal() { #ifdef _DEBUG if (NULL == m_spGlobal) debugf("CAGCModule::GetAGCGlobal(): Init not successfully called!\n"); assert(NULL != m_spGlobal); #endif // _DEBUG return m_spGlobal; } inline _ATL_REGMAP_ENTRY* CAGCModule::GetRegMapEntries() { static OLECHAR s_szModulePath[_MAX_PATH]; static _ATL_REGMAP_ENTRY s_map[] = { {OLESTR("AGCModule"), s_szModulePath}, {NULL , NULL} }; // Get the AGC resource module HINSTANCE hinst = GetAGCGlobal()->GetResourceInstance(); assert(hinst); // Warning: Not thread-safe, // (but it shouldn't matter, since this function will typically only be // called from an application's main thread during server registration.) TCHAR szModulePath[_MAX_PATH]; GetModuleFileName(hinst, szModulePath, sizeofArray(szModulePath)); USES_CONVERSION; wcscpy(s_szModulePath, T2COLE(szModulePath)); // Return the array of registrar replacement entries return s_map; } inline void CAGCModule::SetDebugBreakOnErrors(bool bBreak) { m_bDebugBreakOnErrors = bBreak; } inline bool CAGCModule::GetDebugBreakOnErrors() const { return m_bDebugBreakOnErrors; } /////////////////////////////////////////////////////////////////////////// // Operations inline HRESULT CAGCModule::Init() { if (!IsRegistered()) { HRESULT hr = Register(); assert(hr); if (FAILED(hr)) return hr; } // Create the single instance of the AGCGlobal object RETURN_FAILED(m_spGlobal.CreateInstance(CLSID_AGCGlobal)); // Initialize the AGCGlobal object m_spGlobal->Initialize(); // Indicate success return S_OK; } inline void CAGCModule::Term() { // Terminate the AGCGlobal object if (NULL != m_spGlobal) m_spGlobal->Terminate(); // Release the IAGCGlobal pointer m_spGlobal = NULL; } inline bool CAGCModule::IsRegistered() { // Obviously registered if the global has already been created if (NULL != m_spGlobal) return true; // Attempt to create an instance return SUCCEEDED(m_spGlobal.CreateInstance(CLSID_AGCGlobal)); } inline HRESULT CAGCModule::Register() { // Get the current module name TCHAR szModule[_MAX_PATH]; ::GetModuleFileName(NULL, szModule, sizeofArray(szModule)); // Break the module name into pieces TCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szPath[_MAX_PATH]; _tsplitpath(szModule, szDrive, szDir, NULL, NULL); _tmakepath(szPath, szDrive, szDir, NULL, NULL); // Change the current directory TCHAR szCurDirPrev[_MAX_PATH] = TEXT(""); GetCurrentDirectory(sizeofArray(szCurDirPrev), szCurDirPrev); SetCurrentDirectory(szPath); // Load the AGC module TCHAR szAGC[_MAX_PATH]; _tmakepath(szAGC, szDrive, szDir, TEXT("AGC"), TEXT(".dll")); HINSTANCE hinst = ::LoadLibrary(szAGC); HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); if (hinst) { // Get the specified export procedure address typedef HRESULT (CALLBACK *PFNREG)(); PFNREG pfn = (PFNREG)GetProcAddress(hinst, "DllRegisterServer"); // Call the function hr = pfn ? (*pfn)() : HRESULT_FROM_WIN32(::GetLastError()); // Unload the specified module FreeLibrary(hinst); } // Restore the previous current directory SetCurrentDirectory(szCurDirPrev); // Return the last HRESULT return hr; } /////////////////////////////////////////////////////////////////////////// // Implementation inline void CAGCModule::DoTriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, void* pvArgs) { bool bIsError; if (NULL != m_spGlobal) { // Get the event severity bIsError = m_spGlobal->GetEventSeverity(idEvent) == EVENTLOG_ERROR_TYPE; // Always trigger events with severity level of Error synchronously if (!bIsError) m_spGlobal->TriggerEvent(hListeners, idEvent, pszContext, pszSubject, idSubject, idObject1, idObject2, cArgTriplets, pvArgs); else m_spGlobal->TriggerEventSynchronous(hListeners, idEvent, pszContext, pszSubject, idSubject, idObject1, idObject2, cArgTriplets, pvArgs); } else { // Get the name of the current module TCHAR szModule[_MAX_PATH], szName[_MAX_PATH]; GetModuleFileName(NULL, szModule, sizeofArray(szModule)); _tsplitpath(szModule, NULL, NULL, szName, NULL); // Open the local event log for the module's application TCEventSourceHandle sh = RegisterEventSource(NULL, szName); // Log an event const DWORD dwEventID = (3 << 30) | EventID_AGCNotInitialized; ReportEvent(sh, EVENTLOG_ERROR_TYPE, 0, dwEventID, NULL, 0, 0, NULL, NULL); // Set the event severity bIsError = true; } // Errors (other than Assert's) will break into debugger if (bIsError && EventID_AGCAssert != idEvent) { #ifdef _DEBUG if (GetDebugBreakOnErrors()) *(DWORD*)0 = 0; //DebugBreak(); #endif // _DEBUG // Harsh reality has hit us exit(EXIT_FAILURE); } } #endif // !AGC_MODULE ///////////////////////////////////////////////////////////////////////////// // Operations inline void CAGCModule::TriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...) { va_list argptr; va_start(argptr, cArgTriplets); DoTriggerEvent(hListeners, idEvent, NULL, pszSubject, idSubject, idObject1, idObject2, cArgTriplets, argptr); va_end(argptr); } inline void CAGCModule::TriggerEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...) { USES_CONVERSION; va_list argptr; va_start(argptr, cArgTriplets); DoTriggerEvent(hListeners, idEvent, NULL, A2COLE(pszSubject), idSubject, idObject1, idObject2, cArgTriplets, argptr); va_end(argptr); } inline void CAGCModule::TriggerContextEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...) { va_list argptr; va_start(argptr, cArgTriplets); DoTriggerEvent(hListeners, idEvent, pszContext, pszSubject, idSubject, idObject1, idObject2, cArgTriplets, argptr); va_end(argptr); } inline void CAGCModule::TriggerContextEvent(HAGCLISTENERS hListeners, AGCEventID idEvent, LPCSTR pszContext, LPCSTR pszSubject, AGCUniqueID idSubject, AGCUniqueID idObject1, AGCUniqueID idObject2, long cArgTriplets, ...) { USES_CONVERSION; va_list argptr; va_start(argptr, cArgTriplets); DoTriggerEvent(hListeners, idEvent, pszContext, A2COLE(pszSubject), idSubject, idObject1, idObject2, cArgTriplets, argptr); va_end(argptr); } inline HRESULT CAGCModule::MakeAGCEvent(AGCEventID idEvent, IAGCEvent** ppEvent, LPCSTR pszContext, LPCOLESTR pszSubject, AGCUniqueID idSubject, long cArgTriplets, ...) { va_list argptr; va_start(argptr, cArgTriplets); HRESULT hr = GetAGCGlobal()->MakeAGCEvent(idEvent, pszContext, pszSubject, idSubject, cArgTriplets, argptr, ppEvent); va_end(argptr); return hr; } inline HRESULT CAGCModule::MakeAGCEvent(AGCEventID idEvent, IAGCEvent** ppEvent, LPCSTR pszContext, LPCSTR pszSubject, AGCUniqueID idSubject, long cArgTriplets, ...) { USES_CONVERSION; va_list argptr; va_start(argptr, cArgTriplets); HRESULT hr = GetAGCGlobal()->MakeAGCEvent(idEvent, pszContext, A2COLE(pszSubject), idSubject, cArgTriplets, argptr, ppEvent); va_end(argptr); return hr; } ///////////////////////////////////////////////////////////////////////////// #endif // !__AGCModule_h__