Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -692,57 +692,6 @@
 			break;
 		}
 
-	case WM_GETCONFIG:
-		{
-			try
-			{
-				chcore::TConfig& rConfig = GetConfig();
-
-				TShellExtMenuConfig cfgShellExt;
-
-				// experimental - doesn't work on all systems 
-				cfgShellExt.SetShowShortcutIcons(GetPropValue<PP_SHSHOWSHELLICONS>(rConfig));
-
-				cfgShellExt.SetInterceptDragAndDrop(GetPropValue<PP_SHINTERCEPTDRAGDROP>(rConfig));
-				cfgShellExt.SetInterceptKeyboardActions(GetPropValue<PP_SHINTERCEPTKEYACTIONS>(rConfig));
-				cfgShellExt.SetInterceptCtxMenuActions(GetPropValue<PP_SHINTERCEPTCTXMENUACTIONS>(rConfig));
-
-				cfgShellExt.GetFormatter()->SetValues(
-					GetResManager().LoadString(IDS_BYTE_STRING),
-					GetResManager().LoadString(IDS_KBYTE_STRING),
-					GetResManager().LoadString(IDS_MBYTE_STRING),
-					GetResManager().LoadString(IDS_GBYTE_STRING),
-					GetResManager().LoadString(IDS_TBYTE_STRING)
-					);
-
-				cfgShellExt.SetShowFreeSpace(GetPropValue<PP_SHSHOWFREESPACE>(rConfig));
-
-				PrepareDragAndDropMenuItems(cfgShellExt);
-				PrepareNormalMenuItems(cfgShellExt);
-
-				chcore::TConfig cfgStorage;
-				chcore::TString wstrData;
-
-				cfgShellExt.StoreInConfig(cfgStorage, _T("ShellExtCfg"));
-				cfgStorage.WriteToString(wstrData);
-
-				std::wstring strSHMName = IPCSupport::GenerateSHMName((unsigned long)lParam);
-
-				m_tCHExtharedMemory.Create(strSHMName.c_str(), wstrData);
-			}
-			catch(const std::exception& e)
-			{
-				_ASSERTE(FALSE);
-				CString strMsg;
-				strMsg.Format(L"Encountered problem trying to retrieve shell ext configuration.\nReason: %S", e.what());
-				LOG_ERROR(m_spLog) << strMsg;
-
-				return FALSE;
-			}
-
-			return TRUE;
-		}
-
 	case WM_IDENTIFY:
 		{
 			//decode
@@ -794,160 +743,6 @@
 	return CWnd::WindowProc(message, wParam, lParam);
 }
 
-void CMainWnd::PrepareDragAndDropMenuItems(TShellExtMenuConfig &cfgShellExt) const
-{
-	chcore::TConfig& rConfig = GetConfig();
-	ictranslate::CResourceManager& rResManager = GetResManager();
-
-	TShellMenuItemPtr spDragAndDropRootItem = cfgShellExt.GetDragAndDropRoot();
-	bool bAddedAnyOption = false;
-	if(GetPropValue<PP_SHSHOWCOPY>(rConfig))
-	{
-		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPY_STRING), rResManager.LoadString(IDS_MENUTIPCOPY_STRING),
-			TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
-			TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeIDataObject),
-			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializePidlFolder, chcore::TSmartPath()), false, chcore::eOperation_Copy));
-		bAddedAnyOption = true;
-	}
-
-	if(GetPropValue<PP_SHSHOWMOVE>(rConfig))
-	{
-		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUMOVE_STRING), rResManager.LoadString(IDS_MENUTIPMOVE_STRING),
-			TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Move),
-			TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeIDataObject),
-			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializePidlFolder, chcore::TSmartPath()), false, chcore::eOperation_Move));
-		bAddedAnyOption = true;
-	}
-
-	if(GetPropValue<PP_SHSHOWCOPYMOVE>(rConfig))
-	{
-		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPYMOVESPECIAL_STRING), rResManager.LoadString(IDS_MENUTIPCOPYMOVESPECIAL_STRING),
-			TOperationTypeInfo(TOperationTypeInfo::eOpType_Autodetect, chcore::eOperation_Copy),
-			TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeIDataObject),
-			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializePidlFolder, chcore::TSmartPath()), true));
-		bAddedAnyOption = true;
-	}
-
-	if(bAddedAnyOption)
-	{
-		// insert separator as an addition to other items
-		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>());
-	}
-}
-
-void CMainWnd::PrepareNormalMenuItems(TShellExtMenuConfig &cfgShellExt) const
-{
-	chcore::TConfig& rConfig = GetConfig();
-	ictranslate::CResourceManager& rResManager = GetResManager();
-
-	TShellMenuItemPtr spNormalRootItem = cfgShellExt.GetNormalRoot();
-
-	if(GetPropValue<PP_SHSHOWPASTE>(rConfig))
-	{
-		spNormalRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUPASTE_STRING), rResManager.LoadString(IDS_MENUTIPPASTE_STRING),
-			TOperationTypeInfo(TOperationTypeInfo::eOpType_Autodetect, chcore::eOperation_Copy),
-			TSourcePathsInfo(TSourcePathsInfo::eSrcType_Clipboard),
-			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializeAuto, chcore::TSmartPath()), false));
-	}
-
-	if(GetPropValue<PP_SHSHOWPASTESPECIAL>(rConfig))
-	{
-		spNormalRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUPASTESPECIAL_STRING), rResManager.LoadString(IDS_MENUTIPPASTESPECIAL_STRING),
-			TOperationTypeInfo(TOperationTypeInfo::eOpType_Autodetect, chcore::eOperation_Copy),
-			TSourcePathsInfo(TSourcePathsInfo::eSrcType_Clipboard),
-			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializeAuto, chcore::TSmartPath()), true));
-	}
-
-	if(GetPropValue<PP_SHSHOWCOPYTO>(rConfig) || GetPropValue<PP_SHSHOWMOVETO>(rConfig) || GetPropValue<PP_SHSHOWCOPYMOVETO>(rConfig))
-	{
-		// prepare shortcuts for all menu options
-		std::vector<CString> vShortcutStrings;
-		GetPropValue<PP_SHORTCUTS>(rConfig, vShortcutStrings);
-
-		std::vector<CShortcut> vShortcuts;
-
-		for(const CString& strShortcutString : vShortcutStrings)
-		{
-			CShortcut tShortcut;
-			if(tShortcut.FromString(strShortcutString))
-				vShortcuts.push_back(tShortcut);
-			else
-				BOOST_ASSERT(false);	// non-critical, but not very nice
-		}
-
-		if(GetPropValue<PP_SHSHOWCOPYTO>(rConfig))
-		{
-			std::shared_ptr<TShellMenuItem> menuItem(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPYTO_STRING), rResManager.LoadString(IDS_MENUTIPCOPYTO_STRING)));
-			for(const CShortcut& tShortcut : vShortcuts)
-			{
-				menuItem->AddChild(std::make_shared<TShellMenuItem>((PCTSTR)tShortcut.m_strName, (PCTSTR)tShortcut.m_strPath,
-					TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
-					TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
-					TDestinationPathInfo(TDestinationPathInfo::eDstType_Specified, chcore::PathFromString((PCTSTR)tShortcut.m_strPath)), false));
-			}
-
-			spNormalRootItem->AddChild(menuItem);
-
-			// optionally separator
-			if(!vShortcuts.empty())
-				menuItem->AddChild(std::make_shared<TShellMenuItem>());
-
-			// "Choose" menu option
-			menuItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_STRING), rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_TOOLTIP_STRING),
-				TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
-				TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
-				TDestinationPathInfo(TDestinationPathInfo::eDstType_Choose, chcore::TSmartPath()), false));
-		}
-
-		if(GetPropValue<PP_SHSHOWMOVETO>(rConfig))
-		{
-			std::shared_ptr<TShellMenuItem> menuItem(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUMOVETO_STRING), rResManager.LoadString(IDS_MENUTIPMOVETO_STRING)));
-			for(const CShortcut& tShortcut : vShortcuts)
-			{
-				menuItem->AddChild(std::make_shared<TShellMenuItem>((PCTSTR)tShortcut.m_strName, (PCTSTR)tShortcut.m_strPath,
-					TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Move),
-					TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
-					TDestinationPathInfo(TDestinationPathInfo::eDstType_Specified, chcore::PathFromString((PCTSTR)tShortcut.m_strPath)), false));
-			}
-
-			spNormalRootItem->AddChild(menuItem);
-
-			// optionally separator
-			if(!vShortcuts.empty())
-				menuItem->AddChild(std::make_shared<TShellMenuItem>());
-
-			// "Choose" menu option
-			menuItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_STRING), rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_TOOLTIP_STRING),
-				TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Move),
-				TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
-				TDestinationPathInfo(TDestinationPathInfo::eDstType_Choose, chcore::TSmartPath()), false));
-		}
-
-		if(GetPropValue<PP_SHSHOWCOPYMOVETO>(rConfig))
-		{
-			std::shared_ptr<TShellMenuItem> menuItem(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPYMOVETOSPECIAL_STRING), rResManager.LoadString(IDS_MENUTIPCOPYMOVETOSPECIAL_STRING)));
-			for(const CShortcut& tShortcut : vShortcuts)
-			{
-				menuItem->AddChild(std::make_shared<TShellMenuItem>((PCTSTR)tShortcut.m_strName, (PCTSTR)tShortcut.m_strPath,
-					TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
-					TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
-					TDestinationPathInfo(TDestinationPathInfo::eDstType_Specified, chcore::PathFromString((PCTSTR)tShortcut.m_strPath)), true));
-			}
-
-			spNormalRootItem->AddChild(menuItem);
-
-			// optionally separator
-			if(!vShortcuts.empty())
-				menuItem->AddChild(std::make_shared<TShellMenuItem>());
-
-			// "Choose" menu option
-			menuItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_STRING), rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_TOOLTIP_STRING),
-				TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
-				TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
-				TDestinationPathInfo(TDestinationPathInfo::eDstType_Choose, chcore::TSmartPath()), true));
-		}
-	}
-}
 void CMainWnd::OnAppAbout() 
 {
 	CAboutDlg *pdlg=new CAboutDlg;
Index: src/ch/OptionsDlg.cpp
===================================================================
diff -u -ra008bec4207ec5e71dfa8fd85cfe71d72e996a48 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/OptionsDlg.cpp	(.../OptionsDlg.cpp)	(revision a008bec4207ec5e71dfa8fd85cfe71d72e996a48)
+++ src/ch/OptionsDlg.cpp	(.../OptionsDlg.cpp)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -39,7 +39,8 @@
 // COptionsDlg dialog
 
 COptionsDlg::COptionsDlg(CWnd* pParent /*=nullptr*/)
-	:ictranslate::CLanguageDialog(IDD_OPTIONS_DIALOG, pParent, &m_bLock)
+	:ictranslate::CLanguageDialog(IDD_OPTIONS_DIALOG, pParent, &m_bLock),
+	m_spLog(logger::MakeLogger(GetLogFileData(), L"OptionsDlg"))
 {
 }
 
@@ -211,6 +212,7 @@
 	ApplyProperties();
 
 	SendClosingNotify();
+
 	CLanguageDialog::OnOK();
 }
 
