]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: afs_shl_ext improve overlay handlers
authorStefan Kueng <tortoisesvn@gmail.com>
Sat, 4 Dec 2010 09:56:01 +0000 (10:56 +0100)
committerJeffrey Altman <jaltman@openafs.org>
Sun, 5 Dec 2010 19:47:36 +0000 (11:47 -0800)
Add link.ico and mount.ico Windows icon files.
Use these images as overlays instead of extracting an image
from shell32.dll which is a bad idea.  See

Change-Id: I624f959229a91329507aec5ff61045c49d296401
http://blogs.msdn.com/b/oldnewthing/archive/2005/10/26/485133.aspx
Reviewed-on: http://gerrit.openafs.org/3445
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Tested-by: Stefan Kueng <tortoisesvn@gmail.com>
Reviewed-by: Stefan Kueng <tortoisesvn@gmail.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
src/WINNT/client_exp/afs_shl_ext.cpp
src/WINNT/client_exp/link.ico [new file with mode: 0644]
src/WINNT/client_exp/mount.ico [new file with mode: 0644]
src/WINNT/client_exp/shell_ext.cpp
src/WINNT/client_exp/shell_ext.h

index 70ef8067243e87371a7b705c18578ff632812e00..2d06444004eefa325b9dc274d1e42ab914f40ae3 100644 (file)
@@ -38,12 +38,16 @@ static char THIS_FILE[] = __FILE__;
 // 32-bit
 static const IID IID_IShellExt =
     { 0xdc515c27, 0x6cac, 0x11d1, { 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd2 } };
+static const IID IID_IShellExt2 =
+    { 0xdc515c27, 0x6cac, 0x11d1, { 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd3 } };
 
 #else
 
 // 64-bit
 static const IID IID_IShellExt =
     { 0x5f820ca1, 0x3dde, 0x11db, {0xb2, 0xce, 0x00, 0x15, 0x58, 0x09, 0x2d, 0xb5} };
+static const IID IID_IShellExt2 =
+    { 0x5f820ca1, 0x3dde, 0x11db, {0xb2, 0xce, 0x00, 0x15, 0x58, 0x09, 0x2d, 0xb6} };
 
 #endif
 
@@ -302,7 +306,65 @@ STDAPI DllRegisterServer(void)
            RegCloseKey(hKey);
        } else
            return SELFREG_E_CLASS;
-    }  
+    }
+
+    StringFromIID(IID_IShellExt2, &pwsz);
+    if(pwsz)
+    {
+#ifdef UNICODE
+        StringCbCopy(szCLSID, sizeof(szCLSID), pwsz);
+#else
+       WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL);
+#endif
+        CoTaskMemFree(pwsz);
+    } else {
+       return E_FAIL;
+    }
+
+    /*
+    [HKEY_CLASSES_ROOT\CLSID\{$CLSID}\InprocServer32]
+    @="Y:\\DEST\\root.client\\usr\\vice\\etc\\afs_shl_ext.dll"
+    "ThreadingModel"="Apartment"
+    */
+    hModule=GetModuleHandle(TEXT("afs_shl_ext.dll"));
+    z=GetModuleFileName(hModule,szModule,sizeof(szModule));
+    wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szModule))!=NOERROR)
+       return lResult;
+
+    wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,
+                            TEXT("Apartment"),TEXT("ThreadingModel")))!=NOERROR)
+       return lResult;
+
+    /*
+    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\AFS Client Shell Extension]
+    @="{EA3775F2-28BE-11D3-9C8D-00105A24ED29}"
+    */
+
+    wsprintf(szSubKey, TEXT("%s\\%s"), STR_REG_PATH, STR_EXT_TITLE2);
+    if ((lResult=DoRegCLSID(HKEY_LOCAL_MACHINE,szSubKey,szCLSID))!=NOERROR)
+       return lResult;
+
+    //If running on NT, register the extension as approved.
+    /*
+    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]
+    "{$(CLSID)}"="AFS Client Shell Extension"
+
+    [HKEY_CLASSES_ROOT\Folder\shellex\ContextMenuHandlers\AFS Client Shell Extension]
+    @="{$(CLSID)}"
+    */
+
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+    GetVersionEx(&osvi);
+    if(VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
+    {
+        wsprintf(szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"));
+        if ((lResult=DoRegCLSID(HKEY_LOCAL_MACHINE,szSubKey,_TEXT(STR_EXT_TITLE2),szCLSID))!=NOERROR)
+            return lResult;
+    }
+
+
     return S_OK;
 }
 
@@ -358,6 +420,22 @@ STDAPI DllUnregisterServer(void)
     DoValueDelete(HKEY_CLASSES_ROOT, szSubKey);
     wsprintf(szSubKey, TEXT("%s\\%s"), STR_REG_PATH, STR_EXT_TITLE);
     DoValueDelete(HKEY_LOCAL_MACHINE, szSubKey);
+
+    StringFromIID(IID_IShellExt2, &pwsz);
+    if(pwsz)
+    {
+#ifdef UNICODE
+        StringCbCopy(szCLSID, sizeof(szCLSID), pwsz);
+#else
+       WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL);
+#endif
+        CoTaskMemFree(pwsz);
+    } else {
+       return E_FAIL;
+    }
+    wsprintf(szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"));
+    DoValueDelete(HKEY_LOCAL_MACHINE,szSubKey,szCLSID);
+
     return S_OK;
 }      
 
