Commit 57a47b08 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

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.
parent 07183b28
......@@ -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);
......
......@@ -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 );
......
......@@ -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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment