Windows: afs_shl_ext Show icon mount point overlay
[openafs.git] / src / WINNT / client_exp / shell_ext.cpp
index d923138..d2e573f 100644 (file)
 #include "stdafx.h"
 #include <winsock2.h>
 #include <ws2tcpip.h>
+#include <shtypes.h>
+#include <shlwapi.h>
 
 extern "C" {
 #include <afs/param.h>
 #include <afs/stds.h>
+#include <afs/afs_consts.h>
 }
 
 #include <atlconv.h>
@@ -46,15 +49,14 @@ ULONG nICRefCount=0;
 ULONG nTPRefCount=0;
 ULONG nXPRefCount=0;
 
-#define MAXSIZE 2048 /* most I'll get back from PIOCTL */
 #define PCCHAR(str)    ((char *)(const char *)str)
-static char space[MAXSIZE];
+static char space[AFS_PIOCTL_MAXSIZE];
 
 static BOOL IsADir(const CString& strName)
 {
     struct _stat statbuf;
 
-    if (_stat(strName, &statbuf) < 0)
+    if (_tstat(strName, &statbuf) < 0)
        return FALSE;
 
     return statbuf.st_mode & _S_IFDIR;
@@ -81,7 +83,7 @@ CShellExt::CShellExt()
        m_pAlloc = NULL;
     RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &NPKey);
     LSPsize=sizeof(ShellOption);
-    code=RegQueryValueEx(NPKey, "ShellOption", NULL,
+    code=RegQueryValueEx(NPKey, _T("ShellOption"), NULL,
                          &LSPtype, (LPBYTE)&ShellOption, &LSPsize);
     RegCloseKey (NPKey);
     m_bIsOverlayEnabled=((code==0) && (LSPtype==REG_DWORD) && ((ShellOption & OVERLAYENABLED)!=0));
@@ -206,11 +208,11 @@ STDMETHODIMP CShellExt::XMenuExt::QueryContextMenu(HMENU hMenu,UINT indexMenu,
            DeleteMenu (hMenu, iItem, MF_BYPOSITION);
            continue;
        }
-       if ((!lstrcmp(szItemText,"&Delete"))&&(pThis->m_bIsSymlink)) {  /*this is a symlink - don't present a delete menu!*/
+       if ((!lstrcmp(szItemText,_T("&Delete")))&&(pThis->m_bIsSymlink)) {      /*this is a symlink - don't present a delete menu!*/
            DeleteMenu (hMenu, iItem, MF_BYPOSITION);
            continue;
        }
-       if ((!lstrcmp(szItemText,"Cu&t"))&&(pThis->m_bIsSymlink)) {     /*same for cut*/
+       if ((!lstrcmp(szItemText,_T("Cu&t")))&&(pThis->m_bIsSymlink)) { /*same for cut*/
            DeleteMenu (hMenu, iItem, MF_BYPOSITION);
            continue;
        }
@@ -411,7 +413,7 @@ STDMETHODIMP CShellExt::XMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
     }
 
     case IDM_SYMBOLICLINK_ADD: {
-       CString msg=files.GetAt(0);
+       CStringA msg(files.GetAt(0));
        int i;
        if ((i=msg.ReverseFind('\\'))>0)
            msg=msg.Left(i+1);
@@ -531,7 +533,7 @@ STDMETHODIMP CShellExt::XMenuExt::GetCommandString(UINT_PTR idCmd, UINT uType,
     CString strMsg;
     LoadString (strMsg, nCmdStrID);
 
-    strncpy(pszName, strMsg, cchMax);
+    _tcsncpy((LPTSTR) pszName, strMsg, cchMax);
 
     return NOERROR;
 }
@@ -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;
 }
 
@@ -658,12 +689,16 @@ STDMETHODIMP CShellExt::XIconExt::GetOverlayInfo(LPWSTR pwszIconFile
     if(IsBadWritePtr(pdwFlags, sizeof(DWORD)))
        return E_INVALIDARG;
 
-    HMODULE hModule=GetModuleHandle("shell32.dll");
+    HMODULE hModule=GetModuleHandle(_T("shell32.dll"));
     TCHAR szModule[MAX_PATH];
     DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
+#ifndef UNICODE
     MultiByteToWideChar( CP_ACP,0,szModule,-1,pwszIconFile,cchMax); 
+#else
+    _tcsncpy(pwszIconFile, szModule, cchMax);
+#endif
     *pIndex = 30;
-    *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
+    *pdwFlags = ISIOI_ICONFILE|ISIOI_ICONINDEX;
     return S_OK;
 }
 
@@ -678,9 +713,14 @@ STDMETHODIMP CShellExt::XIconExt::GetPriority(int* pPriority)
 STDMETHODIMP CShellExt::XIconExt::IsMemberOf(LPCWSTR pwszPath,DWORD dwAttrib)
 {
     TCHAR szPath[MAX_PATH];
+#ifdef UNICODE
+    _tcscpy(szPath, pwszPath);
+#else
     WideCharToMultiByte( CP_ACP,0,pwszPath,-1,szPath,MAX_PATH,NULL,NULL);
-    if (IsSymlink(szPath))
-       return S_OK;
+#endif
+    if (IsSymlink(szPath) || IsMountPoint(szPath)) {
+        return S_OK;
+    }
     return S_FALSE;
 }      
 
@@ -782,4 +822,4 @@ STDMETHODIMP CShellExt::XPersistFileExt::SaveCompleted(LPCOLESTR)
 STDMETHODIMP CShellExt::XPersistFileExt::GetCurFile(LPOLESTR FAR*)
 { 
     return E_NOTIMPL; 
-}
+}
\ No newline at end of file