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