Index: src/ch/ch.cpp =================================================================== diff -u -r8068e0c351055554340ac9755d1bc846893bf2b8 -re98c03b108baad889dfd7c7fbb1a49f5ea5a55d8 --- src/ch/ch.cpp (.../ch.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/ch/ch.cpp (.../ch.cpp) (revision e98c03b108baad889dfd7c7fbb1a49f5ea5a55d8) @@ -32,17 +32,11 @@ #include "../common/version.h" #include "TCommandLineParser.h" #include "../libchcore/TStringSet.h" -#include "../libchcore/TSimpleTimer.h" -#include "../libchcore/SerializerTrace.h" -#include -#include "../libchcore/TSQLiteTaskSchema.h" -#include "../libchcore/TSQLiteSerializer.h" -#include "../libchcore/ISerializerContainer.h" -#include "../libchcore/ISerializerRowData.h" -#include "../libchcore/TFileInfo.h" #include "TMsgBox.h" -#include "../libchcore/TWin32ErrorFormatter.h" #include "resource.h" +#include "../liblogger/TLogger.h" +#include "../liblogger/TAsyncMultiLogger.h" +#include "TWindowMessageFilterHelper.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -97,8 +91,14 @@ } CCopyHandlerApp::CCopyHandlerApp() : + m_spAppLoggerConfig(std::make_shared()), + m_spEngineLoggerConfig(std::make_shared()), m_pMainWindow(nullptr) { +#ifdef _DEBUG + AfxEnableMemoryLeakDump(FALSE); +#endif + // this is the one-instance application InitProtection(); } @@ -113,17 +113,17 @@ } } -CCopyHandlerApp& GetApp() +CCopyHandlerApp& GetApplication() { return theApp; } -ictranslate::CResourceManager& GetResManager() +ictranslate::CResourceManager& CCopyHandlerApp::GetResManager() { return ictranslate::CResourceManager::Acquire(); } -chcore::TConfig& GetConfig() +chcore::TConfig& CCopyHandlerApp::GetConfig() { static chcore::TConfig tCfg; return tCfg; @@ -209,66 +209,6 @@ BOOL CCopyHandlerApp::InitInstance() { -#ifdef DO_TEST - using namespace chcore; - - DeleteFile(_T("C:\\Users\\ixen\\AppData\\Local\\Copy Handler\\Tasks\\test.sqlite")); - TSQLiteTaskSchemaPtr spTaskSchema(new TSQLiteTaskSchema); - - TSQLiteSerializer serializer(PathFromString(_T("C:\\Users\\ixen\\AppData\\Local\\Copy Handler\\Tasks\\test.sqlite")), spTaskSchema); - //TSQLiteSerializer serializer(PathFromString(_T(":memory:")), spTaskSchema); - - TSimpleTimer timer(true); - - { - ISerializerContainerPtr spContainer = serializer.GetContainer(_T("scanned_files")); - - IColumnsDefinition& rColumns = spContainer->GetColumnsDefinition(); - TFileInfo::InitColumns(rColumns); - - const size_t rel_path = rColumns.GetColumnIndex(_T("rel_path")); - const size_t base_path_id = rColumns.GetColumnIndex(_T("base_path_id")); - const size_t attr = rColumns.GetColumnIndex(_T("attr")); - const size_t size = rColumns.GetColumnIndex(_T("size")); - const size_t time_created = rColumns.GetColumnIndex(_T("time_created")); - const size_t time_last_write = rColumns.GetColumnIndex(_T("time_last_write")); - const size_t time_last_access = rColumns.GetColumnIndex(_T("time_last_access")); - const size_t flags = rColumns.GetColumnIndex(_T("flags")); - - TString strPath(_T("C:\\Users\\ixen\\AppData\\Local\\Copy Handler\\Tasks\\sometask.xxx")); - TSmartPath path(PathFromString(_T("C:\\Users\\ixen\\AppData\\Local\\Copy Handler\\Tasks\\sometask.xxx"))); - - for(object_id_t oidIndex = 0; oidIndex < 200000; ++oidIndex) - { - ISerializerRowData& rRow = spContainer->GetRow(oidIndex, true); - rRow.SetValue(rel_path, path); //C:\\Users\\ixen\\AppData\\Local\\Copy Handler\\Tasks\\sometask.xxx - rRow.SetValue(base_path_id, 24735275ull); - rRow.SetValue(attr, 0x56533234ul); - rRow.SetValue(size, 0x565332340897ff12ull); - rRow.SetValue(time_created, 0x565332340897ff12ull); - rRow.SetValue(time_last_write, 0x565122340897ff12ull); - rRow.SetValue(time_last_access, 0x565517840897ff12ull); - rRow.SetValue(flags, 0x56551114u); - } - - unsigned long long ullFillTime = timer.Checkpoint(); ullFillTime; - GTRACE1(_T("***** [FillTime]: %I64u ms\n"), ullFillTime); - - serializer.Flush(); - unsigned long long ullFlushTime = timer.Checkpoint(); ullFlushTime; - GTRACE1(_T("***** [FlushTime]: %I64u ms\n"), ullFlushTime); - - spContainer.reset(); - unsigned long long ullDeleteContainerTime = timer.Checkpoint(); ullDeleteContainerTime; - GTRACE1(_T("***** [DeleteContainer]: %I64u ms\n"), ullDeleteContainerTime); - } - - unsigned long long ullDestructTime = timer.Checkpoint(); ullDestructTime; - GTRACE1(_T("***** [DestructTime]: %I64u ms\n"), ullDestructTime); - - return FALSE; -#else - // ================================= Crash handling ======================================= SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter); @@ -281,7 +221,6 @@ // ================================= Configuration ======================================== CString strPath; CString strCfgPath; - CString strLogPath; // note that the GetProgramDataPath() below should create a directory; ExpandPath() could // depend on the directory to be created earlier @@ -300,46 +239,66 @@ // read the configuration try { - GetConfig().Read(strCfgPath); + rCfg.Read(strCfgPath); } catch(...) { } // ================================= Logging ======================================== + InitLoggers(); + + // logger config + m_spAppLoggerConfig->SetLogLevel(L"default", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"default", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Filesystem", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Filesystem-File", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"DataBuffer", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Task", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"ST-FastMove", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"ST-CopyMove", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"ST-Delete", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"ST-ScanDirs", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Serializer", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Serializer-RowReader", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Serializer-RowData", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Serializer-Container", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"TaskManager", (logger::ESeverityLevel)GetPropValue(rCfg)); + // initialize the global log file if it is requested by configuration file - strLogPath = strPath + _T("\\ch.log"); + CString strLogPath = strPath + _T("\\ch.log"); - chcore::TLogger& rLogger = chcore::TLogger::Acquire(); - try - { - rLogger.init(strLogPath, GetPropValue(rCfg), GetPropValue(rCfg), false, false); - rLogger.Enable(GetPropValue(rCfg)); - } - catch(...) - { - BOOST_ASSERT(false); - } + m_spLog = logger::MakeLogger(logger::TAsyncMultiLogger::GetInstance()->CreateLoggerData(strLogPath, m_spAppLoggerConfig), L"App"); - LOG_INFO(_T("============================ Initializing Copy Handler ============================")); - LOG_INFO(_T("")); + LOG_INFO(m_spLog) << _T("============================ Initializing Copy Handler ============================"); // ================================= COM ======================================== - LOG_INFO(_T("Initializing COM")); + LOG_INFO(m_spLog) << _T("Initializing COM"); HRESULT hResult = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if(FAILED(hResult)) { - CString strMsg; - strMsg.Format(_T("Cannot initialize COM, the application will now exit (result = 0x%lx)"), hResult); + // NOTE: with CH code (including external libraries directly referenced by it) the RPC_E_CHANGED_MODE error code + // should not occur. One of the users reported such problem - it is unclear whether there is something being injected + // into CH process or there is some other problem. It seems that RPC_E_CHANGED_MODE error is not a blocker to CH use, + // so we're allowing the initialization to continue. + if(hResult != RPC_E_CHANGED_MODE) + { + 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; + LOG_ERROR(m_spLog) << strMsg; + AfxMessageBox(strMsg, MB_ICONERROR | MB_OK); + return FALSE; + } + + LOG_WARNING(m_spLog) << L"COM already initialized (CoInitializeEx returned RPC_E_CHANGED_MODE)"; } + else + m_bComInitialized = true; // ================================= Resource manager ======================================== - LOG_INFO(_T("Initializing resource manager...")); + LOG_INFO(m_spLog) << _T("Initializing resource manager..."); ictranslate::CResourceManager& rResManager = ictranslate::CResourceManager::Acquire(); @@ -352,7 +311,7 @@ { 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."), (PCTSTR)strPath); - LOG_ERROR(szData); + LOG_ERROR(m_spLog) << szData; AfxMessageBox(szData, MB_ICONSTOP | MB_OK); return FALSE; } @@ -377,7 +336,7 @@ // ================================= Checking for running instances of CH ======================================== // check instance - return false if it's the second one - LOG_INFO(_T("Checking for other running instances of Copy Handler")); + LOG_INFO(m_spLog) << _T("Checking for other running instances of Copy Handler"); if(!IsFirstInstance()) { // if there is a command line specified, send it to the existing instance @@ -387,7 +346,7 @@ if(hWnd == nullptr) { // cannot pass command line to running ch - LOG_ERROR(_T("Cannot determine running CH's window. Cannot pass command line there.")); + LOG_ERROR(m_spLog) << _T("Cannot determine running CH's window. Cannot pass command line there."); MsgBox(IDS_COMMAND_LINE_FAILED_STRING, MB_OK | MB_ICONERROR); return FALSE; } @@ -402,22 +361,22 @@ // send a message to ch if(::SendMessage(hWnd, WM_COPYDATA, 0, reinterpret_cast(&cds)) == 0) { - LOG_ERROR(_T("Command line was not processed properly at the running CH's instance.")); + LOG_ERROR(m_spLog) << _T("Command line was not processed properly at the running CH's instance."); MsgBox(IDS_COMMAND_LINE_FAILED_STRING, MB_OK | MB_ICONERROR); } return FALSE; } else { - LOG_WARNING(_T("Other instance of Copy Handler is already running. Exiting.")); + LOG_WARNING(m_spLog) << _T("Other instance of Copy Handler is already running. Exiting."); MsgBox(IDS_ONECOPY_STRING, MB_OK | MB_ICONWARNING); return FALSE; } } // ================================= Common controls ======================================== - LOG_INFO(_T("Initializing GUI common controls")); + LOG_INFO(m_spLog) << _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 @@ -429,25 +388,25 @@ InitCtrls.dwICC = ICC_WIN95_CLASSES; if(!InitCommonControlsEx(&InitCtrls)) { - LOG_ERROR(_T("Cannot initialize common controls.")); + LOG_ERROR(m_spLog) << _T("Cannot initialize common controls."); MsgBox(IDS_ERROR_INITIALIZING_COMMON_CONTROLS, MB_OK | MB_ICONERROR); return FALSE; } if(!AfxInitRichEdit2()) { - LOG_ERROR(_T("Cannot initialize rich edit control.")); + LOG_ERROR(m_spLog) << _T("Cannot initialize rich edit control."); MsgBox(IDS_ERROR_INITIALIZING_RICH_EDIT_CONTROL, MB_OK | MB_ICONERROR); return FALSE; } // ================================= Shell extension ======================================== - LOG_INFO(_T("Checking shell extension compatibility")); + LOG_INFO(m_spLog) << _T("Checking shell extension compatibility"); InitShellExtension(); // ================================= Initial settings ======================================== - LOG_INFO(_T("Applying initial settings")); + LOG_INFO(m_spLog) << _T("Applying initial settings"); // set this process priority class HANDLE hProcess = GetCurrentProcess(); @@ -458,8 +417,25 @@ SetAutorun(GetPropValue(rCfg)); #endif + // ================================= Shell extension config ============================= + LOG_INFO(m_spLog) << _T("Initializing shell extension configuration"); + try + { + m_shellExtConfig = std::make_unique(m_spLog->GetLogFileData()); + m_shellExtConfig->PrepareConfig(); + } + catch(const std::exception& e) + { + LOG_ERROR(m_spLog) << L"Failed to initialize shell extension configuration. Shell extension will be inactive. Error: " << e.what(); + } + + // ================================= User Interface Privilege Isolation ================= + LOG_INFO(m_spLog) << _T("Enabling communication between non-admin explorer and admin Copy Handler"); + if(!TWindowMessageHelper::AllowToReceiveCopyDataMessages()) + LOG_WARNING(m_spLog) << _T("Failed to enable communication between non-admin explorer and admin Copy Handler"); + // ================================= Main window ======================================== - LOG_INFO(_T("Creating main application window")); + LOG_INFO(m_spLog) << _T("Creating main application window"); // create main window m_pMainWindow=new CMainWnd; if (!((CMainWnd*)m_pMainWindow)->Create()) @@ -468,10 +444,9 @@ m_pMainWnd = m_pMainWindow; CWinApp::InitInstance(); - LOG_INFO(_T("Copy Handler initialized successfully")); + LOG_INFO(m_spLog) << _T("Copy Handler initialized successfully"); return TRUE; -#endif } bool CCopyHandlerApp::ParseCommandLine() @@ -498,6 +473,14 @@ return true; } +void CCopyHandlerApp::InitLoggers() +{ + chcore::TConfig& rConfig = GetConfig(); + + logger::TAsyncMultiLogger::GetInstance()->SetMaxLogSize(GetPropValue(rConfig)); + logger::TAsyncMultiLogger::GetInstance()->SetMaxRotatedCount(GetPropValue(rConfig)); +} + void CCopyHandlerApp::InitShellExtension() { // validate ch version against extension version @@ -517,7 +500,7 @@ { CString strMsg; strMsg.Format(_T("Shell extension is not registered.")); - LOG_WARNING(strMsg); + LOG_WARNING(m_spLog) << strMsg; switch(iDoNotShowAgain_Unregistered) { @@ -542,7 +525,7 @@ { CString strMsg; strMsg.Format(_T("Shell extension has different version (0x%lx) than Copy Handler (0x%lx)."), (unsigned long)lExtensionVersion, (unsigned long)(PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4)); - LOG_WARNING(strMsg); + LOG_WARNING(m_spLog) << strMsg; switch(iDoNotShowAgain_VersionMismatch) { @@ -575,75 +558,81 @@ } } -void CCopyHandlerApp::RegisterShellExtension() +logger::TLogFileDataPtr CCopyHandlerApp::GetLogFileData() const { - CString strPath = CString(m_pathProcessor.GetProgramPath()) + _T("\\"); + return m_spLog->GetLogFileData(); +} -#ifdef _WIN64 - strPath += _T("chext64.dll"); -#else - strPath += _T("chext.dll"); -#endif +logger::TMultiLoggerConfigPtr CCopyHandlerApp::GetEngineLoggerConfig() const +{ + return m_spEngineLoggerConfig; +} +TShellExtensionConfigPtr CCopyHandlerApp::GetShellExtensionConfig() const +{ + return m_shellExtConfig; +} + +void CCopyHandlerApp::RegisterShellExtension() +{ long lExtensionVersion = 0; CString strExtensionVersion; - HRESULT hResult = m_tShellExtClient.RegisterShellExtDll(strPath, PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4, + ERegistrationResult eResult = m_tShellExtClient.RegisterShellExtDll(PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4, lExtensionVersion, strExtensionVersion); - if(FAILED(hResult)) - { - // normal failure - chcore::TString strError = chcore::TWin32ErrorFormatter::FormatWin32ErrorCode(hResult, true); - ictranslate::CFormat fmt(GetResManager().LoadString(IDS_REGISTERERR_STRING)); - fmt.SetParam(_T("%errno"), (unsigned long)hResult); - fmt.SetParam(_T("%errdesc"), strError.c_str()); - AfxMessageBox(fmt, MB_ICONERROR | MB_OK); - } - else if(hResult == S_FALSE) + switch(eResult) { - // registered ok, but incompatible versions - probably restart required - CString strMsg; - strMsg.Format(_T("Registration succeeded, but still the shell extension has different version (0x%lx) than Copy Handler (0x%lx)."), (unsigned long)lExtensionVersion, (unsigned long)(PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4)); - LOG_WARNING(strMsg); + case eFailure: + MsgBox(IDS_REGISTERERR_STRING, MB_ICONERROR | MB_OK); + break; - MsgBox(IDS_SHELL_EXTENSION_REGISTERED_MISMATCH_STRING, MB_ICONWARNING | MB_OK); - } - else if(hResult == S_OK) + case eSuccessNative: + MsgBox(IDS_REGISTERED_ONLYNATIVE, MB_ICONWARNING | MB_OK); + break; + + case eSuccess32Bit: + MsgBox(IDS_REGISTERED_ONLY32BIT, MB_ICONWARNING | MB_OK); + break; + + case eSuccessNeedRestart: + { + // registered ok, but incompatible versions - probably restart required + CString strMsg; + strMsg.Format(_T("Registration succeeded, but still the shell extension has different version (0x%lx) than Copy Handler (0x%lx)."), (unsigned long)lExtensionVersion, (unsigned long)(PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4)); + LOG_WARNING(m_spLog) << strMsg; + + MsgBox(IDS_SHELL_EXTENSION_REGISTERED_MISMATCH_STRING, MB_ICONWARNING | MB_OK); + break; + } + + case eSuccess: MsgBox(IDS_REGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); + break; + } } void CCopyHandlerApp::UnregisterShellExtension() { - CString strPath = CString(m_pathProcessor.GetProgramPath()) + _T("\\"); - -#ifdef _WIN64 - strPath += _T("chext64.dll"); -#else - strPath += _T("chext.dll"); -#endif - - HRESULT hResult = m_tShellExtClient.UnRegisterShellExtDll(strPath); - if(hResult == TYPE_E_REGISTRYACCESS) + ERegistrationResult eResult = m_tShellExtClient.UnRegisterShellExtDll(); + switch(eResult) { - MsgBox(IDS_CHEXT_ALREADY_UNREGISTERED, MB_ICONINFORMATION | MB_OK); - } - else if(FAILED(hResult)) - { - chcore::TString strError = chcore::TWin32ErrorFormatter::FormatWin32ErrorCode(hResult, true); + case eSuccess: + case eSuccessNative: + case eSuccess32Bit: + MsgBox(IDS_UNREGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); + break; - ictranslate::CFormat fmt(GetResManager().LoadString(IDS_UNREGISTERERR_STRING)); - fmt.SetParam(_T("%errno"), (unsigned long)hResult); - fmt.SetParam(_T("%errdesc"), strError.c_str()); - - AfxMessageBox(fmt, MB_ICONERROR | MB_OK); + case eFailure: + MsgBox(IDS_UNREGISTERERR_STRING, MB_ICONERROR | MB_OK); + break; } - else if(hResult == S_OK) - MsgBox(IDS_UNREGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); } void CCopyHandlerApp::OnConfigNotify(const chcore::TStringSet& setPropNames) { + chcore::TConfig& rCfg = GetConfig(); + // is this language if(setPropNames.HasValue(PropData::GetPropertyName())) { @@ -653,26 +642,32 @@ GetResManager().SetLanguage(m_pathProcessor.ExpandPath(strPath)); } - if(setPropNames.HasValue(PropData::GetPropertyName())) - { - chcore::TLogger& rLogger = chcore::TLogger::Acquire(); + if(setPropNames.HasValue(PropData::GetPropertyName())) + logger::TAsyncMultiLogger::GetInstance()->SetMaxLogSize(GetPropValue(GetConfig())); + if(setPropNames.HasValue(PropData::GetPropertyName())) + logger::TAsyncMultiLogger::GetInstance()->SetMaxRotatedCount(GetPropValue(GetConfig())); - rLogger.Enable(GetPropValue(GetConfig())); - } + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spLog->GetLogFileData()->GetMultiLoggerConfig()->SetLogLevel(L"default", (logger::ESeverityLevel)GetPropValue(rCfg)); - if(setPropNames.HasValue(PropData::GetPropertyName())) + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spEngineLoggerConfig->SetLogLevel(L"default", (logger::ESeverityLevel)GetPropValue(rCfg)); + if(setPropNames.HasValue(PropData::GetPropertyName())) { - chcore::TLogger& rLogger = chcore::TLogger::Acquire(); - - rLogger.set_log_level(GetPropValue(GetConfig())); + m_spEngineLoggerConfig->SetLogLevel(L"Filesystem", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"Filesystem-File", (logger::ESeverityLevel)GetPropValue(rCfg)); + m_spEngineLoggerConfig->SetLogLevel(L"DataBuffer", (logger::ESeverityLevel)GetPropValue(rCfg)); } - - if(setPropNames.HasValue(PropData::GetPropertyName())) - { - chcore::TLogger& rLogger = chcore::TLogger::Acquire(); - - rLogger.set_max_size(GetPropValue(GetConfig())); - } + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spEngineLoggerConfig->SetLogLevel(L"Task", (logger::ESeverityLevel)GetPropValue(rCfg)); + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spEngineLoggerConfig->SetLogLevel(L"ST-FastMove", (logger::ESeverityLevel)GetPropValue(rCfg)); + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spEngineLoggerConfig->SetLogLevel(L"ST-CopyMove", (logger::ESeverityLevel)GetPropValue(rCfg)); + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spEngineLoggerConfig->SetLogLevel(L"ST-Delete", (logger::ESeverityLevel)GetPropValue(rCfg)); + if(setPropNames.HasValue(PropData::GetPropertyName())) + m_spEngineLoggerConfig->SetLogLevel(L"ST-ScanDirs", (logger::ESeverityLevel)GetPropValue(rCfg)); } void CCopyHandlerApp::OnResManNotify(UINT uiType) @@ -755,14 +750,21 @@ int CCopyHandlerApp::ExitInstance() { - LOG_INFO(_T("Pre-exit step - releasing shell extension")); + LOG_INFO(m_spLog) << _T("Pre-exit step - releasing shell extension"); m_tShellExtClient.Close(); - LOG_INFO(_T("Pre-exit step - uninitializing COM")); - CoUninitialize(); + if(m_bComInitialized) + { + LOG_INFO(m_spLog) << _T("Pre-exit step - uninitializing COM"); + CoUninitialize(); + } + else + LOG_WARNING(m_spLog) << _T("COM was not initialized by CH. Leaving uninit to original caller."); - LOG_INFO(_T("============================ Leaving Copy Handler ============================")); + LOG_INFO(m_spLog) << _T("============================ Leaving Copy Handler ============================"); + logger::TAsyncMultiLogger::GetInstance()->FinishLogging(); + return __super::ExitInstance(); }