Index: .gitignore =================================================================== diff -u -N -r4a481bbe77043e0bda2435c6d62a02700b3e46c5 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- .gitignore (.../.gitignore) (revision 4a481bbe77043e0bda2435c6d62a02700b3e46c5) +++ .gitignore (.../.gitignore) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -8,6 +8,7 @@ *.opendb *.aps *.db +*.bak src/ch/help/HTMLDefines.h src/ch/help/*/HTMLDefines.h src/ch/help/*/*.chm Index: src/chext/DropMenuExt.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -25,22 +25,20 @@ #include "ShellPathsHelpers.h" #include "../common/TShellExtMenuConfig.h" #include "../libchcore/TSharedMemory.h" -#include "TLogger.h" +#include "Logger.h" #include "ShellExtensionVerifier.h" #include "HResultFormatter.h" ///////////////////////////////////////////////////////////////////////////// // CDropMenuExt CDropMenuExt::CDropMenuExt() : - m_piShellExtControl(nullptr) + m_piShellExtControl(nullptr), + m_spLog(GetLogger(L"CDropMenuExt")) { - BOOST_LOG_FUNC(); - HRESULT hResult = CoCreateInstance(CLSID_CShellExtControl, nullptr, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); - TLogger& rLogger = Logger::get(); - BOOST_LOG_HRESULT(rLogger, hResult) << L"CoCreateInstance()"; + LOG_HRESULT(m_spLog, hResult) << L"Create instance of ShellExtControl"; } CDropMenuExt::~CDropMenuExt() @@ -54,28 +52,25 @@ STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Initializing"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - // When called: // 1. R-click on a directory // 2. R-click on a directory background // 3. Pressed Ctrl+C, Ctrl+X on a specified file/directory if(!pidlFolder && !piDataObject) { - BOOST_LOG_SEV(rLogger, error) << L"Missing both pointers."; + LOG_ERROR(m_spLog) << L"Missing both pointers."; return E_FAIL; } if(!pidlFolder || !piDataObject) - BOOST_LOG_SEV(rLogger, warning) << L"Missing at least one parameter - it's unexpected."; + LOG_WARNING(m_spLog) << L"Missing at least one parameter - it's unexpected."; if(!piDataObject) { - BOOST_LOG_SEV(rLogger, error) << L"Missing piDataObject."; + LOG_ERROR(m_spLog) << L"Missing piDataObject."; return E_FAIL; } @@ -85,21 +80,20 @@ return E_FAIL; HRESULT hResult = ReadShellConfig(); + LOG_HRESULT(m_spLog, hResult) << L"Read shell config"; if(SUCCEEDED(hResult)) + { hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject); + LOG_HRESULT(m_spLog, hResult) << L"Gather data from initialize"; + } - BOOST_LOG_HRESULT(rLogger, hResult) << L""; - return hResult; } STDMETHODIMP CDropMenuExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Querying context menu"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - // check options HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); if(!hWnd) @@ -124,11 +118,8 @@ STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Invoking command"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); if(hWnd == nullptr) return E_FAIL; @@ -176,11 +167,8 @@ STDMETHODIMP CDropMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Retrieving command string for cmd: " << idCmd; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - memset(pszName, 0, cchMax); if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA) @@ -231,10 +219,6 @@ HRESULT CDropMenuExt::ReadShellConfig() { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - try { HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); @@ -245,7 +229,7 @@ unsigned long ulSHMID = GetTickCount(); if(::SendMessage(hWnd, WM_GETCONFIG, eLocation_DragAndDropMenu, ulSHMID) != TRUE) { - BOOST_LOG_SEV(rLogger, error) << L"Failed to retrieve configuration from Copy Handler"; + LOG_ERROR(m_spLog) << L"Failed to retrieve configuration from Copy Handler"; return E_FAIL; } Index: src/chext/DropMenuExt.h =================================================================== diff -u -N -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/DropMenuExt.h (.../DropMenuExt.h) (revision 633a533cb6e741d44fe28aa56339e1d2709b1b27) +++ src/chext/DropMenuExt.h (.../DropMenuExt.h) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -23,6 +23,7 @@ #include "TContextMenuHandler.h" #include "..\common\TShellExtMenuConfig.h" #include "TShellExtData.h" +#include "..\liblogger\TLogger.h" ///////////////////////////////////////////////////////////////////////////// // CDropMenuExt @@ -66,10 +67,10 @@ TContextMenuHandler m_tContextMenuHandler; -// TActionSelector m_asSelector; - chcore::TPathContainer m_vPaths; chcore::TSmartPath m_pathPidl; + + logger::TLoggerPtr m_spLog; }; #endif //__DROPMENUEXT_H_ Index: src/chext/Logger.cpp =================================================================== diff -u -N --- src/chext/Logger.cpp (revision 0) +++ src/chext/Logger.cpp (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -0,0 +1,98 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "Logger.h" + +#include +#include "../liblogger/TMultiLoggerConfig.h" +#include "../liblogger/TAsyncMultiLogger.h" + +namespace +{ + struct LoggerInfo + { + std::wstring strLogPath; + DWORD dwMinLogLevel = 0; + }; + + bool ReadLoggerConfig(LoggerInfo& rInfo) + { + HKEY hKeyShellExt = nullptr; + LSTATUS lStatus = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\CopyHandler\\ShellExtension"), 0, KEY_QUERY_VALUE, &hKeyShellExt); + if(lStatus != ERROR_SUCCESS) + return false; + + // log path + DWORD dwType = REG_SZ; + const DWORD stMaxBuffer = 1024; + std::unique_ptr buf(new wchar_t[stMaxBuffer]); + + DWORD dwCount = stMaxBuffer; + lStatus = RegQueryValueEx(hKeyShellExt, L"LogPath", nullptr, &dwType, (BYTE*)buf.get(), &dwCount); + if(lStatus != ERROR_SUCCESS) + { + RegCloseKey(hKeyShellExt); + return false; + } + + buf[ dwCount / 2 ] = L'\0'; + rInfo.strLogPath = buf.get(); + + // log level + dwType = REG_DWORD; + dwCount = sizeof(DWORD); + DWORD dwValue = 0; + lStatus = RegQueryValueEx(hKeyShellExt, L"MinLogLevel", nullptr, &dwType, (BYTE*)&dwValue, &dwCount); + if(lStatus != ERROR_SUCCESS) + { + RegCloseKey(hKeyShellExt); + return false; + } + + rInfo.dwMinLogLevel = dwValue; + + RegCloseKey(hKeyShellExt); + + return true; + } + + logger::TLogFileDataPtr CreateLoggerData() + { + LoggerInfo li; + if(ReadLoggerConfig(li)) + { + logger::TMultiLoggerConfigPtr spConfig(std::make_shared()); + spConfig->SetLogLevel(L"default", (logger::ESeverityLevel)li.dwMinLogLevel); + + DWORD dwProcessId = GetProcessId(GetCurrentProcess()); + boost::replace_all(li.strLogPath, L"%pid%", boost::lexical_cast(dwProcessId)); + + return logger::TAsyncMultiLogger::GetInstance()->CreateLoggerData(li.strLogPath.c_str(), spConfig); + } + + logger::TLogFileDataPtr spLogData(std::make_shared()); + return spLogData; + } +} + +logger::TLoggerPtr GetLogger(PCTSTR pszChannel) +{ + static logger::TLogFileDataPtr spLogFileData = CreateLoggerData(); + return logger::MakeLogger(spLogFileData, pszChannel); +} Index: src/chext/Logger.h =================================================================== diff -u -N --- src/chext/Logger.h (revision 0) +++ src/chext/Logger.h (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -0,0 +1,62 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __LOGGER_H__ +#define __LOGGER_H__ + +#include "HResultFormatter.h" +#include "../liblogger/SeverityLevels.h" +#include "../liblogger/TLogger.h" + +// logging helpers +namespace details +{ + inline logger::ESeverityLevel HRESULT2Severity(HRESULT hResult) + { + return (SUCCEEDED(hResult)) ? logger::debug : logger::error; + } +} + +logger::TLoggerPtr GetLogger(PCTSTR pszChannel); + +#define LOG_HRESULT(lg, hr)\ + LOG(lg, details::HRESULT2Severity(hr)) << L" <" << HResultFormatter::FormatHResult(hr) << L"> " + +#define LOG_PARAM(param)\ + #param << "=" << param + +#define LOG_PARAMS2(a1, a2)\ + LOG_PARAM(a1) << ", " << LOG_PARAM(a2) +#define LOG_PARAMS3(a1, a2, a3)\ + LOG_PARAMS2(a1, a2) << ", " << LOG_PARAM(a3) +#define LOG_PARAMS4(a1, a2, a3, a4)\ + LOG_PARAMS3(a1, a2, a3) << ", " << LOG_PARAM(a4) +#define LOG_PARAMS5(a1, a2, a3, a4, a5)\ + LOG_PARAMS4(a1, a2, a3, a4) << ", " << LOG_PARAM(a5) +#define LOG_PARAMS6(a1, a2, a3, a4, a5, a6)\ + LOG_PARAMS5(a1, a2, a3, a4, a5) << ", " << LOG_PARAM(a6) +#define LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7)\ + LOG_PARAMS6(a1, a2, a3, a4, a5, a6) << ", " << LOG_PARAM(a7) +#define LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8)\ + LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7) << ", " << LOG_PARAM(a8) +#define LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9)\ + LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8) << ", " << LOG_PARAM(a9) +#define LOG_PARAMS10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)\ + LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9) << ", " << LOG_PARAM(a10) + +#endif Index: src/chext/TLogger.h =================================================================== diff -u -N --- src/chext/TLogger.h (revision bfc7a8378a96c5b58def559b343918fca32f05a6) +++ src/chext/TLogger.h (revision 0) @@ -1,69 +0,0 @@ -// ============================================================================ -// Copyright (C) 2001-2015 by Jozef Starosczyk -// ixen@copyhandler.com -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU Library General Public License -// (version 2) as published by the Free Software Foundation; -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ============================================================================ -#ifndef __TLOGGER_H__ -#define __TLOGGER_H__ - -#include -#include -#include -#include -#include "HResultFormatter.h" - -// ugly way to include severity_level in the global namespace -using namespace boost::log::trivial; - -typedef boost::log::sources::wseverity_logger_mt TLogger; - -BOOST_LOG_GLOBAL_LOGGER(Logger, TLogger) - -// logging helpers -namespace details -{ - inline severity_level HRESULT2Severity(HRESULT hResult) - { - return (SUCCEEDED(hResult)) ? debug : error; - } -} - -#define BOOST_LOG_HRESULT(lg, hr)\ - BOOST_LOG_SEV(lg, details::HRESULT2Severity(hr)) << L" <" << HResultFormatter::FormatHResult(hr) << L"> " - -#define LOG_PARAM(param)\ - #param << "=" << param - -#define LOG_PARAMS2(a1, a2)\ - LOG_PARAM(a1) << ", " << LOG_PARAM(a2) -#define LOG_PARAMS3(a1, a2, a3)\ - LOG_PARAMS2(a1, a2) << ", " << LOG_PARAM(a3) -#define LOG_PARAMS4(a1, a2, a3, a4)\ - LOG_PARAMS3(a1, a2, a3) << ", " << LOG_PARAM(a4) -#define LOG_PARAMS5(a1, a2, a3, a4, a5)\ - LOG_PARAMS4(a1, a2, a3, a4) << ", " << LOG_PARAM(a5) -#define LOG_PARAMS6(a1, a2, a3, a4, a5, a6)\ - LOG_PARAMS5(a1, a2, a3, a4, a5) << ", " << LOG_PARAM(a6) -#define LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7)\ - LOG_PARAMS6(a1, a2, a3, a4, a5, a6) << ", " << LOG_PARAM(a7) -#define LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8)\ - LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7) << ", " << LOG_PARAM(a8) -#define LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9)\ - LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8) << ", " << LOG_PARAM(a9) -#define LOG_PARAMS10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)\ - LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9) << ", " << LOG_PARAM(a10) - -#endif Index: src/chext/MenuExt.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -29,7 +29,7 @@ #include "../libchcore/TTaskDefinition.h" #include #include "ShellExtensionVerifier.h" -#include "TLogger.h" +#include "Logger.h" // globals static void CutAmpersands(LPTSTR lpszString) @@ -50,13 +50,11 @@ ///////////////////////////////////////////////////////////////////////////// // CMenuExt CMenuExt::CMenuExt() : - m_piShellExtControl(nullptr) + m_piShellExtControl(nullptr), + m_spLog(GetLogger(L"CMenuExt")) { - BOOST_LOG_FUNC(); - HRESULT hResult = CoCreateInstance(CLSID_CShellExtControl, nullptr, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); - TLogger& rLogger = Logger::get(); - BOOST_LOG_HRESULT(rLogger, hResult) << LOG_PARAM(m_piShellExtControl); + LOG_HRESULT(m_spLog, hResult) << L"Creation of ShellExtControl " << LOG_PARAM(m_piShellExtControl); } CMenuExt::~CMenuExt() @@ -70,14 +68,11 @@ STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Initializing"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - if(!pidlFolder && !piDataObject) { - BOOST_LOG_SEV(rLogger, error) << L"Missing both pointers."; + LOG_ERROR(m_spLog) << L"Missing both pointers."; return E_INVALIDARG; } @@ -87,21 +82,21 @@ return S_OK; HRESULT hResult = ReadShellConfig(); + LOG_HRESULT(m_spLog, hResult) << L"Read shell config"; + if(SUCCEEDED(hResult)) + { hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject); + LOG_HRESULT(m_spLog, hResult) << L"Gather data from initialize"; + } - BOOST_LOG_HRESULT(rLogger, hResult) << L""; - return hResult; } STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Querying context menu"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - // check options HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); if(!hWnd) @@ -156,11 +151,8 @@ STDMETHODIMP CMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Invoking command"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - // textual verbs are not supported by this extension if(HIWORD(lpici->lpVerb) != 0) return E_FAIL; @@ -218,11 +210,8 @@ HRESULT CMenuExt::HandleMenuMsg2(UINT uMsg, WPARAM /*wParam*/, LPARAM lParam, LRESULT* /*plResult*/) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Handle menu message (2)"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - switch(uMsg) { case WM_INITMENUPOPUP: @@ -279,14 +268,11 @@ HRESULT CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Drawing menu item"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - if(!lpdis) { - BOOST_LOG_SEV(rLogger, error) << L"Missing argument"; + LOG_ERROR(m_spLog) << L"Missing argument"; return E_FAIL; } @@ -346,11 +332,8 @@ STDMETHODIMP CMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Retrieving command string for cmd " << idCmd; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - memset(pszName, 0, cchMax); if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA) @@ -388,10 +371,6 @@ HRESULT CMenuExt::ReadShellConfig() { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - try { HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); @@ -402,7 +381,7 @@ unsigned long ulSHMID = GetTickCount(); if(::SendMessage(hWnd, WM_GETCONFIG, eLocation_ContextMenu, ulSHMID) != TRUE) { - BOOST_LOG_SEV(rLogger, error) << L"Failed to retrieve configuration from Copy Handler"; + LOG_ERROR(m_spLog) << L"Failed to retrieve configuration from Copy Handler"; return E_FAIL; } Index: src/chext/MenuExt.h =================================================================== diff -u -N -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/MenuExt.h (.../MenuExt.h) (revision 633a533cb6e741d44fe28aa56339e1d2709b1b27) +++ src/chext/MenuExt.h (.../MenuExt.h) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -23,6 +23,7 @@ #include "TContextMenuHandler.h" #include "..\common\TShellExtMenuConfig.h" #include "TShellExtData.h" +#include "..\liblogger\TLogger.h" class TShellMenuItem; @@ -71,6 +72,7 @@ TContextMenuHandler m_tContextMenuHandler; IShellExtControl* m_piShellExtControl; + logger::TLoggerPtr m_spLog; }; #endif //__MENUEXT_H_ Index: src/chext/ShellExtControl.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -21,30 +21,28 @@ #include #include "ShellExtControl.h" #include "../common/version.h" -#include "TLogger.h" +#include "Logger.h" CShellExtControl::CShellExtControl() : m_pShellExtData(nullptr), m_hMemory(nullptr), - m_hMutex(nullptr) + m_hMutex(nullptr), + m_spLog(GetLogger(L"ShellExtControl")) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Constructing CShellExtControl"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - // create protection mutex m_hMutex = ::CreateMutex(nullptr, FALSE, _T("CHShellExtControlDataMutex")); if(!m_hMutex) { - BOOST_LOG_SEV(rLogger, error) << L"Cannot create mutex."; + LOG_ERROR(m_spLog) << L"Cannot create mutex."; return; } DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); if(dwRes != WAIT_OBJECT_0) { - BOOST_LOG_SEV(rLogger, error) << L"Timeout or fail waiting for mutex."; + LOG_ERROR(m_spLog) << L"Timeout or fail waiting for mutex."; ReleaseMutex(m_hMutex); return; } @@ -54,7 +52,7 @@ DWORD dwLastError = GetLastError(); // NOTE: last error is needed also for success case (for already exists status) if(!m_hMemory) { - BOOST_LOG_HRESULT(rLogger, dwLastError) << L"Cannot create file mapping."; + LOG_HRESULT(m_spLog, dwLastError) << L"Cannot create file mapping."; ReleaseMutex(m_hMutex); CloseHandle(m_hMutex); return; @@ -65,7 +63,7 @@ { DWORD dwError = GetLastError(); // NOTE: do not overwrite dwLastError, as the value is needed later - BOOST_LOG_HRESULT(rLogger, dwError) << L"Cannot map view of file."; + LOG_HRESULT(m_spLog, dwError) << L"Cannot map view of file."; ReleaseMutex(m_hMutex); CloseHandle(m_hMutex); CloseHandle(m_hMemory); @@ -77,11 +75,11 @@ { if(dwLastError == ERROR_SUCCESS) { - BOOST_LOG_SEV(rLogger, debug) << L"Copy Handler is not running. Disabling shell extension."; + LOG_DEBUG(m_spLog) << L"Copy Handler is not running. Disabling shell extension."; } else { - BOOST_LOG_HRESULT(rLogger, dwLastError) << L"Copy Handler is not running. Disabling shell extension."; + LOG_HRESULT(m_spLog, dwLastError) << L"Copy Handler is not running. Disabling shell extension."; } m_pShellExtData->m_lFlags = 0; m_pShellExtData->m_lID = GetTickCount(); @@ -106,48 +104,42 @@ STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion, BSTR* pbstrVersion) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << "Retrieving version"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << ""; - if(!plVersion || !pbstrVersion || (*pbstrVersion)) { - BOOST_LOG_SEV(rLogger, error) << "Invalid arguments."; + LOG_ERROR(m_spLog) << "Invalid arguments."; return E_INVALIDARG; } (*plVersion) = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; _bstr_t strVer(SHELLEXT_PRODUCT_FULL_VERSION); *pbstrVersion = strVer.Detach(); - BOOST_LOG_SEV(rLogger, debug) << LOG_PARAMS2(*plVersion, *pbstrVersion); + LOG_DEBUG(m_spLog) << LOG_PARAMS2(*plVersion, *pbstrVersion); return S_OK; } STDMETHODIMP CShellExtControl::SetFlags(LONG lFlags, LONG lMask) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << L"Setting flags: " << LOG_PARAMS2(lFlags, lMask); - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << LOG_PARAMS2(lFlags, lMask); - if(!m_hMutex || !m_pShellExtData) { - BOOST_LOG_SEV(rLogger, error) << "Wrong internal state."; + LOG_ERROR(m_spLog) << "Wrong internal state."; return E_FAIL; } DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); if(dwRes != WAIT_OBJECT_0) { - BOOST_LOG_SEV(rLogger, error) << "Failed waiting for mutex."; + LOG_ERROR(m_spLog) << "Failed waiting for mutex."; return E_FAIL; } m_pShellExtData->m_lFlags = (m_pShellExtData->m_lFlags & ~lMask) | (lFlags & lMask); - BOOST_LOG_SEV(rLogger, debug) << LOG_PARAM(m_pShellExtData->m_lFlags); + LOG_DEBUG(m_spLog) << L"Set flags: " << LOG_PARAM(m_pShellExtData->m_lFlags); ReleaseMutex(m_hMutex); @@ -156,33 +148,30 @@ STDMETHODIMP CShellExtControl::GetFlags(LONG* plFlags) { - BOOST_LOG_FUNC(); + LOG_DEBUG(m_spLog) << "Retrieving flags"; - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << ""; - if(!m_hMutex || !m_pShellExtData) { - BOOST_LOG_SEV(rLogger, error) << "Wrong internal state."; + LOG_ERROR(m_spLog) << "Wrong internal state."; return E_FAIL; } if(!plFlags) { - BOOST_LOG_SEV(rLogger, error) << "Invalid argument."; + LOG_ERROR(m_spLog) << "Invalid argument."; return E_INVALIDARG; } DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); if(dwRes != WAIT_OBJECT_0) { - BOOST_LOG_SEV(rLogger, error) << "Failed waiting for mutex."; + LOG_ERROR(m_spLog) << "Failed waiting for mutex."; return E_FAIL; } (*plFlags) = m_pShellExtData->m_lFlags; - BOOST_LOG_SEV(rLogger, debug) << "Returning flags. " << LOG_PARAM(m_pShellExtData->m_lFlags); + LOG_DEBUG(m_spLog) << "Returning flags: " << LOG_PARAM(m_pShellExtData->m_lFlags); ReleaseMutex(m_hMutex); Index: src/chext/ShellExtControl.h =================================================================== diff -u -N -rd5c3edd0d167db9b5d47d04248820fda49499a5e -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/ShellExtControl.h (.../ShellExtControl.h) (revision d5c3edd0d167db9b5d47d04248820fda49499a5e) +++ src/chext/ShellExtControl.h (.../ShellExtControl.h) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -20,6 +20,7 @@ #define __SHELLEXTCONTROL_H_ #include "resource.h" // main symbols +#include "..\liblogger\TLogger.h" ///////////////////////////////////////////////////////////////////////////// // CDropMenuExt @@ -55,6 +56,7 @@ } *m_pShellExtData; CComAutoCriticalSection m_lock; + logger::TLoggerPtr m_spLog; }; #endif //__SHELLEXTCONTROL_H_ Index: src/chext/ShellExtensionVerifier.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/ShellExtensionVerifier.cpp (.../ShellExtensionVerifier.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/ShellExtensionVerifier.cpp (.../ShellExtensionVerifier.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -18,24 +18,24 @@ // ============================================================================ #include "stdafx.h" #include "ShellExtensionVerifier.h" -#include "TLogger.h" +#include "Logger.h" HWND ShellExtensionVerifier::VerifyShellExt(IShellExtControl* piShellExtControl) { - TLogger& rLogger = Logger::get(); + logger::TLoggerPtr rLogger = GetLogger(L"ShellExtVerifier"); HRESULT hResult = IsShellExtEnabled(piShellExtControl); if(FAILED(hResult) || hResult == S_FALSE) { - BOOST_LOG_SEV(rLogger, debug) << L"Shell extension is disabled."; + LOG_DEBUG(rLogger) << L"Shell extension is disabled."; return nullptr; } // find CH's window HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); if(!hWnd) { - BOOST_LOG_SEV(rLogger, debug) << L"Cannot find Copy Handler's window."; + LOG_DEBUG(rLogger) << L"Cannot find Copy Handler's window."; return nullptr; } @@ -54,6 +54,6 @@ if(lFlags & eShellExt_Enabled) return S_OK; - else - return S_FALSE; + + return S_FALSE; } Index: src/chext/TLogger.cpp =================================================================== diff -u -N --- src/chext/TLogger.cpp (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/TLogger.cpp (revision 0) @@ -1,137 +0,0 @@ -// ============================================================================ -// Copyright (C) 2001-2015 by Jozef Starosczyk -// ixen@copyhandler.com -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU Library General Public License -// (version 2) as published by the Free Software Foundation; -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ============================================================================ -#include "stdafx.h" -#include "TLogger.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace logging = boost::log; -namespace src = boost::log::sources; -namespace sinks = boost::log::sinks; -namespace keywords = boost::log::keywords; -namespace expr = boost::log::expressions; -namespace attrs = boost::log::attributes; - -namespace -{ - struct LoggerInfo - { - std::wstring strLogPath; - DWORD dwMinLogLevel = 0; - }; - - bool ReadLoggerConfig(LoggerInfo& rInfo) - { - HKEY hKeyShellExt = nullptr; - LSTATUS lStatus = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\CopyHandler\\ShellExtension"), 0, KEY_QUERY_VALUE, &hKeyShellExt); - if(lStatus != ERROR_SUCCESS) - return false; - - // log path - DWORD dwType = REG_SZ; - const DWORD stMaxBuffer = 1024; - std::unique_ptr buf(new wchar_t[stMaxBuffer]); - - DWORD dwCount = stMaxBuffer; - lStatus = RegQueryValueEx(hKeyShellExt, L"LogPath", nullptr, &dwType, (BYTE*)buf.get(), &dwCount); - if(lStatus != ERROR_SUCCESS) - { - RegCloseKey(hKeyShellExt); - return false; - } - - buf[ dwCount / 2 ] = L'\0'; - rInfo.strLogPath = buf.get(); - - // log level - dwType = REG_DWORD; - dwCount = sizeof(DWORD); - DWORD dwValue = 0; - lStatus = RegQueryValueEx(hKeyShellExt, L"MinLogLevel", nullptr, &dwType, (BYTE*)&dwValue, &dwCount); - if(lStatus != ERROR_SUCCESS) - { - RegCloseKey(hKeyShellExt); - return false; - } - - rInfo.dwMinLogLevel = dwValue; - - RegCloseKey(hKeyShellExt); - - return true; - } -} - -BOOST_LOG_GLOBAL_LOGGER_INIT(Logger, TLogger) -{ - LoggerInfo li; - if(ReadLoggerConfig(li)) - { - DWORD dwProcessId = GetProcessId(GetCurrentProcess()); - boost::replace_all(li.strLogPath, L"%pid%", boost::lexical_cast(dwProcessId)); - - logging::add_common_attributes(); - logging::core::get()->add_global_attribute("Scope", attrs::named_scope()); - - auto sink = logging::add_file_log( - keywords::file_name = li.strLogPath, - keywords::rotation_size = 10 * 1024 * 1024, - keywords::open_mode = (std::ios::out | std::ios::app), - keywords::format = - ( - expr::stream - << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "[%Y-%m-%d %H:%M:%S]") - << "[" << severity << "]: " - << expr::wmessage - << expr::if_(expr::has_attr("Scope")) - [ - expr::stream - << " (" - << expr::format_named_scope("Scope", - keywords::format = "%n", - keywords::depth = 1, - keywords::iteration = expr::forward) - << ")" - ] - ) - ); - - std::locale loc = boost::locale::generator()("en_EN.UTF-8"); - sink->imbue(loc); - - severity_level eSeverity = (severity_level)li.dwMinLogLevel; - logging::core::get()->set_filter( - severity >= eSeverity - ); - } - - boost::log::sources::wseverity_logger_mt lg; - return lg; -} Index: src/chext/chext.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/chext.cpp (.../chext.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/chext.cpp (.../chext.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -24,23 +24,16 @@ #include "resource.h" #include "chext.h" #include "dllmain.h" -#include "TLogger.h" +#include "Logger.h" #include "GuidFormatter.h" ///////////////////////////////////////////////////////////////////////////// // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow() { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - HRESULT hResult = _AtlModule.DllCanUnloadNow(); - BOOST_LOG_HRESULT(rLogger, hResult) << L""; - return hResult; } @@ -49,15 +42,8 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - HRESULT hResult = _AtlModule.DllGetClassObject(rclsid, riid, ppv); - BOOST_LOG_HRESULT(rLogger, hResult) << L"clsid=" << GuidFormatter::FormatGuid(rclsid) << ", riid=" << GuidFormatter::FormatGuid(riid) << ", ppv=" << ppv; - return hResult; } @@ -66,16 +52,9 @@ STDAPI DllRegisterServer() { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - // registers object, typelib and all interfaces in typelib HRESULT hResult = _AtlModule.DllRegisterServer(); - BOOST_LOG_HRESULT(rLogger, hResult) << L""; - return hResult; } @@ -84,28 +63,15 @@ STDAPI DllUnregisterServer() { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - HRESULT hResult = _AtlModule.DllUnregisterServer(); - BOOST_LOG_HRESULT(rLogger, hResult) << L""; - return hResult; } // DllInstall - Adds/Removes entries to the system registry per user // per machine. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) { - BOOST_LOG_FUNC(); - - TLogger& rLogger = Logger::get(); - BOOST_LOG_SEV(rLogger, debug) << L""; - - HRESULT hr = E_FAIL; static const wchar_t szUserSwitch[] = _T("user"); if (pszCmdLine != nullptr) @@ -114,23 +80,15 @@ AtlSetPerUserRegistration(true); } + HRESULT hResult = E_FAIL; if (bInstall) { - hr = DllRegisterServer(); - if (FAILED(hr)) + hResult = DllRegisterServer(); + if (FAILED(hResult)) DllUnregisterServer(); } else - hr = DllUnregisterServer(); + hResult = DllUnregisterServer(); - if(pszCmdLine) - { - BOOST_LOG_HRESULT(rLogger, hr) << LOG_PARAMS2(bInstall, pszCmdLine); - } - else - { - BOOST_LOG_HRESULT(rLogger, hr) << LOG_PARAM(bInstall); - } - - return hr; + return hResult; } Index: src/chext/chext.vc140.vcxproj =================================================================== diff -u -N -r4a481bbe77043e0bda2435c6d62a02700b3e46c5 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/chext.vc140.vcxproj (.../chext.vc140.vcxproj) (revision 4a481bbe77043e0bda2435c6d62a02700b3e46c5) +++ src/chext/chext.vc140.vcxproj (.../chext.vc140.vcxproj) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -553,7 +553,7 @@ - + @@ -596,7 +596,7 @@ - + @@ -654,6 +654,9 @@ {cbbf380b-7b16-4a1e-8194-758dad7d8011} + + {df9957d4-3d95-4ac3-ad3f-dcbea058f79d} + Index: src/chext/chext.vc140.vcxproj.filters =================================================================== diff -u -N -r3d1de44762647618faf9b5b3a87f89b293899d8d -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/chext.vc140.vcxproj.filters (.../chext.vc140.vcxproj.filters) (revision 3d1de44762647618faf9b5b3a87f89b293899d8d) +++ src/chext/chext.vc140.vcxproj.filters (.../chext.vc140.vcxproj.filters) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -65,9 +65,6 @@ Tests - - Source Files\Tools - Source Files\Tools @@ -77,6 +74,9 @@ Source Files\Tools + + Source Files\Tools + @@ -115,9 +115,6 @@ Resource Files - - Source Files\Tools - Source Files\Tools @@ -127,6 +124,9 @@ Source Files\Tools + + Source Files\Tools + Index: src/chext/dllmain.cpp =================================================================== diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/chext/dllmain.cpp (.../dllmain.cpp) (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/chext/dllmain.cpp (.../dllmain.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -4,7 +4,6 @@ #include "MenuExt.h" #include "DropMenuExt.h" #include "ShellExtControl.h" -#include "TLogger.h" CCHExtModule _AtlModule; @@ -15,31 +14,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { - if (dwReason == DLL_PROCESS_ATTACH) - { + if(dwReason == DLL_PROCESS_ATTACH) DisableThreadLibraryCalls(hInstance); - try - { - TLogger lg; - BOOST_LOG_SEV(lg, debug) << L"DllMain - attaching to process: " << hInstance << L", " << dwReason << L", " << lpReserved; - } - catch (const std::exception&) - { - } - } - else if (dwReason == DLL_PROCESS_DETACH) - { - try - { - TLogger lg; - BOOST_LOG_SEV(lg, debug) << L"DllMain - detaching from process: " << hInstance << L", " << dwReason << L", " << lpReserved; - } - catch (const std::exception&) - { - - } - } - return _AtlModule.DllMain(dwReason, lpReserved); } Index: src/liblogger/TAsyncMultiLogger.cpp =================================================================== diff -u -N -ra08ca9e12d93e9a036a5cf739348ff3ef2a58be8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/liblogger/TAsyncMultiLogger.cpp (.../TAsyncMultiLogger.cpp) (revision a08ca9e12d93e9a036a5cf739348ff3ef2a58be8) +++ src/liblogger/TAsyncMultiLogger.cpp (.../TAsyncMultiLogger.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -32,32 +32,33 @@ TAsyncMultiLogger::TAsyncMultiLogger() : m_spStopEvent(CreateEvent(nullptr, TRUE, FALSE, nullptr), CloseHandle), + m_spStoppedEvent(CreateEvent(nullptr, TRUE, TRUE, nullptr), CloseHandle), m_spGlobalRotationInfo(std::make_shared()) { if (!m_spStopEvent) throw std::runtime_error("Cannot create stop event"); } - void TAsyncMultiLogger::FinishLogging() + TAsyncMultiLogger::~TAsyncMultiLogger() { - std::unique_ptr spThread; + FinishLogging(); + } + void TAsyncMultiLogger::FinishLogging() + { + SetEvent(m_spStopEvent.get()); + if(m_hThread) { - boost::unique_lock lock(m_mutex); - SetEvent(m_spStopEvent.get()); - std::swap(m_spThread, spThread); - } + WaitForSingleObject(m_spStoppedEvent.get(), INFINITE); - if(spThread) - { - if(spThread->joinable()) - spThread->join(); + // NOTE: for some unknown reason we can't wait for the thread event in shell extension even when the thread + // exited successfully. For that reason we're synchronizing thread exit with m_spStoppedEvent. + //WaitForSingleObject(m_hThread, INFINITE); + CloseHandle(m_hThread); + m_hThread = nullptr; } - { - boost::unique_lock lock(m_mutex); - m_setLoggerData.clear(); - } + m_setLoggerData.clear(); } TLogFileDataPtr TAsyncMultiLogger::CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig) @@ -67,8 +68,8 @@ boost::unique_lock lock(m_mutex); m_setLoggerData.insert(spLogFileData); - if(!m_spThread) - m_spThread.reset(new std::thread(&TAsyncMultiLogger::LoggingThread, this)); + if(!m_hThread) + m_hThread = CreateThread(nullptr, 0, &LoggingThread, this, 0, nullptr); return spLogFileData; } @@ -88,19 +89,23 @@ m_spGlobalRotationInfo->SetRotatedCount(uiMaxRotatedCount); } - void TAsyncMultiLogger::LoggingThread() + DWORD TAsyncMultiLogger::LoggingThread(void* pParam) { + TAsyncMultiLogger* pAsyncLogger = (TAsyncMultiLogger*)pParam; + + ResetEvent(pAsyncLogger->m_spStoppedEvent.get()); + std::vector vHandles; bool bStopProcessing = false; do { { - boost::unique_lock lock(m_mutex); + boost::unique_lock lock(pAsyncLogger->m_mutex); vHandles.clear(); - vHandles.push_back(m_spStopEvent.get()); + vHandles.push_back(pAsyncLogger->m_spStopEvent.get()); - std::transform(m_setLoggerData.begin(), m_setLoggerData.end(), std::back_inserter(vHandles), [](const TLogFileDataPtr& rData) { return rData->GetEntriesEvent().get(); }); + std::transform(pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end(), std::back_inserter(vHandles), [](const TLogFileDataPtr& rData) { return rData->GetEntriesEvent().get(); }); } DWORD dwWaitResult = WaitForMultipleObjectsEx(boost::numeric_cast(vHandles.size()), &vHandles[ 0 ], FALSE, 500, FALSE); @@ -112,8 +117,8 @@ std::vector vLogs; { - boost::shared_lock lock(m_mutex); - vLogs.insert(vLogs.begin(), m_setLoggerData.begin(), m_setLoggerData.end()); + boost::shared_lock lock(pAsyncLogger->m_mutex); + vLogs.insert(vLogs.begin(), pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end()); } for (const TLogFileDataPtr& spLogData : vLogs) @@ -131,5 +136,8 @@ } } while(!bStopProcessing); + + SetEvent(pAsyncLogger->m_spStoppedEvent.get()); + return 0; } } Index: src/liblogger/TAsyncMultiLogger.h =================================================================== diff -u -N -ra08ca9e12d93e9a036a5cf739348ff3ef2a58be8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/liblogger/TAsyncMultiLogger.h (.../TAsyncMultiLogger.h) (revision a08ca9e12d93e9a036a5cf739348ff3ef2a58be8) +++ src/liblogger/TAsyncMultiLogger.h (.../TAsyncMultiLogger.h) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -38,6 +38,7 @@ public: TAsyncMultiLogger(); + ~TAsyncMultiLogger(); void FinishLogging(); TLogFileDataPtr CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig); @@ -47,7 +48,7 @@ void SetMaxRotatedCount(unsigned int uiMaxRotatedCount); private: - void LoggingThread(); + static DWORD LoggingThread(void* pParam); private: #pragma warning(push) @@ -56,7 +57,8 @@ boost::shared_mutex m_mutex; std::shared_ptr m_spStopEvent; - std::unique_ptr m_spThread; + std::shared_ptr m_spStoppedEvent; + HANDLE m_hThread = nullptr; TLoggerRotationInfoPtr m_spGlobalRotationInfo; #pragma warning(pop) Index: src/liblogger/TLogFileData.cpp =================================================================== diff -u -N -rd89ed8602b3992f26835fe68cb6e89c6d1270044 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 --- src/liblogger/TLogFileData.cpp (.../TLogFileData.cpp) (revision d89ed8602b3992f26835fe68cb6e89c6d1270044) +++ src/liblogger/TLogFileData.cpp (.../TLogFileData.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) @@ -51,18 +51,28 @@ void TLogFileData::PushLogEntry(std::wstring strLine) { - boost::unique_lock lock(m_mutex); if(m_spLogFile) { - m_listEntries.emplace_back(strLine); + boost::unique_lock lock(m_mutex); + m_listEntries.push_back(strLine); SetEvent(m_spHasEntriesEvent.get()); } } void TLogFileData::StoreLogEntries() { if(m_spLogFile) - m_spLogFile->Write(m_listEntries); + { + std::list listEntries; + + { + boost::unique_lock lock(m_mutex); + std::swap(listEntries, m_listEntries); + ResetEvent(m_spHasEntriesEvent.get()); + } + + m_spLogFile->Write(listEntries); + } } void TLogFileData::CloseUnusedFile()