Piotr Caban : shell32: Improved IShellFolder_GetUIObjectOf implementation.

Alexandre Julliard julliard at winehq.org
Wed Nov 10 11:09:42 CST 2010


Module: wine
Branch: master
Commit: e062d4a6fffd6ee2806919aea7109bffa9a73408
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e062d4a6fffd6ee2806919aea7109bffa9a73408

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Nov 10 14:19:29 2010 +0100

shell32: Improved IShellFolder_GetUIObjectOf implementation.

---

 dlls/shell32/shell32_main.h  |    2 +
 dlls/shell32/shfldr.h        |    2 +
 dlls/shell32/shfldr_fs.c     |   90 ++++++++++++++++++++++++++++++++++++++++++
 dlls/shell32/shfldr_unixfs.c |    7 +++
 4 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index af83fe4..77fd42a 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -69,6 +69,8 @@ BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD dwAttributes);
 DWORD WINAPI ParseFieldA(LPCSTR src, DWORD nField, LPSTR dst, DWORD len);
 DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len);
 
+BOOL WINAPI GUIDFromStringW(LPCWSTR, LPGUID);
+
 /****************************************************************************
  * Class constructors
  */
diff --git a/dlls/shell32/shfldr.h b/dlls/shell32/shfldr.h
index 38e0a0b..56833d1 100644
--- a/dlls/shell32/shfldr.h
+++ b/dlls/shell32/shfldr.h
@@ -49,6 +49,8 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
 HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
 LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
 
+HRESULT SHELL32_CreateExtensionUIObject(IShellFolder2 *iface, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut);
+
 static inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str)
 {
     return sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c
index 305902c..850424d 100644
--- a/dlls/shell32/shfldr_fs.c
+++ b/dlls/shell32/shfldr_fs.c
@@ -611,6 +611,90 @@ IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl,
 }
 
 /**************************************************************************
+ * SHELL32_CreateExtensionUIObject (internal)
+ */
+HRESULT SHELL32_CreateExtensionUIObject(IShellFolder2 *iface,
+        LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut)
+{
+    static const WCHAR reg_blockedW[] = {'S','o','f','t','w','a','r','e','\\',
+        'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
+        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+        'S','h','e','l','l',' ','E','x','t','e','n','s','i','o','n','s','\\',
+        'B','l','o','c','k','e','d',0};
+    static const WCHAR formatW[] = {'.','%','s','\\','S','h','e','l','l','E','x','\\',
+        '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
+        '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x',
+        '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0};
+
+    IPersistFile *persist_file;
+    char extensionA[20];
+    WCHAR extensionW[20], buf[MAX_PATH];
+    DWORD size = MAX_PATH;
+    STRRET path;
+    WCHAR *file;
+    GUID guid;
+    HKEY key;
+    HRESULT hr;
+
+
+    if(!_ILGetExtension(pidl, extensionA, 20))
+        return S_FALSE;
+
+    MultiByteToWideChar(CP_ACP, 0, extensionA, -1, extensionW, 20);
+
+    sprintfW(buf, formatW, extensionW, riid->Data1, riid->Data2, riid->Data3,
+            riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
+            riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
+
+    if(RegGetValueW(HKEY_CLASSES_ROOT, buf, NULL, RRF_RT_REG_SZ,
+                NULL, buf, &size) != ERROR_SUCCESS)
+        return S_FALSE;
+
+    if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, reg_blockedW, 0, 0, 0,
+                KEY_READ, NULL, &key, NULL) != ERROR_SUCCESS)
+        return E_FAIL;
+    if(RegQueryValueExW(key, buf, 0, NULL, NULL, NULL)
+            != ERROR_FILE_NOT_FOUND)
+        return E_ACCESSDENIED;
+    RegCloseKey(key);
+
+    if(RegCreateKeyExW(HKEY_CURRENT_USER, reg_blockedW, 0, 0, 0,
+                KEY_READ, NULL, &key, NULL) != ERROR_SUCCESS)
+        return E_FAIL;
+    if(RegQueryValueExW(key, buf, 0, NULL, NULL, NULL)
+            != ERROR_FILE_NOT_FOUND)
+        return E_ACCESSDENIED;
+    RegCloseKey(key);
+
+    if(!GUIDFromStringW(buf, &guid))
+        return E_FAIL;
+
+    hr = CoCreateInstance(&guid, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IPersistFile, (void**)&persist_file);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_FORPARSING, &path);
+    if(SUCCEEDED(hr))
+        hr = StrRetToStrW(&path, NULL, &file);
+    if(FAILED(hr)) {
+        IPersistFile_Release(persist_file);
+        return hr;
+    }
+
+    hr = IPersistFile_Load(persist_file, file, STGM_READ);
+    CoTaskMemFree(file);
+    if(FAILED(hr)) {
+        IPersistFile_Release(persist_file);
+        return hr;
+    }
+
+    hr = IPersistFile_QueryInterface(persist_file, riid, ppvOut);
+    IPersistFile_Release(persist_file);
+    return hr;
+}
+
+/**************************************************************************
 *  IShellFolder_fnGetUIObjectOf
 *
 * PARAMETERS
@@ -651,6 +735,12 @@ IShellFolder_fnGetUIObjectOf (IShellFolder2 * iface,
     if (ppvOut) {
         *ppvOut = NULL;
 
+        if(cidl == 1) {
+            hr = SHELL32_CreateExtensionUIObject(iface, *apidl, riid, ppvOut);
+            if(hr != S_FALSE)
+                return hr;
+        }
+
         if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
             pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
              This->pidlRoot, apidl, cidl);
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index e02399a..11f3686 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -1115,6 +1115,7 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_GetUIObjectOf(IShellFolder2* ifac
 {
     UnixFolder *This = ADJUST_THIS(UnixFolder, IShellFolder2, iface);
     UINT i;
+    HRESULT hr;
     
     TRACE("(iface=%p, hwndOwner=%p, cidl=%d, apidl=%p, riid=%s, prgfInOut=%p, ppv=%p)\n",
         iface, hwndOwner, cidl, apidl, debugstr_guid(riid), prgfInOut, ppvOut);
@@ -1125,6 +1126,12 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_GetUIObjectOf(IShellFolder2* ifac
     for (i=0; i<cidl; i++) 
         if (!apidl[i]) 
             return E_INVALIDARG;
+
+    if(cidl == 1) {
+        hr = SHELL32_CreateExtensionUIObject(iface, *apidl, riid, ppvOut);
+        if(hr != S_FALSE)
+            return hr;
+    }
     
     if (IsEqualIID(&IID_IContextMenu, riid)) {
         *ppvOut = ISvItemCm_Constructor((IShellFolder*)iface, This->m_pidlLocation, apidl, cidl);




More information about the wine-cvs mailing list