@@ -473,6 +475,18 @@
 	rConfig.ResumeNotifications();
 
 	rConfig.Write();
+
+	LOG_INFO(m_spLog) << L"Updating shell extension configuration";
+	try
+	{
+		TShellExtensionConfigPtr spConfig = GetShellExtensionConfig();
+		if(spConfig)
+			spConfig->PrepareConfig();
+	}
+	catch(const std::exception& e)
+	{
+		LOG_INFO(m_spLog) << L"Failed to set shell extension configuration. Error: " << e.what();
+	}
 }
 
 void COptionsDlg::OnCancel() 
Index: src/ch/OptionsDlg.h
===================================================================
diff -u -r8068e0c351055554340ac9755d1bc846893bf2b8 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/OptionsDlg.h	(.../OptionsDlg.h)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/ch/OptionsDlg.h	(.../OptionsDlg.h)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -61,6 +61,7 @@
 	DECLARE_MESSAGE_MAP()
 
 private:
+	logger::TLoggerPtr m_spLog;
 	static bool m_bLock;				// locker
 
 	std::vector<CString> m_cvRecent;
Index: src/ch/TShellExtensionConfig.cpp
===================================================================
diff -u
--- src/ch/TShellExtensionConfig.cpp	(revision 0)
+++ src/ch/TShellExtensionConfig.cpp	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,229 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 "TShellExtensionConfig.h"
+#include "ch.h"
+#include "../common/TShellExtMenuConfig.h"
+#include "CfgProperties.h"
+#include "resource.h"
+#include "shortcuts.h"
+
+TShellExtensionConfig::TShellExtensionConfig(const logger::TLogFileDataPtr& spLogData) :
+	m_spLog(logger::MakeLogger(spLogData, L"ShellExtConfig"))
+{
+}
+
+void TShellExtensionConfig::PrepareConfig()
+{
+	try
+	{
+		chcore::TConfig& rConfig = GetConfig();
+
+		TShellExtMenuConfig cfgShellExt;
+
+		// experimental - doesn't work on all systems 
+		cfgShellExt.SetShowShortcutIcons(GetPropValue<PP_SHSHOWSHELLICONS>(rConfig));
+
+		cfgShellExt.SetInterceptDragAndDrop(GetPropValue<PP_SHINTERCEPTDRAGDROP>(rConfig));
+		cfgShellExt.SetInterceptKeyboardActions(GetPropValue<PP_SHINTERCEPTKEYACTIONS>(rConfig));
+		cfgShellExt.SetInterceptCtxMenuActions(GetPropValue<PP_SHINTERCEPTCTXMENUACTIONS>(rConfig));
+
+		cfgShellExt.GetFormatter()->SetValues(
+			GetResManager().LoadString(IDS_BYTE_STRING),
+			GetResManager().LoadString(IDS_KBYTE_STRING),
+			GetResManager().LoadString(IDS_MBYTE_STRING),
+			GetResManager().LoadString(IDS_GBYTE_STRING),
+			GetResManager().LoadString(IDS_TBYTE_STRING)
+		);
+
+		cfgShellExt.SetShowFreeSpace(GetPropValue<PP_SHSHOWFREESPACE>(rConfig));
+
+		PrepareDragAndDropMenuItems(cfgShellExt);
+		PrepareNormalMenuItems(cfgShellExt);
+
+		chcore::TConfig cfgStorage;
+		chcore::TString wstrData;
+
+		cfgShellExt.StoreInConfig(cfgStorage, _T("ShellExtCfg"));
+		cfgStorage.WriteToString(wstrData);
+
+		m_shellExtProvider.SetConfigData(wstrData);
+	}
+	catch(const std::exception& e)
+	{
+		CString strMsg;
+		strMsg.Format(L"Encountered problem trying to provide shell ext configuration.\nReason: %S", e.what());
+		LOG_ERROR(m_spLog) << strMsg;
+	}
+}
+
+void TShellExtensionConfig::PrepareDragAndDropMenuItems(TShellExtMenuConfig &cfgShellExt) const
+{
+	chcore::TConfig& rConfig = GetConfig();
+	ictranslate::CResourceManager& rResManager = GetResManager();
+
+	TShellMenuItemPtr spDragAndDropRootItem = cfgShellExt.GetDragAndDropRoot();
+	bool bAddedAnyOption = false;
+	if(GetPropValue<PP_SHSHOWCOPY>(rConfig))
+	{
+		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPY_STRING), rResManager.LoadString(IDS_MENUTIPCOPY_STRING),
+			TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
+			TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeIDataObject),
+			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializePidlFolder, chcore::TSmartPath()), false, chcore::eOperation_Copy));
+		bAddedAnyOption = true;
+	}
+
+	if(GetPropValue<PP_SHSHOWMOVE>(rConfig))
+	{
+		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUMOVE_STRING), rResManager.LoadString(IDS_MENUTIPMOVE_STRING),
+			TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Move),
+			TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeIDataObject),
+			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializePidlFolder, chcore::TSmartPath()), false, chcore::eOperation_Move));
+		bAddedAnyOption = true;
+	}
+
+	if(GetPropValue<PP_SHSHOWCOPYMOVE>(rConfig))
+	{
+		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPYMOVESPECIAL_STRING), rResManager.LoadString(IDS_MENUTIPCOPYMOVESPECIAL_STRING),
+			TOperationTypeInfo(TOperationTypeInfo::eOpType_Autodetect, chcore::eOperation_Copy),
+			TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeIDataObject),
+			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializePidlFolder, chcore::TSmartPath()), true));
+		bAddedAnyOption = true;
+	}
+
+	if(bAddedAnyOption)
+	{
+		// insert separator as an addition to other items
+		spDragAndDropRootItem->AddChild(std::make_shared<TShellMenuItem>());
+	}
+}
+
+void TShellExtensionConfig::PrepareNormalMenuItems(TShellExtMenuConfig &cfgShellExt) const
+{
+	chcore::TConfig& rConfig = GetConfig();
+	ictranslate::CResourceManager& rResManager = GetResManager();
+
+	TShellMenuItemPtr spNormalRootItem = cfgShellExt.GetNormalRoot();
+
+	if(GetPropValue<PP_SHSHOWPASTE>(rConfig))
+	{
+		spNormalRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUPASTE_STRING), rResManager.LoadString(IDS_MENUTIPPASTE_STRING),
+			TOperationTypeInfo(TOperationTypeInfo::eOpType_Autodetect, chcore::eOperation_Copy),
+			TSourcePathsInfo(TSourcePathsInfo::eSrcType_Clipboard),
+			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializeAuto, chcore::TSmartPath()), false));
+	}
+
+	if(GetPropValue<PP_SHSHOWPASTESPECIAL>(rConfig))
+	{
+		spNormalRootItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUPASTESPECIAL_STRING), rResManager.LoadString(IDS_MENUTIPPASTESPECIAL_STRING),
+			TOperationTypeInfo(TOperationTypeInfo::eOpType_Autodetect, chcore::eOperation_Copy),
+			TSourcePathsInfo(TSourcePathsInfo::eSrcType_Clipboard),
+			TDestinationPathInfo(TDestinationPathInfo::eDstType_InitializeAuto, chcore::TSmartPath()), true));
+	}
+
+	if(GetPropValue<PP_SHSHOWCOPYTO>(rConfig) || GetPropValue<PP_SHSHOWMOVETO>(rConfig) || GetPropValue<PP_SHSHOWCOPYMOVETO>(rConfig))
+	{
+		// prepare shortcuts for all menu options
+		std::vector<CString> vShortcutStrings;
+		GetPropValue<PP_SHORTCUTS>(rConfig, vShortcutStrings);
+
+		std::vector<CShortcut> vShortcuts;
+
+		for(const CString& strShortcutString : vShortcutStrings)
+		{
+			CShortcut tShortcut;
+			if(tShortcut.FromString(strShortcutString))
+				vShortcuts.push_back(tShortcut);
+			else
+				BOOST_ASSERT(false);	// non-critical, but not very nice
+		}
+
+		if(GetPropValue<PP_SHSHOWCOPYTO>(rConfig))
+		{
+			std::shared_ptr<TShellMenuItem> menuItem(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPYTO_STRING), rResManager.LoadString(IDS_MENUTIPCOPYTO_STRING)));
+			for(const CShortcut& tShortcut : vShortcuts)
+			{
+				menuItem->AddChild(std::make_shared<TShellMenuItem>((PCTSTR)tShortcut.m_strName, (PCTSTR)tShortcut.m_strPath,
+					TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
+					TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
+					TDestinationPathInfo(TDestinationPathInfo::eDstType_Specified, chcore::PathFromString((PCTSTR)tShortcut.m_strPath)), false));
+			}
+
+			spNormalRootItem->AddChild(menuItem);
+
+			// optionally separator
+			if(!vShortcuts.empty())
+				menuItem->AddChild(std::make_shared<TShellMenuItem>());
+
+			// "Choose" menu option
+			menuItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_STRING), rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_TOOLTIP_STRING),
+				TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
+				TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
+				TDestinationPathInfo(TDestinationPathInfo::eDstType_Choose, chcore::TSmartPath()), false));
+		}
+
+		if(GetPropValue<PP_SHSHOWMOVETO>(rConfig))
+		{
+			std::shared_ptr<TShellMenuItem> menuItem(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUMOVETO_STRING), rResManager.LoadString(IDS_MENUTIPMOVETO_STRING)));
+			for(const CShortcut& tShortcut : vShortcuts)
+			{
+				menuItem->AddChild(std::make_shared<TShellMenuItem>((PCTSTR)tShortcut.m_strName, (PCTSTR)tShortcut.m_strPath,
+					TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Move),
+					TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
+					TDestinationPathInfo(TDestinationPathInfo::eDstType_Specified, chcore::PathFromString((PCTSTR)tShortcut.m_strPath)), false));
+			}
+
+			spNormalRootItem->AddChild(menuItem);
+
+			// optionally separator
+			if(!vShortcuts.empty())
+				menuItem->AddChild(std::make_shared<TShellMenuItem>());
+
+			// "Choose" menu option
+			menuItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_STRING), rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_TOOLTIP_STRING),
+				TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Move),
+				TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
+				TDestinationPathInfo(TDestinationPathInfo::eDstType_Choose, chcore::TSmartPath()), false));
+		}
+
+		if(GetPropValue<PP_SHSHOWCOPYMOVETO>(rConfig))
+		{
+			std::shared_ptr<TShellMenuItem> menuItem(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_MENUCOPYMOVETOSPECIAL_STRING), rResManager.LoadString(IDS_MENUTIPCOPYMOVETOSPECIAL_STRING)));
+			for(const CShortcut& tShortcut : vShortcuts)
+			{
+				menuItem->AddChild(std::make_shared<TShellMenuItem>((PCTSTR)tShortcut.m_strName, (PCTSTR)tShortcut.m_strPath,
+					TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
+					TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
+					TDestinationPathInfo(TDestinationPathInfo::eDstType_Specified, chcore::PathFromString((PCTSTR)tShortcut.m_strPath)), true));
+			}
+
+			spNormalRootItem->AddChild(menuItem);
+
+			// optionally separator
+			if(!vShortcuts.empty())
+				menuItem->AddChild(std::make_shared<TShellMenuItem>());
+
+			// "Choose" menu option
+			menuItem->AddChild(std::make_shared<TShellMenuItem>(rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_STRING), rResManager.LoadString(IDS_SHELLEXT_CHOOSE_DIR_TOOLTIP_STRING),
+				TOperationTypeInfo(TOperationTypeInfo::eOpType_Specified, chcore::eOperation_Copy),
+				TSourcePathsInfo(TSourcePathsInfo::eSrcType_InitializeAuto),
+				TDestinationPathInfo(TDestinationPathInfo::eDstType_Choose, chcore::TSmartPath()), true));
+		}
+	}
+}
Index: src/ch/TShellExtensionConfig.h
===================================================================
diff -u
--- src/ch/TShellExtensionConfig.h	(revision 0)
+++ src/ch/TShellExtensionConfig.h	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,45 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 __TSHELLEXTENSIONCONFIG_H__
+#define __TSHELLEXTENSIONCONFIG_H__
+
+#include "../common/TShellExtIpcConfigDataProvider.h"
+#include "../liblogger/TLogFileData.h"
+#include "../liblogger/TLogger.h"
+
+class TShellExtMenuConfig;
+
+class TShellExtensionConfig
+{
+public:
+	TShellExtensionConfig(const logger::TLogFileDataPtr& spLogData);
+
+	void PrepareConfig();
+
+	void PrepareDragAndDropMenuItems(TShellExtMenuConfig &cfgShellExt) const;
+	void PrepareNormalMenuItems(TShellExtMenuConfig &cfgShellExt) const;
+
+private:
+	TShellExtIpcConfigDataProvider m_shellExtProvider;
+	logger::TLoggerPtr m_spLog;
+};
+
+using TShellExtensionConfigPtr = std::shared_ptr<TShellExtensionConfig>;
+
+#endif
Index: src/ch/ch.cpp
===================================================================
diff -u -rb2102d724fda96a2533b866dbf1efca9f499713b -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/ch.cpp	(.../ch.cpp)	(revision b2102d724fda96a2533b866dbf1efca9f499713b)
+++ src/ch/ch.cpp	(.../ch.cpp)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -475,6 +475,18 @@
 	SetAutorun(GetPropValue<PP_PRELOADAFTERRESTART>(rCfg));
 #endif
 
