Index: ch.vc90.sln =================================================================== diff -u -N -r2eabdea6d63640f34fb1f8bcf928336cc1a660af -rd0fdcc905035e648382256101a3d99f429af6d56 --- ch.vc90.sln (.../ch.vc90.sln) (revision 2eabdea6d63640f34fb1f8bcf928336cc1a660af) +++ ch.vc90.sln (.../ch.vc90.sln) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -6,6 +6,7 @@ {5510B933-046F-4F75-8B46-5E8279C8CCDE} = {5510B933-046F-4F75-8B46-5E8279C8CCDE} {DD1F3242-7EE4-4F41-8B8D-D833300C445F} = {DD1F3242-7EE4-4F41-8B8D-D833300C445F} {10FB6B7E-81A1-47F9-BC6F-7017E5695D3A} = {10FB6B7E-81A1-47F9-BC6F-7017E5695D3A} + {7CE8B0C5-8CD4-4551-ACBF-EC4749E15E69} = {7CE8B0C5-8CD4-4551-ACBF-EC4749E15E69} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chext", "src\chext\chext.vc90.vcproj", "{7CE8B0C5-8CD4-4551-ACBF-EC4749E15E69}" Index: src/ch/MainWnd.cpp =================================================================== diff -u -N -rf6c4389122d92e5f84a509e9be0facebac429151 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision f6c4389122d92e5f84a509e9be0facebac429151) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -1789,6 +1789,9 @@ BOOL CMainWnd::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { + if(!GetApp()->IsShellExtEnabled()) + return FALSE; + // copying or moving ? bool bMove=false; switch(pCopyDataStruct->dwData & OPERATION_MASK) Index: src/ch/ch.cpp =================================================================== diff -u -N -rf6c4389122d92e5f84a509e9be0facebac429151 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/ch/ch.cpp (.../ch.cpp) (revision f6c4389122d92e5f84a509e9be0facebac429151) +++ src/ch/ch.cpp (.../ch.cpp) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -21,7 +21,7 @@ #include "CfgProperties.h" #include "MainWnd.h" -#include "..\common\ipcstructs.h" +#include "../common/ipcstructs.h" #include #include "CrashDlg.h" #include "../common/version.h" @@ -84,7 +84,8 @@ CCopyHandlerApp::CCopyHandlerApp() : m_lfLog(), - m_cfgSettings(icpf::config::eIni) + m_cfgSettings(icpf::config::eIni), + m_piShellExtControl(NULL) { m_pMainWindow=NULL; @@ -106,6 +107,12 @@ delete m_pMainWindow; m_pMainWnd=NULL; } + + if(m_piShellExtControl) + { + m_piShellExtControl->Release(); + m_piShellExtControl = NULL; + } } CCopyHandlerApp* GetApp() @@ -206,6 +213,10 @@ // set the exception handler to catch the crash dumps SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter); + HRESULT hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if(FAILED(hResult)) + AfxMessageBox(_T("Cannot initialize COM, the application will now exit."), MB_ICONERROR | MB_OK); + // InitCommonControlsEx() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. @@ -226,7 +237,7 @@ return FALSE; // Get a pointer to the file-mapped shared memory. - g_pscsShared=(CSharedConfigStruct*)MapViewOfFile(m_hMapObject, FILE_MAP_WRITE, 0, 0, 0); + g_pscsShared=(CSharedConfigStruct*)MapViewOfFile(m_hMapObject, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (g_pscsShared == NULL) return FALSE; @@ -298,6 +309,32 @@ return FALSE; } + // calculate ch version + LONG lCHVersion = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; + + // check the version of shell extension + LONG lVersion = 0; + BSTR bstrVersion = NULL; + + hResult = CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); + if(SUCCEEDED(hResult) && !m_piShellExtControl) + hResult = E_FAIL; + if(SUCCEEDED(hResult)) + hResult = m_piShellExtControl->GetVersion(&lVersion, &bstrVersion); + if(SUCCEEDED(hResult) && lVersion == lCHVersion) + hResult = m_piShellExtControl->SetFlags(eShellExt_Enabled, eShellExt_Enabled); + if(FAILED(hResult) || lCHVersion != lVersion) + { + MsgBox(IDS_SHELL_EXTENSION_MISMATCH_STRING); + + if(m_piShellExtControl) + m_piShellExtControl->SetFlags(0, eShellExt_Enabled); + } + + if(bstrVersion) + ::SysFreeString(bstrVersion); + + // create main window m_pMainWindow=new CMainWnd; if (!((CMainWnd*)m_pMainWindow)->Create()) return FALSE; // will be deleted at destructor @@ -307,6 +344,18 @@ return TRUE; } +bool CCopyHandlerApp::IsShellExtEnabled() const +{ + if(m_piShellExtControl) + { + LONG lFlags = 0; + HRESULT hResult = m_piShellExtControl->GetFlags(&lFlags); + if(SUCCEEDED(hResult) && (lFlags & eShellExt_Enabled)) + return true; + } + return false; +} + void CCopyHandlerApp::OnConfigNotify(uint_t uiPropID) { // is this language @@ -397,3 +446,15 @@ } } } + +int CCopyHandlerApp::ExitInstance() +{ + if(m_piShellExtControl) + { + m_piShellExtControl->Release(); + m_piShellExtControl = NULL; + } + CoUninitialize(); + + return __super::ExitInstance(); +} Index: src/ch/ch.h =================================================================== diff -u -N -rf6c4389122d92e5f84a509e9be0facebac429151 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/ch/ch.h (.../ch.h) (revision f6c4389122d92e5f84a509e9be0facebac429151) +++ src/ch/ch.h (.../ch.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -26,6 +26,7 @@ #include "resource.h" // main symbols #include "AppHelper.h" #include "CfgProperties.h" +#include "../chext/chext.h" //#include "LogFile.h" #include "../libicpf/log.h" #include "../libchcore/EngineCfg.h" @@ -41,17 +42,14 @@ class CCopyHandlerApp : public CWinApp, public CAppHelper { public: -// BOOL RegisterShellExt(); CCopyHandlerApp(); ~CCopyHandlerApp(); // Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CCopyHandlerApp) - public: +public: virtual BOOL InitInstance(); - //}}AFX_VIRTUAL + virtual void HtmlHelp(DWORD_PTR dwData, UINT nCmd); PCTSTR GetHelpPath() const { return m_pszHelpFilePath; }; @@ -63,6 +61,8 @@ friend chcore::engine_config* GetConfig(); // friend CLogFile* GetLog(); + bool IsShellExtEnabled() const; + void OnConfigNotify(uint_t uiPropID); void OnResManNotify(UINT uiType); protected: @@ -75,6 +75,8 @@ chcore::engine_config m_cfgSettings; icpf::log_file m_lfLog; + IShellExtControl* m_piShellExtControl; + CWnd *m_pMainWindow; // currently opened dialogs // list m_lhDialogs; @@ -88,6 +90,8 @@ //{{AFX_MSG(CCopyHandlerApp) //}}AFX_MSG DECLARE_MESSAGE_MAP() +public: + virtual int ExitInstance(); }; Index: src/ch/ch.rc =================================================================== diff -u -N -r9795c1ee9cf5ac865a61c12d0196a8ba5d9758c6 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/ch/ch.rc (.../ch.rc) (revision 9795c1ee9cf5ac865a61c12d0196a8ba5d9758c6) +++ src/ch/ch.rc (.../ch.rc) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -80,15 +80,15 @@ MENUITEM "Show mini-status...", ID_SHOW_MINI_VIEW MENUITEM "Enter copy parametres...", ID_POPUP_CUSTOM_COPY MENUITEM SEPARATOR - MENUITEM "&Register shell extension dll", ID_POPUP_REGISTERDLL - MENUITEM "&Unregister shell extension dll", ID_POPUP_UNREGISTERDLL - MENUITEM SEPARATOR MENUITEM "Monitor clipboard", ID_POPUP_MONITORING, CHECKED MENUITEM "Shutdown after finished", ID_POPUP_SHUTAFTERFINISHED, CHECKED MENUITEM SEPARATOR POPUP "&Tools|ID_POPUP_TOOLS" BEGIN MENUITEM "&Check for updates...", ID_POPUP_CHECKFORUPDATES + MENUITEM SEPARATOR + MENUITEM "&Register shell extension dll", ID_POPUP_REGISTERDLL + MENUITEM "&Unregister shell extension dll", ID_POPUP_UNREGISTERDLL END MENUITEM SEPARATOR MENUITEM "&Options...", ID_POPUP_OPTIONS @@ -1291,6 +1291,8 @@ "There was an error when trying to retrieve version information from the official web page (%errdesc)." IDS_UPDATER_WAITING_STRING "Please wait for the connection with %site to be established..." + IDS_SHELL_EXTENSION_MISMATCH_STRING + "CH shell extension registered on your system does not match the Copy Handler version you are currently running.\nPlease re-register the shell extension using Copy Handler context menu and reboot your system to make sure the proper version is loaded.\n\nCopy Handler shell extension will be disabled." END #endif // English (U.S.) resources Index: src/ch/ch.vc90.vcproj =================================================================== diff -u -N -r9541872ea40cb4a5418162e61090ebaa3d7e2121 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision 9541872ea40cb4a5418162e61090ebaa3d7e2121) +++ src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -77,8 +77,8 @@ /> + + + + + + + + + + + + + + + + + + Release(); + m_piShellExtControl = NULL; + } +} + STDMETHODIMP CDropMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + // find CH's window HWND hWnd; hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); @@ -106,6 +128,14 @@ STDMETHODIMP CDropMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) { + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + { + pszName[0] = _T('\0'); + return hResult; + } + if (uFlags == GCS_HELPTEXTW) { USES_CONVERSION; @@ -170,6 +200,10 @@ STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) { // OTF2("Initialize cdropmenuext\r\n"); + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + // find window HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); if (hWnd == NULL) @@ -306,6 +340,10 @@ STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + // find window HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); if (hWnd == NULL) Index: src/chext/DropMenuExt.h =================================================================== diff -u -N -rd2b121c78f510b5384b8ef0ca80afbfd7f77fef7 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/DropMenuExt.h (.../DropMenuExt.h) (revision d2b121c78f510b5384b8ef0ca80afbfd7f77fef7) +++ src/chext/DropMenuExt.h (.../DropMenuExt.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -36,9 +36,9 @@ public IContextMenuImpl { public: - CDropMenuExt() - { - } + CDropMenuExt(); + ~CDropMenuExt(); + public: class CBuffer { @@ -56,6 +56,8 @@ UINT m_uiDropEffect; bool m_bExplorer; // if the operation has been retrieved from explorer or from the program + IShellExtControl* m_piShellExtControl; + DECLARE_REGISTRY_RESOURCEID(IDR_DROPMENUEXT) DECLARE_NOT_AGGREGATABLE(CDropMenuExt) Index: src/chext/MenuExt.cpp =================================================================== diff -u -N -rd2b121c78f510b5384b8ef0ca80afbfd7f77fef7 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision d2b121c78f510b5384b8ef0ca80afbfd7f77fef7) +++ src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -25,6 +25,7 @@ #include "stdio.h" #include "memory.h" #include "StringHelpers.h" +#include "chext-utils.h" extern CSharedConfigStruct* g_pscsShared; @@ -46,6 +47,21 @@ ///////////////////////////////////////////////////////////////////////////// // CMenuExt +CMenuExt::CMenuExt() : + m_piShellExtControl(NULL) +{ + CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); +} + +CMenuExt::~CMenuExt() +{ + if(m_piShellExtControl) + { + m_piShellExtControl->Release(); + m_piShellExtControl = NULL; + } +} + HRESULT CMenuExt::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { // OTF("CMenuExt::HandleMenuMsg\r\n"); @@ -166,11 +182,16 @@ STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + // find ch window HWND hWnd; hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); - if (!hWnd) - return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); + if(!hWnd) + return S_OK; /* OTF("CMenuExt::QueryContextMenu - idCmdFirst=%lu, uFlags=%lu (", idCmdFirst, uFlags); if (uFlags & CMF_CANRENAME) @@ -363,6 +384,27 @@ STDMETHODIMP CMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) { + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + { + pszName[0] = _T('\0'); + return hResult; + } + + LONG lFlags = eShellExt_None; + hResult = m_piShellExtControl->GetFlags(&lFlags); + if(FAILED(hResult)) + { + pszName[0] = _T('\0'); + return hResult; + } + if(!(lFlags & eShellExt_Enabled)) + { + pszName[0] = _T('\0'); + return S_OK; + } + if (uFlags == GCS_HELPTEXTW) { USES_CONVERSION; @@ -438,6 +480,11 @@ STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) { + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + // find ch window HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); if (hWnd == NULL) @@ -511,6 +558,11 @@ STDMETHODIMP CMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici) { + // check options + HRESULT hResult = IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult) || hResult == S_FALSE) + return hResult; + // find window HWND hWnd=::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); if (hWnd == NULL) Index: src/chext/MenuExt.h =================================================================== diff -u -N -rd2b121c78f510b5384b8ef0ca80afbfd7f77fef7 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/MenuExt.h (.../MenuExt.h) (revision d2b121c78f510b5384b8ef0ca80afbfd7f77fef7) +++ src/chext/MenuExt.h (.../MenuExt.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -42,9 +42,9 @@ public IContextMenuImpl { public: - CMenuExt() - { - } + CMenuExt(); + ~CMenuExt(); + public: // class for making sure memory is freed class CBuffer @@ -79,6 +79,8 @@ UINT m_uiFirstID; // first menu ID bool m_bShown; // have the menu been already shown ? + IShellExtControl* m_piShellExtControl; + DECLARE_REGISTRY_RESOURCEID(IDR_MENUEXT) DECLARE_NOT_AGGREGATABLE(CMenuExt) Index: src/chext/ShellExtControl.cpp =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -18,13 +18,108 @@ ***************************************************************************/ #include "stdafx.h" #include "chext.h" +#include #include "ShellExtControl.h" #include "../common/version.h" -STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion) +CShellExtControl::CShellExtControl() : + m_pShellExtData(NULL), + m_hMemory(NULL), + m_hMutex(NULL) { - if(!plVersion) + // create protection mutex + m_hMutex = ::CreateMutex(NULL, FALSE, _T("CHShellExtControlDataMutex")); + if(!m_hMutex) + return; + + DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); + if(dwRes != WAIT_OBJECT_0) + return; + + // memory mapped file + m_hMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(SHELLEXT_DATA), _T("CHShellExtControlData")); // name of map object + if(!m_hMemory) + { + ReleaseMutex(m_hMutex); + CloseHandle(m_hMutex); + return; + } + + DWORD dwLastError = GetLastError(); + m_pShellExtData = (SHELLEXT_DATA*)MapViewOfFile(m_hMemory, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); + if(!m_pShellExtData) + { + ReleaseMutex(m_hMutex); + CloseHandle(m_hMutex); + CloseHandle(m_hMemory); + m_hMemory = NULL; + return; + } + + if(dwLastError != ERROR_ALREADY_EXISTS) + { + m_pShellExtData->m_lFlags = 0; + m_pShellExtData->m_lID = GetTickCount(); + } + + ReleaseMutex(m_hMutex); +} + +CShellExtControl::~CShellExtControl() +{ + if(m_pShellExtData) + { + UnmapViewOfFile((LPVOID)m_pShellExtData); + + // 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) +{ + if(!plVersion || !pbstrVersion || (*pbstrVersion)) return E_INVALIDARG; + (*plVersion) = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; + _bstr_t strVer(SHELLEXT_PRODUCT_FULL_VERSION); + pbstrVersion = strVer.GetAddress(); + return S_OK; } + +STDMETHODIMP CShellExtControl::SetFlags(LONG lFlags, LONG lMask) +{ + if(!m_hMutex || !m_pShellExtData) + return E_FAIL; + + DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); + if(dwRes != WAIT_OBJECT_0) + return E_FAIL; + m_pShellExtData->m_lFlags = (m_pShellExtData->m_lFlags & ~lMask) | (lFlags & lMask); + + ReleaseMutex(m_hMutex); + + return S_OK; +} + +STDMETHODIMP CShellExtControl::GetFlags(LONG* plFlags) +{ + if(!m_hMutex || !m_pShellExtData) + return E_FAIL; + if(!plFlags) + return E_INVALIDARG; + + DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); + if(dwRes != WAIT_OBJECT_0) + return E_FAIL; + + (*plFlags) = m_pShellExtData->m_lFlags; + + ReleaseMutex(m_hMutex); + + return S_OK; +} Index: src/chext/ShellExtControl.h =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/ShellExtControl.h (.../ShellExtControl.h) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/ShellExtControl.h (.../ShellExtControl.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -26,13 +26,15 @@ class ATL_NO_VTABLE CShellExtControl : public CComObjectRootEx, public CComCoClass, - public IShellExtControl + public IDispatchImpl { public: - CShellExtControl() { } - ~CShellExtControl() { } + CShellExtControl(); + ~CShellExtControl(); - STDMETHOD(GetVersion)(LONG* plVersion); + STDMETHOD(GetVersion)(LONG* plVersion, BSTR* pbstrVersion); + STDMETHOD(SetFlags)(LONG lFlags, LONG lMask); + STDMETHOD(GetFlags)(LONG* plFlags); DECLARE_REGISTRY_RESOURCEID(IDR_SHELLEXTCONTROL) @@ -42,6 +44,17 @@ COM_INTERFACE_ENTRY(IUnknown) COM_INTERFACE_ENTRY(IShellExtControl) END_COM_MAP() + +protected: + HANDLE m_hMemory; + HANDLE m_hMutex; + struct SHELLEXT_DATA + { + long m_lID; + long m_lFlags; + } *m_pShellExtData; + + CComAutoCriticalSection m_lock; }; #endif //__SHELLEXTCONTROL_H_ Index: src/chext/ShellExtControl.rgs =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/ShellExtControl.rgs (.../ShellExtControl.rgs) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/ShellExtControl.rgs (.../ShellExtControl.rgs) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -2,16 +2,16 @@ { chext.ShellExtControl.1 = s 'ShellExtControl Class' { - CLSID = s '{317E503A-9D2F-4f42-995E-D314CB9D89B0}' + CLSID = s '{3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF}' } chext.ShellExtControl = s 'ShellExtControl Class' { - CLSID = s '{317E503A-9D2F-4f42-995E-D314CB9D89B0}' + CLSID = s '{3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF}' CurVer = s 'chext.MenuExt.1' } NoRemove CLSID { - ForceRemove {317E503A-9D2F-4f42-995E-D314CB9D89B0} = s 'ShellExtControl Class' + ForceRemove {3D855ACA-8274-4f1f-94E9-6BEF4FC2A2AF} = s 'ShellExtControl Class' { ProgID = s 'chext.ShellExtControl.1' VersionIndependentProgID = s 'chext.ShellExtControl' Index: src/chext/StdAfx.h =================================================================== diff -u -N -rd2b121c78f510b5384b8ef0ca80afbfd7f77fef7 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/StdAfx.h (.../StdAfx.h) (revision d2b121c78f510b5384b8ef0ca80afbfd7f77fef7) +++ src/chext/StdAfx.h (.../StdAfx.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -25,17 +25,12 @@ #endif #define _ATL_APARTMENT_THREADED -// include for MFC Support -//#include -//#include +#include + +#include "resource.h" #include -//You may derive a class from CComModule and use it if you want to override -//something, but do not change the name of _Module -extern CComModule _Module; #include +#include -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - #endif Index: src/chext/chext.cpp =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/chext.cpp (.../chext.cpp) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/chext.cpp (.../chext.cpp) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -22,93 +22,72 @@ #include "stdafx.h" #include "resource.h" -#include #include "chext.h" +#include "dllmain.h" +//#include -#include "chext_i.c" -#include "MenuExt.h" -#include "DropMenuExt.h" -#include "ShellExtControl.h" - -CComModule _Module; - -// common memory - exactly 64kB -CSharedConfigStruct* g_pscsShared; -static HANDLE hMapObject=NULL; - -BEGIN_OBJECT_MAP(ObjectMap) -OBJECT_ENTRY(CLSID_MenuExt, CMenuExt) -OBJECT_ENTRY(CLSID_DropMenuExt, CDropMenuExt) -END_OBJECT_MAP() - ///////////////////////////////////////////////////////////////////////////// -// DLL Entry Point - -extern "C" -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) -{ - if (dwReason == DLL_PROCESS_ATTACH) - { - _Module.Init(ObjectMap, hInstance, &LIBID_CHEXTLib); - DisableThreadLibraryCalls(hInstance); - - // memory mapped file - hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(CSharedConfigStruct), _T("CHLMFile")); // name of map object - if (hMapObject == NULL) - return FALSE; - - // The first process to attach initializes memory. -// bool bInit = (GetLastError() != ERROR_ALREADY_EXISTS); - - // Get a pointer to the file-mapped shared memory. - g_pscsShared = (CSharedConfigStruct*)MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0); - if (g_pscsShared == NULL) - return FALSE; - } - else if (dwReason == DLL_PROCESS_DETACH) - { - // Unmap shared memory from the process's address space. - UnmapViewOfFile((LPVOID)g_pscsShared); - - // Close the process's handle to the file-mapping object. - CloseHandle(hMapObject); - - _Module.Term(); - } - return TRUE; // ok -} - -///////////////////////////////////////////////////////////////////////////// // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow(void) { - return (_Module.GetLockCount()==0) ? S_OK : S_FALSE; + return _AtlModule.DllCanUnloadNow(); } ///////////////////////////////////////////////////////////////////////////// // Returns a class factory to create an object of the requested type STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { - return _Module.GetClassObject(rclsid, riid, ppv); + return _AtlModule.DllGetClassObject(rclsid, riid, ppv); } ///////////////////////////////////////////////////////////////////////////// // DllRegisterServer - Adds entries to the system registry -STDAPI DllRegisterServer(void) +STDAPI DllRegisterServer() { // registers object, typelib and all interfaces in typelib - return _Module.RegisterServer(TRUE); + return _AtlModule.DllRegisterServer(); } ///////////////////////////////////////////////////////////////////////////// // DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void) { - return _Module.UnregisterServer(TRUE); + return _AtlModule.DllUnregisterServer(); } +// DllInstall - Adds/Removes entries to the system registry per user +// per machine. +STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) +{ + HRESULT hr = E_FAIL; + static const wchar_t szUserSwitch[] = _T("user"); + if (pszCmdLine != NULL) + { + if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0) + { + AtlSetPerUserRegistration(true); + } + } + + if (bInstall) + { + hr = DllRegisterServer(); + if (FAILED(hr)) + { + DllUnregisterServer(); + } + } + else + { + hr = DllUnregisterServer(); + } + + return hr; +} + + Index: src/chext/chext.def =================================================================== diff -u -N -r47da0c5883b1bf97972b1bcd3dc70b2d64024969 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/chext.def (.../chext.def) (revision 47da0c5883b1bf97972b1bcd3dc70b2d64024969) +++ src/chext/chext.def (.../chext.def) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -7,3 +7,4 @@ DllGetClassObject PRIVATE DllRegisterServer PRIVATE DllUnregisterServer PRIVATE + DllInstall PRIVATE Index: src/chext/chext.idl =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/chext.idl (.../chext.idl) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/chext.idl (.../chext.idl) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -25,6 +25,17 @@ import "oaidl.idl"; import "ocidl.idl"; [ + v1_enum, + uuid(54F8BFDD-6685-4792-94BD-40DF00099F9B), + helpstring("Shell extension flags") + ] + enum EShellExtFlags + { + eShellExt_None = 0, + eShellExt_Enabled = 1 + }; + + [ object, uuid(413AA618-E769-4E6E-A610-7BDC8A189FB2), dual, @@ -63,8 +74,15 @@ ] interface IShellExtControl : IDispatch { - [helpstring("Retrieves the extension version information")] - HRESULT GetVersion([out]LONG* plVersion); + // 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); }; [ Index: src/chext/chext.rc =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/chext.rc (.../chext.rc) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/chext.rc (.../chext.rc) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -44,23 +44,38 @@ "\0" END -4 TEXTINCLUDE +4 TEXTINCLUDE BEGIN - "#include ""res\chext.rc2""\r\n" + "#include ""res\\chext.rc2""\r\n" "\0" END #endif // APSTUDIO_INVOKED +#endif // Polish resources ///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// // // REGISTRY // IDR_MENUEXT REGISTRY "MenuExt.rgs" IDR_DROPMENUEXT REGISTRY "DropMenuExt.rgs" IDR_SHELLEXTCONTROL REGISTRY "ShellExtControl.rgs" -#endif // Polish resources +IDR_CHEXT REGISTRY "chext.rgs" + +#endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// Index: src/chext/chext.vc90.vcproj =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/chext.vc90.vcproj (.../chext.vc90.vcproj) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/chext.vc90.vcproj (.../chext.vc90.vcproj) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -490,6 +490,10 @@ > + + @@ -587,6 +591,10 @@ > + + @@ -644,6 +652,46 @@ > + + + + + + + + + + + + + + + + Index: src/chext/dllmain.cpp =================================================================== diff -u -N --- src/chext/dllmain.cpp (revision 0) +++ src/chext/dllmain.cpp (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -0,0 +1,49 @@ +#include "stdafx.h" +#include "resource.h" +#include "chext.h" + +#include "dllmain.h" + +#include "MenuExt.h" +#include "DropMenuExt.h" +#include "ShellExtControl.h" + +CCHExtModule _AtlModule; + +// common memory - exactly 64kB +CSharedConfigStruct* g_pscsShared; +static HANDLE hMapObject=NULL; + +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) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + DisableThreadLibraryCalls(hInstance); + + // memory mapped file + hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(CSharedConfigStruct), _T("CHLMFile")); // name of map object + if (hMapObject == NULL) + return FALSE; + + // Get a pointer to the file-mapped shared memory. + g_pscsShared = (CSharedConfigStruct*)MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0); + if (g_pscsShared == NULL) + return FALSE; + } + else if (dwReason == DLL_PROCESS_DETACH) + { + // Unmap shared memory from the process's address space. + UnmapViewOfFile((LPVOID)g_pscsShared); + + // Close the process's handle to the file-mapping object. + CloseHandle(hMapObject); + } + + return _AtlModule.DllMain(dwReason, lpReserved); +} \ No newline at end of file Index: src/chext/dllmain.h =================================================================== diff -u -N --- src/chext/dllmain.h (revision 0) +++ src/chext/dllmain.h (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -0,0 +1,9 @@ + +class CCHExtModule : public CAtlDllModuleT +{ +public : + DECLARE_LIBID(LIBID_CHEXTLib) + DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CHEXT, "{9D4C4C5F-EE90-4a6b-9245-244C369E4FAE}") +}; + +extern class CCHExtModule _AtlModule; Index: src/chext/resource.h =================================================================== diff -u -N -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/resource.h (.../resource.h) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/resource.h (.../resource.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -15,6 +15,7 @@ #define IDR_MENUEXT 102 #define IDR_DROPMENUEXT 103 #define IDR_SHELLEXTCONTROL 104 +#define IDR_CHEXT 105 // Next default values for new objects // @@ -23,6 +24,6 @@ #define _APS_NEXT_RESOURCE_VALUE 201 #define _APS_NEXT_COMMAND_VALUE 32768 #define _APS_NEXT_CONTROL_VALUE 201 -#define _APS_NEXT_SYMED_VALUE 104 +#define _APS_NEXT_SYMED_VALUE 106 #endif #endif Index: src/common/version.h =================================================================== diff -u -N -r0393922fa3537db761993ffcda8938499ac4d15f -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/common/version.h (.../version.h) (revision 0393922fa3537db761993ffcda8938499ac4d15f) +++ src/common/version.h (.../version.h) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -13,10 +13,10 @@ // Version of program #define PRODUCT_VERSION1 1 #define PRODUCT_VERSION2 31 -#define PRODUCT_VERSION3 129 +#define PRODUCT_VERSION3 145 #define PRODUCT_VERSION4 0 -#define PRODUCT_VERSION "1.31beta-svn129" +#define PRODUCT_VERSION "1.31beta-svn145" #if SETUP_COMPILER != 1 #define SHELLEXT_PRODUCT_FULL_VERSION SHELLEXT_PRODUCT_NAME " " PRODUCT_VERSION