hlink: Implement HLINKGETREF flags handling.

This commit is contained in:
Andrew Eikum 2010-08-16 13:55:14 -05:00 committed by Alexandre Julliard
parent 40bc5f646f
commit cb5eb33159
2 changed files with 334 additions and 39 deletions

View File

@ -69,20 +69,40 @@ static inline HlinkImpl* HlinkImpl_from_IDataObject( IDataObject* iface)
return (HlinkImpl*) ((CHAR*)iface - FIELD_OFFSET(HlinkImpl, lpDOVtbl));
}
static inline void __GetMoniker(HlinkImpl* This, IMoniker** moniker)
static HRESULT __GetMoniker(HlinkImpl* This, IMoniker** moniker,
DWORD ref_type)
{
*moniker = NULL;
if (This->Moniker)
HRESULT hres;
if (ref_type == HLINKGETREF_DEFAULT)
ref_type = HLINKGETREF_RELATIVE;
if (ref_type == HLINKGETREF_ABSOLUTE && This->Site)
{
*moniker = This->Moniker;
if (*moniker)
IMoniker_AddRef(*moniker);
}
else if (This->Site)
{
IHlinkSite_GetMoniker(This->Site, This->SiteData,
OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, moniker);
IMoniker *hls_moniker;
hres = IHlinkSite_GetMoniker(This->Site, This->SiteData,
OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, &hls_moniker);
if (FAILED(hres))
return hres;
if (This->Moniker)
{
hres = IMoniker_ComposeWith(hls_moniker, This->Moniker, FALSE,
moniker);
IMoniker_Release(hls_moniker);
return hres;
}
*moniker = hls_moniker;
return S_OK;
}
*moniker = This->Moniker;
if (*moniker)
IMoniker_AddRef(*moniker);
return S_OK;
}
HRESULT WINAPI HLink_Constructor(IUnknown *pUnkOuter, REFIID riid,
@ -307,8 +327,16 @@ static HRESULT WINAPI IHlink_fnGetMonikerReference(IHlink* iface,
TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppimkTarget,
ppwzLocation);
if(ppimkTarget)
__GetMoniker(This, ppimkTarget);
if (ppimkTarget)
{
HRESULT hres = __GetMoniker(This, ppimkTarget, dwWhichRef);
if (FAILED(hres))
{
if (ppwzLocation)
*ppwzLocation = NULL;
return hres;
}
}
if (ppwzLocation)
IHlink_GetStringReference(iface, dwWhichRef, NULL, ppwzLocation);
@ -323,7 +351,6 @@ static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation);
/* note: undocumented behavior with dwWhichRef == -1 */
if(dwWhichRef != -1 && dwWhichRef & ~(HLINKGETREF_DEFAULT | HLINKGETREF_ABSOLUTE | HLINKGETREF_RELATIVE))
{
if(ppwzTarget)
@ -333,13 +360,16 @@ static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
return E_INVALIDARG;
}
if(dwWhichRef != HLINKGETREF_DEFAULT)
FIXME("unhandled flags: 0x%x\n", dwWhichRef);
if (ppwzTarget)
{
IMoniker* mon;
__GetMoniker(This, &mon);
HRESULT hres = __GetMoniker(This, &mon, dwWhichRef);
if (FAILED(hres))
{
if (ppwzLocation)
*ppwzLocation = NULL;
return hres;
}
if (mon)
{
IBindCtx *pbc;
@ -389,7 +419,12 @@ static HRESULT WINAPI IHlink_fnGetFriendlyName (IHlink* iface,
else
{
IMoniker *moniker;
__GetMoniker(This, &moniker);
HRESULT hres = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
if (FAILED(hres))
{
*ppwzFriendlyName = NULL;
return hres;
}
if (moniker)
{
IBindCtx *bcxt;
@ -440,20 +475,17 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
{
HlinkImpl *This = (HlinkImpl*)iface;
IMoniker *mon = NULL;
HRESULT r;
FIXME("Semi-Stub:(%p)->(%i %p %p %p)\n", This, grfHLNF, pbc, pbsc, phbc);
if (This->Site)
IHlinkSite_ReadyToNavigate(This->Site, This->SiteData, 0);
__GetMoniker(This, &mon);
r = __GetMoniker(This, &mon, HLINKGETREF_ABSOLUTE);
TRACE("Moniker %p\n", mon);
if (mon)
if (SUCCEEDED(r))
{
IBindCtx *bcxt;
IHlinkTarget *target = NULL;
HRESULT r = S_OK;
CreateBindCtx(0, &bcxt);
@ -488,10 +520,10 @@ static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
}
if (This->Site)
IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, 0, NULL);
IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, r, NULL);
TRACE("Finished Navigation\n");
return S_OK;
return r;
}
static HRESULT WINAPI IHlink_fnSetAdditonalParams(IHlink* iface,
@ -782,14 +814,17 @@ end:
static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface,
IStream* pStm, BOOL fClearDirty)
{
HRESULT r = E_FAIL;
HRESULT r;
HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
DWORD hdr[2];
IMoniker *moniker;
TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
__GetMoniker(This, &moniker);
r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
if (FAILED(r))
return r;
r = E_FAIL;
hdr[0] = HLINK_SAVE_MAGIC;
hdr[1] = 0;
@ -850,7 +885,7 @@ end:
static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
ULARGE_INTEGER* pcbSize)
{
HRESULT r = E_FAIL;
HRESULT r;
HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
IMoniker *moniker;
@ -864,7 +899,11 @@ static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
if (This->FriendlyName)
pcbSize->QuadPart += size_hlink_string(This->FriendlyName);
__GetMoniker(This, &moniker);
r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
if (FAILED(r))
return r;
r = E_FAIL;
if (moniker)
{
IPersistStream* monstream = NULL;

View File

@ -57,6 +57,11 @@ DEFINE_EXPECT(IsSystemMoniker);
DEFINE_EXPECT(BindToStorage);
DEFINE_EXPECT(GetDisplayName);
DEFINE_EXPECT(ComposeWith);
DEFINE_EXPECT(OnNavigationComplete);
DEFINE_EXPECT(Enum);
DEFINE_EXPECT(Reduce);
static const char *debugstr_guid(REFIID riid)
{
static char buf[50];
@ -437,7 +442,7 @@ static void test_persist(void)
hr = HlinkCreateFromString(url, NULL, NULL, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
ok(hr == S_OK, "IHlinkCreateFromString failed with error 0x%08x\n", hr);
ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
if (!lnk) {
skip("Can't create lnk, skipping test_persist.\n");
return;
@ -449,7 +454,7 @@ static void test_persist(void)
hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
test_persist_save_data("url + friendly name", lnk,
expected_hlink_data2, sizeof(expected_hlink_data2),
expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
@ -457,7 +462,7 @@ static void test_persist(void)
hr = HlinkCreateFromString(url, location, friendly_name, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
test_persist_save_data("url + friendly_name + location", lnk,
expected_hlink_data3, sizeof(expected_hlink_data3),
expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
@ -465,7 +470,7 @@ static void test_persist(void)
hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
test_persist_save_data("relative url", lnk,
expected_hlink_data4, sizeof(expected_hlink_data4),
expected_hlink_data4, sizeof(expected_hlink_data4));
@ -473,7 +478,7 @@ static void test_persist(void)
hr = HlinkCreateFromString(url, NULL, NULL, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
test_persist_save_data("url + target frame name", lnk,
@ -483,7 +488,7 @@ static void test_persist(void)
hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &lnk);
ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
test_persist_save_data("filename", lnk,
expected_hlink_data6, sizeof(expected_hlink_data6),
expected_hlink_data6, sizeof(expected_hlink_data6));
@ -876,7 +881,7 @@ static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMon
static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
{
ok(0, "unexpected call\n");
CHECK_EXPECT(Reduce);
return E_NOTIMPL;
}
@ -889,7 +894,7 @@ static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
{
ok(0, "unexpected call\n");
CHECK_EXPECT(Enum);
return E_NOTIMPL;
}
@ -1442,6 +1447,256 @@ static void test_HashLink(void)
}
}
static WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
static WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
{
ok(0, "BTS: %p %p %p %p %p\n", iface, pbc, toLeft, riid, obj);
return E_NOTIMPL;
}
static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
{
LPOLESTR rightName;
HRESULT hres;
ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
CHECK_EXPECT(ComposeWith);
hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
ok(!lstrcmpW(rightName, ref_monikerW),
"Expected to get moniker set via SetMonikerReference, instead got: %s\n",
wine_dbgstr_w(rightName));
CoTaskMemFree(rightName);
*composite = NULL;
/* unlikely error code to verify this return result is used */
return E_OUTOFMEMORY;
}
static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
{
*displayName = CoTaskMemAlloc(sizeof(site_monikerW));
memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
return S_OK;
}
static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
{
*displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
return S_OK;
}
static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
DWORD *mksys)
{
return S_FALSE;
}
static IMonikerVtbl hls_site_MonikerVtbl = {
Moniker_QueryInterface,
Moniker_AddRef,
Moniker_Release,
Moniker_GetClassID,
Moniker_IsDirty,
Moniker_Load,
Moniker_Save,
Moniker_GetSizeMax,
Moniker_BindToObject,
hls_test_Moniker_BindToStorage,
Moniker_Reduce,
hls_site_Moniker_ComposeWith,
Moniker_Enum,
Moniker_IsEqual,
Moniker_Hash,
Moniker_IsRunning,
Moniker_GetTimeOfLastChange,
Moniker_Inverse,
Moniker_CommonPrefixWith,
Moniker_RelativePathTo,
hls_site_Moniker_GetDisplayName,
Moniker_ParseDisplayName,
hls_test_Moniker_IsSystemMoniker
};
static IMonikerVtbl hls_ref_MonikerVtbl = {
Moniker_QueryInterface,
Moniker_AddRef,
Moniker_Release,
Moniker_GetClassID,
Moniker_IsDirty,
Moniker_Load,
Moniker_Save,
Moniker_GetSizeMax,
Moniker_BindToObject,
hls_test_Moniker_BindToStorage,
Moniker_Reduce,
Moniker_ComposeWith,
Moniker_Enum,
Moniker_IsEqual,
Moniker_Hash,
Moniker_IsRunning,
Moniker_GetTimeOfLastChange,
Moniker_Inverse,
Moniker_CommonPrefixWith,
Moniker_RelativePathTo,
hls_ref_Moniker_GetDisplayName,
Moniker_ParseDisplayName,
hls_test_Moniker_IsSystemMoniker
};
static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
void **obj)
{
ok(0, "QI: %p %s %p\n", iface, debugstr_guid(iid), obj);
return E_NOTIMPL;
}
static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
{
return 2;
}
static ULONG WINAPI hls_Release(IHlinkSite *iface)
{
return 1;
}
static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
REFGUID service, REFIID riid, IUnknown **punk)
{
ok(0, "QS: %p %x %s %s %p\n", iface, siteData, debugstr_guid(service),
debugstr_guid(riid), punk);
return E_NOTIMPL;
}
static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
DWORD assign, DWORD which, IMoniker **pmk)
{
ok(siteData == 17, "Expected siteData == 17, got: %d\n", siteData);
*pmk = &hls_site_Moniker;
return S_OK;
}
static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
DWORD reserved)
{
ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
return E_NOTIMPL;
}
static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
{
CHECK_EXPECT(OnNavigationComplete);
ok(siteData == 17, "Expected siteData == 17, got: %d\n", siteData);
ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
return E_NOTIMPL;
}
static IHlinkSiteVtbl HlinkSiteVtbl = {
hls_QueryInterface,
hls_AddRef,
hls_Release,
hls_QueryService,
hls_GetMoniker,
hls_ReadyToNavigate,
hls_OnNavigationComplete
};
static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
static void test_HlinkSite(void)
{
IHlink *hl;
IMoniker *mon_ref;
IBindCtx *pbc;
HRESULT hres;
hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
&IID_IHlink, (LPVOID*)&hl);
ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
getMonikerRef(hl, NULL, NULL);
hres = IHlink_SetHlinkSite(hl, &HlinkSite, 17);
ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
getMonikerRef(hl, NULL, NULL);
getStringRef(hl, NULL, NULL);
hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
SET_EXPECT(Reduce);
SET_EXPECT(Enum);
hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
todo_wine CHECK_CALLED(Reduce);
todo_wine CHECK_CALLED(Enum);
getMonikerRef(hl, &hls_ref_Moniker, NULL);
SET_EXPECT(Enum);
getStringRef(hl, ref_monikerW, NULL);
todo_wine CHECK_CALLED(Enum);
hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
IMoniker_Release(mon_ref);
SET_EXPECT(ComposeWith);
hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
CHECK_CALLED(ComposeWith);
hres = CreateBindCtx(0, &pbc);
ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
SET_EXPECT(ComposeWith);
SET_EXPECT(OnNavigationComplete);
hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
CHECK_CALLED(ComposeWith);
CHECK_CALLED(OnNavigationComplete);
IBindCtx_Release(pbc);
IHlink_Release(hl);
SET_EXPECT(Reduce);
SET_EXPECT(Enum);
hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, 17,
NULL, &IID_IHlink, (LPVOID*)&hl);
ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
todo_wine CHECK_CALLED(Reduce);
todo_wine CHECK_CALLED(Enum);
getMonikerRef(hl, &hls_ref_Moniker, NULL);
IHlink_Release(hl);
hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, 17,
NULL, &IID_IHlink, (LPVOID*)&hl);
ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
getMonikerRef(hl, NULL, NULL);
IHlink_Release(hl);
}
START_TEST(hlink)
{
CoInitialize(NULL);
@ -1457,6 +1712,7 @@ START_TEST(hlink)
test_HlinkGetSetStringReference();
test_HlinkMoniker();
test_HashLink();
test_HlinkSite();
CoUninitialize();
}