From f8f8c0a48fbe086870a0cf35a62278c2b4ab743b Mon Sep 17 00:00:00 2001 From: Stefan Kueng Date: Fri, 3 Dec 2010 21:24:33 +0100 Subject: [PATCH] Windows: afs_shl_ext folder bkgrnd context menu Make the context menu handler also work for folder backgrounds and on Win7 for library folder backgrounds For folder backgrounds, the shell passes the PIDL of the folder instead of a data object. Extract the path from that PIDL. Also extended the register function of the dll to add the required registry keys. Change-Id: I8928efd25058dced3820478a2858ce20336b4301 Reviewed-on: http://gerrit.openafs.org/3443 Tested-by: BuildBot Tested-by: Stefan Kueng Reviewed-by: Stefan Kueng Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/client_exp/afs_shl_ext.cpp | 6 ++ src/WINNT/client_exp/shell_ext.cpp | 123 +++++++++++++++++---------- 2 files changed, 83 insertions(+), 46 deletions(-) diff --git a/src/WINNT/client_exp/afs_shl_ext.cpp b/src/WINNT/client_exp/afs_shl_ext.cpp index a6bed8e04..70ef80672 100644 --- a/src/WINNT/client_exp/afs_shl_ext.cpp +++ b/src/WINNT/client_exp/afs_shl_ext.cpp @@ -221,6 +221,12 @@ STDAPI DllRegisterServer(void) if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR) return lResult; wsprintf(szSubKey, TEXT("Folder\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE); + if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR) + return lResult; + wsprintf(szSubKey, TEXT("Directory\\Background\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE); + if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR) + return lResult; + wsprintf(szSubKey, TEXT("LibraryFolder\\background\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE); if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR) return lResult; diff --git a/src/WINNT/client_exp/shell_ext.cpp b/src/WINNT/client_exp/shell_ext.cpp index 7f6fa1cbf..f821b3493 100644 --- a/src/WINNT/client_exp/shell_ext.cpp +++ b/src/WINNT/client_exp/shell_ext.cpp @@ -11,6 +11,8 @@ #include "stdafx.h" #include #include +#include +#include extern "C" { #include @@ -571,58 +573,87 @@ STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataOb STGMEDIUM medium; // We must have a data object - if (pdobj == NULL) - return E_FAIL; + if ((pdobj == NULL) && (pidlFolder == NULL)) + return E_FAIL; - // Use the given IDataObject to get a list of filenames (CF_HDROP) - hres = pdobj->GetData(&fmte, &medium); - if (FAILED(hres)) { - return E_FAIL; + if (pdobj) { + // Use the given IDataObject to get a list of filenames (CF_HDROP) + hres = pdobj->GetData(&fmte, &medium); + if (FAILED(hres)) { + return E_FAIL; + } + + int nNumFiles = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0); + if (nNumFiles == 0) + hres = E_FAIL; + else { + pThis->m_bDirSelected = FALSE; + + for (int ii = 0; ii < nNumFiles; ii++) { + CString strFileName; + + // Get the size of the file name string + int nNameLen = DragQueryFile((HDROP)medium.hGlobal, ii, 0, 0); + + // Make room for it in our string object + LPTSTR pszFileNameBuf = strFileName.GetBuffer(nNameLen + 1); // +1 for the terminating NULL + ASSERT(pszFileNameBuf); + + // Get the file name + DragQueryFile((HDROP)medium.hGlobal, ii, pszFileNameBuf, nNameLen + 1); + + strFileName.ReleaseBuffer(); + if (!IsPathInAfs(strFileName)) { + pThis->m_astrFileNames.RemoveAll(); + break; + } else { + pThis->m_bIsSymlink=IsSymlink(strFileName); + } + + if (IsADir(strFileName)) + pThis->m_bDirSelected = TRUE; + + pThis->m_astrFileNames.Add(strFileName); + } + // Release the data + ReleaseStgMedium(&medium); + } + } + if ((pThis->m_astrFileNames.GetSize() == 0)&&(pidlFolder)) { + // if there are no valid files selected, try the folder background + IShellFolder *parentFolder = NULL; + STRRET name; + TCHAR * szDisplayName = NULL; + + hres = ::SHGetDesktopFolder(&parentFolder); + if (FAILED(hres)) + return hres; + + hres = parentFolder->GetDisplayNameOf(pidlFolder, SHGDN_NORMAL | SHGDN_FORPARSING, &name); + if (FAILED(hres)) { + parentFolder->Release(); + return hres; + } + + hres = StrRetToStr (&name, pidlFolder, &szDisplayName); + if (FAILED(hres)) + return hres; + parentFolder->Release(); + if (szDisplayName) { + pThis->m_bDirSelected = TRUE; + CString strFileName = CString(szDisplayName); + if (IsPathInAfs(strFileName)) { + pThis->m_bIsSymlink=IsSymlink(strFileName); + pThis->m_astrFileNames.Add(strFileName); + } + CoTaskMemFree(szDisplayName); + } } - - int nNumFiles = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0); - if (nNumFiles == 0) - hres = E_FAIL; - else { - pThis->m_bDirSelected = FALSE; - - for (int ii = 0; ii < nNumFiles; ii++) { - CString strFileName; - - // Get the size of the file name string - int nNameLen = DragQueryFile((HDROP)medium.hGlobal, ii, 0, 0); - - // Make room for it in our string object - LPTSTR pszFileNameBuf = strFileName.GetBuffer(nNameLen + 1); // +1 for the terminating NULL - ASSERT(pszFileNameBuf); - - // Get the file name - DragQueryFile((HDROP)medium.hGlobal, ii, pszFileNameBuf, nNameLen + 1); - - strFileName.ReleaseBuffer(); - - if (!IsPathInAfs(strFileName)) { - pThis->m_astrFileNames.RemoveAll(); - break; - } else { - pThis->m_bIsSymlink=IsSymlink(strFileName); - } - - if (IsADir(strFileName)) - pThis->m_bDirSelected = TRUE; - - pThis->m_astrFileNames.Add(strFileName); - } - if (pThis->m_astrFileNames.GetSize() > 0) hres = NOERROR; else hres = E_FAIL; - } - // Release the data - ReleaseStgMedium(&medium); - return hres; } @@ -790,4 +821,4 @@ STDMETHODIMP CShellExt::XPersistFileExt::SaveCompleted(LPCOLESTR) STDMETHODIMP CShellExt::XPersistFileExt::GetCurFile(LPOLESTR FAR*) { return E_NOTIMPL; -} +} \ No newline at end of file -- 2.39.5