From: Stefan Kueng Date: Sat, 4 Dec 2010 09:56:01 +0000 (+0100) Subject: Windows: afs_shl_ext improve overlay handlers X-Git-Tag: upstream/1.6.0.pre2^2~118 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=5f02e76f11922bf010e24f004c9d628f8402ad03;p=packages%2Fo%2Fopenafs.git Windows: afs_shl_ext improve overlay handlers 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 http://blogs.msdn.com/b/oldnewthing/archive/2005/10/26/485133.aspx Reviewed-on: http://gerrit.openafs.org/3445 Tested-by: BuildBot Tested-by: Stefan Kueng Reviewed-by: Stefan Kueng Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman (cherry picked from commit 3ff9c24c0e2d72dcce65fc7706dcdb1cd3090965) Change-Id: Ifa20508a1b30ebd88e4968d76d325c2e2be51039 Reviewed-on: http://gerrit.openafs.org/3786 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/WINNT/client_exp/afs_shl_ext.cpp b/src/WINNT/client_exp/afs_shl_ext.cpp index 70ef80672..2d0644400 100644 --- a/src/WINNT/client_exp/afs_shl_ext.cpp +++ b/src/WINNT/client_exp/afs_shl_ext.cpp @@ -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 index 000000000..8b76796f1 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 index 000000000..1b12b24c7 Binary files /dev/null and b/src/WINNT/client_exp/mount.ico differ diff --git a/src/WINNT/client_exp/shell_ext.cpp b/src/WINNT/client_exp/shell_ext.cpp index d2e573fa9..12c134d80 100644 --- a/src/WINNT/client_exp/shell_ext.cpp +++ b/src/WINNT/client_exp/shell_ext.cpp @@ -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; diff --git a/src/WINNT/client_exp/shell_ext.h b/src/WINNT/client_exp/shell_ext.h index 526801948..46f21bbbb 100644 --- a/src/WINNT/client_exp/shell_ext.h +++ b/src/WINNT/client_exp/shell_ext.h @@ -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}}