[PATCH] Add IPersist support for desktop IShellFolder

Nikolay Sivov nsivov at codeweavers.com
Sun Mar 21 10:44:44 CDT 2010


---
 dlls/shell32/shfldr_desktop.c  |   49 +++++++++++++++++++++++++++++++++++++++-
 dlls/shell32/tests/shlfolder.c |   31 +++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/dlls/shell32/shfldr_desktop.c b/dlls/shell32/shfldr_desktop.c
index d6ccb72..8e6b751 100644
--- a/dlls/shell32/shfldr_desktop.c
+++ b/dlls/shell32/shfldr_desktop.c
@@ -66,6 +66,7 @@ extern HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisp
 typedef struct {
     const IShellFolder2Vtbl *lpVtbl;
     LONG ref;
+    const IPersistVtbl *lpVtblIPersist;
 
     /* both paths are parsible from the desktop */
     LPWSTR sPathTarget;     /* complete path to target used for enumeration and ChangeNotify */
@@ -78,6 +79,11 @@ typedef struct {
 #define _IUnknown_(This)    (IShellFolder*)&(This->lpVtbl)
 #define _IShellFolder_(This)    (IShellFolder*)&(This->lpVtbl)
 
+static inline IGenericSFImpl *impl_from_IPersist( IPersist *iface )
+{
+    return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpVtblIPersist));
+}
+
 static const shvheader DesktopSFHeader[] = {
     {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
     {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
@@ -91,7 +97,7 @@ static const shvheader DesktopSFHeader[] = {
 /**************************************************************************
  *    ISF_Desktop_fnQueryInterface
  *
- * NOTES supports not IPersist/IPersistFolder
+ * NOTES supports not IPersistFolder
  */
 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
                 IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
@@ -108,6 +114,10 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
     {
         *ppvObj = This;
     }
+    else if (IsEqualIID (riid, &IID_IPersist))
+    {
+        *ppvObj = &This->lpVtblIPersist;
+    }
 
     if (*ppvObj)
     {
@@ -862,6 +872,42 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
 };
 
 /**************************************************************************
+ *    IPersist
+ */
+static HRESULT WINAPI ISF_Desktop_IPersist_fnQueryInterface(
+    IPersist *iface, REFIID riid, LPVOID *ppvObj)
+{
+    IGenericSFImpl *This = impl_from_IPersist( iface );
+    return IShellFolder2_QueryInterface((IShellFolder2*)This, riid, ppvObj);
+}
+
+static ULONG WINAPI ISF_Desktop_IPersist_fnAddRef(IPersist *iface)
+{
+    IGenericSFImpl *This = impl_from_IPersist( iface );
+    return IShellFolder2_AddRef((IShellFolder2*)This);
+}
+
+static ULONG WINAPI ISF_Desktop_IPersist_fnRelease(IPersist *iface)
+{
+    IGenericSFImpl *This = impl_from_IPersist( iface );
+    return IShellFolder2_Release((IShellFolder2*)This);
+}
+
+static HRESULT WINAPI ISF_Desktop_IPersist_fnGetClassID(IPersist *iface, CLSID *clsid)
+{
+    *clsid = CLSID_ShellDesktop;
+    return S_OK;
+}
+
+static const IPersistVtbl vt_IPersist =
+{
+    ISF_Desktop_IPersist_fnQueryInterface,
+    ISF_Desktop_IPersist_fnAddRef,
+    ISF_Desktop_IPersist_fnRelease,
+    ISF_Desktop_IPersist_fnGetClassID
+};
+
+/**************************************************************************
  *    ISF_Desktop_Constructor
  */
 HRESULT WINAPI ISF_Desktop_Constructor (
@@ -890,6 +936,7 @@ HRESULT WINAPI ISF_Desktop_Constructor (
 
         sf->ref = 1;
         sf->lpVtbl = &vt_MCFldr_ShellFolder2;
+        sf->lpVtblIPersist = &vt_IPersist;
         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 bce7c3e..560033b 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -2044,6 +2044,36 @@ if (0)
     IShellFolder_Release(desktop);
 }
 
+static void test_desktop_IPersist(void)
+{
+    IShellFolder *desktop;
+    IPersist *persist;
+    CLSID clsid;
+    HRESULT hr;
+
+    hr = SHGetDesktopFolder(&desktop);
+    ok(hr == S_OK, "failed %08x\n", hr);
+
+    hr = IShellFolder_QueryInterface(desktop, &IID_IPersist, (void**)&persist);
+    ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* NT4, W9X */, "failed %08x\n", hr);
+
+    if (hr == S_OK)
+    {
+    if (0)
+    {
+        /* crashes on native */
+        hr = IPersist_GetClassID(persist, NULL);
+    }
+        memset(&clsid, 0, sizeof(clsid));
+        hr = IPersist_GetClassID(persist, &clsid);
+        ok(hr == S_OK, "failed %08x\n", hr);
+        ok(IsEqualIID(&CLSID_ShellDesktop, &clsid), "Expected CLSID_ShellDesktop\n");
+        IPersist_Release(persist);
+    }
+
+    IShellFolder_Release(desktop);
+}
+
 START_TEST(shlfolder)
 {
     init_function_pointers();
@@ -2064,6 +2094,7 @@ START_TEST(shlfolder)
     test_SHGetFolderPathAndSubDirA();
     test_LocalizedNames();
     test_SHCreateShellItem();
+    test_desktop_IPersist();
 
     OleUninitialize();
 }
-- 
1.5.6.5


--=-IZdZJ019+Byt9TqY/AcC--




More information about the wine-patches mailing list