diff --git a/src/WINNT/client_exp/link.ico b/src/WINNT/client_exp/link.ico
new file mode 100644 (file)
index 0000000..8b76796
Binary files /dev/null and b/src/WINNT/client_exp/link.ico differ
diff --git a/src/WINNT/client_exp/mount.ico b/src/WINNT/client_exp/mount.ico
new file mode 100644 (file)
index 0000000..1b12b24
Binary files /dev/null and b/src/WINNT/client_exp/mount.ico differ
index d2e573fa9b345fd418c5f53991e320740bb80f57..12c134d808b653ea873e51c0718286d364ab2263 100644 (file)
@@ -66,6 +66,7 @@ static BOOL IsADir(const CString& strName)
 // CShellExt
 
 IMPLEMENT_DYNCREATE(CShellExt, CCmdTarget)
+IMPLEMENT_DYNCREATE(CShellExt2, CCmdTarget)
 #define REG_CLIENT_PARMS_KEY    "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"
 #define OVERLAYENABLED 1
 
@@ -77,6 +78,7 @@ CShellExt::CShellExt()
     HRESULT hr;
     UINT code;
     DWORD ShellOption,LSPsize,LSPtype;
+    m_overlayObject = 0;
     hr = SHGetMalloc(&m_pAlloc);
     m_bIsOverlayEnabled=FALSE;
     if (FAILED(hr))
@@ -131,11 +133,15 @@ END_DISPATCH_MAP()
 // {DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
 static const IID IID_IShellExt =
 { 0xdc515c27, 0x6cac, 0x11d1, { 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd2 } };
+static const IID IID_IShellExt2 =
+{ 0xdc515c27, 0x6cac, 0x11d1, { 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd3 } };
 #else
 // 64-bit
 // {5f820ca1-3dde-11db-b2ce-001558092db5}
 static const IID IID_IShellExt =
 { 0x5f820ca1, 0x3dde, 0x11db, {0xb2, 0xce, 0x00, 0x15, 0x58, 0x09, 0x2d, 0xb5 } };
+static const IID IID_IShellExt2 =
+{ 0x5f820ca1, 0x3dde, 0x11db, {0xb2, 0xce, 0x00, 0x15, 0x58, 0x09, 0x2d, 0xb6 } };
 #endif
 
 BEGIN_INTERFACE_MAP(CShellExt, CCmdTarget)
@@ -150,9 +156,11 @@ END_INTERFACE_MAP()
 #ifndef _WIN64
     // 32-bit
 IMPLEMENT_OLECREATE(CShellExt, STR_EXT_TITLE, 0xdc515c27, 0x6cac, 0x11d1, 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd2)
+IMPLEMENT_OLECREATE(CShellExt2, STR_EXT_TITLE, 0xdc515c27, 0x6cac, 0x11d1, 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd3)
 #else
     // 64-bit
 IMPLEMENT_OLECREATE(CShellExt, STR_EXT_TITLE, 0x5f820ca1, 0x3dde, 0x11db, 0xb2, 0xce, 0x0, 0x15, 0x58, 0x09, 0x2d, 0xb5)
+IMPLEMENT_OLECREATE(CShellExt2, STR_EXT_TITLE, 0x5f820ca1, 0x3dde, 0x11db, 0xb2, 0xce, 0x0, 0x15, 0x58, 0x09, 0x2d, 0xb6)
 #endif
 
 