+	// ================================= Shell extension config =============================
+	LOG_INFO(m_spLog) << _T("Initializing shell extension configuration");
+	try
+	{
+		m_shellExtConfig = std::make_unique<TShellExtensionConfig>(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();
+	}
+
 	// ================================= Main window ========================================
 	LOG_INFO(m_spLog) << _T("Creating main application window");
 	// create main window
@@ -610,6 +622,11 @@
 	return m_spEngineLoggerConfig;
 }
 
+TShellExtensionConfigPtr CCopyHandlerApp::GetShellExtensionConfig() const
+{
+	return m_shellExtConfig;
+}
+
 void CCopyHandlerApp::RegisterShellExtension() 
 {
 	CString strPath = CString(m_pathProcessor.GetProgramPath()) + _T("\\");
Index: src/ch/ch.h
===================================================================
diff -u -rb2102d724fda96a2533b866dbf1efca9f499713b -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/ch.h	(.../ch.h)	(revision b2102d724fda96a2533b866dbf1efca9f499713b)
+++ src/ch/ch.h	(.../ch.h)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -26,6 +26,7 @@
 #include "TCommandLineParser.h"
 #include "../liblogger/TLogger.h"
 #include "../libchcore/TCoreEngine.h"
+#include "TShellExtensionConfig.h"
 
 class CCopyHandlerApp : public CWinApp, public CAppHelper
 {
@@ -48,6 +49,7 @@
 
 	logger::TLogFileDataPtr GetLogFileData() const;
 	logger::TMultiLoggerConfigPtr GetEngineLoggerConfig() const;
+	TShellExtensionConfigPtr GetShellExtensionConfig() const;
 
 	void RegisterShellExtension();
 	void UnregisterShellExtension();
@@ -73,6 +75,7 @@
 
 	logger::TMultiLoggerConfigPtr m_spAppLoggerConfig;
 	logger::TMultiLoggerConfigPtr m_spEngineLoggerConfig;
+	TShellExtensionConfigPtr m_shellExtConfig;
 
 	CWnd *m_pMainWindow;
 	bool m_bComInitialized = false;
@@ -103,4 +106,9 @@
 	return CCopyHandlerApp::GetConfig();
 }
 
+inline TShellExtensionConfigPtr GetShellExtensionConfig()
+{
+	return GetApp().GetShellExtensionConfig();
+}
+
 #endif
Index: src/ch/ch.vc140.vcxproj
===================================================================
diff -u -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/ch.vc140.vcxproj	(.../ch.vc140.vcxproj)	(revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4)
+++ src/ch/ch.vc140.vcxproj	(.../ch.vc140.vcxproj)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -518,6 +518,7 @@
   <ItemGroup>
     <ClInclude Include="..\Common\ipcstructs.h" />
     <ClInclude Include="..\common\targetver.h" />
+    <ClInclude Include="..\common\TShellExtIpcConfigDataProvider.h" />
     <ClInclude Include="..\common\TShellExtMenuConfig.h" />
     <ClInclude Include="..\common\version.h" />
     <ClInclude Include="AsyncHttpFile.h" />
@@ -537,6 +538,7 @@
     <ClInclude Include="TProgressCtrlEx.h" />
     <ClInclude Include="TRecentPathsTools.h" />
     <ClInclude Include="TRegistry.h" />
+    <ClInclude Include="TShellExtensionConfig.h" />
     <ClInclude Include="TTaskManagerWrapper.h" />
     <ClInclude Include="UpdateChecker.h" />
     <ClInclude Include="ch.h" />
@@ -769,6 +771,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Testing Debug|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="..\common\TShellExtIpcConfigDataProvider.cpp" />
     <ClCompile Include="..\common\TShellExtMenuConfig.cpp" />
     <ClCompile Include="AsyncHttpFile.cpp" />
     <ClCompile Include="CDragDropComboEx.cpp" />
@@ -786,6 +789,7 @@
     <ClCompile Include="TProgressCtrlEx.cpp" />
     <ClCompile Include="TRecentPathsTools.cpp" />
     <ClCompile Include="TRegistry.cpp" />
+    <ClCompile Include="TShellExtensionConfig.cpp" />
     <ClCompile Include="TTaskManagerWrapper.cpp" />
     <ClCompile Include="UpdateChecker.cpp" />
     <ClCompile Include="ch.cpp" />
Index: src/ch/ch.vc140.vcxproj.filters
===================================================================
diff -u -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/ch/ch.vc140.vcxproj.filters	(.../ch.vc140.vcxproj.filters)	(revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4)
+++ src/ch/ch.vc140.vcxproj.filters	(.../ch.vc140.vcxproj.filters)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -242,6 +242,12 @@
     <ClInclude Include="TTaskManagerWrapper.h">
       <Filter>Source Files\Core</Filter>
     </ClInclude>
+    <ClInclude Include="..\common\TShellExtIpcConfigDataProvider.h">
+      <Filter>Source Files\Shared</Filter>
+    </ClInclude>
+    <ClInclude Include="TShellExtensionConfig.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\common\TShellExtMenuConfig.cpp">
@@ -412,6 +418,12 @@
     <ClCompile Include="TTaskManagerWrapper.cpp">
       <Filter>Source Files\Core</Filter>
     </ClCompile>
+    <ClCompile Include="..\common\TShellExtIpcConfigDataProvider.cpp">
+      <Filter>Source Files\Shared</Filter>
+    </ClCompile>
+    <ClCompile Include="TShellExtensionConfig.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\ch.rc2">
Index: src/chext/ShellExtControl.cpp
===================================================================
diff -u -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/chext/ShellExtControl.cpp	(.../ShellExtControl.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
+++ src/chext/ShellExtControl.cpp	(.../ShellExtControl.cpp)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -22,39 +22,25 @@
 #include "ShellExtControl.h"
 #include "../common/version.h"
 #include "Logger.h"
+#include "../libchcore/TIpcMutexLock.h"
 
 CShellExtControl::CShellExtControl() :
 	m_pShellExtData(nullptr),
 	m_hMemory(nullptr),
-	m_hMutex(nullptr),
+	m_mutex(L"CHShellExtControlDataMutex"),
 	m_spLog(GetLogger(L"ShellExtControl"))
 {
 	LOG_DEBUG(m_spLog) << L"Constructing CShellExtControl";
 
 	// create protection mutex
-	m_hMutex = ::CreateMutex(nullptr, FALSE, _T("CHShellExtControlDataMutex"));
-	if(!m_hMutex)
-	{
-		LOG_ERROR(m_spLog) << L"Cannot create mutex.";
-		return;
-	}
+	chcore::TIpcMutexLock lock(m_mutex);
 
-	DWORD dwRes = WaitForSingleObject(m_hMutex, 10000);
-	if(dwRes != WAIT_OBJECT_0)
-	{
-		LOG_ERROR(m_spLog) << L"Timeout or fail waiting for mutex.";
-		ReleaseMutex(m_hMutex);
-		return;
-	}
-	
 	// memory mapped file
 	m_hMemory = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, sizeof(SHELLEXT_DATA), _T("CHShellExtControlData"));    // name of map object
 	DWORD dwLastError = GetLastError();	// NOTE: last error is needed also for success case (for already exists status)
 	if(!m_hMemory)
 	{
 		LOG_HRESULT(m_spLog, dwLastError) << L"Cannot create file mapping.";
-		ReleaseMutex(m_hMutex);
-		CloseHandle(m_hMutex);
 		return;
 	}
 
@@ -64,8 +50,6 @@
 		DWORD dwError = GetLastError();		// NOTE: do not overwrite dwLastError, as the value is needed later
 
 		LOG_HRESULT(m_spLog, dwError) << L"Cannot map view of file.";
-		ReleaseMutex(m_hMutex);
-		CloseHandle(m_hMutex);
 		CloseHandle(m_hMemory);
 		m_hMemory = nullptr;
 		return;
@@ -84,8 +68,6 @@
 		m_pShellExtData->m_lFlags = 0;
 		m_pShellExtData->m_lID = GetTickCount();
 	}
-
-	ReleaseMutex(m_hMutex);
 }
 
 CShellExtControl::~CShellExtControl()
