hlink: String target reference is actually moniker target's display name.

The original implementation treated the string target in IHlink as a
separate entity from the moniker target.  In reality, the string target 
is just the moniker target's display name and setting one reference also
sets the other.
This commit is contained in:
Andrew Eikum 2009-12-30 11:43:05 -06:00 committed by Alexandre Julliard
parent 07183b28eb
commit 57a47b0833
3 changed files with 165 additions and 57 deletions

View file

@ -77,14 +77,12 @@ HRESULT WINAPI HlinkCreateFromMoniker( IMoniker *pimkTrgt, LPCWSTR pwzLocation,
if (FAILED(r))
return r;
if (pwzLocation)
IHlink_SetStringReference(hl, HLINKSETF_LOCATION, NULL, pwzLocation);
IHlink_SetMonikerReference(hl, HLINKSETF_LOCATION | HLINKSETF_TARGET, pimkTrgt, pwzLocation);
if (pwzFriendlyName)
IHlink_SetFriendlyName(hl, pwzFriendlyName);
if (pihlsite)
IHlink_SetHlinkSite(hl, pihlsite, dwSiteData);
if (pimkTrgt)
IHlink_SetMonikerReference(hl, HLINKSETF_LOCATION | HLINKSETF_TARGET, pimkTrgt, pwzLocation);
*ppvObj = hl;
@ -111,43 +109,12 @@ HRESULT WINAPI HlinkCreateFromString( LPCWSTR pwzTarget, LPCWSTR pwzLocation,
if (FAILED(r))
return r;
if (pwzLocation)
IHlink_SetStringReference(hl, HLINKSETF_LOCATION, NULL, pwzLocation);
if (pwzTarget)
{
IMoniker *pTgtMk = NULL;
IBindCtx *pbc = NULL;
ULONG eaten;
CreateBindCtx(0, &pbc);
r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pTgtMk);
IBindCtx_Release(pbc);
if (FAILED(r))
{
LPCWSTR p = strchrW(pwzTarget, ':');
if (p && (p - pwzTarget > 1))
r = CreateURLMoniker(NULL, pwzTarget, &pTgtMk);
else
r = CreateFileMoniker(pwzTarget,&pTgtMk);
}
if (FAILED(r))
{
ERR("couldn't create moniker for %s, failed with error 0x%08x\n",
debugstr_w(pwzTarget), r);
return r;
}
IHlink_SetMonikerReference(hl, HLINKSETF_TARGET | HLINKSETF_LOCATION, pTgtMk, pwzLocation);
IMoniker_Release(pTgtMk);
IHlink_SetStringReference(hl, HLINKSETF_TARGET, pwzTarget, NULL);
}
IHlink_SetStringReference(hl, HLINKSETF_TARGET | HLINKSETF_LOCATION,
pwzTarget, pwzLocation);
if (pwzFriendlyName)
IHlink_SetFriendlyName(hl, pwzFriendlyName);
if (pihlsite)
IHlink_SetHlinkSite(hl, pihlsite, dwSiteData);

View file

@ -51,7 +51,6 @@ typedef struct
LPWSTR FriendlyName;
LPWSTR Location;
LPWSTR Target;
LPWSTR TargetFrameName;
IMoniker *Moniker;
IHlinkSite *Site;
@ -155,7 +154,6 @@ static ULONG WINAPI IHlink_fnRelease (IHlink* iface)
TRACE("-- destroying IHlink (%p)\n", This);
heap_free(This->FriendlyName);
heap_free(This->Target);
heap_free(This->TargetFrameName);
heap_free(This->Location);
if (This->Moniker)
@ -251,9 +249,45 @@ static HRESULT WINAPI IHlink_fnSetStringReference(IHlink* iface,
if (grfHLSETF & HLINKSETF_TARGET)
{
heap_free(This->Target);
This->Target = hlink_strdupW( pwzTarget );
if (This->Moniker)
{
IMoniker_Release(This->Moniker);
This->Moniker = NULL;
}
if (pwzTarget && *pwzTarget)
{
IMoniker *pMon;
IBindCtx *pbc = NULL;
ULONG eaten;
HRESULT r;
r = CreateBindCtx(0, &pbc);
if (FAILED(r))
return E_OUTOFMEMORY;
r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pMon);
IBindCtx_Release(pbc);
if (FAILED(r))
{
LPCWSTR p = strchrW(pwzTarget, ':');
if (p && (p - pwzTarget > 1))
r = CreateURLMoniker(NULL, pwzTarget, &pMon);
else
r = CreateFileMoniker(pwzTarget, &pMon);
if (FAILED(r))
{
ERR("couldn't create moniker for %s, failed with error 0x%08x\n",
debugstr_w(pwzTarget), r);
return r;
}
}
IHlink_SetMonikerReference(iface, HLINKSETF_TARGET, pMon, NULL);
IMoniker_Release(pMon);
}
}
if (grfHLSETF & HLINKSETF_LOCATION)
{
heap_free(This->Location);
@ -302,22 +336,19 @@ static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
if (ppwzTarget)
{
*ppwzTarget = hlink_co_strdupW( This->Target );
if (!This->Target)
IMoniker* mon;
__GetMoniker(This, &mon);
if (mon)
{
IMoniker* mon;
__GetMoniker(This, &mon);
if (mon)
{
IBindCtx *pbc;
IBindCtx *pbc;
CreateBindCtx( 0, &pbc);
IMoniker_GetDisplayName(mon, pbc, NULL, ppwzTarget);
IBindCtx_Release(pbc);
IMoniker_Release(mon);
}
CreateBindCtx( 0, &pbc);
IMoniker_GetDisplayName(mon, pbc, NULL, ppwzTarget);
IBindCtx_Release(pbc);
IMoniker_Release(mon);
}
else
*ppwzTarget = NULL;
}
if (ppwzLocation)
*ppwzLocation = hlink_co_strdupW( This->Location );

View file

@ -137,9 +137,7 @@ static void test_reference(void)
r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
ok(r == S_OK, "failed\n");
todo_wine {
ok(!lstrcmpW(str, url2), "url wrong\n");
}
CoTaskMemFree(str);
r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
@ -1215,6 +1213,117 @@ static void test_HlinkGetSetStringReference(void)
IHlink_Release(link);
}
#define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
{
HRESULT hres;
hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
}
#define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
{
HRESULT hres;
WCHAR *fnd_tgt, *fnd_loc;
hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
if(exp_tgt)
ok_(__FILE__,line) (!lstrcmpW(fnd_tgt, exp_tgt), "Found string target should have been %s, was: %s\n", wine_dbgstr_w(exp_tgt), wine_dbgstr_w(fnd_tgt));
else
ok_(__FILE__,line) (exp_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
if(exp_loc)
ok_(__FILE__,line) (!lstrcmpW(fnd_loc, exp_loc), "Found string location should have been %s, was: %s\n", wine_dbgstr_w(exp_loc), wine_dbgstr_w(fnd_loc));
else
ok_(__FILE__,line) (exp_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
CoTaskMemFree(fnd_tgt);
CoTaskMemFree(fnd_loc);
}
#define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
{
HRESULT hres;
hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
}
/* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
#define getMonikerRef(h,t,l) r_getMonikerRef(__LINE__,h,t,l)
static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc)
{
HRESULT hres;
IMoniker *fnd_tgt;
WCHAR *fnd_loc;
hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
if(exp_loc)
ok_(__FILE__,line) (!lstrcmpW(fnd_loc, exp_loc), "Found string location should have been %s, was: %s\n", wine_dbgstr_w(exp_loc), wine_dbgstr_w(fnd_loc));
else
ok_(__FILE__,line) (exp_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
CoTaskMemFree(fnd_loc);
if(exp_tgt == (IMoniker*)0xFFFFFFFF)
return fnd_tgt;
ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
if(fnd_tgt)
IMoniker_Release(fnd_tgt);
return NULL;
}
static void test_HlinkMoniker(void)
{
IHlink *hlink;
IMoniker *aMon, *file_mon;
static const WCHAR emptyW[] = {0};
static const WCHAR wordsW[] = {'w','o','r','d','s',0};
static const WCHAR aW[] = {'a',0};
static const WCHAR bW[] = {'b',0};
HRESULT hres;
hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
getStringRef(hlink, NULL, NULL);
getMonikerRef(hlink, NULL, NULL);
/* setting a string target creates a moniker reference */
setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
getStringRef(hlink, aW, wordsW);
aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW);
ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
if(aMon)
IMoniker_Release(aMon);
/* setting target & location to the empty string deletes the moniker
* reference */
setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
getStringRef(hlink, NULL, NULL);
getMonikerRef(hlink, NULL, NULL);
/* setting a moniker target also sets the target string to that moniker's
* display name */
hres = CreateFileMoniker(bW, &file_mon);
ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
getStringRef(hlink, bW, wordsW);
getMonikerRef(hlink, file_mon, wordsW);
IMoniker_Release(file_mon);
IHlink_Release(hlink);
}
START_TEST(hlink)
{
CoInitialize(NULL);
@ -1228,6 +1337,7 @@ START_TEST(hlink)
test_HlinkResolveMonikerForData();
test_HlinkGetSetMonikerReference();
test_HlinkGetSetStringReference();
test_HlinkMoniker();
CoUninitialize();
}