From ba7067eafad977454df510243fa5ea2ac1575701 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 20 Sep 2009 04:21:29 +0000 Subject: [PATCH] - Fix several bugs in printer ' IShellFolder implementation - Partly implement IShellFolder::GetAttributesOf - Implement IShellFolder::GetDisplayNameOf for root pidl - Implement ISF_ControlPanel_fnParseDisplayName to parse display names Gets rid of the annoying message box when clicking on the printer folder in the start menu svn path=/trunk/; revision=43094 --- reactos/dll/win32/shell32/pidl.c | 11 +++++ reactos/dll/win32/shell32/pidl.h | 1 + reactos/dll/win32/shell32/shfldr_cpanel.c | 48 ++++++++++++++++++--- reactos/dll/win32/shell32/shfldr_printers.c | 37 ++++++++++++++-- 4 files changed, 89 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/shell32/pidl.c b/reactos/dll/win32/shell32/pidl.c index 919f7cf8d03..72c712bc61c 100644 --- a/reactos/dll/win32/shell32/pidl.c +++ b/reactos/dll/win32/shell32/pidl.c @@ -1654,6 +1654,17 @@ BOOL _ILIsMyComputer(LPCITEMIDLIST pidl) return FALSE; } +BOOL _ILIsPrinter(LPCITEMIDLIST pidl) +{ + REFIID iid = _ILGetGUIDPointer(pidl); + + TRACE("(%p)\n",pidl); + + if (iid) + return IsEqualIID(iid, &CLSID_Printers); + return FALSE; +} + BOOL _ILIsBitBucket(LPCITEMIDLIST pidl) { REFIID iid = _ILGetGUIDPointer(pidl); diff --git a/reactos/dll/win32/shell32/pidl.h b/reactos/dll/win32/shell32/pidl.h index e6859688e2a..692f56f0a83 100644 --- a/reactos/dll/win32/shell32/pidl.h +++ b/reactos/dll/win32/shell32/pidl.h @@ -232,6 +232,7 @@ DWORD _ILGetDrive (LPCITEMIDLIST, LPSTR, UINT); BOOL _ILIsUnicode (LPCITEMIDLIST pidl); BOOL _ILIsDesktop (LPCITEMIDLIST pidl); BOOL _ILIsMyComputer (LPCITEMIDLIST pidl); +BOOL _ILIsPrinter (LPCITEMIDLIST pidl); BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl); BOOL _ILIsControlPanel (LPCITEMIDLIST pidl); BOOL _ILIsBitBucket (LPCITEMIDLIST pidl); diff --git a/reactos/dll/win32/shell32/shfldr_cpanel.c b/reactos/dll/win32/shell32/shfldr_cpanel.c index 2f100992443..57e3701d88f 100644 --- a/reactos/dll/win32/shell32/shfldr_cpanel.c +++ b/reactos/dll/win32/shell32/shfldr_cpanel.c @@ -204,17 +204,55 @@ ISF_ControlPanel_fnParseDisplayName(IShellFolder2 * iface, DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) { ICPanelImpl *This = (ICPanelImpl *)iface; + WCHAR szElement[MAX_PATH]; + LPCWSTR szNext = NULL; + LPITEMIDLIST pidlTemp = NULL; + HRESULT hr = S_OK; + CLSID clsid; - HRESULT hr = E_INVALIDARG; + TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", + This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName), + pchEaten, ppidl, pdwAttributes); - FIXME("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", - This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName), pchEaten, ppidl, pdwAttributes); + if (!lpszDisplayName || !ppidl) + return E_INVALIDARG; *ppidl = 0; + if (pchEaten) - *pchEaten = 0; + *pchEaten = 0; /* strange but like the original */ + + if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') + { + szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); + TRACE ("-- element: %s\n", debugstr_w (szElement)); + CLSIDFromString (szElement + 2, &clsid); + pidlTemp = _ILCreateGuid (PT_GUID, &clsid); + } + else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) ) + { + *ppidl = pidlTemp; + return S_OK; + } + + if (SUCCEEDED(hr) && pidlTemp) + { + if (szNext && *szNext) + { + hr = SHELL32_ParseNextElement(iface, hwndOwner, pbc, + &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes); + } + else + { + if (pdwAttributes && *pdwAttributes) + hr = SHELL32_GetItemAttributes(_IShellFolder_ (This), + pidlTemp, pdwAttributes); + } + } + + *ppidl = pidlTemp; - TRACE("(%p)->(-- ret=0x%08x)\n", This, hr); + TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr); return hr; } diff --git a/reactos/dll/win32/shell32/shfldr_printers.c b/reactos/dll/win32/shell32/shfldr_printers.c index 39497e83bff..f819952ec64 100644 --- a/reactos/dll/win32/shell32/shfldr_printers.c +++ b/reactos/dll/win32/shell32/shfldr_printers.c @@ -333,7 +333,7 @@ static HRESULT WINAPI ISF_Printers_fnQueryInterface( IsEqualIID (riid, &IID_IShellFolder) || IsEqualIID (riid, &IID_IShellFolder2)) { - *ppvObj = This; + *ppvObj = _IShellFolder_(This); } else if (IsEqualIID (riid, &IID_IPersist) || @@ -609,12 +609,20 @@ static HRESULT WINAPI ISF_Printers_fnCreateViewObject (IShellFolder2 * iface, static HRESULT WINAPI ISF_Printers_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) { + static const DWORD dwPrintersAttributes = + SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE; + HRESULT hr = S_OK; IGenericSFImpl *This = (IGenericSFImpl *)iface; FIXME ("(%p)->(cidl=%d apidl=%p mask=0x%08lx): stub\n", This, cidl, apidl, *rgfInOut); - return E_NOTIMPL; + *rgfInOut &= dwPrintersAttributes; + + *rgfInOut &= ~SFGAO_VALIDATE; + + TRACE ("-- result=0x%08x\n", *rgfInOut); + return hr; } /************************************************************************** @@ -669,6 +677,7 @@ static HRESULT WINAPI ISF_Printers_fnGetUIObjectOf (IShellFolder2 * iface, static HRESULT WINAPI ISF_Printers_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { + LPWSTR pszName; IGenericSFImpl *This = (IGenericSFImpl *)iface; PIDLPrinterStruct * p; @@ -676,12 +685,34 @@ static HRESULT WINAPI ISF_Printers_fnGetDisplayNameOf (IShellFolder2 * iface, pdump (pidl); if (!strRet) + { + WARN("no strRet\n"); return E_INVALIDARG; + } + + if (_ILIsPrinter(pidl)) + { + pszName = CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR)); + if (!pszName) + return E_OUTOFMEMORY; + + if (LoadStringW(shell32_hInstance, IDS_PRINTERS, pszName, MAX_PATH)) + { + pszName[MAX_PATH-1] = L'\0'; + strRet->uType = STRRET_WSTR; + strRet->u.pOleStr = pszName; + return S_OK; + } + CoTaskMemFree(pszName); + return E_FAIL; + } p = _ILGetPrinterStruct(pidl); if (!p) + { + WARN("no printer struct\n"); return E_INVALIDARG; - + } strRet->u.pOleStr = SHAlloc(p->offsServer * sizeof(WCHAR)); if (!strRet->u.pOleStr) return E_OUTOFMEMORY; -- 2.17.1