@@ -97,9 +79,6 @@
 		// Close the process's handle to the file-mapping object.
 		CloseHandle(m_hMemory); 
 	}
-
-	if(m_hMutex)
-		CloseHandle(m_hMutex);
 }
 
 STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion, BSTR* pbstrVersion)
@@ -125,32 +104,25 @@
 {
 	LOG_DEBUG(m_spLog) << L"Setting flags: " << LOG_PARAMS2(lFlags, lMask);
 
-	if(!m_hMutex || !m_pShellExtData)
+	if(!m_pShellExtData)
 	{
 		LOG_ERROR(m_spLog) << "Wrong internal state.";
 		return E_FAIL;
 	}
 
-	DWORD dwRes = WaitForSingleObject(m_hMutex, 10000);
-	if(dwRes != WAIT_OBJECT_0)
-	{
-		LOG_ERROR(m_spLog) << "Failed waiting for mutex.";
-		return E_FAIL;
-	}
+	chcore::TIpcMutexLock lock(m_mutex);
 	m_pShellExtData->m_lFlags = (m_pShellExtData->m_lFlags & ~lMask) | (lFlags & lMask);
 
 	LOG_DEBUG(m_spLog) << L"Set flags: " << LOG_PARAM(m_pShellExtData->m_lFlags);
 
-	ReleaseMutex(m_hMutex);
-
 	return S_OK;
 }
 
 STDMETHODIMP CShellExtControl::GetFlags(LONG* plFlags)
 {
 	LOG_DEBUG(m_spLog) << "Retrieving flags";
 
-	if(!m_hMutex || !m_pShellExtData)
+	if(!m_pShellExtData)
 	{
 		LOG_ERROR(m_spLog) << "Wrong internal state.";
 		return E_FAIL;
@@ -162,18 +134,11 @@
 		return E_INVALIDARG;
 	}
 
-	DWORD dwRes = WaitForSingleObject(m_hMutex, 10000);
-	if(dwRes != WAIT_OBJECT_0)
-	{
-		LOG_ERROR(m_spLog) << "Failed waiting for mutex.";
-		return E_FAIL;
-	}
+	chcore::TIpcMutexLock lock(m_mutex);
 
 	(*plFlags) = m_pShellExtData->m_lFlags;
 
 	LOG_DEBUG(m_spLog) << "Returning flags: " << LOG_PARAM(m_pShellExtData->m_lFlags);
 
-	ReleaseMutex(m_hMutex);
-
 	return S_OK;
 }
