David Hedberg : shell32: Implement IPersistFolder2 for the desktop folder.

Alexandre Julliard julliard at winehq.org
Tue Jul 20 11:20:32 CDT 2010


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

Author: David Hedberg <david.hedberg at gmail.com>
Date:   Sun Jul 18 14:34:56 2010 +0200

shell32: Implement IPersistFolder2 for the desktop folder.

---

 dlls/shell32/shfldr_desktop.c  |   60 ++++++++++++++++++++++++++-------------
 dlls/shell32/tests/shlfolder.c |   46 ++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 20 deletions(-)

diff --git a/dlls/shell32/shfldr_desktop.c b/dlls/shell32/shfldr_desktop.c
index e3798a6..e4a612a 100644
--- a/dlls/shell32/shfldr_desktop.c
+++ b/dlls/shell32/shfldr_desktop.c
@@ -65,7 +65,7 @@ extern HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisp
 
 typedef struct {
     const IShellFolder2Vtbl *lpVtbl;
-    const IPersistVtbl *lpVtblIPersist;
+    const IPersistFolder2Vtbl *lpVtblPF2;
     LONG ref;
 
     /* both paths are parsible from the desktop */
@@ -76,9 +76,9 @@ typedef struct {
     BOOL fAcceptFmt;        /* flag for pending Drop */
 } IDesktopFolderImpl;
 
-static inline IDesktopFolderImpl *impl_from_IPersist( IPersist *iface )
+static inline IDesktopFolderImpl *impl_from_IPersistFolder2( IPersistFolder2 *iface )
 {
-    return (IDesktopFolderImpl *)((char*)iface - FIELD_OFFSET(IDesktopFolderImpl, lpVtblIPersist));
+    return (IDesktopFolderImpl *)((char*)iface - FIELD_OFFSET(IDesktopFolderImpl, lpVtblPF2));
 }
 
 static const shvheader desktop_header[] = {
@@ -94,7 +94,6 @@ static const shvheader desktop_header[] = {
 /**************************************************************************
  *    ISF_Desktop_fnQueryInterface
  *
- * NOTES supports not IPersistFolder
  */
 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
                 IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
@@ -111,9 +110,11 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
     {
         *ppvObj = This;
     }
-    else if (IsEqualIID (riid, &IID_IPersist))
+    else if (IsEqualIID (riid, &IID_IPersist) ||
+             IsEqualIID (riid, &IID_IPersistFolder) ||
+             IsEqualIID (riid, &IID_IPersistFolder2))
     {
-        *ppvObj = &This->lpVtblIPersist;
+        *ppvObj = &This->lpVtblPF2;
     }
 
     if (*ppvObj)
@@ -877,37 +878,56 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
 /**************************************************************************
  *    IPersist
  */
-static HRESULT WINAPI ISF_Desktop_IPersist_fnQueryInterface(
-    IPersist *iface, REFIID riid, LPVOID *ppvObj)
+static HRESULT WINAPI ISF_Desktop_IPersistFolder2_fnQueryInterface(
+    IPersistFolder2 *iface, REFIID riid, LPVOID *ppvObj)
 {
-    IDesktopFolderImpl *This = impl_from_IPersist( iface );
+    IDesktopFolderImpl *This = impl_from_IPersistFolder2( iface );
     return IShellFolder2_QueryInterface((IShellFolder2*)This, riid, ppvObj);
 }
 
-static ULONG WINAPI ISF_Desktop_IPersist_fnAddRef(IPersist *iface)
+static ULONG WINAPI ISF_Desktop_IPersistFolder2_fnAddRef(
+    IPersistFolder2 *iface)
 {
-    IDesktopFolderImpl *This = impl_from_IPersist( iface );
+    IDesktopFolderImpl *This = impl_from_IPersistFolder2( iface );
     return IShellFolder2_AddRef((IShellFolder2*)This);
 }
 
-static ULONG WINAPI ISF_Desktop_IPersist_fnRelease(IPersist *iface)
+static ULONG WINAPI ISF_Desktop_IPersistFolder2_fnRelease(
+    IPersistFolder2 *iface)
 {
-    IDesktopFolderImpl *This = impl_from_IPersist( iface );
+    IDesktopFolderImpl *This = impl_from_IPersistFolder2( iface );
     return IShellFolder2_Release((IShellFolder2*)This);
 }
 
-static HRESULT WINAPI ISF_Desktop_IPersist_fnGetClassID(IPersist *iface, CLSID *clsid)
+static HRESULT WINAPI ISF_Desktop_IPersistFolder2_fnGetClassID(
+    IPersistFolder2 *iface, CLSID *clsid)
 {
     *clsid = CLSID_ShellDesktop;
     return S_OK;
 }
+static HRESULT WINAPI ISF_Desktop_IPersistFolder2_fnInitialize(
+    IPersistFolder2 *iface, LPCITEMIDLIST pidl)
+{
+    IDesktopFolderImpl *This = impl_from_IPersistFolder2( iface );
+    FIXME ("(%p)->(%p) stub\n", This, pidl);
+    return E_NOTIMPL;
+}
+static HRESULT WINAPI ISF_Desktop_IPersistFolder2_fnGetCurFolder(
+    IPersistFolder2 *iface, LPITEMIDLIST *ppidl)
+{
+    IDesktopFolderImpl *This = impl_from_IPersistFolder2( iface );
+    *ppidl = ILClone(This->pidlRoot);
+    return S_OK;
+}
 
-static const IPersistVtbl vt_IPersist =
+static const IPersistFolder2Vtbl vt_IPersistFolder2 =
 {
-    ISF_Desktop_IPersist_fnQueryInterface,
-    ISF_Desktop_IPersist_fnAddRef,
-    ISF_Desktop_IPersist_fnRelease,
-    ISF_Desktop_IPersist_fnGetClassID
+    ISF_Desktop_IPersistFolder2_fnQueryInterface,
+    ISF_Desktop_IPersistFolder2_fnAddRef,
+    ISF_Desktop_IPersistFolder2_fnRelease,
+    ISF_Desktop_IPersistFolder2_fnGetClassID,
+    ISF_Desktop_IPersistFolder2_fnInitialize,
+    ISF_Desktop_IPersistFolder2_fnGetCurFolder
 };
 
 /**************************************************************************
@@ -939,7 +959,7 @@ HRESULT WINAPI ISF_Desktop_Constructor (
 
         sf->ref = 1;
         sf->lpVtbl = &vt_MCFldr_ShellFolder2;
-        sf->lpVtblIPersist = &vt_IPersist;
+        sf->lpVtblPF2 = &vt_IPersistFolder2;
         sf->pidlRoot = _ILCreateDesktop();    /* my qualified pidl */
         sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
         lstrcpyW( sf->sPathTarget, szMyPath );
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 2909818..210631d 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -2014,6 +2014,26 @@ static void test_SHCreateShellItem(void)
         IShellItem_Release(shellitem);
     }
 
+    ret = pSHCreateShellItem(NULL, desktopfolder, pidl_testfile, &shellitem);
+    ok(SUCCEEDED(ret), "SHCreateShellItem returned %x\n", ret);
+    if (SUCCEEDED(ret))
+    {
+        ret = IShellItem_QueryInterface(shellitem, &IID_IPersistIDList, (void**)&persistidl);
+        ok(SUCCEEDED(ret), "QueryInterface returned %x\n", ret);
+        if (SUCCEEDED(ret))
+        {
+            ret = IPersistIDList_GetIDList(persistidl, &pidl_test);
+            ok(SUCCEEDED(ret), "GetIDList returned %x\n", ret);
+            if (SUCCEEDED(ret))
+            {
+                ok(ILIsEqual(pidl_testfile, pidl_test), "id lists are not equal\n");
+                pILFree(pidl_test);
+            }
+            IPersistIDList_Release(persistidl);
+        }
+        IShellItem_Release(shellitem);
+    }
+
     DeleteFileA(".\\testfile");
     pILFree(pidl_abstestfile);
     pILFree(pidl_testfile);
@@ -2084,6 +2104,7 @@ static void test_desktop_IPersist(void)
 {
     IShellFolder *desktop;
     IPersist *persist;
+    IPersistFolder2 *ppf2;
     CLSID clsid;
     HRESULT hr;
 
@@ -2107,6 +2128,31 @@ static void test_desktop_IPersist(void)
         IPersist_Release(persist);
     }
 
+    hr = IShellFolder_QueryInterface(desktop, &IID_IPersistFolder2, (void**)&ppf2);
+    ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* pre-Vista */, "failed %08x\n", hr);
+    if(SUCCEEDED(hr))
+    {
+        IPersistFolder *ppf;
+        LPITEMIDLIST pidl;
+        hr = IShellFolder_QueryInterface(desktop, &IID_IPersistFolder, (void**)&ppf);
+        ok(hr == S_OK, "IID_IPersistFolder2 without IID_IPersistFolder.\n");
+        if(SUCCEEDED(hr))
+            IPersistFolder_Release(ppf);
+
+        todo_wine {
+            hr = IPersistFolder2_Initialize(ppf2, NULL);
+            ok(hr == S_OK, "got %08x\n", hr);
+        }
+
+        pidl = NULL;
+        hr = IPersistFolder2_GetCurFolder(ppf2, &pidl);
+        ok(hr == S_OK, "got %08x\n", hr);
+        ok(pidl != NULL, "pidl was NULL.\n");
+        if(SUCCEEDED(hr)) pILFree(pidl);
+
+        IPersistFolder2_Release(ppf2);
+    }
+
     IShellFolder_Release(desktop);
 }
 




More information about the wine-cvs mailing list