@@ -684,21 +692,35 @@ STDMETHODIMP_(ULONG) CShellExt::XIconExt::Release(void)
 STDMETHODIMP CShellExt::XIconExt::GetOverlayInfo(LPWSTR pwszIconFile
        ,int cchMax,int* pIndex,DWORD* pdwFlags)
 {
+    METHOD_PROLOGUE(CShellExt, IconExt);
     if(IsBadWritePtr(pIndex, sizeof(int)))
        return E_INVALIDARG;
     if(IsBadWritePtr(pdwFlags, sizeof(DWORD)))
        return E_INVALIDARG;
 
-    HMODULE hModule=GetModuleHandle(_T("shell32.dll"));
+    // The icons must reside in the same path as this dll
     TCHAR szModule[MAX_PATH];
-    DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
+    GetModuleFileName(theApp.m_hInstance, szModule, MAX_PATH);
+    TCHAR * slash = _tcsrchr(szModule, '\\');
+    if (slash) {
+        *slash = 0;
+        switch (pThis->GetOverlayObject())
+        {
+            case 0:
+                _tcscat(szModule, _T("\\link.ico"));
+            break;
+            case 1:
+                _tcscat(szModule, _T("\\mount.ico"));
+            break;
+        }
+    }
 #ifndef UNICODE
     MultiByteToWideChar( CP_ACP,0,szModule,-1,pwszIconFile,cchMax); 
 #else
     _tcsncpy(pwszIconFile, szModule, cchMax);
 #endif
-    *pIndex = 30;
-    *pdwFlags = ISIOI_ICONFILE|ISIOI_ICONINDEX;
+    *pIndex = 0;
+    *pdwFlags = ISIOI_ICONFILE;
     return S_OK;
 }
 
@@ -712,13 +734,17 @@ STDMETHODIMP CShellExt::XIconExt::GetPriority(int* pPriority)
 
 STDMETHODIMP CShellExt::XIconExt::IsMemberOf(LPCWSTR pwszPath,DWORD dwAttrib)
 {
+    METHOD_PROLOGUE(CShellExt, IconExt);
     TCHAR szPath[MAX_PATH];
 #ifdef UNICODE
     _tcscpy(szPath, pwszPath);
 #else
     WideCharToMultiByte( CP_ACP,0,pwszPath,-1,szPath,MAX_PATH,NULL,NULL);
 #endif
-    if (IsSymlink(szPath) || IsMountPoint(szPath)) {
+    if ((pThis->GetOverlayObject() == 0)&&(IsSymlink(szPath))) {
+        return S_OK;
+    }
+    if ((pThis->GetOverlayObject() == 1)&&(IsMountPoint(szPath))) {
         return S_OK;
     }
     return S_FALSE;
index 526801948baf0b2633fd6721092d62e21dd48ff3..46f21bbbb26b4976036a341e08404c5ebc4a8de7 100644 (file)
@@ -25,6 +25,7 @@ extern ULONG nTPRefCount;     // IQueryInfo ref count
 extern ULONG nXPRefCount;      // IPersistFile ref count
 
 #define STR_EXT_TITLE   "AfsClientContextMenu"
+#define STR_EXT_TITLE2  "AfsClientOverlayHandler"
 #define STR_REG_PATH    TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers")
 
 /////////////////////////////////////////////////////////////////////////////
@@ -38,6 +39,7 @@ class CShellExt : public CCmdTarget
     BOOL m_bIsSymlink; // is symbolic link!
     TCHAR m_szFile[MAX_PATH];
     BOOL m_bIsOverlayEnabled;
+    int  m_overlayObject;
     BOOL IsOverlayEnabled(){return m_bIsOverlayEnabled;}
 
     CStringArray m_astrFileNames;
@@ -50,7 +52,7 @@ public:
 
 // Operations
 public:
-
+    int GetOverlayObject() {return m_overlayObject;}
 // Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CShellExt)
@@ -113,6 +115,20 @@ protected:
     DECLARE_INTERFACE_MAP()
 };
 
+class CShellExt2 : public CShellExt
+{
+public:
+    DECLARE_DYNCREATE(CShellExt2)
+    CShellExt2() : CShellExt()
+    {
+        m_overlayObject = 1;
+    }
+    ~CShellExt2()
+    {
+    }
+    DECLARE_OLECREATE(CShellExt2)
+};
+
 /////////////////////////////////////////////////////////////////////////////
 
 //{{AFX_INSERT_LOCATION}}