Index: src/chext/ShellExtControl.h
===================================================================
diff -u -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/chext/ShellExtControl.h	(.../ShellExtControl.h)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
+++ src/chext/ShellExtControl.h	(.../ShellExtControl.h)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -20,7 +20,9 @@
 #define __SHELLEXTCONTROL_H_
 
 #include "resource.h"       // main symbols
-#include "..\liblogger\TLogger.h"
+#include "../liblogger/TLogger.h"
+#include "../libchcore/TIpcMutex.h"
+#include "../libchcore/TSharedMemory.h"
 
 /////////////////////////////////////////////////////////////////////////////
 // CDropMenuExt
@@ -48,7 +50,8 @@
 
 protected:
 	HANDLE m_hMemory;
-	HANDLE m_hMutex;
+	chcore::TIpcMutex m_mutex;
+
 	struct SHELLEXT_DATA
 	{
 		long m_lID;
@@ -57,6 +60,7 @@
 
 	CComAutoCriticalSection m_lock;
 	logger::TLoggerPtr m_spLog;
+	chcore::TSharedMemory m_shmConfiguration;
 };
 
 #endif //__SHELLEXTCONTROL_H_
Index: src/chext/ShellExtControl.rgs
===================================================================
diff -u -rd0fdcc905035e648382256101a3d99f429af6d56 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/chext/ShellExtControl.rgs	(.../ShellExtControl.rgs)	(revision d0fdcc905035e648382256101a3d99f429af6d56)
+++ src/chext/ShellExtControl.rgs	(.../ShellExtControl.rgs)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -18,7 +18,7 @@
 			ForceRemove 'Programmable'
 			InprocServer32 = s '%MODULE%'
 			{
-				val ThreadingModel = s 'Neutral'
+				val ThreadingModel = s 'Both'
 			}
 			'TypeLib' = s '{68FAFC14-8EB8-4DA1-90EB-6B3D22010505}'
 		}
Index: src/chext/ShellExtensionVerifier.cpp
===================================================================
diff -u -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/chext/ShellExtensionVerifier.cpp	(.../ShellExtensionVerifier.cpp)	(revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4)
+++ src/chext/ShellExtensionVerifier.cpp	(.../ShellExtensionVerifier.cpp)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -19,11 +19,11 @@
 #include "stdafx.h"
 #include "ShellExtensionVerifier.h"
 #include "Logger.h"
