Index: src/ch/TRegistry.cpp =================================================================== diff -u -N --- src/ch/TRegistry.cpp (revision 8068e0c351055554340ac9755d1bc846893bf2b8) +++ src/ch/TRegistry.cpp (revision 0) @@ -1,64 +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 "TRegistry.h" - -TRegistry::TRegistry(HKEY key, const wchar_t* pszKey) -{ - LSTATUS lStatus = RegOpenKeyEx(key, pszKey, 0, KEY_QUERY_VALUE, &m_hKey); - if (lStatus != ERROR_SUCCESS || m_hKey == nullptr) - throw std::runtime_error("Cannot open registry key"); -} - -TRegistry::~TRegistry() -{ - if(m_hKey) - RegCloseKey(m_hKey); -} - -bool TRegistry::QueryString(const wchar_t* pszValueKey, std::wstring& wstrValue) -{ - DWORD dwType = REG_SZ; - const DWORD stMaxBuffer = 1024; - std::unique_ptr buf(new wchar_t[stMaxBuffer]); - - DWORD dwCount = stMaxBuffer; - LSTATUS lStatus = RegQueryValueEx(m_hKey, pszValueKey, nullptr, &dwType, (BYTE*)buf.get(), &dwCount); - if (lStatus != ERROR_SUCCESS) - return false; - - buf[dwCount / 2] = L'\0'; - wstrValue = buf.get(); - - return true; -} - -bool TRegistry::QueryDword(const wchar_t* pszValueKey, DWORD& dwOutValue) -{ - DWORD dwType = REG_DWORD; - DWORD dwCount = sizeof(DWORD); - DWORD dwValue = 0; - LSTATUS lStatus = RegQueryValueEx(m_hKey, pszValueKey, nullptr, &dwType, (BYTE*)&dwValue, &dwCount); - if (lStatus != ERROR_SUCCESS) - return false; - - dwOutValue = dwValue; - - return true; -} Index: src/ch/TShellExtensionClient.cpp =================================================================== diff -u -N -r9ddf8fdd5f641491dd30c49eb90f8f740314b6af -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/ch/TShellExtensionClient.cpp (.../TShellExtensionClient.cpp) (revision 9ddf8fdd5f641491dd30c49eb90f8f740314b6af) +++ src/ch/TShellExtensionClient.cpp (.../TShellExtensionClient.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -20,6 +20,7 @@ #include "TShellExtensionClient.h" #include "objbase.h" #include "../chext/Logger.h" +#include "../chext/guids.h" #ifdef _DEBUG #define new DEBUG_NEW Index: src/ch/TShellExtensionClient.h =================================================================== diff -u -N -rb556d023b748dfea230575959b6513acf29fd7b3 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/ch/TShellExtensionClient.h (.../TShellExtensionClient.h) (revision b556d023b748dfea230575959b6513acf29fd7b3) +++ src/ch/TShellExtensionClient.h (.../TShellExtensionClient.h) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -19,9 +19,9 @@ #ifndef __TSHELLEXTENSIONCLIENT_H__ #define __TSHELLEXTENSIONCLIENT_H__ -#include "../chext/chext.h" #include "../liblogger/TLogger.h" #include "../common/ERegistrationResult.h" +#include "../chext/IShellExtControl.h" class TShellExtensionClient { Index: src/ch/WindowsVersion.cpp =================================================================== diff -u -N -rb26ced3298e3e7e51d91f3ac70b56746786da83b -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/ch/WindowsVersion.cpp (.../WindowsVersion.cpp) (revision b26ced3298e3e7e51d91f3ac70b56746786da83b) +++ src/ch/WindowsVersion.cpp (.../WindowsVersion.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -18,7 +18,7 @@ // ============================================================================ #include "stdafx.h" #include "WindowsVersion.h" -#include "TRegistry.h" +#include "../common/TRegistry.h" #include #include Index: src/ch/ch.vc140.vcxproj =================================================================== diff -u -N -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/ch/ch.vc140.vcxproj (.../ch.vc140.vcxproj) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/ch/ch.vc140.vcxproj (.../ch.vc140.vcxproj) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -518,6 +518,7 @@ + @@ -538,7 +539,6 @@ - @@ -773,6 +773,7 @@ NotUsing NotUsing + @@ -791,7 +792,6 @@ - @@ -837,24 +837,6 @@ - - - - - - - - - - - - - - - - - - Index: src/ch/ch.vc140.vcxproj.filters =================================================================== diff -u -N -r5f6477e71c348782f8149a86c7a3ae903e5ff635 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/ch/ch.vc140.vcxproj.filters (.../ch.vc140.vcxproj.filters) (revision 5f6477e71c348782f8149a86c7a3ae903e5ff635) +++ src/ch/ch.vc140.vcxproj.filters (.../ch.vc140.vcxproj.filters) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -203,9 +203,6 @@ Source Files\Tools - - Source Files\Tools - Source Files\Tools @@ -257,6 +254,9 @@ Source Files\GUI\Dialogs\Feedback + + Source Files\Shared + @@ -361,9 +361,6 @@ Source Files\Shell Extension - - Generated Files - Source Files\GUI\Controls @@ -385,9 +382,6 @@ Source Files\Tools - - Source Files\Tools - Source Files\Tools @@ -439,6 +433,9 @@ Source Files\GUI\Dialogs\Feedback + + Source Files\Shared + Index: src/chext/ClassFactory.cpp =================================================================== diff -u -N --- src/chext/ClassFactory.cpp (revision 0) +++ src/chext/ClassFactory.cpp (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,74 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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 "ClassFactory.h" +#include "Logger.h" + +extern LONG g_DllRefCount; + +ClassFactory::ClassFactory() : + m_spLog(GetLogger(L"ClassFactory")) +{ + InterlockedIncrement(&g_DllRefCount); + LOG_DEBUG(m_spLog) << L"Constructing ClassFactory"; +} + +ClassFactory::~ClassFactory() +{ + InterlockedDecrement(&g_DllRefCount); +} + +STDMETHODIMP ClassFactory::QueryInterface(REFIID riid, LPVOID *ppReturn) +{ + if (!ppReturn) + return E_POINTER; + + *ppReturn = nullptr; + + if (IsEqualIID(riid, IID_IUnknown)) + *ppReturn = this; + else if (IsEqualIID(riid, IID_IClassFactory)) + *ppReturn = (IClassFactory*)this; + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) ClassFactory::AddRef() +{ + return InterlockedIncrement(&m_ulRefCnt); +} + +STDMETHODIMP_(ULONG) ClassFactory::Release() +{ + ULONG ulNewValue = InterlockedDecrement(&m_ulRefCnt); + if(ulNewValue) + return ulNewValue; + + delete this; + + return 0UL; +} + +STDMETHODIMP ClassFactory::LockServer(BOOL) +{ + return E_NOTIMPL; +} Index: src/chext/ClassFactory.h =================================================================== diff -u -N --- src/chext/ClassFactory.h (revision 0) +++ src/chext/ClassFactory.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,40 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ +#pragma once + +#include "../liblogger/TLogger.h" + +class ClassFactory : public IClassFactory +{ +public: + ClassFactory(); + virtual ~ClassFactory(); + + //IUnknown methods + STDMETHODIMP QueryInterface(REFIID, LPVOID*) override; + STDMETHODIMP_(DWORD) AddRef() override; + STDMETHODIMP_(DWORD) Release() override; + + //IClassFactory methods + STDMETHODIMP LockServer(BOOL) override; + +private: + DWORD m_ulRefCnt = 0; + logger::TLoggerPtr m_spLog; +}; Index: src/chext/DllRegistration.cpp =================================================================== diff -u -N --- src/chext/DllRegistration.cpp (revision 0) +++ src/chext/DllRegistration.cpp (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,214 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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 "DllRegistration.h" +#include "guids.h" +#include "../common/TRegistry.h" + +namespace +{ + std::wstring CLSID2String(REFCLSID rclsid) + { + const size_t stBufferSize = 64; + wchar_t szBuffer[stBufferSize] = {}; + _sntprintf_s(szBuffer, stBufferSize, _TRUNCATE, L"{%08lX-%04hX-%04hX-%02hX%02hX-%02hX%02hX%02hX%02hX%02hX%02hX}", + rclsid.Data1, rclsid.Data2, rclsid.Data3, + rclsid.Data4[0], rclsid.Data4[1], rclsid.Data4[2], rclsid.Data4[3], + rclsid.Data4[4], rclsid.Data4[5], rclsid.Data4[6], rclsid.Data4[7]); + + return szBuffer; + } + + std::wstring GetModulePath(HMODULE hModule) + { + wchar_t szPath[MAX_PATH + 2] = {}; + DWORD dwSize = ::GetModuleFileName(hModule, szPath, MAX_PATH + 1); + if (dwSize != 0 && dwSize < MAX_PATH) + { + szPath[dwSize] = L'\0'; + return szPath; + } + + return std::wstring(); + } + + void CreateSingleValue(HKEY key, const wchar_t* pszKey, const wchar_t* pszValueKey, const wchar_t* pszValue) + { + TRegistry reg(key, pszKey, false); + reg.SetString(pszValueKey, pszValue); + } + + void DeleteSingleValue(HKEY key, const wchar_t* pszKey, const wchar_t* pszValueKey) + { + TRegistry reg(key, pszKey, false); + reg.DeleteValue(pszValueKey); + } + + void CreateNodeWithDefaultValue(HKEY key, const wchar_t* pszKey, const wchar_t* pszSubKey, const wchar_t* pszValue) + { + TRegistry reg(key, pszKey, false); + reg.CreateSubKey(pszSubKey); + + std::wstring strNewKey = pszKey; + strNewKey += L'\\'; + strNewKey += pszSubKey; + + reg.ReOpen(key, strNewKey.c_str(), false); + reg.SetString(L"", pszValue); + } + + void DeleteSingleNode(HKEY key, const wchar_t* pszKey, const wchar_t* pszValueKey) + { + TRegistry reg(key, pszKey, false); + reg.DeleteSubKey(pszValueKey); + } + + void CreateNodes(HKEY key, const wchar_t* pszKey, std::wstring strSubKey) + { + TRegistry reg(key, pszKey, false); + reg.CreateSubKey(strSubKey.c_str()); + } +} + +DllRegistration::DllRegistration(HMODULE hModule) +{ + if (hModule == nullptr) + throw std::invalid_argument("hModule"); + + m_strModulePath = GetModulePath(hModule); + if (m_strModulePath.empty()) + throw std::runtime_error("Cannot retrieve module path"); +} + +void DllRegistration::RegisterAll() +{ + RemoveLegacyEntries(); + + RegisterShellExtensionControl(); + RegisterMenuExt(); + RegisterDropMenuExt(); +} + +void DllRegistration::UnregisterAll() +{ + RemoveLegacyEntries(); + + UnregisterShellExtensionControl(); + UnregisterMenuExt(); + UnregisterDropMenuExt(); +} + +void DllRegistration::RegisterMenuExt() +{ + std::wstring strClsID = CLSID2String(CLSID_MenuExt); + + RegisterClass(strClsID, L"MenuExt Class", L"Apartment"); + + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"Directory\\Shellex\\ContextMenuHandlers", L"chext", strClsID.c_str()); + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"Directory\\Background\\Shellex\\ContextMenuHandlers", L"chext", strClsID.c_str()); + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"Folder\\Shellex\\ContextMenuHandlers", L"chext", strClsID.c_str()); + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"*\\Shellex\\ContextMenuHandlers", L"chext", strClsID.c_str()); + + CreateSingleValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", strClsID.c_str(), L"chext"); +} + +void DllRegistration::RegisterDropMenuExt() +{ + std::wstring strClsID = CLSID2String(CLSID_DropMenuExt); + RegisterClass(strClsID, L"DropMenuExt Class", L"Apartment"); + + CreateNodes(HKEY_CLASSES_ROOT, L"CLSID", strClsID + L"\\shellex\\MayChangeDefaultMenu"); + + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"Directory\\Shellex\\DragDropHandlers", L"chext", strClsID.c_str()); + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"Drive\\Shellex\\DragDropHandlers", L"chext", strClsID.c_str()); + CreateNodeWithDefaultValue(HKEY_CLASSES_ROOT, L"Folder\\Shellex\\DragDropHandlers", L"chext", strClsID.c_str()); + + CreateSingleValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", strClsID.c_str(), L"chext"); +} + +void DllRegistration::RegisterShellExtensionControl() +{ + RegisterClass(CLSID2String(CLSID_CShellExtControl), L"ShellExtControl Class", L"Both"); +} + +void DllRegistration::UnregisterMenuExt() +{ + std::wstring strClsID = CLSID2String(CLSID_MenuExt); + + UnregisterClass(strClsID); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Directory\\Shellex\\ContextMenuHandlers", L"chext"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Directory\\Background\\Shellex\\ContextMenuHandlers", L"chext"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Folder\\Shellex\\ContextMenuHandlers", L"chext"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"*\\Shellex\\ContextMenuHandlers", L"chext"); + + DeleteSingleValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", strClsID.c_str()); +} + +void DllRegistration::UnregisterDropMenuExt() +{ + std::wstring strClsID = CLSID2String(CLSID_DropMenuExt); + + UnregisterClass(strClsID); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Directory\\Shellex\\DragDropHandlers", L"chext"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Drive\\Shellex\\DragDropHandlers", L"chext"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Folder\\Shellex\\DragDropHandlers", L"chext"); + + DeleteSingleValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", strClsID.c_str()); +} + +void DllRegistration::UnregisterShellExtensionControl() +{ + UnregisterClass(CLSID2String(CLSID_CShellExtControl)); +} + +void DllRegistration::RemoveLegacyEntries() +{ + DeleteSingleNode(HKEY_CLASSES_ROOT, L"", L"chext.MenuExt"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"", L"chext.MenuExt.1"); + + DeleteSingleNode(HKEY_CLASSES_ROOT, L"", L"chext.DropMenuExt"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"", L"chext.DropMenuExt.1"); + + DeleteSingleNode(HKEY_CLASSES_ROOT, L"", L"chext.ShellExtControl"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"", L"chext.ShellExtControl.1"); + + DeleteSingleNode(HKEY_CLASSES_ROOT, L"Interface", L"{317E503A-9D2F-4F42-995E-D314CB9D89B0}"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"TypeLib", L"{68FAFC14-8EB8-4DA1-90EB-6B3D22010505}"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"AppID", L"{9D4C4C5F-EE90-4a6b-9245-244C369E4FAE}"); + DeleteSingleNode(HKEY_CLASSES_ROOT, L"AppID", L"chext.dll"); +} + +void DllRegistration::RegisterClass(std::wstring strClsId, std::wstring strClassDescription, std::wstring strThreadingModel) +{ + std::wstring strGuidNode = L"CLSID\\" + strClsId; + std::wstring strInprocServerNode = strGuidNode + L"\\InprocServer32"; + + CreateNodes(HKEY_CLASSES_ROOT, L"CLSID", strClsId + L"\\InprocServer32"); + + CreateSingleValue(HKEY_CLASSES_ROOT, strGuidNode.c_str(), L"", strClassDescription.c_str()); + + TRegistry reg(HKEY_CLASSES_ROOT, strInprocServerNode.c_str(), false); + reg.SetString(L"", m_strModulePath.c_str()); + reg.SetString(L"ThreadingModel", strThreadingModel.c_str()); +} + +void DllRegistration::UnregisterClass(std::wstring strClsId) +{ + DeleteSingleNode(HKEY_CLASSES_ROOT, L"CLSID", strClsId.c_str()); +} Index: src/chext/DllRegistration.h =================================================================== diff -u -N --- src/chext/DllRegistration.h (revision 0) +++ src/chext/DllRegistration.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,46 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ + +#pragma once + +class DllRegistration +{ +public: + DllRegistration(HMODULE hModule); + + void RegisterAll(); + void UnregisterAll(); + + void RegisterMenuExt(); + void RegisterDropMenuExt(); + void RegisterShellExtensionControl(); + + void UnregisterMenuExt(); + void UnregisterDropMenuExt(); + void UnregisterShellExtensionControl(); + + void RemoveLegacyEntries(); + +private: + void RegisterClass(std::wstring strClsId, std::wstring strClassDescription, std::wstring strThreadingModel); + void UnregisterClass(std::wstring strClsId); + +private: + std::wstring m_strModulePath; +}; Index: src/chext/DropMenuExt.cpp =================================================================== diff -u -N -r9ddf8fdd5f641491dd30c49eb90f8f740314b6af -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision 9ddf8fdd5f641491dd30c49eb90f8f740314b6af) +++ src/chext/DropMenuExt.cpp (.../DropMenuExt.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -17,7 +17,6 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" -#include "chext.h" #include "DropMenuExt.h" #include "../Common/ipcstructs.h" #include "../libchengine/TTaskDefinition.h" @@ -48,6 +47,44 @@ } } +STDMETHODIMP CDropMenuExt::QueryInterface(REFIID riid, LPVOID FAR *ppvObject) +{ + if (!ppvObject) + return E_POINTER; + + *ppvObject = nullptr; + + if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IContextMenu)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IContextMenu2)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IContextMenu3)) + *ppvObject = static_cast(this); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) CDropMenuExt::AddRef() +{ + return InterlockedIncrement(&m_ulRefCnt); +} + +STDMETHODIMP_(ULONG) CDropMenuExt::Release() +{ + ULONG ulNewValue = InterlockedDecrement(&m_ulRefCnt); + if (ulNewValue) + return ulNewValue; + + delete this; + + return 0UL; +} + STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) { try Index: src/chext/DropMenuExt.h =================================================================== diff -u -N -rb26ced3298e3e7e51d91f3ac70b56746786da83b -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/DropMenuExt.h (.../DropMenuExt.h) (revision b26ced3298e3e7e51d91f3ac70b56746786da83b) +++ src/chext/DropMenuExt.h (.../DropMenuExt.h) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -24,30 +24,23 @@ #include "../common/TShellExtMenuConfig.h" #include "TShellExtData.h" #include "../liblogger/TLogger.h" +#include "ShellExtControl.h" ///////////////////////////////////////////////////////////////////////////// // CDropMenuExt -class ATL_NO_VTABLE CDropMenuExt : - public CComObjectRootEx, - public CComCoClass, +class CDropMenuExt : public IShellExtInit, public IContextMenu3 { public: CDropMenuExt(); ~CDropMenuExt(); -DECLARE_REGISTRY_RESOURCEID(IDR_DROPMENUEXT) -DECLARE_NOT_AGGREGATABLE(CDropMenuExt) - -DECLARE_PROTECT_FINAL_CONSTRUCT() - -BEGIN_COM_MAP(CDropMenuExt) - COM_INTERFACE_ENTRY(IShellExtInit) - COM_INTERFACE_ENTRY(IContextMenu) -END_COM_MAP() - public: + STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + STDMETHOD(InvokeCommand) (LPCMINVOKECOMMANDINFO lpici); STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/); STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax); @@ -57,6 +50,8 @@ STDMETHOD(HandleMenuMsg2)(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plResult); protected: + volatile ULONG m_ulRefCnt = 0; + IShellExtControl* m_piShellExtControl; TShellExtData m_tShellExtData; Index: src/chext/DropMenuExt.htm =================================================================== diff -u -N --- src/chext/DropMenuExt.htm (revision 3493e9fc470285b0a0b417d50be281467a071eb7) +++ src/chext/DropMenuExt.htm (revision 0) @@ -1,8 +0,0 @@ - - -ATL 3.0 test page for object DropMenuExt - - - - - \ No newline at end of file Index: src/chext/DropMenuExt.rgs =================================================================== diff -u -N --- src/chext/DropMenuExt.rgs (revision 47da0c5883b1bf97972b1bcd3dc70b2d64024969) +++ src/chext/DropMenuExt.rgs (revision 0) @@ -1,63 +0,0 @@ -HKCR -{ - chext.DropMenuExt.1 = s 'DropMenuExt Class' - { - CLSID = s '{B46F8244-86E6-43CF-B8AB-8C3A89928A48}' - } - chext.DropMenuExt = s 'DropMenuExt Class' - { - CLSID = s '{B46F8244-86E6-43CF-B8AB-8C3A89928A48}' - CurVer = s 'chext.DropMenuExt.1' - } - NoRemove CLSID - { - ForceRemove {B46F8244-86E6-43CF-B8AB-8C3A89928A48} = s 'DropMenuExt Class' - { - ProgID = s 'chext.DropMenuExt.1' - VersionIndependentProgID = s 'chext.DropMenuExt' - ForceRemove 'Programmable' - InprocServer32 = s '%MODULE%' - { - val ThreadingModel = s 'Apartment' - } - 'TypeLib' = s '{68FAFC14-8EB8-4DA1-90EB-6B3D22010505}' - ForceRemove shellex - { - ForceRemove MayChangeDefaultMenu - } - } - } - - NoRemove Directory - { - NoRemove Shellex - { - NoRemove DragDropHandlers - { - chext = s '{B46F8244-86E6-43CF-B8AB-8C3A89928A48}' - } - } - } - - NoRemove Drive - { - NoRemove Shellex - { - NoRemove DragDropHandlers - { - chext = s '{B46F8244-86E6-43CF-B8AB-8C3A89928A48}' - } - } - } - - NoRemove Folder - { - NoRemove Shellex - { - NoRemove DragDropHandlers - { - chext = s '{B46F8244-86E6-43CF-B8AB-8C3A89928A48}' - } - } - } -} Index: src/chext/DropMenuExtClassFactory.cpp =================================================================== diff -u -N --- src/chext/DropMenuExtClassFactory.cpp (revision 0) +++ src/chext/DropMenuExtClassFactory.cpp (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,41 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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 "DropMenuExtClassFactory.h" +#include +#include "DropMenuExt.h" + +STDMETHODIMP DropMenuExtClassFactory::CreateInstance(LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject) +{ + if (!ppObject) + return E_POINTER; + + *ppObject = nullptr; + if (pUnknown != nullptr) + return CLASS_E_NOAGGREGATION; + + auto pMenuExt = new (std::nothrow) CDropMenuExt(); + if (!pMenuExt) + return E_OUTOFMEMORY; + + const HRESULT hr = pMenuExt->QueryInterface(riid, ppObject); + if (FAILED(hr)) + delete pMenuExt; + return hr; +} Index: src/chext/DropMenuExtClassFactory.h =================================================================== diff -u -N --- src/chext/DropMenuExtClassFactory.h (revision 0) +++ src/chext/DropMenuExtClassFactory.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,27 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ +#pragma once + +#include "ClassFactory.h" + +class DropMenuExtClassFactory : public ClassFactory +{ +protected: + STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID*) override; +}; Index: src/chext/IShellExtControl.h =================================================================== diff -u -N --- src/chext/IShellExtControl.h (revision 0) +++ src/chext/IShellExtControl.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,35 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ +#pragma once + +#include + +enum EShellExtFlags +{ + eShellExt_None = 0, + eShellExt_Enabled = 1 +}; + +interface IShellExtControl : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetVersion(/* [out] */ LONG *plVersion, /* [out] */ BSTR *pbstrVersion) = 0; + virtual HRESULT STDMETHODCALLTYPE SetFlags(LONG lFlags, LONG lMask) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFlags(LONG *plFlags) = 0; +}; Index: src/chext/MenuExt.cpp =================================================================== diff -u -N -rd3371a00eafb40afa4251953591ff1004343e1be -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision d3371a00eafb40afa4251953591ff1004343e1be) +++ src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -17,7 +17,6 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" -#include "chext.h" #include "MenuExt.h" #include "../common/ipcstructs.h" #include "stdio.h" @@ -49,6 +48,44 @@ } } +STDMETHODIMP CMenuExt::QueryInterface(REFIID riid, LPVOID FAR *ppvObject) +{ + if (!ppvObject) + return E_POINTER; + + *ppvObject = nullptr; + + if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IContextMenu)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IContextMenu2)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IContextMenu3)) + *ppvObject = static_cast(this); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) CMenuExt::AddRef() +{ + return InterlockedIncrement(&m_ulRefCnt); +} + +STDMETHODIMP_(ULONG) CMenuExt::Release() +{ + ULONG ulNewValue = InterlockedDecrement(&m_ulRefCnt); + if (ulNewValue) + return ulNewValue; + + delete this; + + return 0UL; +} + STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) { try Index: src/chext/MenuExt.h =================================================================== diff -u -N -rb26ced3298e3e7e51d91f3ac70b56746786da83b -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/MenuExt.h (.../MenuExt.h) (revision b26ced3298e3e7e51d91f3ac70b56746786da83b) +++ src/chext/MenuExt.h (.../MenuExt.h) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -24,35 +24,26 @@ #include "../common/TShellExtMenuConfig.h" #include "TShellExtData.h" #include "../liblogger/TLogger.h" +#include "ShellExtControl.h" class TShellMenuItem; ///////////////////////////////////////////////////////////////////////////// // CMenuExt -class ATL_NO_VTABLE CMenuExt : - public CComObjectRootEx, - public CComCoClass, +class CMenuExt : public IShellExtInit, public IContextMenu3 { public: CMenuExt(); ~CMenuExt(); -DECLARE_REGISTRY_RESOURCEID(IDR_MENUEXT) -DECLARE_NOT_AGGREGATABLE(CMenuExt) - -DECLARE_PROTECT_FINAL_CONSTRUCT() - -BEGIN_COM_MAP(CMenuExt) - COM_INTERFACE_ENTRY(IShellExtInit) - COM_INTERFACE_ENTRY(IContextMenu) - COM_INTERFACE_ENTRY(IContextMenu2) - COM_INTERFACE_ENTRY(IContextMenu3) -END_COM_MAP() - // IMenuExt public: + STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/); STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici); STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax); @@ -64,6 +55,7 @@ HRESULT DrawMenuItem(LPDRAWITEMSTRUCT lpdis); private: + volatile ULONG m_ulRefCnt = 0; TShellExtData m_tShellExtData; TShellExtMenuConfig m_tShellExtMenuConfig; Index: src/chext/MenuExt.htm =================================================================== diff -u -N --- src/chext/MenuExt.htm (revision 3493e9fc470285b0a0b417d50be281467a071eb7) +++ src/chext/MenuExt.htm (revision 0) @@ -1,8 +0,0 @@ - - -ATL 3.0 test page for object MenuExt - - - - - \ No newline at end of file Index: src/chext/MenuExt.rgs =================================================================== diff -u -N --- src/chext/MenuExt.rgs (revision 47da0c5883b1bf97972b1bcd3dc70b2d64024969) +++ src/chext/MenuExt.rgs (revision 0) @@ -1,74 +0,0 @@ -HKCR -{ - chext.MenuExt.1 = s 'MenuExt Class' - { - CLSID = s '{E7A4C2DA-F3AF-4145-AC19-E3B215306A54}' - } - chext.MenuExt = s 'MenuExt Class' - { - CLSID = s '{E7A4C2DA-F3AF-4145-AC19-E3B215306A54}' - CurVer = s 'chext.MenuExt.1' - } - NoRemove CLSID - { - ForceRemove {E7A4C2DA-F3AF-4145-AC19-E3B215306A54} = s 'MenuExt Class' - { - ProgID = s 'chext.MenuExt.1' - VersionIndependentProgID = s 'chext.MenuExt' - ForceRemove 'Programmable' - InprocServer32 = s '%MODULE%' - { - val ThreadingModel = s 'Apartment' - } - 'TypeLib' = s '{68FAFC14-8EB8-4DA1-90EB-6B3D22010505}' - } - } - - NoRemove Directory - { - NoRemove Shellex - { - NoRemove ContextMenuHandlers - { - chext = s '{E7A4C2DA-F3AF-4145-AC19-E3B215306A54}' - } - } - } - - NoRemove Directory - { - NoRemove Background - { - NoRemove Shellex - { - NoRemove ContextMenuHandlers - { - chext = s '{E7A4C2DA-F3AF-4145-AC19-E3B215306A54}' - } - } - } - } - - NoRemove Folder - { - NoRemove Shellex - { - NoRemove ContextMenuHandlers - { - chext = s '{E7A4C2DA-F3AF-4145-AC19-E3B215306A54}' - } - } - } - - NoRemove * - { - NoRemove Shellex - { - NoRemove ContextMenuHandlers - { - chext = s '{E7A4C2DA-F3AF-4145-AC19-E3B215306A54}' - } - } - } - -} Index: src/chext/MenuExtClassFactory.cpp =================================================================== diff -u -N --- src/chext/MenuExtClassFactory.cpp (revision 0) +++ src/chext/MenuExtClassFactory.cpp (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,41 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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 "MenuExtClassFactory.h" +#include "MenuExt.h" +#include + +STDMETHODIMP MenuExtClassFactory::CreateInstance(LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject) +{ + if (!ppObject) + return E_POINTER; + + *ppObject = nullptr; + if (pUnknown != nullptr) + return CLASS_E_NOAGGREGATION; + + auto pMenuExt = new (std::nothrow) CMenuExt(); + if (!pMenuExt) + return E_OUTOFMEMORY; + + const HRESULT hr = pMenuExt->QueryInterface(riid, ppObject); + if (FAILED(hr)) + delete pMenuExt; + return hr; +} Index: src/chext/MenuExtClassFactory.h =================================================================== diff -u -N --- src/chext/MenuExtClassFactory.h (revision 0) +++ src/chext/MenuExtClassFactory.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,27 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ +#pragma once + +#include "ClassFactory.h" + +class MenuExtClassFactory : public ClassFactory +{ +public: + STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID*) override; +}; Index: src/chext/ShellExtControl.cpp =================================================================== diff -u -N -rd9527df01ee91b35d9a5fdccb80ded25a9c8265f -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision d9527df01ee91b35d9a5fdccb80ded25a9c8265f) +++ src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -17,17 +17,14 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" -#include "chext.h" #include #include "ShellExtControl.h" #include "../common/version.h" #include "Logger.h" #include "../libchcore/TIpcMutexLock.h" CShellExtControl::CShellExtControl() : - m_hMemory(nullptr), m_mutex(L"CHShellExtControlDataMutex"), - m_pShellExtData(nullptr), m_spLog(GetLogger(L"ShellExtControl")) { LOG_DEBUG(m_spLog) << L"Constructing CShellExtControl"; @@ -44,6 +41,40 @@ } } +STDMETHODIMP CShellExtControl::QueryInterface(REFIID riid, LPVOID FAR *ppvObject) +{ + if (!ppvObject) + return E_POINTER; + + *ppvObject = nullptr; + + if (IsEqualIID(riid, IID_IUnknown)) + *ppvObject = static_cast(this); + else if (IsEqualIID(riid, IID_IShellExtControl)) + *ppvObject = static_cast(this); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) CShellExtControl::AddRef() +{ + return InterlockedIncrement(&m_ulRefCnt); +} + +STDMETHODIMP_(ULONG) CShellExtControl::Release() +{ + ULONG ulNewValue = InterlockedDecrement(&m_ulRefCnt); + if (ulNewValue) + return ulNewValue; + + delete this; + + return 0UL; +} + STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion, BSTR* pbstrVersion) { try Index: src/chext/ShellExtControl.h =================================================================== diff -u -N -r134983cab6122e3fff73994a6f9c417aaeab3bc2 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/ShellExtControl.h (.../ShellExtControl.h) (revision 134983cab6122e3fff73994a6f9c417aaeab3bc2) +++ src/chext/ShellExtControl.h (.../ShellExtControl.h) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -20,47 +20,40 @@ #define __SHELLEXTCONTROL_H_ #include "resource.h" // main symbols +#include "guids.h" #include "../liblogger/TLogger.h" #include "../libchcore/TIpcMutex.h" #include "../libchcore/TSharedMemory.h" +#include "IShellExtControl.h" -///////////////////////////////////////////////////////////////////////////// -// CDropMenuExt -class ATL_NO_VTABLE CShellExtControl : - public CComObjectRootEx, - public CComCoClass, - public IDispatchImpl +class CShellExtControl : public IShellExtControl { public: CShellExtControl(); ~CShellExtControl(); + STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + STDMETHOD(GetVersion)(LONG* plVersion, BSTR* pbstrVersion); STDMETHOD(SetFlags)(LONG lFlags, LONG lMask); STDMETHOD(GetFlags)(LONG* plFlags); -DECLARE_REGISTRY_RESOURCEID(IDR_SHELLEXTCONTROL) - -DECLARE_PROTECT_FINAL_CONSTRUCT() - -BEGIN_COM_MAP(CShellExtControl) - COM_INTERFACE_ENTRY(IUnknown) - COM_INTERFACE_ENTRY(IShellExtControl) -END_COM_MAP() - private: HRESULT Initialize(); private: + volatile ULONG m_ulRefCnt = 0; + HANDLE m_hMemory = nullptr; chcore::TIpcMutex m_mutex; struct SHELLEXT_DATA { long m_lFlags = 0; - } *m_pShellExtData; + } *m_pShellExtData = nullptr; - CComAutoCriticalSection m_lock; logger::TLoggerPtr m_spLog; chcore::TSharedMemory m_shmConfiguration; bool m_bInitialized = false; Index: src/chext/ShellExtControl.rgs =================================================================== diff -u -N --- src/chext/ShellExtControl.rgs (revision 306fbe693c70290af9de9a5779084a697de22d75) +++ src/chext/ShellExtControl.rgs (revision 0) @@ -1,26 +0,0 @@ -HKCR -{ - chext.ShellExtControl.1 = s 'ShellExtControl Class' - { - CLSID = s '{3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF}' - } - chext.ShellExtControl = s 'ShellExtControl Class' - { - CLSID = s '{3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF}' - CurVer = s 'chext.MenuExt.1' - } - NoRemove CLSID - { - ForceRemove {3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF} = s 'ShellExtControl Class' - { - ProgID = s 'chext.ShellExtControl.1' - VersionIndependentProgID = s 'chext.ShellExtControl' - ForceRemove 'Programmable' - InprocServer32 = s '%MODULE%' - { - val ThreadingModel = s 'Both' - } - 'TypeLib' = s '{68FAFC14-8EB8-4DA1-90EB-6B3D22010505}' - } - } -} Index: src/chext/ShellExtControlClassFactory.cpp =================================================================== diff -u -N --- src/chext/ShellExtControlClassFactory.cpp (revision 0) +++ src/chext/ShellExtControlClassFactory.cpp (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,41 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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 "ShellExtControlClassFactory.h" +#include "ShellExtControl.h" +#include + +STDMETHODIMP ShellExtControlClassFactory::CreateInstance(LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject) +{ + if (!ppObject) + return E_POINTER; + + *ppObject = nullptr; + if (pUnknown != nullptr) + return CLASS_E_NOAGGREGATION; + + auto pShellExtControl = new (std::nothrow) CShellExtControl(); + if (!pShellExtControl) + return E_OUTOFMEMORY; + + const HRESULT hr = pShellExtControl->QueryInterface(riid, ppObject); + if (FAILED(hr)) + delete pShellExtControl; + return hr; +} Index: src/chext/ShellExtControlClassFactory.h =================================================================== diff -u -N --- src/chext/ShellExtControlClassFactory.h (revision 0) +++ src/chext/ShellExtControlClassFactory.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,27 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ +#pragma once + +#include "ClassFactory.h" + +class ShellExtControlClassFactory : public ClassFactory +{ +public: + STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID*) override; +}; Index: src/chext/dllmain.h =================================================================== diff -u -N --- src/chext/dllmain.h (revision b79aca0d66b1084f230022efe39cc89307482e6d) +++ src/chext/dllmain.h (revision 0) @@ -1,31 +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 __DLLMAIN_H__ -#define __DLLMAIN_H__ - -class CCHExtModule : public CAtlDllModuleT -{ -public : - DECLARE_LIBID(LIBID_CHEXTLib) - DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CHEXT, "{9D4C4C5F-EE90-4a6b-9245-244C369E4FAE}") -}; - -extern class CCHExtModule _AtlModule; - -#endif Index: src/chext/ShellExtensionVerifier.h =================================================================== diff -u -N -rd9527df01ee91b35d9a5fdccb80ded25a9c8265f -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/ShellExtensionVerifier.h (.../ShellExtensionVerifier.h) (revision d9527df01ee91b35d9a5fdccb80ded25a9c8265f) +++ src/chext/ShellExtensionVerifier.h (.../ShellExtensionVerifier.h) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -19,7 +19,7 @@ #ifndef __SHELLEXTENSIONVERIFIER_H__ #define __SHELLEXTENSIONVERIFIER_H__ -#include "chext.h" +#include "IShellExtControl.h" class TShellExtMenuConfig; Index: src/chext/StdAfx.cpp =================================================================== diff -u -N -rd5c3edd0d167db9b5d47d04248820fda49499a5e -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/StdAfx.cpp (.../StdAfx.cpp) (revision d5c3edd0d167db9b5d47d04248820fda49499a5e) +++ src/chext/StdAfx.cpp (.../StdAfx.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -17,10 +17,3 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" - -#ifdef _ATL_STATIC_REGISTRY -#include -//#include -#endif - -//#include Index: src/chext/StdAfx.h =================================================================== diff -u -N -r2f696d06139af4d0fab14dd1613507b66f5169cb -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/StdAfx.h (.../StdAfx.h) (revision 2f696d06139af4d0fab14dd1613507b66f5169cb) +++ src/chext/StdAfx.h (.../StdAfx.h) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -24,25 +24,14 @@ #include "../common/targetver.h" -#define _ATL_APARTMENT_THREADED +#include -#include - #include "resource.h" -#include -#include -#include #include -#include #include #include -#pragma warning(push) -#pragma warning(disable: 4985) - #include -#pragma warning(pop) - #endif Index: src/chext/chext.cpp =================================================================== diff -u -N -re2054db3fa2be3652ca376a318d49dbaba8539ed -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/chext.cpp (.../chext.cpp) (revision e2054db3fa2be3652ca376a318d49dbaba8539ed) +++ src/chext/chext.cpp (.../chext.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -16,77 +16,106 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -// Note: Proxy/Stub Information -// To build a separate proxy/stub DLL, -// run nmake -f CopyHandlerShellExtps.mk in the project directory. - #include "stdafx.h" -#include "chext.h" -#include "dllmain.h" #include "Logger.h" +#include "guids.h" +#include "MenuExtClassFactory.h" +#include "DropMenuExtClassFactory.h" +#include "ShellExtControlClassFactory.h" +#include "../common/TRegistry.h" +#include "DllRegistration.h" +LONG g_DllRefCount = 0; // Reference count of this DLL. +extern HINSTANCE g_hInstance; + +namespace +{ + template + HRESULT CreateFactory(REFIID riid, LPVOID* ppv) + { + auto classFactory = new (std::nothrow) T; + if (!classFactory) + return E_OUTOFMEMORY; + + HRESULT hResult = classFactory->QueryInterface(riid, ppv); + if (hResult != S_OK) + delete classFactory; + + return hResult; + } +} + ///////////////////////////////////////////////////////////////////////////// // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow() { - HRESULT hResult = _AtlModule.DllCanUnloadNow(); - - return hResult; + return (g_DllRefCount == 0 ? S_OK : S_FALSE); } ///////////////////////////////////////////////////////////////////////////// // Returns a class factory to create an object of the requested type STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { - HRESULT hResult = _AtlModule.DllGetClassObject(rclsid, riid, ppv); + if (!ppv) + return E_POINTER; - return hResult; + *ppv = nullptr; + + try + { + if (IsEqualIID(rclsid, CLSID_MenuExt)) + return CreateFactory(riid, ppv); + else if (IsEqualIID(rclsid, CLSID_DropMenuExt)) + return CreateFactory(riid, ppv); + else if (IsEqualIID(rclsid, CLSID_CShellExtControl)) + return CreateFactory(riid, ppv); + } + catch (const std::exception& e) + { + OutputDebugStringA(e.what()); + return E_FAIL; + } + + return CLASS_E_CLASSNOTAVAILABLE; } ///////////////////////////////////////////////////////////////////////////// // DllRegisterServer - Adds entries to the system registry STDAPI DllRegisterServer() { - // registers object, typelib and all interfaces in typelib - HRESULT hResult = _AtlModule.DllRegisterServer(); + try + { + DllRegistration regDll(g_hInstance); - return hResult; + regDll.RegisterAll(); + } + catch (const std::exception& e) + { + OutputDebugStringA(e.what()); + return E_FAIL; + } + + return S_OK; } ///////////////////////////////////////////////////////////////////////////// // DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer() { - HRESULT hResult = _AtlModule.DllUnregisterServer(); - - return hResult; -} - -// DllInstall - Adds/Removes entries to the system registry per user -// per machine. -STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) -{ - static const wchar_t szUserSwitch[] = _T("user"); - - if (pszCmdLine != nullptr) + try { - if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0) - AtlSetPerUserRegistration(true); + DllRegistration regDll(g_hInstance); + regDll.UnregisterAll(); } - - HRESULT hResult = E_FAIL; - if (bInstall) + catch (const std::exception& e) { - hResult = DllRegisterServer(); - if (FAILED(hResult)) - DllUnregisterServer(); + OutputDebugStringA(e.what()); + return E_FAIL; } - else - hResult = DllUnregisterServer(); - return hResult; + return S_OK; } Index: src/chext/chext.def =================================================================== diff -u -N --- src/chext/chext.def (revision 0) +++ src/chext/chext.def (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,5 @@ +EXPORTS + DllCanUnloadNow private + DllGetClassObject private + DllRegisterServer private + DllUnregisterServer private Index: src/chext/chext.idl =================================================================== diff -u -N --- src/chext/chext.idl (revision 0373359eff650e8cf04a5992711ef9f20347536f) +++ src/chext/chext.idl (revision 0) @@ -1,96 +0,0 @@ -/*************************************************************************** -* Copyright (C) 2001-2008 by J�zef 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. * -***************************************************************************/ -// chext.idl : IDL source for chext.dll -// - -// This file will be processed by the MIDL tool to -// produce the type library (chext.tlb) and marshalling code. - -import "oaidl.idl"; -import "ocidl.idl"; -import "shobjidl.idl"; - -[ - v1_enum, - uuid(54F8BFDD-6685-4792-94BD-40DF00099F9B), - helpstring("Shell extension flags") -] -enum EShellExtFlags -{ - eShellExt_None = 0, - eShellExt_Enabled = 1 -}; - -[ - object, - uuid(317E503A-9D2F-4f42-995E-D314CB9D89B0), - dual, - helpstring("IShellExtControl Interface"), - pointer_default(unique) -] -interface IShellExtControl : IDispatch -{ - // Shell extension version (numeric and readable) - [id(1),helpstring("Retrieves the extension version information")] - HRESULT GetVersion([out]LONG* plVersion, [out]BSTR* pbstrVersion); - - // Flag setting/retrieving - [id(2),helpstring("Sets the flags for shell extension")] - HRESULT SetFlags(LONG lFlags, LONG lMask); - [id(3),helpstring("Retrieves the shell extension flags")] - HRESULT GetFlags(LONG* plFlags); -}; - -[ - uuid(68FAFC14-8EB8-4DA1-90EB-6B3D22010505), - version(1.0), - helpstring("chext 1.0 Type Library") -] -library CHEXTLib -{ - importlib("stdole32.tlb"); - importlib("stdole2.tlb"); - - [ - uuid(E7A4C2DA-F3AF-4145-AC19-E3B215306A54), - helpstring("MenuExt Class") - ] - coclass MenuExt - { - [default] interface IContextMenu3; - interface IShellExtControl; - }; - [ - uuid(B46F8244-86E6-43CF-B8AB-8C3A89928A48), - helpstring("DropMenuExt Class") - ] - coclass DropMenuExt - { - [default] interface IContextMenu3; - interface IShellExtControl; - }; - [ - uuid(3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF), - helpstring("CShellExtControl Class") - ] - coclass CShellExtControl - { - [default] interface IShellExtControl; - }; -}; Index: src/chext/chext.rc =================================================================== diff -u -N -r8163be49a92698ada689f27b2dbe0caae69a7d5c -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/chext.rc (.../chext.rc) (revision 8163be49a92698ada689f27b2dbe0caae69a7d5c) +++ src/chext/chext.rc (.../chext.rc) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -40,12 +40,6 @@ 3 TEXTINCLUDE BEGIN - "1 TYPELIB ""chext.tlb""\r\n" - "\0" -END - -4 TEXTINCLUDE -BEGIN "#include ""res\\chext.rc2""\r\n" "\0" END @@ -65,16 +59,6 @@ #pragma code_page(1252) #endif //_WIN32 -///////////////////////////////////////////////////////////////////////////// -// -// REGISTRY -// - -IDR_MENUEXT REGISTRY "MenuExt.rgs" -IDR_DROPMENUEXT REGISTRY "DropMenuExt.rgs" -IDR_SHELLEXTCONTROL REGISTRY "ShellExtControl.rgs" -IDR_CHEXT REGISTRY "chext.rgs" - #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// @@ -85,10 +69,8 @@ // // Generated from the TEXTINCLUDE 3 resource. // -1 TYPELIB "chext.tlb" #include "res\chext.rc2" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED - Index: src/chext/chext.rgs =================================================================== diff -u -N --- src/chext/chext.rgs (revision bc695e56772e5a5eb4574a17905afafb4c62b6dd) +++ src/chext/chext.rgs (revision 0) @@ -1,11 +0,0 @@ -HKCR -{ - NoRemove AppID - { - '%APPID%' = s 'chext' - 'chext.dll' - { - val AppID = s '%APPID%' - } - } -} Index: src/chext/chext.vc140.vcxproj =================================================================== diff -u -N -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/chext.vc140.vcxproj (.../chext.vc140.vcxproj) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/chext/chext.vc140.vcxproj (.../chext.vc140.vcxproj) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -214,7 +214,7 @@ false comctl32.lib;%(AdditionalDependencies) - chext32.def + chext.def true Windows MachineX86 @@ -250,7 +250,7 @@ false comctl32.lib;gmock32d.lib;%(AdditionalDependencies) - chext32.def + chext.def true Windows MachineX86 @@ -301,7 +301,7 @@ false comctl32.lib;%(AdditionalDependencies) - chext64.def + chext.def true Windows MachineX64 @@ -338,7 +338,7 @@ false comctl32.lib;gmock64d.lib;%(AdditionalDependencies) - chext64.def + chext.def true Windows MachineX64 @@ -389,7 +389,7 @@ false comctl32.lib;%(AdditionalDependencies) - chext32.def + chext.def true Windows MachineX86 @@ -426,7 +426,7 @@ false comctl32.lib;gmock32.lib;%(AdditionalDependencies) - chext32.def + chext.def true Windows MachineX86 @@ -477,7 +477,7 @@ false comctl32.lib;%(AdditionalDependencies) - chext64.def + chext.def true Windows MachineX64 @@ -514,7 +514,7 @@ false comctl32.lib;gmock64.lib;%(AdditionalDependencies) - chext64.def + chext.def true Windows MachineX64 @@ -553,12 +553,18 @@ NotUsing NotUsing + + + + + + @@ -577,40 +583,29 @@ Create Create - - - - - - - - - - - - - - - - - - + + + + + + + + - @@ -622,42 +617,6 @@ - - true - true - .\chext.tlb - .\chext.tlb - chext.h - chext.h - chext_i.c - chext_i.c - true - true - .\chext.tlb - .\chext.tlb - chext.h - chext.h - chext_i.c - chext_i.c - true - true - .\chext.tlb - .\chext.tlb - chext.h - chext.h - chext_i.c - chext_i.c - true - true - .\chext.tlb - .\chext.tlb - chext.h - chext.h - chext_i.c - chext_i.c - - - Index: src/chext/chext.vc140.vcxproj.filters =================================================================== diff -u -N -r306fbe693c70290af9de9a5779084a697de22d75 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/chext.vc140.vcxproj.filters (.../chext.vc140.vcxproj.filters) (revision 306fbe693c70290af9de9a5779084a697de22d75) +++ src/chext/chext.vc140.vcxproj.filters (.../chext.vc140.vcxproj.filters) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -27,6 +27,9 @@ {65a70a57-2fd2-49a6-90f2-e0597f13adfe} + + {4c68be3a-4d21-48ce-b3f0-e166072c66d3} + @@ -59,9 +62,6 @@ Source Files\Main - - Generated Files - Tests @@ -80,6 +80,24 @@ Source Files\Common + + Source Files\Common + + + Source Files\Tools + + + Source Files\Interfaces\ClassFactories + + + Source Files\Interfaces\ClassFactories + + + Source Files\Interfaces\ClassFactories + + + Source Files\Interfaces\ClassFactories + @@ -106,9 +124,6 @@ Source Files\Common - - Source Files\Main - Source Files\Main @@ -133,6 +148,30 @@ Source Files\Common + + Source Files\Interfaces + + + Source Files\Interfaces + + + Source Files\Common + + + Source Files\Tools + + + Source Files\Interfaces\ClassFactories + + + Source Files\Interfaces\ClassFactories + + + Source Files\Interfaces\ClassFactories + + + Source Files\Interfaces\ClassFactories + @@ -149,11 +188,6 @@ - - Source Files\Main - - - Resource Files Index: src/chext/chext32.def =================================================================== diff -u -N --- src/chext/chext32.def (revision 47d0095dc08bfef8ff8f95e213b75016037f7398) +++ src/chext/chext32.def (revision 0) @@ -1,10 +0,0 @@ -; chext.def : Declares the module parameters. - -LIBRARY "chext.dll" - -EXPORTS - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE - DllInstall PRIVATE Index: src/chext/chext64.def =================================================================== diff -u -N --- src/chext/chext64.def (revision 47d0095dc08bfef8ff8f95e213b75016037f7398) +++ src/chext/chext64.def (revision 0) @@ -1,10 +0,0 @@ -; chext.def : Declares the module parameters. - -LIBRARY "chext64.dll" - -EXPORTS - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE - DllInstall PRIVATE Index: src/chext/chextps.def =================================================================== diff -u -N --- src/chext/chextps.def (revision 47da0c5883b1bf97972b1bcd3dc70b2d64024969) +++ src/chext/chextps.def (revision 0) @@ -1,11 +0,0 @@ - -LIBRARY "chextPS" - -DESCRIPTION 'Proxy/Stub DLL' - -EXPORTS - DllGetClassObject @1 PRIVATE - DllCanUnloadNow @2 PRIVATE - GetProxyDllInfo @3 PRIVATE - DllRegisterServer @4 PRIVATE - DllUnregisterServer @5 PRIVATE Index: src/chext/chextps.mk =================================================================== diff -u -N --- src/chext/chextps.mk (revision 47da0c5883b1bf97972b1bcd3dc70b2d64024969) +++ src/chext/chextps.mk (revision 0) @@ -1,16 +0,0 @@ - -chextps.dll: dlldata.obj chext_p.obj chext_i.obj - link /dll /out:chextps.dll /def:chextps.def /entry:DllMain dlldata.obj chext_p.obj chext_i.obj \ - kernel32.lib rpcndr.lib rpcns4.lib rpcrt4.lib oleaut32.lib uuid.lib \ - -.c.obj: - cl /c /Ox /DWIN32 /D_WIN32_WINNT=0x0400 /DREGISTER_PROXY_DLL \ - $< - -clean: - @del chextps.dll - @del chextps.lib - @del chextps.exp - @del dlldata.obj - @del chext_p.obj - @del chext_i.obj Index: src/chext/dllmain.cpp =================================================================== diff -u -N -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12 -r6609ba39811176f4803f0556db3da30e9e457b9d --- src/chext/dllmain.cpp (.../dllmain.cpp) (revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12) +++ src/chext/dllmain.cpp (.../dllmain.cpp) (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -1,21 +1,18 @@ #include "stdafx.h" -#include "chext.h" -#include "dllmain.h" #include "MenuExt.h" #include "DropMenuExt.h" #include "ShellExtControl.h" -CCHExtModule _AtlModule; +HINSTANCE g_hInstance = nullptr; -OBJECT_ENTRY_AUTO(CLSID_MenuExt, CMenuExt) -OBJECT_ENTRY_AUTO(CLSID_DropMenuExt, CDropMenuExt) -OBJECT_ENTRY_AUTO(CLSID_CShellExtControl, CShellExtControl) - extern "C" -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if(dwReason == DLL_PROCESS_ATTACH) + { DisableThreadLibraryCalls(hInstance); + g_hInstance = hInstance; + } - return _AtlModule.DllMain(dwReason, lpReserved); + return TRUE; } Index: src/chext/guids.h =================================================================== diff -u -N --- src/chext/guids.h (revision 0) +++ src/chext/guids.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,28 @@ +// ============================================================================ +// Copyright (C) 2001-2019 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. +// ============================================================================ +#pragma once + +#include +#include + +DEFINE_GUID(IID_IShellExtControl, 0x317E503A, 0x9D2F, 0x4f42, 0x99, 0x5E, 0xD3, 0x14, 0xCB, 0x9D, 0x89, 0xB0); +//DEFINE_GUID(LIBID_CHEXTLib, 0x68FAFC14, 0x8EB8, 0x4DA1, 0x90, 0xEB, 0x6B, 0x3D, 0x22, 0x01, 0x05, 0x05); +DEFINE_GUID(CLSID_MenuExt, 0xE7A4C2DA, 0xF3AF, 0x4145, 0xAC, 0x19, 0xE3, 0xB2, 0x15, 0x30, 0x6A, 0x54); +DEFINE_GUID(CLSID_DropMenuExt, 0xB46F8244, 0x86E6, 0x43CF, 0xB8, 0xAB, 0x8C, 0x3A, 0x89, 0x92, 0x8A, 0x48); +DEFINE_GUID(CLSID_CShellExtControl, 0x3D855ACA, 0x8274, 0x4f1f, 0x94, 0xE9, 0x6B, 0xEF, 0x4F, 0xC2, 0xA2, 0xAF); Index: src/common/TRegistry.cpp =================================================================== diff -u -N --- src/common/TRegistry.cpp (revision 0) +++ src/common/TRegistry.cpp (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,126 @@ +// ============================================================================ +// 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 "TRegistry.h" +#include + +TRegistry::TRegistry(HKEY key, const wchar_t* pszKey, bool bReadOnly) +{ + ReOpen(key, pszKey, bReadOnly); +} + +TRegistry::~TRegistry() +{ + if(m_hKey) + RegCloseKey(m_hKey); +} + +void TRegistry::ReOpen(HKEY key, const wchar_t* pszKey, bool bReadOnly /*= true*/) +{ + if (!pszKey) + throw std::invalid_argument("pszKey"); + + if (m_hKey) + RegCloseKey(m_hKey); + + LSTATUS lStatus = RegOpenKeyEx(key, pszKey, 0, bReadOnly ? KEY_QUERY_VALUE : KEY_ALL_ACCESS, &m_hKey); + if (lStatus != ERROR_SUCCESS || m_hKey == nullptr) + throw std::runtime_error("Cannot open registry key"); +} + +void TRegistry::CreateSubKey(const wchar_t* pszKey) +{ + if (!pszKey) + throw std::invalid_argument("pszKey"); + + HKEY newKey = nullptr; + LSTATUS status = RegCreateKeyEx(m_hKey, pszKey, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, nullptr, &newKey, nullptr); + if(status != ERROR_SUCCESS) + throw std::runtime_error("Cannot create registry key"); +} + +void TRegistry::DeleteSubKey(const wchar_t* pszKey) +{ + if (!pszKey) + throw std::invalid_argument("pszKey"); + + LSTATUS status = SHDeleteKey(m_hKey, pszKey); + if (status != ERROR_SUCCESS && status != ERROR_FILE_NOT_FOUND) + throw std::runtime_error("Cannot delete registry key"); +} + +void TRegistry::DeleteValue(const wchar_t* pszValueKey) +{ + if (!pszValueKey) + throw std::invalid_argument("pszValueKey"); + + LSTATUS status = RegDeleteValue(m_hKey, pszValueKey); + if (status != ERROR_SUCCESS && status != ERROR_FILE_NOT_FOUND) + throw std::runtime_error("Cannot delete value"); +} + +bool TRegistry::QueryString(const wchar_t* pszValueKey, std::wstring& wstrValue) +{ + if (!pszValueKey) + throw std::invalid_argument("pszValueKey"); + + DWORD dwType = REG_SZ; + const DWORD stMaxBuffer = 1024; + std::unique_ptr buf(new wchar_t[stMaxBuffer]); + + DWORD dwCount = stMaxBuffer; + LSTATUS lStatus = RegQueryValueEx(m_hKey, pszValueKey, nullptr, &dwType, (BYTE*)buf.get(), &dwCount); + if (lStatus != ERROR_SUCCESS) + return false; + + buf[dwCount / 2] = L'\0'; + wstrValue = buf.get(); + + return true; +} + +bool TRegistry::QueryDword(const wchar_t* pszValueKey, DWORD& dwOutValue) +{ + if (!pszValueKey) + throw std::invalid_argument("pszValueKey"); + + DWORD dwType = REG_DWORD; + DWORD dwCount = sizeof(DWORD); + DWORD dwValue = 0; + LSTATUS lStatus = RegQueryValueEx(m_hKey, pszValueKey, nullptr, &dwType, (BYTE*)&dwValue, &dwCount); + if (lStatus != ERROR_SUCCESS) + return false; + + dwOutValue = dwValue; + + return true; +} + +void TRegistry::SetString(const wchar_t* pszValueKey, const wchar_t* pszValue) +{ + if (!pszValueKey) + throw std::invalid_argument("pszValueKey"); + if (!pszValue) + throw std::invalid_argument("pszValue"); + + size_t stValueLen = wcslen(pszValue) + 1; + LSTATUS status = RegSetValueEx(m_hKey, pszValueKey, 0, REG_SZ, (const BYTE*)pszValue, boost::numeric_cast(stValueLen * sizeof(wchar_t))); + if (status != ERROR_SUCCESS) + throw std::runtime_error("Cannot set string value in registry"); +} Index: src/common/TRegistry.h =================================================================== diff -u -N --- src/common/TRegistry.h (revision 0) +++ src/common/TRegistry.h (revision 6609ba39811176f4803f0556db3da30e9e457b9d) @@ -0,0 +1,44 @@ +// ============================================================================ +// 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 __TREGISTRY_H__ +#define __TREGISTRY_H__ + +class TRegistry +{ +public: + TRegistry(HKEY key, const wchar_t* pszKey, bool bReadOnly = true); + ~TRegistry(); + + void ReOpen(HKEY key, const wchar_t* pszKey, bool bReadOnly = true); + + void CreateSubKey(const wchar_t* pszKey); + void DeleteSubKey(const wchar_t* pszKey); + + void DeleteValue(const wchar_t* pszValueKey); + + bool QueryString(const wchar_t* pszValueKey, std::wstring& wstrValue); + bool QueryDword(const wchar_t* pszValueKey, DWORD& dwOutValue); + + void SetString(const wchar_t* pszValueKey, const wchar_t* pszValue); + +private: + HKEY m_hKey = nullptr; +}; + +#endif Index: src/ch/TRegistry.h =================================================================== diff -u -N --- src/ch/TRegistry.h (revision 62bf985594e79a03316e29434cbdcf446a64f369) +++ src/ch/TRegistry.h (revision 0) @@ -1,35 +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 __TREGISTRY_H__ -#define __TREGISTRY_H__ - -class TRegistry -{ -public: - TRegistry(HKEY key, const wchar_t* pszKey); - ~TRegistry(); - - bool QueryString(const wchar_t* pszValueKey, std::wstring& wstrValue); - bool QueryDword(const wchar_t* pszValueKey, DWORD& dwOutValue); - -private: - HKEY m_hKey = nullptr; -}; - -#endif