Nikolay Sivov : shell32: Add IPersistFile:: GetCurFile implementation for IShellLink.

Alexandre Julliard julliard at winehq.org
Fri Mar 19 11:16:38 CDT 2010


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Mar 19 00:52:41 2010 +0300

shell32: Add IPersistFile::GetCurFile implementation for IShellLink.

---

 dlls/shell32/shelllink.c       |   36 +++++++++++++++++++++--
 dlls/shell32/tests/shelllink.c |   60 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/dlls/shell32/shelllink.c b/dlls/shell32/shelllink.c
index 1718df7..88a188f 100644
--- a/dlls/shell32/shelllink.c
+++ b/dlls/shell32/shelllink.c
@@ -161,6 +161,8 @@ typedef struct
 	BOOL          bDirty;
         INT           iIdOpen;  /* id of the "Open" entry in the context menu */
 	IUnknown      *site;
+
+	LPOLESTR      filepath; /* file path returned by IPersistFile::GetCurFile */
 } IShellLinkImpl;
 
 static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface )
@@ -307,6 +309,7 @@ static ULONG ShellLink_Release( IShellLinkImpl *This )
     HeapFree(GetProcessHeap(), 0, This->sPathRel);
     HeapFree(GetProcessHeap(), 0, This->sProduct);
     HeapFree(GetProcessHeap(), 0, This->sComponent);
+    HeapFree(GetProcessHeap(), 0, This->filepath);
 
     if (This->site)
         IUnknown_Release( This->site );
@@ -392,6 +395,11 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFile
             r = IPersistStream_Load(StreamThis, stm);
             ShellLink_UpdatePath(This->sPathRel, pszFileName, This->sWorkDir, &This->sPath);
             IStream_Release( stm );
+
+            /* update file path */
+            HeapFree(GetProcessHeap(), 0, This->filepath);
+            This->filepath = strdupW(pszFileName);
+
             This->bDirty = FALSE;
         }
         TRACE("-- returning hr %08x\n", r);
@@ -477,6 +485,10 @@ static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFile
 	{
             StartLinkProcessor( pszFileName );
 
+            /* update file path */
+            HeapFree(GetProcessHeap(), 0, This->filepath);
+            This->filepath = strdupW(pszFileName);
+
             This->bDirty = FALSE;
         }
 	else
@@ -496,11 +508,26 @@ static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLEST
 	return NOERROR;
 }
 
-static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *ppszFileName)
+static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *filename)
 {
-	IShellLinkImpl *This = impl_from_IPersistFile(iface);
-	FIXME("(%p)->(%p): stub\n", This, ppszFileName);
-	return NOERROR;
+    IShellLinkImpl *This = impl_from_IPersistFile(iface);
+    IMalloc *pMalloc;
+
+    TRACE("(%p)->(%p)\n", This, filename);
+
+    if (!This->filepath)
+    {
+        *filename = NULL;
+        return S_FALSE;
+    }
+
+    SHGetMalloc(&pMalloc);
+    *filename = IMalloc_Alloc(pMalloc, (strlenW(This->filepath)+1)*sizeof(WCHAR));
+    if (!*filename) return E_OUTOFMEMORY;
+
+    strcpyW(*filename, This->filepath);
+
+    return S_OK;
 }
 
 static const IPersistFileVtbl pfvt =
@@ -1239,6 +1266,7 @@ HRESULT WINAPI IShellLink_Constructor( IUnknown *pUnkOuter,
 	sl->bDirty = FALSE;
 	sl->iIdOpen = -1;
 	sl->site = NULL;
+	sl->filepath = NULL;
 
 	TRACE("(%p)->()\n",sl);
 
diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c
index bb2d5b3..52a21f1 100644
--- a/dlls/shell32/tests/shelllink.c
+++ b/dlls/shell32/tests/shelllink.c
@@ -421,6 +421,22 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
     lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08x)\n", r);
     if (SUCCEEDED(r))
     {
+        CHAR buff[MAX_PATH], buff2[MAX_PATH];
+        IMalloc *pmalloc;
+        LPOLESTR str;
+
+    if (0)
+    {
+        /* crashes on XP */
+        r = IPersistFile_GetCurFile(pf, NULL);
+    }
+
+        /* test GetCurFile before ::Save */
+        str = (LPWSTR)0xdeadbeef;
+        r = IPersistFile_GetCurFile(pf, &str);
+        lok(r == S_FALSE, "got 0x%08x\n", r);
+        ok(str == NULL, "got %p\n", str);
+
         r = IPersistFile_Save(pf, path, TRUE);
         if (save_fails)
         {
@@ -432,6 +448,18 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
         {
             lok(SUCCEEDED(r), "save failed (0x%08x)\n", r);
         }
+
+        /* test GetCurFile after ::Save */
+        r = IPersistFile_GetCurFile(pf, &str);
+        lok(r == S_OK, "got 0x%08x\n", r);
+
+        WideCharToMultiByte( CP_ACP, 0, str, -1, buff, sizeof(buff), NULL, NULL );
+        WideCharToMultiByte( CP_ACP, 0, path, -1, buff2, sizeof(buff2), NULL, NULL );
+
+        lok(!strcmp(buff, buff2), "Expected %s, got %s\n", buff2, buff);
+
+        SHGetMalloc(&pmalloc);
+        IMalloc_Free(pmalloc, str);
         IPersistFile_Release(pf);
     }
 
@@ -444,6 +472,9 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
     IShellLinkA *sl;
     IPersistFile *pf;
     char buffer[INFOTIPSIZE];
+    CHAR buff[MAX_PATH], buff2[MAX_PATH];
+    IMalloc *pmalloc;
+    LPOLESTR str;
 
     r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IShellLinkA, (LPVOID*)&sl);
@@ -459,8 +490,28 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
         return;
     }
 
+    SHGetMalloc(&pmalloc);
+
+    /* test GetCurFile before ::Load */
+    str = (LPWSTR)0xdeadbeef;
+    r = IPersistFile_GetCurFile(pf, &str);
+    lok(r == S_FALSE, "got 0x%08x\n", r);
+    lok(str == NULL, "got %p\n", str);
+
     r = IPersistFile_Load(pf, path, STGM_READ);
     lok(SUCCEEDED(r), "load failed (0x%08x)\n", r);
+
+    /* test GetCurFile after ::Save */
+    r = IPersistFile_GetCurFile(pf, &str);
+    lok(r == S_OK, "got 0x%08x\n", r);
+
+    WideCharToMultiByte( CP_ACP, 0, str, -1, buff, sizeof(buff), NULL, NULL );
+    WideCharToMultiByte( CP_ACP, 0, path, -1, buff2, sizeof(buff2), NULL, NULL );
+
+    lok(!strcmp(buff, buff2), "Expected %s, got %s\n", buff2, buff);
+
+    IMalloc_Free(pmalloc, str);
+
     IPersistFile_Release(pf);
     if (FAILED(r))
     {
@@ -744,10 +795,11 @@ static void test_datalink(void)
     r = IShellLinkW_SetPath(sl, lnk);
     ok(r == S_OK, "set path failed\n");
 
-    /*
-     * The following crashes:
-     * r = IShellLinkDataList_GetFlags( dl, NULL );
-     */
+if (0)
+{
+    /* the following crashes */
+    r = IShellLinkDataList_GetFlags( dl, NULL );
+}
 
     flags = 0;
     r = IShellLinkDataList_GetFlags( dl, &flags );




More information about the wine-cvs mailing list