// ExceptionAttacher.cpp // // This module contains the code that you need to add to any // MFC app in order to wrap the main thread in an exception handler. // The original version of this by Hans Dietrich replaced AfxWinMain, // but that fails to link properly, for unknown reasons, when UNICODE is // defined. // The code in this source file consists of two parts. // // The first part replaces code found in appmodul.cpp in the MFC // library. This is a verbatim copy with the exception of commenting // out the #pragma init_seg. The only reason for this code being here // is to fix the link problem; the MFC provided version of _tWinMain // won't call the replacement AfxWinMain because for mysterious reasons // it has a different decorated name when UNICODE is defined. // // The second part is a replacement for AfxWinMain. This is a direct copy // from winmain.cpp, modified by inserting the __try/__except. There is a // small difference here from the way it was done by Hans Deitrich: the call // to AfxWinTerm is moved outside the __try/__except. The reason for this // is that AfxWinTerm calls CToolTipCtrl::DestroyToolTipCtrl. If it's not // done now, it will be done later by ExitProcess, but it's too late then // and will result in a secondary exception. // // Warning: Any time MFC is updated, this file may need to be updated as well. // /////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ExceptionHandler.h" #ifdef UNICODE // When UNICODE is defined, the compiler thinks the AfxWinMain is not a // replacement for the one in winmain.cpp. Fortunately, it accepts our // replacement for wWinMain, which ends up correctly calling our version // of AfxWinMain. // the following section is a copy from appmodul.cpp ///////////////////////////////////////////////////////////////////////////// // export WinMain to force linkage to this module extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow); extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } ///////////////////////////////////////////////////////////////////////////// // initialize app state such that it points to this module's core state BOOL AFXAPI AfxInitialize(BOOL bDLL, DWORD dwVersion) { AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); pModuleState->m_bDLL = (BYTE)bDLL; ASSERT(dwVersion <= _MFC_VER); UNUSED(dwVersion); // not used in release build #ifdef _AFXDLL pModuleState->m_dwVersion = dwVersion; #endif #ifdef _MBCS // set correct multi-byte code-page for Win32 apps if (!bDLL) _setmbcp(_MB_CP_ANSI); #endif //_MBCS return TRUE; } // force initialization early #pragma warning(disable: 4074) //#pragma init_seg(lib) #ifndef _AFXDLL void AFX_CDECL _AfxTermAppState() { // terminate local data and critical sections AfxTermLocalData(NULL, TRUE); AfxCriticalTerm(); // release the reference to thread local storage data AfxTlsRelease(); } #endif #ifndef _AFXDLL char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER), atexit(&_AfxTermAppState)); #else char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER)); #endif ///////////////////////////////////////////////////////////////////////////// #endif //UNICODE // the following section is a modified version of AfxWinMain from winmain.cpp: ///////////////////////////////////////////////////////////////////////////// // Standard WinMain implementation // Can be replaced as long as 'AfxWinInit' is called first int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ASSERT(hPrevInstance == NULL); int nReturnCode = -1; __try { CWinThread* pThread = AfxGetThread(); CWinApp* pApp = AfxGetApp(); // AFX internal initialization if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) goto InitFailure; // App global initializations (rare) if (pApp != NULL && !pApp->InitApplication()) goto InitFailure; // Perform specific initializations if (!pThread->InitInstance()) { if (pThread->m_pMainWnd != NULL) { TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n"); pThread->m_pMainWnd->DestroyWindow(); } nReturnCode = pThread->ExitInstance(); goto InitFailure; } nReturnCode = pThread->Run(); InitFailure: #ifdef _DEBUG // Check for missing AfxLockTempMap calls if (AfxGetModuleThreadState()->m_nTempMapLock != 0) { TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n", AfxGetModuleThreadState()->m_nTempMapLock); } AfxLockTempMaps(); AfxUnlockTempMaps(-1); #else ; #endif } __except(RecordExceptionInfo(GetExceptionInformation())) { } // must call AfxWinTerm after handling exception or we'll crash // again trying to destroy the tooltip window AfxWinTerm(); return nReturnCode; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 16169 | perforce_software | Move files to follow new path scheme for branches. | ||
//guest/perforce_software/p4win/common/ExceptionAttacher.cpp | |||||
#1 | 8562 | Matt Attaway |
These feet never stop running. Initial commit of the P4Win source code. To the best of our knowledge this compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes as we refine the build process. Please post any build issues to the forums. |