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)
- {
- *moniker = This->Moniker;
- if (*moniker)
- IMoniker_AddRef(*moniker);
- }
- else if (This->Site)
+ HRESULT hres;
+
+ if (ref_type == HLINKGETREF_DEFAULT)
+ ref_type = HLINKGETREF_RELATIVE;
+
+ if (ref_type == HLINKGETREF_ABSOLUTE && 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,
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);
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)
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;
else
{
IMoniker *moniker;
- __GetMoniker(This, &moniker);
+ HRESULT hres = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
+ if (FAILED(hres))
+ {
+ *ppwzFriendlyName = NULL;
+ return hres;
+ }
if (moniker)
{
IBindCtx *bcxt;
{
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);
}
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,
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;
static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
ULARGE_INTEGER* pcbSize)
{
- HRESULT r = E_FAIL;
+ HRESULT r;
HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
IMoniker *moniker;
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;
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];
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;
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));
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));
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));
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,
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));
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;
}
static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
{
- ok(0, "unexpected call\n");
+ CHECK_EXPECT(Enum);
return E_NOTIMPL;
}
}
}
+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);
test_HlinkGetSetStringReference();
test_HlinkMoniker();
test_HashLink();
+ test_HlinkSite();
CoUninitialize();
}