- Fix several bugs in printer ' IShellFolder implementation
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 20 Sep 2009 04:21:29 +0000 (04:21 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 20 Sep 2009 04:21:29 +0000 (04:21 +0000)
- Partly implement IShellFolder::GetAttributesOf
- Implement IShellFolder::GetDisplayNameOf for root pidl
- Implement ISF_ControlPanel_fnParseDisplayName to parse display names
<spoiler>Gets rid of the annoying message box when clicking on the printer folder in the start menu</spoiler>

svn path=/trunk/; revision=43094

reactos/dll/win32/shell32/pidl.c
reactos/dll/win32/shell32/pidl.h
reactos/dll/win32/shell32/shfldr_cpanel.c
reactos/dll/win32/shell32/shfldr_printers.c

index 919f7cf..72c712b 100644 (file)
@@ -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);
index e685968..692f56f 100644 (file)
@@ -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);
index 2f10099..57e3701 100644 (file)
@@ -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;
 }
index 39497e8..f819952 100644 (file)
@@ -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;