Index: src/ch/ch.cpp =================================================================== diff -u -N -rbfe720fda9529e7a77b4fb6410b4d4945b69188b -r2457755b4084e3d1c80a8e7c77c9f0996312941b --- src/ch/ch.cpp (.../ch.cpp) (revision bfe720fda9529e7a77b4fb6410b4d4945b69188b) +++ src/ch/ch.cpp (.../ch.cpp) (revision 2457755b4084e3d1c80a8e7c77c9f0996312941b) @@ -83,11 +83,10 @@ } CCopyHandlerApp::CCopyHandlerApp() : - m_lfLog(), - m_piShellExtControl(NULL) + m_piShellExtControl(NULL), + m_hMapObject(NULL), + m_pMainWindow(NULL) { - m_pMainWindow=NULL; - // this is the one-instance application InitProtection(); } @@ -124,9 +123,9 @@ return ictranslate::CResourceManager::Acquire(); } -chcore::engine_config& GetConfig() +chcore::TCoreConfig& GetConfig() { - return chcore::engine_config::Acquire(); + return chcore::TCoreConfig::Acquire(); } int MsgBox(UINT uiID, UINT nType, UINT nIDHelp) @@ -210,76 +209,91 @@ BOOL CCopyHandlerApp::InitInstance() { - // set the exception handler to catch the crash dumps + // ================================= Crash handling ======================================= SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter); - HRESULT hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if(FAILED(hResult)) - AfxMessageBox(_T("Cannot initialize COM, the application will now exit."), MB_ICONERROR | MB_OK); + // ================================= Configuration ======================================== + CString strPath; + CString strCfgPath; + CString strLogPath; - // InitCommonControlsEx() is required on Windows XP if an application - // manifest specifies use of ComCtl32.dll version 6 or later to enable - // visual styles. Otherwise, any window creation will fail. - INITCOMMONCONTROLSEX InitCtrls; - InitCtrls.dwSize = sizeof(InitCtrls); - // Set this to include all the common control classes you want to use - // in your application. - InitCtrls.dwICC = ICC_WIN95_CLASSES; - InitCommonControlsEx(&InitCtrls); + // note that the GetProgramDataPath() below should create a directory; ExpandPath() could + // depend on the directory to be created earlier + if(!GetProgramDataPath(strPath)) + { + AfxMessageBox(_T("Cannot initialize Copy Handler (data path cannot be established)."), MB_ICONERROR | MB_OK); + return FALSE; + } - EnableHtmlHelp(); - //SetHelpMode(afxHTMLHelp); + strCfgPath = strPath + _T("\\ch.ini"); - CWinApp::InitInstance(); - - m_hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(CSharedConfigStruct), _T("CHLMFile")); - if (m_hMapObject == NULL) - return FALSE; - - // Get a pointer to the file-mapped shared memory. - g_pscsShared=(CSharedConfigStruct*)MapViewOfFile(m_hMapObject, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); - if (g_pscsShared == NULL) - return FALSE; - - chcore::engine_config& rConfig = chcore::engine_config::Acquire(); - ictranslate::CResourceManager& rResManager = ictranslate::CResourceManager::Acquire(); - - // load configuration + // initialize configuration file + chcore::TCoreConfig& rConfig = chcore::TCoreConfig::Acquire(); rConfig.set_callback(ConfigPropertyChangedCallback, NULL); - CString strPath; - // note that the GetProgramDataPath() below should create a directory; ExpandPath() could - // depend on the directory to be created earlier - if(GetProgramDataPath(strPath)) + + // read the configuration + try { - strPath += _T("\\ch.ini"); - try - { - rConfig.read(strPath); - } - catch(...) - { - } + rConfig.read(strCfgPath); } + catch(...) + { + } // set working dir for the engine - rConfig.set_base_path(strPath); + rConfig.SetBasePath(strPath); // register all properties RegisterProperties(&rConfig); - // set this process class - HANDLE hProcess=GetCurrentProcess(); - ::SetPriorityClass(hProcess, (DWORD)rConfig.get_signed_num(PP_PPROCESSPRIORITYCLASS)); + // ================================= Logging ======================================== + // initialize the global log file if it is requested by configuration file + strLogPath = strPath + + _T("\\ch.log"); + chcore::TLogger& rLogger = chcore::TLogger::Acquire(); + try + { + rLogger.init(strLogPath, (int_t)rConfig.get_signed_num(PP_LOGMAXSIZE), (int_t)rConfig.get_unsigned_num(PP_LOGLEVEL), false, false); + rLogger.Enable(rConfig.get_bool(PP_LOGENABLELOGGING)); + } + catch(...) + { + BOOST_ASSERT(false); + } + + LOG_INFO(_T("============================ Initializing Copy Handler ============================")); + LOG_INFO(_T("")); + + // ================================= COM ======================================== + LOG_INFO(_T("Initializing COM")); + + HRESULT hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if(FAILED(hResult)) + { + CString strMsg; + strMsg.Format(_T("Cannot initialize COM, the application will now exit (result = 0x%lx)"), hResult); + + LOG_ERROR(strMsg); + AfxMessageBox(strMsg, MB_ICONERROR | MB_OK); + return FALSE; + } + + // ================================= Resource manager ======================================== + LOG_INFO(_T("Initializing resource manager...")); + + ictranslate::CResourceManager& rResManager = ictranslate::CResourceManager::Acquire(); + // set current language TCHAR szPath[_MAX_PATH]; + rResManager.Init(AfxGetInstanceHandle()); rResManager.SetCallback(ResManCallback); rConfig.get_string(PP_PLANGUAGE, szPath, _MAX_PATH); TRACE(_T("Help path=%s\n"), szPath); - if (!rResManager.SetLanguage(ExpandPath(szPath))) + if(!rResManager.SetLanguage(ExpandPath(szPath))) { TCHAR szData[2048]; _sntprintf(szData, 2048, _T("Couldn't find the language file specified in configuration file:\n%s\nPlease correct this path to point the language file to use.\nProgram will now exit."), szPath); + LOG_ERROR(szData); AfxMessageBox(szData, MB_ICONSTOP | MB_OK); return FALSE; } @@ -289,31 +303,47 @@ // for dialogs ictranslate::CLanguageDialog::SetResManager(&rResManager); - // initialize log file - rConfig.get_string(PP_LOGPATH, szPath, _MAX_PATH); - m_lfLog.init(ExpandPath(szPath), (int_t)rConfig.get_signed_num(PP_LOGMAXLIMIT), icpf::log_file::level_debug, false, false); + EnableHtmlHelp(); - // TODO: remove unused properties from configuration -/* m_lfLog.EnableLogging(m_cfgManager.GetBoolValue(PP_LOGENABLELOGGING)); - m_lfLog.SetPreciseLimiting(m_cfgManager.GetBoolValue(PP_LOGPRECISELIMITING)); - m_lfLog.SetSizeLimit(m_cfgManager.GetBoolValue(PP_LOGLIMITATION), m_cfgManager.GetIntValue(PP_LOGMAXLIMIT)); - m_lfLog.SetTruncateBufferSize(m_cfgManager.GetIntValue(PP_LOGTRUNCBUFFERSIZE)); - m_lfLog.Init(ExpandPath(szPath), GetResManager());*/ - -#ifndef _DEBUG // for easier writing the program - doesn't collide with std CH - // set "run with system" registry settings - SetAutorun(rConfig.get_bool(PP_PRELOADAFTERRESTART)); -#endif - + // ================================= Checking for running instances of CH ======================================== // check instance - return false if it's the second one - if (!IsFirstInstance()) + LOG_INFO(_T("Checking for other running instances of Copy Handler")); + if(!IsFirstInstance()) { + LOG_WARNING(_T("Other instance of Copy Handler is already running. Exiting.")); MsgBox(IDS_ONECOPY_STRING); return FALSE; } + // ================================= Common controls ======================================== + LOG_INFO(_T("Initializing GUI common controls")); + + // InitCommonControlsEx() is required on Windows XP if an application + // manifest specifies use of ComCtl32.dll version 6 or later to enable + // visual styles. Otherwise, any window creation will fail. + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // Set this to include all the common control classes you want to use + // in your application. + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + + // ================================= Shell extension ======================================== + LOG_INFO(_T("Initializing shared memory for communication with shell extension")); + + m_hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(CSharedConfigStruct), _T("CHLMFile")); + if (m_hMapObject == NULL) + return FALSE; + + // Get a pointer to the file-mapped shared memory. + g_pscsShared=(CSharedConfigStruct*)MapViewOfFile(m_hMapObject, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); + if (g_pscsShared == NULL) + return FALSE; + + LOG_INFO(_T("Checking shell extension compatibility")); + // calculate ch version - LONG lCHVersion = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; + long lCHVersion = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; // check the version of shell extension LONG lVersion = 0; @@ -328,6 +358,10 @@ hResult = m_piShellExtControl->SetFlags(eShellExt_Enabled, eShellExt_Enabled); if(FAILED(hResult) || lCHVersion != lVersion) { + CString strMsg; + strMsg.Format(_T("Shell extension has different version (0x%lx) than Copy Handler (0x%lx). Shell extension will be disabled."), lVersion, lCHVersion); + + LOG_WARNING(strMsg); MsgBox(IDS_SHELL_EXTENSION_MISMATCH_STRING); if(m_piShellExtControl) @@ -337,13 +371,30 @@ if(bstrVersion) ::SysFreeString(bstrVersion); + // ================================= Initial settings ======================================== + LOG_INFO(_T("Applying initial settings")); + + // set this process priority class + HANDLE hProcess=GetCurrentProcess(); + ::SetPriorityClass(hProcess, (DWORD)rConfig.get_signed_num(PP_PPROCESSPRIORITYCLASS)); + +#ifndef _DEBUG // for easier writing the program - doesn't collide with std CH + // set "run with system" registry settings + SetAutorun(rConfig.get_bool(PP_PRELOADAFTERRESTART)); +#endif + + // ================================= Main window ======================================== + LOG_INFO(_T("Creating main application window")); // create main window m_pMainWindow=new CMainWnd; if (!((CMainWnd*)m_pMainWindow)->Create()) return FALSE; // will be deleted at destructor m_pMainWnd = m_pMainWindow; + CWinApp::InitInstance(); + LOG_INFO(_T("Copy Handler initialized successfully")); + return TRUE; } @@ -362,12 +413,37 @@ void CCopyHandlerApp::OnConfigNotify(uint_t uiPropID) { // is this language - if(uiPropID == PP_PLANGUAGE) + switch(uiPropID) { - // update language in resource manager - TCHAR szPath[_MAX_PATH]; - GetConfig().get_string(PP_PLANGUAGE, szPath, _MAX_PATH); - GetResManager().SetLanguage(ExpandPath(szPath)); + case PP_PLANGUAGE: + { + // update language in resource manager + TCHAR szPath[_MAX_PATH]; + GetConfig().get_string(PP_PLANGUAGE, szPath, _MAX_PATH); + GetResManager().SetLanguage(ExpandPath(szPath)); + break; + } + case PP_LOGENABLELOGGING: + { + chcore::TLogger& rLogger = chcore::TLogger::Acquire(); + + rLogger.Enable(GetConfig().get_bool(PP_LOGENABLELOGGING)); + break; + } + case PP_LOGLEVEL: + { + chcore::TLogger& rLogger = chcore::TLogger::Acquire(); + + rLogger.set_log_level((int_t)GetConfig().get_unsigned_num(PP_LOGLEVEL)); + break; + } + case PP_LOGMAXSIZE: + { + chcore::TLogger& rLogger = chcore::TLogger::Acquire(); + + rLogger.set_max_size((int_t)GetConfig().get_signed_num(PP_LOGMAXSIZE)); + break; + } } } @@ -381,7 +457,7 @@ } } -HWND CCopyHandlerApp::HHelp(HWND hwndCaller, LPCTSTR pszFile, UINT uCommand, DWORD dwData) +HWND CCopyHandlerApp::HHelp(HWND hwndCaller, LPCTSTR pszFile, UINT uCommand, DWORD_PTR dwData) { PCTSTR pszPath=NULL; WIN32_FIND_DATA wfd; @@ -452,12 +528,17 @@ int CCopyHandlerApp::ExitInstance() { + LOG_INFO(_T("Pre-exit step - releasing shell extension")); if(m_piShellExtControl) { m_piShellExtControl->Release(); m_piShellExtControl = NULL; } + + LOG_INFO(_T("Pre-exit step - uninitializing COM")); CoUninitialize(); + LOG_INFO(_T("============================ Leaving Copy Handler ============================")); + return __super::ExitInstance(); }