Andrew Eikum : hlink: Implement HlinkClone.
Alexandre Julliard
julliard at winehq.org
Tue Nov 2 11:10:53 CDT 2010
Module: wine
Branch: master
Commit: 5c5e53ae215abc9a2c0fd63a5ae58c8d4e41926a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5c5e53ae215abc9a2c0fd63a5ae58c8d4e41926a
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Mon Nov 1 12:06:05 2010 -0500
hlink: Implement HlinkClone.
---
dlls/hlink/hlink.spec | 2 +-
dlls/hlink/hlink_main.c | 65 +++++++++++++++++++++++
dlls/hlink/tests/hlink.c | 131 ++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 193 insertions(+), 5 deletions(-)
diff --git a/dlls/hlink/hlink.spec b/dlls/hlink/hlink.spec
index 0cc761f..ca8144e 100644
--- a/dlls/hlink/hlink.spec
+++ b/dlls/hlink/hlink.spec
@@ -2,7 +2,7 @@
4 stdcall HlinkCreateFromString(wstr wstr wstr ptr long ptr ptr ptr)
5 stdcall HlinkCreateFromData(ptr ptr long ptr ptr ptr)
6 stdcall HlinkCreateBrowseContext(ptr ptr ptr)
-7 stub HlinkClone
+7 stdcall HlinkClone(ptr ptr ptr long ptr)
8 stdcall HlinkNavigateToStringReference(wstr wstr ptr long ptr long ptr ptr ptr)
9 stdcall HlinkOnNavigate(ptr ptr long ptr wstr wstr ptr)
10 stdcall HlinkNavigate(ptr ptr long ptr ptr ptr)
diff --git a/dlls/hlink/hlink_main.c b/dlls/hlink/hlink_main.c
index e96f206..cda9683 100644
--- a/dlls/hlink/hlink_main.c
+++ b/dlls/hlink/hlink_main.c
@@ -428,6 +428,71 @@ HRESULT WINAPI HlinkResolveMonikerForData(LPMONIKER pimkReference, DWORD reserve
return IMoniker_BindToStorage(pimkReference, pibc, NULL, &IID_IUnknown, &obj);
}
+/***********************************************************************
+ * HlinkClone (HLINK.@)
+ */
+HRESULT WINAPI HlinkClone(IHlink *hlink, REFIID riid, IHlinkSite *hls,
+ DWORD site_data, void **obj)
+{
+ IMoniker *mk, *clone_mk = NULL;
+ WCHAR *loc, *name = NULL;
+ HRESULT hres;
+
+ if(!hlink || !riid || !obj)
+ return E_INVALIDARG;
+
+ *obj = NULL;
+
+ hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &mk, &loc);
+ if(FAILED(hres))
+ return hres;
+
+ if(mk) {
+ IStream *strm;
+ LARGE_INTEGER lgint;
+
+ hres = CreateStreamOnHGlobal(NULL, TRUE, &strm);
+ if(FAILED(hres)) {
+ IMoniker_Release(mk);
+ goto cleanup;
+ }
+
+ hres = OleSaveToStream((IPersistStream*)mk, strm);
+ if(FAILED(hres)) {
+ IStream_Release(strm);
+ IMoniker_Release(mk);
+ goto cleanup;
+ }
+ IMoniker_Release(mk);
+
+ lgint.QuadPart = 0;
+ hres = IStream_Seek(strm, lgint, STREAM_SEEK_SET, NULL);
+ if(FAILED(hres)) {
+ IStream_Release(strm);
+ goto cleanup;
+ }
+
+ hres = OleLoadFromStream(strm, &IID_IMoniker, (void**)&clone_mk);
+ IStream_Release(strm);
+ if(FAILED(hres))
+ goto cleanup;
+ }
+
+ hres = IHlink_GetFriendlyName(hlink, HLFNAMEF_DEFAULT, &name);
+ if(FAILED(hres))
+ goto cleanup;
+
+ hres = HlinkCreateFromMoniker(clone_mk, loc, name, hls, site_data, NULL,
+ &IID_IHlink, obj);
+
+cleanup:
+ if(clone_mk)
+ IMoniker_Release(clone_mk);
+ CoTaskMemFree(loc);
+ CoTaskMemFree(name);
+ return hres;
+}
+
static HRESULT WINAPI HLinkCF_fnQueryInterface ( LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppvObj)
{
diff --git a/dlls/hlink/tests/hlink.c b/dlls/hlink/tests/hlink.c
index 61b9498..21422bc 100644
--- a/dlls/hlink/tests/hlink.c
+++ b/dlls/hlink/tests/hlink.c
@@ -62,6 +62,9 @@ DEFINE_EXPECT(OnNavigationComplete);
DEFINE_EXPECT(Enum);
DEFINE_EXPECT(Reduce);
+DEFINE_EXPECT(GetClassID);
+DEFINE_EXPECT(Save);
+
static const char *debugstr_guid(REFIID riid)
{
static char buf[50];
@@ -818,8 +821,9 @@ static ULONG WINAPI Moniker_Release(IMoniker *iface)
static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
{
- ok(0, "unexpected call\n");
- return E_NOTIMPL;
+ CHECK_EXPECT(GetClassID);
+ *pClassID = IID_IUnknown; /* not a valid CLSID */
+ return S_OK;
}
static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
@@ -836,8 +840,8 @@ static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
{
- ok(0, "unexpected call\n");
- return E_NOTIMPL;
+ CHECK_EXPECT(Save);
+ return S_OK;
}
static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
@@ -1697,6 +1701,124 @@ static void test_HlinkSite(void)
IHlink_Release(hl);
}
+static void test_HlinkClone(void)
+{
+ HRESULT hres;
+ IHlink *hl, *cloned = NULL;
+ IMoniker *dummy, *fnd_mk;
+ IHlinkSite *fnd_site;
+ WCHAR *fnd_name;
+ DWORD fnd_data;
+ const WCHAR one[] = {'1',0};
+ const WCHAR two[] = {'2',0};
+ const WCHAR name[] = {'a',0};
+
+ hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
+ ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
+
+ hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
+ &IID_IHlink, (void**)&hl);
+ ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
+
+ hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
+ ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
+
+ if(0){ /* crash on Windows XP */
+ hres = HlinkClone(hl, NULL, NULL, 0, NULL);
+ ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
+
+ hres = HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
+ ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
+ }
+
+ hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
+ ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
+ ok(cloned != NULL, "Didn't get a clone\n");
+ getMonikerRef(cloned, NULL, NULL);
+ IHlink_Release(cloned);
+
+ IHlink_Release(hl);
+
+ SET_EXPECT(Reduce);
+ SET_EXPECT(Enum);
+ hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
+ todo_wine CHECK_CALLED(Reduce);
+ todo_wine CHECK_CALLED(Enum);
+ ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
+ getMonikerRef(hl, &hls_ref_Moniker, two);
+
+ SET_EXPECT(Save);
+ SET_EXPECT(GetClassID);
+ cloned = (IHlink*)0xdeadbeef;
+ hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
+ /* fails because of invalid CLSID given by Moniker_GetClassID */
+ ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08x\n", hres);
+ ok(cloned == NULL, "Shouldn't have gotten a clone\n");
+ CHECK_CALLED(Save);
+ CHECK_CALLED(GetClassID);
+
+ IHlink_Release(hl);
+
+ hres = CreateItemMoniker(one, one, &dummy);
+ ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
+
+ hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, 17, NULL, &IID_IHlink, (void**)&hl);
+ ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
+ getMonikerRef(hl, dummy, two);
+
+ cloned = NULL;
+ hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
+ ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
+ ok(cloned != NULL, "Should have gotten a clone\n");
+
+ fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two);
+ ok(fnd_mk != NULL, "Expected non-null Moniker\n");
+ ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
+
+ fnd_name = NULL;
+ hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
+ ok(hres == S_OK, "GetFriendlyName failed: %08x\n", hres);
+ ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
+ ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
+ wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
+ CoTaskMemFree(fnd_name);
+
+ fnd_site = (IHlinkSite*)0xdeadbeef;
+ fnd_data = 4;
+ hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
+ ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
+ ok(fnd_site == NULL, "Expected NULL site\n");
+ todo_wine ok(fnd_data == 4, "Expected site data to be 4, was: %d\n", fnd_data);
+
+ IHlink_Release(cloned);
+ IHlink_Release(hl);
+
+ hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
+ ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
+ getMonikerRef(hl, dummy, NULL);
+
+ cloned = NULL;
+ hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, 17, (void**)&cloned);
+ ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
+ ok(cloned != NULL, "Should have gotten a clone\n");
+
+ fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL);
+ ok(fnd_mk != NULL, "Expected non-null Moniker\n");
+ ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
+
+ fnd_site = (IHlinkSite*)0xdeadbeef;
+ fnd_data = 4;
+ hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
+ ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
+ ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
+ ok(fnd_data == 17, "Expected site data to be 17, was: %d\n", fnd_data);
+
+ IHlink_Release(cloned);
+ IHlink_Release(hl);
+
+ IMoniker_Release(dummy);
+}
+
START_TEST(hlink)
{
CoInitialize(NULL);
@@ -1713,6 +1835,7 @@ START_TEST(hlink)
test_HlinkMoniker();
test_HashLink();
test_HlinkSite();
+ test_HlinkClone();
CoUninitialize();
}
More information about the wine-cvs
mailing list