-#include "../libchcore/TSharedMemory.h"
 #include "../libchcore/TConfig.h"
 #include "../liblogger/TLogger.h"
 #include "../common/TShellExtMenuConfig.h"
 #include <stdlib.h>
+#include "../common/TShellExtIpcConfigDataConsumer.h"
 
 HWND ShellExtensionVerifier::VerifyShellExt(IShellExtControl* piShellExtControl)
 {
@@ -72,31 +72,11 @@
 		if(hWnd == nullptr)
 			return E_FAIL;
 
-		// generate a random number for naming shared memory
-		unsigned int uiSHMID = 0;
-		if(rand_s(&uiSHMID) != 0 || uiSHMID == 0)
-		{
-			LOG_WARNING(spLogger) << L"Failed to generate random number for shared memory naming. Falling back to tick count.";
-			uiSHMID = GetTickCount();
-		}
+		LOG_DEBUG(spLogger) << L"Requesting CH configuration";
 
-		LOG_DEBUG(spLogger) << L"Requesting CH configuration. Shared memory identifier " << uiSHMID;
-
-		if(::SendMessage(hWnd, WM_GETCONFIG, 0, uiSHMID) != TRUE)
-		{
-			LOG_ERROR(spLogger) << L"Failed to retrieve configuration from Copy Handler";
-			return E_FAIL;
-		}
-
-		std::wstring strSHMName = IPCSupport::GenerateSHMName(uiSHMID);
-
-		chcore::TSharedMemory tSharedMemory;
-		chcore::TString wstrData;
+		chcore::TString wstrData = TShellExtIpcConfigDataConsumer::GetConfigData();
 		chcore::TConfig cfgShellExtData;
 
-		tSharedMemory.Open(strSHMName.c_str());
-		tSharedMemory.Read(wstrData);
-
 		LOG_TRACE(spLogger) << L"Retrieved shell ext config: " << wstrData;
 
 		cfgShellExtData.ReadFromString(wstrData);
Index: src/chext/chext.vc140.vcxproj
===================================================================
diff -u -rf0b3178897bcff99beb7fde44dfe952ccbf40bec -r306fbe693c70290af9de9a5779084a697de22d75
--- src/chext/chext.vc140.vcxproj	(.../chext.vc140.vcxproj)	(revision f0b3178897bcff99beb7fde44dfe952ccbf40bec)
+++ src/chext/chext.vc140.vcxproj	(.../chext.vc140.vcxproj)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -553,6 +553,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Testing Debug|x64'">NotUsing</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="..\common\TShellExtIpcConfigDataConsumer.cpp" />
     <ClCompile Include="DropMenuExt.cpp" />
     <ClCompile Include="GuidFormatter.cpp" />
     <ClCompile Include="HResultFormatter.cpp" />
@@ -596,6 +597,7 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="..\common\TShellExtIpcConfigDataConsumer.h" />
     <ClInclude Include="DropMenuExt.h" />
     <ClInclude Include="GuidFormatter.h" />
     <ClInclude Include="HResultFormatter.h" />
Index: src/chext/chext.vc140.vcxproj.filters
===================================================================
diff -u -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/chext/chext.vc140.vcxproj.filters	(.../chext.vc140.vcxproj.filters)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
+++ src/chext/chext.vc140.vcxproj.filters	(.../chext.vc140.vcxproj.filters)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -77,6 +77,9 @@
     <ClCompile Include="Logger.cpp">
       <Filter>Source Files\Tools</Filter>
     </ClCompile>
+    <ClCompile Include="..\common\TShellExtIpcConfigDataConsumer.cpp">
+      <Filter>Source Files\Common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="DropMenuExt.h">
@@ -127,6 +130,9 @@
     <ClInclude Include="Logger.h">
       <Filter>Source Files\Tools</Filter>
     </ClInclude>
+    <ClInclude Include="..\common\TShellExtIpcConfigDataConsumer.h">
+      <Filter>Source Files\Common</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="chext.def">
Index: src/common/TShellExtIpcConfigDataConsumer.cpp
===================================================================
diff -u
--- src/common/TShellExtIpcConfigDataConsumer.cpp	(revision 0)
+++ src/common/TShellExtIpcConfigDataConsumer.cpp	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,31 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 "TShellExtIpcConfigDataConsumer.h"
+
+chcore::TString TShellExtIpcConfigDataConsumer::GetConfigData()
+{
+	chcore::TSharedMemory shmConfigData;
+
+	chcore::TString strData;
+	shmConfigData.Open(L"CHShellExtConfig");
+	shmConfigData.Read(strData);
+
+	return strData;
+}
Index: src/common/TShellExtIpcConfigDataConsumer.h
===================================================================
diff -u
--- src/common/TShellExtIpcConfigDataConsumer.h	(revision 0)
+++ src/common/TShellExtIpcConfigDataConsumer.h	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,30 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 __TSHELLEXTIPCCONFIGDATACONSUMER_H__
+#define __TSHELLEXTIPCCONFIGDATACONSUMER_H__
+
+#include "../libchcore/TSharedMemory.h"
+
+class TShellExtIpcConfigDataConsumer
+{
+public:
+	static chcore::TString GetConfigData();
+};
+
+#endif
Index: src/common/TShellExtIpcConfigDataProvider.cpp
===================================================================
diff -u
--- src/common/TShellExtIpcConfigDataProvider.cpp	(revision 0)
+++ src/common/TShellExtIpcConfigDataProvider.cpp	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,26 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 "TShellExtIpcConfigDataProvider.h"
+
+void TShellExtIpcConfigDataProvider::SetConfigData(const chcore::TString& strConfigData)
+{
+	m_shmConfigData.Close();
+	m_shmConfigData.Create(L"CHShellExtConfig", strConfigData);
+}
Index: src/common/TShellExtIpcConfigDataProvider.h
===================================================================
diff -u
--- src/common/TShellExtIpcConfigDataProvider.h	(revision 0)
+++ src/common/TShellExtIpcConfigDataProvider.h	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,33 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 __TSHELLEXTIPCCONFIGDATAPROVIDER_H__
+#define __TSHELLEXTIPCCONFIGDATAPROVIDER_H__
+
+#include "../libchcore/TSharedMemory.h"
+
+class TShellExtIpcConfigDataProvider
+{
+public:
+	void SetConfigData(const chcore::TString& pszConfigData);
+
+private:
+	chcore::TSharedMemory m_shmConfigData;
+};
+
+#endif
Index: src/common/ipcstructs.h
===================================================================
diff -u -rb165add706c4fab9d783f0564b1dd398492da491 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/common/ipcstructs.h	(.../ipcstructs.h)	(revision b165add706c4fab9d783f0564b1dd398492da491)
+++ src/common/ipcstructs.h	(.../ipcstructs.h)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -19,32 +19,12 @@
 #ifndef __SHAREDDATA_H__
 #define __SHAREDDATA_H__
 
-#include <boost/lexical_cast.hpp>
-
 // messages used
-#define WM_GETCONFIG	WM_USER+20
-
 enum ECopyDataType
 {
 	eCDType_TaskDefinitionContent,
 	eCDType_TaskDefinitionContentSpecial,
 	eCDType_CommandLineArguments,
 };
 
-enum ELocation
-{
-	eLocation_DragAndDropMenu,
-	eLocation_ContextMenu
-};
-
-namespace IPCSupport
-{
-	static std::wstring GenerateSHMName(unsigned long ulRequestID)
-	{
-		std::wstring wstrName = _T("CHExtSHM_");
-		wstrName += boost::lexical_cast<std::wstring>(ulRequestID);
-		return wstrName;
-	}
-}
-
 #endif
Index: src/libchcore/ErrorCodes.h
===================================================================
diff -u -r4fe995b304ea342b50293f92d3c1992b43b820f7 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision 4fe995b304ea342b50293f92d3c1992b43b820f7)
+++ src/libchcore/ErrorCodes.h	(.../ErrorCodes.h)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -50,6 +50,7 @@
 		eErr_WaitingFailed = 1007,
 		eErr_CannotSuspendThread = 1008,
 		eErr_CannotSetEvent = 1009,
