Index: src/chext/MenuExt.cpp =================================================================== diff -u -N -r3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4 -r134983cab6122e3fff73994a6f9c417aaeab3bc2 --- src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 3c248d4f6d0fdb1e487cc868b2f0b219eec37ef4) +++ src/chext/MenuExt.cpp (.../MenuExt.cpp) (revision 134983cab6122e3fff73994a6f9c417aaeab3bc2) @@ -23,7 +23,6 @@ #include "stdio.h" #include "memory.h" #include -#include "ShellPathsHelpers.h" #include "../common/TShellExtMenuConfig.h" #include "../libchcore/TSharedMemory.h" #include "../libchcore/TTaskDefinition.h" @@ -68,140 +67,192 @@ STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/) { - LOG_DEBUG(m_spLog) << L"Initializing"; - - if(!pidlFolder && !piDataObject) + try { - LOG_ERROR(m_spLog) << L"Missing both pointers."; - return E_INVALIDARG; - } + LOG_DEBUG(m_spLog) << L"Initializing"; - // check options - HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); - if(!hWnd) - return S_OK; + if(!pidlFolder && !piDataObject) + { + LOG_ERROR(m_spLog) << L"Missing both pointers."; + return E_INVALIDARG; + } - HRESULT hResult = ShellExtensionVerifier::ReadShellConfig(m_piShellExtControl, m_tShellExtMenuConfig); - LOG_HRESULT(m_spLog, hResult) << L"Read shell config"; + // check options + HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); + if(!hWnd) + return S_OK; - if(SUCCEEDED(hResult)) + HRESULT hResult = ShellExtensionVerifier::ReadShellConfig(m_piShellExtControl, m_tShellExtMenuConfig); + LOG_HRESULT(m_spLog, hResult) << L"Read shell config"; + + if(SUCCEEDED(hResult)) + { + hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject); + LOG_HRESULT(m_spLog, hResult) << L"Gather data from initialize"; + } + + return hResult; + } + catch(const std::exception& e) { - hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject); - LOG_HRESULT(m_spLog, hResult) << L"Gather data from initialize"; + LOG_CRITICAL(m_spLog) << L"Unexpected std exception encountered in " << __FUNCTION__ << L": " << e.what(); + return E_FAIL; } - - return hResult; + catch(...) + { + LOG_CRITICAL(m_spLog) << L"Unexpected other exception encountered in " << __FUNCTION__ << L"."; + return E_FAIL; + } } STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) { - LOG_DEBUG(m_spLog) << L"Querying context menu"; + try + { + LOG_DEBUG(m_spLog) << L"Querying context menu"; - // check options - HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); - if(!hWnd) - return S_OK; + if(!hMenu) + { + LOG_ERROR(m_spLog) << L"Received null hMenu from caller"; + return E_INVALIDARG; + } - // current commands count in menu - TCHAR szText[_MAX_PATH]; - int iCount = ::GetMenuItemCount(hMenu); + // check options + HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); + if(!hWnd) + return S_OK; - MENUITEMINFO mii; - mii.cbSize=sizeof(mii); - mii.fMask=MIIM_TYPE; - mii.dwTypeData=szText; - mii.cch=_MAX_PATH; + // current commands count in menu + TCHAR szText[ _MAX_PATH ]; + int iCount = ::GetMenuItemCount(hMenu); - // find a place where the commands should be inserted - for (int i=0;ilpVerb) != 0) - return E_FAIL; + if(!lpici) + { + LOG_ERROR(m_spLog) << L"Parameter lpici is null"; + return E_INVALIDARG; + } - // check options - HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); - if(hWnd == nullptr) - return E_FAIL; + // textual verbs are not supported by this extension + if(HIWORD(lpici->lpVerb) != 0) + return E_FAIL; - // find command to be executed, if not found - fail - TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(lpici->lpVerb)); - if(!spSelectedItem) - return E_FAIL; + // check options + HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl); + if(hWnd == nullptr) + return E_FAIL; - // data retrieval and validation - if(!m_tShellExtData.VerifyItemCanBeExecuted(spSelectedItem)) - return E_FAIL; + // find command to be executed, if not found - fail + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(lpici->lpVerb)); + if(!spSelectedItem) + return E_FAIL; - chcore::TPathContainer vSourcePaths; - chcore::TSmartPath spDestinationPath; - chcore::EOperationType eOperationType = chcore::eOperation_None; + // data retrieval and validation + if(!m_tShellExtData.VerifyItemCanBeExecuted(spSelectedItem)) + return E_FAIL; - if(!m_tShellExtData.GetSourcePathsByItem(spSelectedItem, vSourcePaths)) - return E_FAIL; - if(!m_tShellExtData.GetDestinationPathByItem(spSelectedItem, spDestinationPath)) - return E_FAIL; - if(!m_tShellExtData.GetOperationTypeByItem(spSelectedItem, eOperationType)) - return E_FAIL; + chcore::TPathContainer vSourcePaths; + chcore::TSmartPath spDestinationPath; + chcore::EOperationType eOperationType = chcore::eOperation_None; - chcore::TTaskDefinition tTaskDefinition; - tTaskDefinition.SetSourcePaths(vSourcePaths); - tTaskDefinition.SetDestinationPath(spDestinationPath); - tTaskDefinition.SetOperationType(eOperationType); + if(!m_tShellExtData.GetSourcePathsByItem(spSelectedItem, vSourcePaths)) + return E_FAIL; + if(!m_tShellExtData.GetDestinationPathByItem(spSelectedItem, spDestinationPath)) + return E_FAIL; + if(!m_tShellExtData.GetOperationTypeByItem(spSelectedItem, eOperationType)) + return E_FAIL; - // get task data as xml - chcore::TString wstrData; - tTaskDefinition.StoreInString(wstrData); + chcore::TTaskDefinition tTaskDefinition; + tTaskDefinition.SetSourcePaths(vSourcePaths); + tTaskDefinition.SetDestinationPath(spDestinationPath); + tTaskDefinition.SetOperationType(eOperationType); - // fill struct - COPYDATASTRUCT cds; - cds.dwData = spSelectedItem->IsSpecialOperation() ? eCDType_TaskDefinitionContentSpecial : eCDType_TaskDefinitionContent; - cds.lpData = (void*)wstrData.c_str(); - cds.cbData = (DWORD)((wstrData.GetLength() + 1) * sizeof(wchar_t)); + // get task data as xml + chcore::TString wstrData; + tTaskDefinition.StoreInString(wstrData); - // send a message - ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); + // fill struct + COPYDATASTRUCT cds; + cds.dwData = spSelectedItem->IsSpecialOperation() ? eCDType_TaskDefinitionContentSpecial : eCDType_TaskDefinitionContent; + cds.lpData = (void*)wstrData.c_str(); + cds.cbData = (DWORD)((wstrData.GetLength() + 1) * sizeof(wchar_t)); - return S_OK; + // send a message + ::SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(lpici->hwnd), reinterpret_cast(&cds)); + + return S_OK; + } + catch(const std::exception& e) + { + LOG_CRITICAL(m_spLog) << L"Unexpected std exception encountered in " << __FUNCTION__ << L": " << e.what(); + return E_FAIL; + } + catch(...) + { + LOG_CRITICAL(m_spLog) << L"Unexpected other exception encountered in " << __FUNCTION__ << L"."; + return E_FAIL; + } } HRESULT CMenuExt::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -211,18 +262,20 @@ HRESULT CMenuExt::HandleMenuMsg2(UINT uMsg, WPARAM /*wParam*/, LPARAM lParam, LRESULT* /*plResult*/) { - LOG_DEBUG(m_spLog) << L"Handle menu message (2)"; - - switch(uMsg) + try { - case WM_INITMENUPOPUP: - break; - - case WM_DRAWITEM: - return DrawMenuItem((LPDRAWITEMSTRUCT)lParam); - - case WM_MEASUREITEM: + LOG_DEBUG(m_spLog) << L"Handle menu message (2)"; + + switch(uMsg) { + case WM_INITMENUPOPUP: + break; + + case WM_DRAWITEM: + return DrawMenuItem((LPDRAWITEMSTRUCT)lParam); + + case WM_MEASUREITEM: + { LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam; if(!lpmis) return E_FAIL; @@ -261,110 +314,147 @@ break; } - } + } - return S_OK; + return S_OK; + } + catch(const std::exception& e) + { + LOG_CRITICAL(m_spLog) << L"Unexpected std exception encountered in " << __FUNCTION__ << L": " << e.what(); + return E_FAIL; + } + catch(...) + { + LOG_CRITICAL(m_spLog) << L"Unexpected other exception encountered in " << __FUNCTION__ << L"."; + return E_FAIL; + } } HRESULT CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis) { - LOG_DEBUG(m_spLog) << L"Drawing menu item"; - - if(!lpdis) + try { - LOG_ERROR(m_spLog) << L"Missing argument"; - return E_FAIL; - } + LOG_DEBUG(m_spLog) << L"Drawing menu item"; - // check if menu - if(lpdis->CtlType != ODT_MENU) - return S_OK; + if(!lpdis) + { + LOG_ERROR(m_spLog) << L"Missing argument"; + return E_FAIL; + } - // find command to be executed, if not found - fail - TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByItemID(LOWORD(lpdis->itemID)); - if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) - return E_FAIL; + // check if menu + if(lpdis->CtlType != ODT_MENU) + return S_OK; - // margins and other stuff - const int iSmallIconWidth = GetSystemMetrics(SM_CXSMICON); - const int iSmallIconHeight = GetSystemMetrics(SM_CYSMICON); - const int iLeftMargin = GetSystemMetrics(SM_CXMENUCHECK) / 2; - const int iRightMargin = GetSystemMetrics(SM_CXMENUCHECK) - iLeftMargin; - - // text color - HBRUSH hBrush = nullptr; - if(lpdis->itemState & ODS_SELECTED) - { - SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); - hBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); - } - else - { - SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); - SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU)); - hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU)); - } + // find command to be executed, if not found - fail + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByItemID(LOWORD(lpdis->itemID)); + if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) + return E_FAIL; - // draw background - RECT rcSelect = lpdis->rcItem; - rcSelect.top++; - rcSelect.bottom--; + // margins and other stuff + const int iSmallIconWidth = GetSystemMetrics(SM_CXSMICON); + const int iSmallIconHeight = GetSystemMetrics(SM_CYSMICON); + const int iLeftMargin = GetSystemMetrics(SM_CXMENUCHECK) / 2; + const int iRightMargin = GetSystemMetrics(SM_CXMENUCHECK) - iLeftMargin; - FillRect(lpdis->hDC, &rcSelect, hBrush); - DeleteObject(hBrush); + // text color + HBRUSH hBrush = nullptr; + if(lpdis->itemState & ODS_SELECTED) + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); + hBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); + } + else + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU)); + hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU)); + } - // get img list - SHFILEINFO sfi; - HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo(spSelectedItem->GetDestinationPathInfo().GetDefaultDestinationPath().ToString(), FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON | SHGFI_SYSICONINDEX); - ImageList_Draw(hImageList, sfi.iIcon, lpdis->hDC, lpdis->rcItem.left + iLeftMargin, lpdis->rcItem.top + (lpdis->rcItem.bottom - lpdis->rcItem.top + 1 - iSmallIconHeight) / 2, ILD_TRANSPARENT); + // draw background + RECT rcSelect = lpdis->rcItem; + rcSelect.top++; + rcSelect.bottom--; - RECT rcText; - rcText.left = iLeftMargin + iSmallIconWidth + iRightMargin; - rcText.top = lpdis->rcItem.top; - rcText.right = lpdis->rcItem.right; - rcText.bottom = lpdis->rcItem.bottom; + FillRect(lpdis->hDC, &rcSelect, hBrush); + DeleteObject(hBrush); - DrawText(lpdis->hDC, spSelectedItem->GetLocalName().c_str(), -1, &rcText, DT_LEFT | DT_SINGLELINE | DT_VCENTER); + // get img list + SHFILEINFO sfi; + HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo(spSelectedItem->GetDestinationPathInfo().GetDefaultDestinationPath().ToString(), FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON | SHGFI_SYSICONINDEX); + ImageList_Draw(hImageList, sfi.iIcon, lpdis->hDC, lpdis->rcItem.left + iLeftMargin, lpdis->rcItem.top + (lpdis->rcItem.bottom - lpdis->rcItem.top + 1 - iSmallIconHeight) / 2, ILD_TRANSPARENT); - return S_OK; + RECT rcText; + rcText.left = iLeftMargin + iSmallIconWidth + iRightMargin; + rcText.top = lpdis->rcItem.top; + rcText.right = lpdis->rcItem.right; + rcText.bottom = lpdis->rcItem.bottom; + + DrawText(lpdis->hDC, spSelectedItem->GetLocalName().c_str(), -1, &rcText, DT_LEFT | DT_SINGLELINE | DT_VCENTER); + + return S_OK; + } + catch(const std::exception& e) + { + LOG_CRITICAL(m_spLog) << L"Unexpected std exception encountered in " << __FUNCTION__ << L": " << e.what(); + return E_FAIL; + } + catch(...) + { + LOG_CRITICAL(m_spLog) << L"Unexpected other exception encountered in " << __FUNCTION__ << L"."; + return E_FAIL; + } } STDMETHODIMP CMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax) { - LOG_DEBUG(m_spLog) << L"Retrieving command string for cmd " << idCmd; + try + { + LOG_DEBUG(m_spLog) << L"Retrieving command string for cmd " << idCmd; - memset(pszName, 0, cchMax); + memset(pszName, 0, cchMax); - if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA) - return S_OK; + if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA) + return S_OK; - // check options - HRESULT hResult = ShellExtensionVerifier::IsShellExtEnabled(m_piShellExtControl); - if(FAILED(hResult)) - return hResult; - else if(hResult == S_FALSE) - return S_OK; + // check options + HRESULT hResult = ShellExtensionVerifier::IsShellExtEnabled(m_piShellExtControl); + if(FAILED(hResult)) + return hResult; + else if(hResult == S_FALSE) + return S_OK; - TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(idCmd)); - if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) - return E_FAIL; + TShellMenuItemPtr spSelectedItem = m_tContextMenuHandler.GetCommandByMenuItemOffset(LOWORD(idCmd)); + if(!spSelectedItem || !spSelectedItem->SpecifiesDestinationPath()) + return E_FAIL; - switch(uFlags) - { - case GCS_HELPTEXTW: + switch(uFlags) { - wcsncpy(reinterpret_cast(pszName), spSelectedItem->GetItemTip().c_str(), spSelectedItem->GetItemTip().GetLength() + 1); - break; + case GCS_HELPTEXTW: + { + wcsncpy(reinterpret_cast(pszName), spSelectedItem->GetItemTip().c_str(), spSelectedItem->GetItemTip().GetLength() + 1); + break; + } + case GCS_HELPTEXTA: + { + USES_CONVERSION; + CT2A ct2a(spSelectedItem->GetItemTip().c_str()); + strncpy(reinterpret_cast(pszName), ct2a, strlen(ct2a) + 1); + break; + } } - case GCS_HELPTEXTA: - { - USES_CONVERSION; - CT2A ct2a(spSelectedItem->GetItemTip().c_str()); - strncpy(reinterpret_cast(pszName), ct2a, strlen(ct2a) + 1); - break; - } - } - return S_OK; + return S_OK; + } + catch(const std::exception& e) + { + LOG_CRITICAL(m_spLog) << L"Unexpected std exception encountered in " << __FUNCTION__ << L": " << e.what(); + return E_FAIL; + } + catch(...) + { + LOG_CRITICAL(m_spLog) << L"Unexpected other exception encountered in " << __FUNCTION__ << L"."; + return E_FAIL; + } }