shell32: Add IPersistFile::GetCurFile implementation for IShellLink.

This commit is contained in:
Nikolay Sivov 2010-03-19 00:52:41 +03:00 committed by Alexandre Julliard
parent cecb80a4e8
commit b774baa35c
2 changed files with 88 additions and 8 deletions

View File

@ -161,6 +161,8 @@ typedef struct
BOOL bDirty; BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */ INT iIdOpen; /* id of the "Open" entry in the context menu */
IUnknown *site; IUnknown *site;
LPOLESTR filepath; /* file path returned by IPersistFile::GetCurFile */
} IShellLinkImpl; } IShellLinkImpl;
static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface ) 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->sPathRel);
HeapFree(GetProcessHeap(), 0, This->sProduct); HeapFree(GetProcessHeap(), 0, This->sProduct);
HeapFree(GetProcessHeap(), 0, This->sComponent); HeapFree(GetProcessHeap(), 0, This->sComponent);
HeapFree(GetProcessHeap(), 0, This->filepath);
if (This->site) if (This->site)
IUnknown_Release( This->site ); IUnknown_Release( This->site );
@ -392,6 +395,11 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFile
r = IPersistStream_Load(StreamThis, stm); r = IPersistStream_Load(StreamThis, stm);
ShellLink_UpdatePath(This->sPathRel, pszFileName, This->sWorkDir, &This->sPath); ShellLink_UpdatePath(This->sPathRel, pszFileName, This->sWorkDir, &This->sPath);
IStream_Release( stm ); IStream_Release( stm );
/* update file path */
HeapFree(GetProcessHeap(), 0, This->filepath);
This->filepath = strdupW(pszFileName);
This->bDirty = FALSE; This->bDirty = FALSE;
} }
TRACE("-- returning hr %08x\n", r); TRACE("-- returning hr %08x\n", r);
@ -477,6 +485,10 @@ static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFile
{ {
StartLinkProcessor( pszFileName ); StartLinkProcessor( pszFileName );
/* update file path */
HeapFree(GetProcessHeap(), 0, This->filepath);
This->filepath = strdupW(pszFileName);
This->bDirty = FALSE; This->bDirty = FALSE;
} }
else else
@ -496,11 +508,26 @@ static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLEST
return NOERROR; 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); IShellLinkImpl *This = impl_from_IPersistFile(iface);
FIXME("(%p)->(%p): stub\n", This, ppszFileName); IMalloc *pMalloc;
return NOERROR;
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 = static const IPersistFileVtbl pfvt =
@ -1239,6 +1266,7 @@ HRESULT WINAPI IShellLink_Constructor( IUnknown *pUnkOuter,
sl->bDirty = FALSE; sl->bDirty = FALSE;
sl->iIdOpen = -1; sl->iIdOpen = -1;
sl->site = NULL; sl->site = NULL;
sl->filepath = NULL;
TRACE("(%p)->()\n",sl); TRACE("(%p)->()\n",sl);

View File

@ -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); lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08x)\n", r);
if (SUCCEEDED(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); r = IPersistFile_Save(pf, path, TRUE);
if (save_fails) 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); 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); IPersistFile_Release(pf);
} }
@ -444,6 +472,9 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
IShellLinkA *sl; IShellLinkA *sl;
IPersistFile *pf; IPersistFile *pf;
char buffer[INFOTIPSIZE]; char buffer[INFOTIPSIZE];
CHAR buff[MAX_PATH], buff2[MAX_PATH];
IMalloc *pmalloc;
LPOLESTR str;
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLinkA, (LPVOID*)&sl); &IID_IShellLinkA, (LPVOID*)&sl);
@ -459,8 +490,28 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
return; 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); r = IPersistFile_Load(pf, path, STGM_READ);
lok(SUCCEEDED(r), "load failed (0x%08x)\n", r); 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); IPersistFile_Release(pf);
if (FAILED(r)) if (FAILED(r))
{ {
@ -744,10 +795,11 @@ static void test_datalink(void)
r = IShellLinkW_SetPath(sl, lnk); r = IShellLinkW_SetPath(sl, lnk);
ok(r == S_OK, "set path failed\n"); ok(r == S_OK, "set path failed\n");
/* if (0)
* The following crashes: {
* r = IShellLinkDataList_GetFlags( dl, NULL ); /* the following crashes */
*/ r = IShellLinkDataList_GetFlags( dl, NULL );
}
flags = 0; flags = 0;
r = IShellLinkDataList_GetFlags( dl, &flags ); r = IShellLinkDataList_GetFlags( dl, &flags );