+		eErr_CannotCreateMutex = 1010,
 
 		// string errors (1500+)
 
Index: src/libchcore/TIpcMutex.cpp
===================================================================
diff -u
--- src/libchcore/TIpcMutex.cpp	(revision 0)
+++ src/libchcore/TIpcMutex.cpp	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,79 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 "TIpcMutex.h"
+#include "TCoreWin32Exception.h"
+
+namespace chcore
+{
+	TIpcMutex::TIpcMutex()
+	{
+	}
+
+	TIpcMutex::TIpcMutex(const wchar_t* pszName)
+	{
+		m_hMutex = ::CreateMutex(nullptr, FALSE, pszName);
+		if(!m_hMutex)
+			throw TCoreWin32Exception(eErr_CannotCreateMutex, GetLastError(), L"Cannot create mutex", LOCATION);
+	}
+
+	TIpcMutex::~TIpcMutex()
+	{
+		if(m_bLocked)
+			Unlock();
+
+		if(m_hMutex)
+			CloseHandle(m_hMutex);
+	}
+
+	void TIpcMutex::CreateMutex(const wchar_t* pszName)
+	{
+		m_hMutex = ::CreateMutex(nullptr, FALSE, pszName);
+		if(!m_hMutex)
+			throw TCoreWin32Exception(eErr_CannotCreateMutex, GetLastError(), L"Cannot create mutex", LOCATION);
+	}
+
+	void TIpcMutex::Lock(DWORD dwTimeout)
+	{
+		if(!m_hMutex)
+			throw TCoreException(eErr_InvalidData, L"Mutex not created. Cannot lock.", LOCATION);
+		if(m_bLocked)
+			throw TCoreException(eErr_InvalidData, L"Mutex already locked.", LOCATION);
+
+		DWORD dwRes = WaitForSingleObject(m_hMutex, dwTimeout);
+		if(dwRes != WAIT_OBJECT_0)
+		{
+			ReleaseMutex(m_hMutex);
+			throw TCoreWin32Exception(eErr_CannotCreateMutex, GetLastError(), L"Wait for mutex failed", LOCATION);
+		}
+
+		m_bLocked = true;
+	}
+
+	void TIpcMutex::Unlock()
+	{
+		if(!m_hMutex)
+			throw TCoreException(eErr_InvalidData, L"Mutex not created. Cannot lock.", LOCATION);
+		if(!m_bLocked)
+			throw TCoreException(eErr_InvalidData, L"Mutex not locked. Cannot unlock.", LOCATION);
+
+		ReleaseMutex(m_hMutex);
+		m_bLocked = false;
+	}
+}
Index: src/libchcore/TIpcMutex.h
===================================================================
diff -u
--- src/libchcore/TIpcMutex.h	(revision 0)
+++ src/libchcore/TIpcMutex.h	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,44 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 __TIPCMUTEX_H__
+#define __TIPCMUTEX_H__
+
+#include "libchcore.h"
+
+namespace chcore
+{
+	class LIBCHCORE_API TIpcMutex
+	{
+	public:
+		TIpcMutex();
+		TIpcMutex(const wchar_t* pszName);
+		~TIpcMutex();
+
+		void CreateMutex(const wchar_t* pszName);
+
+		void Lock(DWORD dwTimeout = INFINITE);
+		void Unlock();
+
+	private:
+		HANDLE m_hMutex = nullptr;
+		bool m_bLocked = false;
+	};
+}
+
+#endif
Index: src/libchcore/TIpcMutexLock.cpp
===================================================================
diff -u
--- src/libchcore/TIpcMutexLock.cpp	(revision 0)
+++ src/libchcore/TIpcMutexLock.cpp	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,34 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 "TIpcMutexLock.h"
+
+namespace chcore
+{
+	TIpcMutexLock::TIpcMutexLock(TIpcMutex& rMutex) :
+		m_rMutex(rMutex)
+	{
+		m_rMutex.Lock();
+	}
+
+	TIpcMutexLock::~TIpcMutexLock()
+	{
+		m_rMutex.Unlock();
+	}
+}
Index: src/libchcore/TIpcMutexLock.h
===================================================================
diff -u
--- src/libchcore/TIpcMutexLock.h	(revision 0)
+++ src/libchcore/TIpcMutexLock.h	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -0,0 +1,38 @@
+// ============================================================================
+//  Copyright (C) 2001-2016 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 __TIPCMUTEXLOCK_H__
+#define __TIPCMUTEXLOCK_H__
+
+#include "libchcore.h"
+#include "TIpcMutex.h"
+
+namespace chcore
+{
+	class LIBCHCORE_API TIpcMutexLock
+	{
+	public:
+		explicit TIpcMutexLock(TIpcMutex& rMutex);
+		~TIpcMutexLock();
+
+	private:
+		TIpcMutex& m_rMutex;
+	};
+}
+
+#endif
Index: src/libchcore/TSharedMemory.cpp
===================================================================
diff -u -r8068e0c351055554340ac9755d1bc846893bf2b8 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/libchcore/TSharedMemory.cpp	(.../TSharedMemory.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/libchcore/TSharedMemory.cpp	(.../TSharedMemory.cpp)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -25,42 +25,19 @@
 #include <boost/cast.hpp>
 #include "ErrorCodes.h"
 #include "TCoreException.h"
+#include "TIpcMutexLock.h"
 
 namespace chcore
 {
-#define MUTEX_SUFFIX _T("_Mutex")
+	#define MUTEX_SUFFIX _T("_Mutex")
 
-	class TMutexLock
-	{
-	public:
-		explicit TMutexLock(HANDLE hMutex) :
-			m_hMutex(hMutex)
-		{
-			if (m_hMutex)
-			{
-				DWORD dwRes = WaitForSingleObject(hMutex, 10000);
-				if (dwRes != WAIT_OBJECT_0)
-					throw TCoreException(eErr_MutexTimedOut, L"Waiting for object failed", LOCATION);
-			}
-		}
-
-		~TMutexLock()
-		{
-			if (m_hMutex)
-				ReleaseMutex(m_hMutex);
-		}
-
-	private:
-		HANDLE m_hMutex;
-	};
-
 	///////////////////////////////////////////////////////////////////////////////////////
 	// TSharedMemory class
 
 	TSharedMemory::TSharedMemory() :
 		m_hFileMapping(nullptr),
 		m_pMappedMemory(nullptr),
-		m_hMutex(nullptr),
+		m_mutex(nullptr),
 		m_stSize(0)
 	{
 	}
@@ -84,26 +61,12 @@
 			std::wstring wstrMutexName = pszName;
 			wstrMutexName += MUTEX_SUFFIX;
 
-			SECURITY_DESCRIPTOR secDesc;
-			if (!InitializeSecurityDescriptor(&secDesc, SECURITY_DESCRIPTOR_REVISION))
-				throw TCoreException(eErr_CannotOpenSharedMemory, L"Failed to initialize security descriptor", LOCATION);
+			m_mutex.CreateMutex(wstrMutexName.c_str());
 
-			SECURITY_ATTRIBUTES secAttr;
-			secAttr.nLength = sizeof(secAttr);
-			secAttr.bInheritHandle = FALSE;
-			secAttr.lpSecurityDescriptor = &secDesc;
-
-			if (!SetSecurityDescriptorDacl(secAttr.lpSecurityDescriptor, TRUE, 0, FALSE))
-				throw TCoreException(eErr_CannotOpenSharedMemory, L"Failed to set dacl", LOCATION);
-
-			m_hMutex = ::CreateMutex(&secAttr, FALSE, wstrMutexName.c_str());
-			if (!m_hMutex)
-				throw TCoreException(eErr_CannotOpenSharedMemory, L"Failed to create mutex", LOCATION);
-
-			m_hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, &secAttr, PAGE_READWRITE, 0, boost::numeric_cast<DWORD>(stSize + sizeof(size_t)), pszName);
+			m_hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, boost::numeric_cast<DWORD>(stSize + sizeof(size_t)), pszName);
 			if (!m_hFileMapping)
 				throw TCoreException(eErr_CannotOpenSharedMemory, L"Failed to create file mapping", LOCATION);
