[PATCH] Add IPersistFile::GetCurFile implementation for IShellLink
Nikolay Sivov
nsivov at codeweavers.com
Thu Mar 18 16:52:41 CDT 2010
---
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 );
--
1.5.6.5
--=-kjxLjwRAByV1u2MJsExP--
More information about the wine-patches
mailing list