mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
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:
parent
07183b28eb
commit
57a47b0833
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user