-			else if (GetLastError() == ERROR_ALREADY_EXISTS)
+			if(GetLastError() == ERROR_ALREADY_EXISTS)
 				throw TCoreException(eErr_SharedMemoryAlreadyExists, L"File mapping already exists", LOCATION);		// shared memory already exists - cannot guarantee that the size is correct
 
 			// Get a pointer to the file-mapped shared memory.
@@ -117,7 +80,7 @@
 			throw;
 		}
 
-		TMutexLock lock(m_hMutex);
+		TIpcMutexLock lock(m_mutex);
 
 		m_stSize = stSize + sizeof(shm_size_t);
 		*(shm_size_t*)m_pMappedMemory = sizeof(shm_size_t);  // no data inside (set just in case)
@@ -132,7 +95,7 @@
 	{
 		Create(pszName, stSize);
 
-		TMutexLock lock(m_hMutex);
+		TIpcMutexLock lock(m_mutex);
 
 		*(shm_size_t*)m_pMappedMemory = stSize;
 		memcpy(m_pMappedMemory + sizeof(shm_size_t), pbyData, stSize);
@@ -159,7 +122,7 @@
 			throw;
 		}
 
-		TMutexLock lock(m_hMutex);
+		TIpcMutexLock lock(m_mutex);
 
 		m_stSize = *(shm_size_t*)m_pMappedMemory + sizeof(shm_size_t);
 	}
@@ -168,12 +131,6 @@
 	{
 		try
 		{
-			if (m_hMutex)
-			{
-				CloseHandle(m_hMutex);
-				m_hMutex = nullptr;
-			}
-
 			if (m_pMappedMemory)
 			{
 				UnmapViewOfFile(m_pMappedMemory);
@@ -197,7 +154,7 @@
 		if (!m_hFileMapping || !m_pMappedMemory || m_stSize <= sizeof(shm_size_t))
 			throw TCoreException(eErr_SharedMemoryNotOpen, L"Invalid shared memory state", LOCATION);
 
-		TMutexLock lock(m_hMutex);
+		TIpcMutexLock lock(m_mutex);
 
 		shm_size_t stByteSize = *(shm_size_t*)m_pMappedMemory;
 		if ((stByteSize % 2) != 0)
@@ -222,7 +179,7 @@
 		if (stSize + sizeof(shm_size_t) > m_stSize)
 			throw TCoreException(eErr_BoundsExceeded, L"stSize", LOCATION);
 
-		TMutexLock lock(m_hMutex);
+		TIpcMutexLock lock(m_mutex);
 
 		*(shm_size_t*)m_pMappedMemory = stSize;
 		memcpy(m_pMappedMemory + sizeof(shm_size_t), pbyData, stSize);
@@ -256,7 +213,7 @@
 		if (!m_hFileMapping || !m_pMappedMemory || m_stSize <= sizeof(shm_size_t))
 			return 0;
 
-		TMutexLock lock(m_hMutex);
+		TIpcMutexLock lock(m_mutex);
 
 		return *(shm_size_t*)m_pMappedMemory;
 	}
Index: src/libchcore/TSharedMemory.h
===================================================================
diff -u -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/libchcore/TSharedMemory.h	(.../TSharedMemory.h)	(revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3)
+++ src/libchcore/TSharedMemory.h	(.../TSharedMemory.h)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -24,6 +24,7 @@
 #define __TSHAREDMEMORY_H__
 
 #include "TString.h"
+#include "TIpcMutex.h"
 
 namespace chcore
 {
@@ -59,7 +60,7 @@
 		BYTE* m_pMappedMemory;
 		shm_size_t m_stSize;     // contains full size of the allocated shared memory (in case we created the memory), size of occupied memory in case we opened the memory.
 
-		HANDLE m_hMutex;
+		mutable TIpcMutex m_mutex;
 	};
 }
 
Index: src/libchcore/libchcore.vc140.vcxproj
===================================================================
diff -u -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/libchcore/libchcore.vc140.vcxproj	(.../libchcore.vc140.vcxproj)	(revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4)
+++ src/libchcore/libchcore.vc140.vcxproj	(.../libchcore.vc140.vcxproj)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -511,6 +511,8 @@
     <ClInclude Include="TFilesystemFileFeedbackWrapper.h" />
     <ClInclude Include="TFileTime.h" />
     <ClInclude Include="TFileException.h" />
+    <ClInclude Include="TIpcMutex.h" />
+    <ClInclude Include="TIpcMutexLock.h" />
     <ClInclude Include="TLocalFilesystemFile.h" />
     <ClInclude Include="TLocalFilesystemFind.h" />
     <ClInclude Include="TModificationTracker.h" />
@@ -818,6 +820,8 @@
     <ClCompile Include="TFilesystemFileFeedbackWrapper.cpp" />
     <ClCompile Include="TFileTime.cpp" />
     <ClCompile Include="TFileException.cpp" />
+    <ClCompile Include="TIpcMutex.cpp" />
+    <ClCompile Include="TIpcMutexLock.cpp" />
     <ClCompile Include="TLocalFilesystemFile.cpp" />
     <ClCompile Include="TLocalFilesystemFind.cpp" />
     <ClCompile Include="TModPathContainer.cpp" />
Index: src/libchcore/libchcore.vc140.vcxproj.filters
===================================================================
diff -u -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r306fbe693c70290af9de9a5779084a697de22d75
--- src/libchcore/libchcore.vc140.vcxproj.filters	(.../libchcore.vc140.vcxproj.filters)	(revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4)
+++ src/libchcore/libchcore.vc140.vcxproj.filters	(.../libchcore.vc140.vcxproj.filters)	(revision 306fbe693c70290af9de9a5779084a697de22d75)
@@ -518,6 +518,12 @@
     <ClInclude Include="TSizeFormatter.h">
       <Filter>Source Files\Tools</Filter>
     </ClInclude>
+    <ClInclude Include="TIpcMutex.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
+    <ClInclude Include="TIpcMutexLock.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="TSubTaskArray.cpp">
@@ -958,5 +964,11 @@
     <ClCompile Include="TSizeFormatter.cpp">
       <Filter>Source Files\Tools</Filter>
     </ClCompile>
+    <ClCompile Include="TIpcMutex.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
+    <ClCompile Include="TIpcMutexLock.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file