include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / hlink / tests / hlink.c
blob3c2e8ebf4551985b59d5250ac8295fc7b11165d0
1 /*
2 * Implementation of hyperlinking (hlink.dll)
4 * Copyright 2006 Mike McCormack
5 * Copyright 2007-2008 Jacek Caban for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include <stdio.h>
26 #include <initguid.h>
27 #include <hlink.h>
28 #include <hlguids.h>
30 #include "wine/test.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT2(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
42 }while(0)
44 #define CHECK_EXPECT(func) \
45 do { \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
48 }while(0)
50 #define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
54 }while(0)
56 DEFINE_EXPECT(IsSystemMoniker);
57 DEFINE_EXPECT(BindToStorage);
58 DEFINE_EXPECT(BindToObject);
59 DEFINE_EXPECT(GetDisplayName);
61 DEFINE_EXPECT(ComposeWith);
62 DEFINE_EXPECT(OnNavigationComplete);
63 DEFINE_EXPECT(Enum);
64 DEFINE_EXPECT(Reduce);
66 DEFINE_EXPECT(GetClassID);
67 DEFINE_EXPECT(Save);
69 DEFINE_EXPECT(HBC_QueryInterface_IHlinkHistory);
70 DEFINE_EXPECT(HBC_QueryInterface_IMarshal);
71 DEFINE_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
72 DEFINE_EXPECT(HBC_QueryInterface_IUnknown);
73 DEFINE_EXPECT(HBC_GetObject);
74 DEFINE_EXPECT(HBC_UpdateHlink);
76 DEFINE_EXPECT(HT_QueryInterface_IHlinkTarget);
77 DEFINE_EXPECT(HT_SetBrowseContext);
78 DEFINE_EXPECT(HT_GetBrowseContext);
79 DEFINE_EXPECT(HT_Navigate);
80 DEFINE_EXPECT(HT_GetFriendlyName);
82 DEFINE_EXPECT(HLF_UpdateHlink);
84 DEFINE_EXPECT(BindStatusCallback_GetBindInfo);
85 DEFINE_EXPECT(BindStatusCallback_OnObjectAvailable);
86 DEFINE_EXPECT(BindStatusCallback_OnStartBinding);
87 DEFINE_EXPECT(BindStatusCallback_OnStopBinding);
89 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
90 DEFINE_GUID(IID_IHlinkHistory,0x79eac9c8,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b);
92 static IHlinkTarget HlinkTarget;
94 static const WCHAR winehq_urlW[] =
95 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
96 '/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
97 static const WCHAR winehq_404W[] =
98 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
99 '/','t','e','s','t','s','/','f','a','k','e','u','r','l',0};
101 static void test_HlinkIsShortcut(void)
103 UINT i;
104 HRESULT hres;
106 static const WCHAR file0[] = {'f','i','l','e',0};
107 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
108 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
109 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
110 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
111 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
112 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
113 static const WCHAR file7[] = {'.','u','r','l',0};
115 static struct {
116 LPCWSTR file;
117 HRESULT hres;
118 } shortcut_test[] = {
119 {file0, S_FALSE},
120 {file1, S_OK},
121 {file2, S_FALSE},
122 {file3, S_OK},
123 {file4, S_FALSE},
124 {file5, S_OK},
125 {file6, S_FALSE},
126 {file7, S_OK},
127 {NULL, E_INVALIDARG}
130 for (i=0; i < ARRAY_SIZE(shortcut_test); i++) {
131 hres = HlinkIsShortcut(shortcut_test[i].file);
132 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08lx, expected %08lx\n",
133 i, hres, shortcut_test[i].hres);
137 static void test_reference(void)
139 HRESULT r;
140 IHlink *lnk = NULL;
141 IMoniker *mk = NULL;
142 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
143 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
144 LPWSTR str = NULL;
146 r = HlinkCreateFromString(url, NULL, NULL, NULL,
147 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
148 ok(r == S_OK, "failed to create link\n");
149 if (FAILED(r))
150 return;
152 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
153 ok(r == S_OK, "failed\n");
155 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
156 ok(r == S_OK, "failed\n");
157 ok(mk != NULL, "no moniker\n");
158 ok(str == NULL, "string should be null\n");
160 r = IMoniker_Release(mk);
161 ok( r == 1, "moniker refcount wrong\n");
163 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
164 ok(r == S_OK, "failed\n");
165 CoTaskMemFree(str);
167 r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
168 ok(r == S_OK, "failed, r=%08lx\n", r);
170 r = IHlink_GetStringReference(lnk, -1, NULL, &str);
171 ok(r == S_OK, "failed, r=%08lx\n", r);
172 ok(str == NULL, "string should be null\n");
174 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
175 ok(r == S_OK, "failed\n");
176 ok(!lstrcmpW(str, url2), "url wrong\n");
177 CoTaskMemFree(str);
179 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
180 ok(r == S_OK, "failed\n");
182 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
183 ok(r == S_OK, "failed\n");
184 ok(str == NULL, "string should be null\n");
186 /* Unimplemented functions checks */
187 r = IHlink_GetAdditionalParams(lnk, NULL);
188 ok(r == E_NOTIMPL, "failed\n");
190 r = IHlink_SetAdditionalParams(lnk, NULL);
191 ok(r == E_NOTIMPL, "failed\n");
193 IHlink_Release(lnk);
196 /* url only */
197 static const unsigned char expected_hlink_data[] =
199 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
200 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
201 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
202 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
203 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
204 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
205 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
206 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
207 0x00,0x00,
210 /* url only (IE7) */
211 static const unsigned char expected_hlink_data_ie7[] =
213 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
214 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
215 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
216 0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
217 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
218 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
219 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
220 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
221 0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
222 0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
223 0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
224 0x00,0x00,
227 /* url + friendly name */
228 static const unsigned char expected_hlink_data2[] =
230 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
231 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
232 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
233 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
234 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
235 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
236 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
237 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
238 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
239 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
240 0x67,0x00,0x2f,0x00,0x00,0x00,
243 /* url + friendly name (IE7) */
244 static const unsigned char expected_hlink_data2_ie7[] =
246 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
247 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
248 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
249 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
250 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
251 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
252 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
253 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
254 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
255 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
256 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
257 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
258 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
259 0x00,0x00,0xa5,0xab,0x00,0x00,
262 /* url + friendly name + location */
263 static const unsigned char expected_hlink_data3[] =
265 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
266 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
267 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
268 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
269 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
270 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
271 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
272 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
273 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
274 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
275 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
276 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
277 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
280 /* url + friendly name + location (IE7) */
281 static const unsigned char expected_hlink_data3_ie7[] =
283 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
284 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
285 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
286 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
287 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
288 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
289 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
290 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
291 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
292 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
293 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
294 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
295 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
296 0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
297 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
298 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
301 /* relative url */
302 static const unsigned char expected_hlink_data4[] =
304 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
305 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
306 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
307 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
308 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
309 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
310 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
311 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
312 0x00,0x00,0x00,0x00,0x00,
315 /* url + target frame name */
316 static const unsigned char expected_hlink_data5[] =
318 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
319 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
320 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
321 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
322 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
323 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
324 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
325 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
326 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
327 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
328 0x2f,0x00,0x00,0x00,
331 /* url + target frame name (IE7) */
332 static const unsigned char expected_hlink_data5_ie7[] =
334 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
335 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
336 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
337 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
338 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
339 0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
340 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
341 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
342 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
343 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
344 0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
345 0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
346 0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
347 0xa5,0xab,0x00,0x00,
350 /* filename */
351 static const unsigned char expected_hlink_data6[] =
353 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
354 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
355 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
356 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
357 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
358 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
359 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
360 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
361 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
362 0x5c,0x00,
365 static void test_persist_save_data(const char *testname, IHlink *lnk,
366 const unsigned char *expected_data,
367 unsigned int expected_data_size,
368 const unsigned char *expected_data_alt,
369 unsigned int expected_data_alt_size)
371 HRESULT hr;
372 IStream *stream;
373 IPersistStream *ps;
374 HGLOBAL hglobal;
375 DWORD data_size;
376 const unsigned char *data;
377 DWORD i;
378 BOOL same;
380 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
381 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08lx\n", hr);
383 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
384 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08lx\n", hr);
386 hr = IPersistStream_Save(ps, stream, TRUE);
387 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08lx\n", hr);
389 hr = GetHGlobalFromStream(stream, &hglobal);
390 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08lx\n", hr);
392 data_size = GlobalSize(hglobal);
394 data = GlobalLock(hglobal);
396 /* first check we have the right amount of data */
397 ok((data_size == expected_data_size) ||
398 (data_size == expected_data_alt_size),
399 "%s: Size of saved data differs (expected %d or %d, actual %ld)\n",
400 testname, expected_data_size, expected_data_alt_size, data_size);
402 same = TRUE;
403 /* then do a byte-by-byte comparison */
404 for (i = 0; i < min(data_size, expected_data_size); i++)
406 if ((expected_data[i] != data[i]) &&
407 (((expected_data != expected_hlink_data2) &&
408 (expected_data != expected_hlink_data3)) ||
409 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
411 same = FALSE;
412 break;
416 if (!same && (expected_data_alt != expected_data))
418 /* then try the alternate data */
419 same = TRUE;
420 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
422 if ((expected_data_alt == expected_hlink_data_ie7 && i == 89) /* Win10 */ ||
423 (expected_data_alt == expected_hlink_data2_ie7 && i == 109) /* Win10 */ ||
424 (expected_data_alt == expected_hlink_data3_ie7 && i == 109) /* Win10 */ ||
425 (expected_data_alt == expected_hlink_data5_ie7 && i == 107) /* Win10 */)
427 ok(data[i] == 0 || broken(data[i] == 1) || broken(data[i] == 3),
428 "Expected 0 or 1, got %d\n", data[i]);
429 continue;
431 if ((expected_data_alt[i] != data[i]) &&
432 (((expected_data_alt != expected_hlink_data2) &&
433 (expected_data_alt != expected_hlink_data3)) ||
434 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
436 same = FALSE;
437 break;
442 ok(same, "%s: Saved data differs\n", testname);
443 if (!same)
445 for (i = 0; i < data_size; i++)
447 if (i % 8 == 0) printf(" ");
448 printf("0x%02x,", data[i]);
449 if (i % 8 == 7) printf("\n");
451 printf("\n");
454 GlobalUnlock(hglobal);
456 IStream_Release(stream);
457 IPersistStream_Release(ps);
460 static void test_persist(void)
462 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
463 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
464 static const WCHAR filename[] = { 'c',':','\\',0 };
465 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
466 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
467 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
468 HRESULT hr;
469 IHlink *lnk;
471 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
472 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
473 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08lx\n", hr);
474 if (!lnk) {
475 skip("Can't create lnk, skipping test_persist.\n");
476 return;
478 test_persist_save_data("url only", lnk,
479 expected_hlink_data, sizeof(expected_hlink_data),
480 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
481 IHlink_Release(lnk);
483 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
484 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
485 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08lx\n", hr);
486 test_persist_save_data("url + friendly name", lnk,
487 expected_hlink_data2, sizeof(expected_hlink_data2),
488 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
489 IHlink_Release(lnk);
491 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
492 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
493 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08lx\n", hr);
494 test_persist_save_data("url + friendly_name + location", lnk,
495 expected_hlink_data3, sizeof(expected_hlink_data3),
496 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
497 IHlink_Release(lnk);
499 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
500 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
501 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08lx\n", hr);
502 test_persist_save_data("relative url", lnk,
503 expected_hlink_data4, sizeof(expected_hlink_data4),
504 expected_hlink_data4, sizeof(expected_hlink_data4));
505 IHlink_Release(lnk);
507 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
508 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
509 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08lx\n", hr);
510 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
511 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08lx\n", hr);
512 test_persist_save_data("url + target frame name", lnk,
513 expected_hlink_data5, sizeof(expected_hlink_data5),
514 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
515 IHlink_Release(lnk);
517 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
518 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
519 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08lx\n", hr);
520 test_persist_save_data("filename", lnk,
521 expected_hlink_data6, sizeof(expected_hlink_data6),
522 expected_hlink_data6, sizeof(expected_hlink_data6));
523 IHlink_Release(lnk);
526 static void test_special_reference(void)
528 LPWSTR ref;
529 HRESULT hres;
531 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
532 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08lx\n", hres);
533 ok(ref != NULL, "ref == NULL\n");
534 CoTaskMemFree(ref);
536 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
537 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08lx\n", hres);
538 ok(ref != NULL, "ref == NULL\n");
539 CoTaskMemFree(ref);
541 ref = (void*)0xdeadbeef;
542 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
543 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08lx\n", hres);
544 ok(ref == NULL, "ref=%p\n", ref);
546 ref = (void*)0xdeadbeef;
547 hres = HlinkGetSpecialReference(4, &ref);
548 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08lx\n", hres);
549 ok(ref == NULL, "ref=%p\n", ref);
552 static void test_HlinkCreateExtensionServices(void)
554 IAuthenticate *authenticate;
555 IHttpNegotiate *http_negotiate;
556 LPWSTR password, username, headers;
557 HWND hwnd;
558 HRESULT hres;
560 static const WCHAR usernameW[] = {'u','s','e','r',0};
561 static const WCHAR passwordW[] = {'p','a','s','s',0};
562 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
563 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
565 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
566 NULL, &IID_IAuthenticate, (void**)&authenticate);
567 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08lx\n", hres);
568 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
570 password = username = (void*)0xdeadbeef;
571 hwnd = (void*)0xdeadbeef;
572 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
573 ok(hres == S_OK, "Authenticate failed: %08lx\n", hres);
574 ok(!hwnd, "hwnd != NULL\n");
575 ok(!username, "username != NULL\n");
576 ok(!password, "password != NULL\n");
578 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
579 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08lx\n", hres);
581 headers = (void*)0xdeadbeef;
582 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
583 0, &headers);
584 ok(hres == S_OK, "BeginningTransaction failed: %08lx\n", hres);
585 ok(headers == NULL, "headers != NULL\n");
587 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
588 0, NULL);
589 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08lx, expected E_INVALIDARG\n", hres);
591 headers = (void*)0xdeadbeef;
592 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
593 ok(hres == S_OK, "OnResponse failed: %08lx\n", hres);
594 ok(headers == NULL, "headers != NULL\n");
596 IHttpNegotiate_Release(http_negotiate);
597 IAuthenticate_Release(authenticate);
600 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
601 NULL, &IID_IAuthenticate, (void**)&authenticate);
602 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08lx\n", hres);
603 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
605 password = username = NULL;
606 hwnd = NULL;
607 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
608 ok(hres == S_OK, "Authenticate failed: %08lx\n", hres);
609 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
610 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
611 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
612 CoTaskMemFree(username);
613 CoTaskMemFree(password);
615 password = username = (void*)0xdeadbeef;
616 hwnd = (void*)0xdeadbeef;
617 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
618 ok(hres == E_INVALIDARG, "Authenticate failed: %08lx\n", hres);
619 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
620 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
622 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
623 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08lx\n", hres);
625 headers = (void*)0xdeadbeef;
626 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
627 0, &headers);
628 ok(hres == S_OK, "BeginningTransaction failed: %08lx\n", hres);
629 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
630 CoTaskMemFree(headers);
632 headers = (void*)0xdeadbeef;
633 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
634 ok(hres == S_OK, "OnResponse failed: %08lx\n", hres);
635 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
637 IHttpNegotiate_Release(http_negotiate);
638 IAuthenticate_Release(authenticate);
641 static void test_HlinkParseDisplayName(void)
643 IMoniker *mon = NULL;
644 LPWSTR name;
645 DWORD issys;
646 ULONG eaten = 0;
647 IBindCtx *bctx;
648 HRESULT hres;
650 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
651 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
652 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
653 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
654 static const WCHAR file_urlW[] =
655 {'f','i','l','e',':','/','/','/','c',':','\\','f','i','l','e','.','t','x','t',0};
657 CreateBindCtx(0, &bctx);
659 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
660 ok(hres == S_OK, "HlinkParseDisplayName failed: %08lx\n", hres);
661 ok(eaten == ARRAY_SIZE(winehq_urlW)-1, "eaten=%ld\n", eaten);
662 ok(mon != NULL, "mon == NULL\n");
664 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
665 ok(hres == S_OK, "GetDisplayName failed: %08lx\n", hres);
666 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
667 CoTaskMemFree(name);
669 hres = IMoniker_IsSystemMoniker(mon, &issys);
670 ok(hres == S_OK, "IsSystemMoniker failed: %08lx\n", hres);
671 ok(issys == MKSYS_URLMONIKER, "issys=%lx\n", issys);
673 IMoniker_Release(mon);
675 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
676 ok(hres == S_OK, "HlinkParseDisplayName failed: %08lx\n", hres);
677 ok(eaten == ARRAY_SIZE(clsid_nameW)-1, "eaten=%ld\n", eaten);
678 ok(mon != NULL, "mon == NULL\n");
680 hres = IMoniker_IsSystemMoniker(mon, &issys);
681 ok(hres == S_OK, "IsSystemMoniker failed: %08lx\n", hres);
682 ok(issys == MKSYS_CLASSMONIKER, "issys=%lx\n", issys);
684 IMoniker_Release(mon);
686 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
687 ok(hres == S_OK, "HlinkParseDisplayName failed: %08lx\n", hres);
688 ok(eaten == ARRAY_SIZE(invalid_urlW)-1, "eaten=%ld\n", eaten);
689 ok(mon != NULL, "mon == NULL\n");
691 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
692 ok(hres == S_OK, "GetDisplayName failed: %08lx\n", hres);
693 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
694 CoTaskMemFree(name);
696 hres = IMoniker_IsSystemMoniker(mon, &issys);
697 ok(hres == S_OK, "IsSystemMoniker failed: %08lx\n", hres);
698 ok(issys == MKSYS_FILEMONIKER, "issys=%lx\n", issys);
700 IMoniker_Release(mon);
702 hres = HlinkParseDisplayName(bctx, file_urlW, FALSE, &eaten, &mon);
703 ok(hres == S_OK, "HlinkParseDisplayName failed: %08lx\n", hres);
704 ok(eaten == ARRAY_SIZE(file_urlW)-1, "eaten=%ld\n", eaten);
705 ok(mon != NULL, "mon == NULL\n");
707 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
708 ok(hres == S_OK, "GetDisplayName failed: %08lx\n", hres);
709 ok(!lstrcmpW(name, file_urlW+8), "wrong display name %s\n", wine_dbgstr_w(name));
710 CoTaskMemFree(name);
712 hres = IMoniker_IsSystemMoniker(mon, &issys);
713 ok(hres == S_OK, "IsSystemMoniker failed: %08lx\n", hres);
714 ok(issys == MKSYS_FILEMONIKER, "issys=%lx\n", issys);
716 IMoniker_Release(mon);
717 IBindCtx_Release(bctx);
720 static IBindCtx *_bctx;
722 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
724 ok(0, "unexpected call\n");
725 return E_NOINTERFACE;
728 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
730 return 2;
733 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
735 return 1;
738 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
739 REFGUID guidService, REFIID riid, void **ppv)
741 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
742 return E_NOINTERFACE;
745 static IServiceProviderVtbl ServiceProviderVtbl = {
746 ServiceProvider_QueryInterface,
747 ServiceProvider_AddRef,
748 ServiceProvider_Release,
749 ServiceProvider_QueryService
752 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
754 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
756 *ppv = NULL;
758 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
759 *ppv = &ServiceProvider;
760 return S_OK;
763 ok(0, "unexpected interface %s\n", wine_dbgstr_guid(riid));
764 return E_NOINTERFACE;
767 static LONG bind_callback_refs = 1;
769 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
771 return ++bind_callback_refs;
774 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
776 return --bind_callback_refs;
779 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
780 DWORD reserved, IBinding *binding)
782 CHECK_EXPECT(BindStatusCallback_OnStartBinding);
784 ok(!binding, "binding = %p\n", binding);
785 return S_OK;
788 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
790 ok(0, "unexpected call\n");
791 return E_NOTIMPL;
794 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
796 ok(0, "unexpected call\n");
797 return E_NOTIMPL;
800 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
801 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
803 ok(0, "unexpected call\n");
804 return E_NOTIMPL;
807 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hr, const WCHAR *error)
809 CHECK_EXPECT(BindStatusCallback_OnStopBinding);
811 ok(hr == S_OK, "got hr %#lx\n", hr);
812 ok(!error, "got error %s\n", wine_dbgstr_w(error));
814 return 0xdeadbeef;
817 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *bind_flags, BINDINFO *bind_info)
819 CHECK_EXPECT(BindStatusCallback_GetBindInfo);
821 return E_NOTIMPL;
824 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
825 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
827 ok(0, "unexpected call\n");
828 return E_NOTIMPL;
831 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID iid, IUnknown *out)
833 CHECK_EXPECT(BindStatusCallback_OnObjectAvailable);
835 ok(IsEqualGUID(iid, &IID_IUnknown), "iid = %s\n", wine_dbgstr_guid(iid));
836 ok(out == (IUnknown *)&HlinkTarget, "out = %p\n", out);
838 return 0xdeadbeef;
841 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
842 BindStatusCallback_QueryInterface,
843 BindStatusCallback_AddRef,
844 BindStatusCallback_Release,
845 BindStatusCallback_OnStartBinding,
846 BindStatusCallback_GetPriority,
847 BindStatusCallback_OnLowResource,
848 BindStatusCallback_OnProgress,
849 BindStatusCallback_OnStopBinding,
850 BindStatusCallback_GetBindInfo,
851 BindStatusCallback_OnDataAvailable,
852 BindStatusCallback_OnObjectAvailable
855 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
857 static HRESULT WINAPI HlinkBrowseContext_QueryInterface(
858 IHlinkBrowseContext *iface, REFIID riid, void **ppv)
860 *ppv = NULL;
862 if (IsEqualGUID(&IID_IHlinkHistory, riid))
863 CHECK_EXPECT(HBC_QueryInterface_IHlinkHistory);
864 else if (IsEqualGUID(&IID_IMarshal, riid))
865 CHECK_EXPECT2(HBC_QueryInterface_IMarshal);
866 else if (IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
867 CHECK_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
868 else if (IsEqualGUID(&IID_IUnknown, riid))
869 CHECK_EXPECT(HBC_QueryInterface_IUnknown);
870 else
871 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
873 return E_NOINTERFACE;
876 static LONG browse_ctx_refs = 1;
878 static ULONG WINAPI HlinkBrowseContext_AddRef(IHlinkBrowseContext *iface)
880 return ++browse_ctx_refs;
883 static ULONG WINAPI HlinkBrowseContext_Release(IHlinkBrowseContext *iface)
885 return --browse_ctx_refs;
888 static HRESULT WINAPI HlinkBrowseContext_Register(IHlinkBrowseContext *iface,
889 DWORD reserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister)
891 ok(0, "unexpected call\n");
892 return E_NOTIMPL;
895 static IUnknown *HBC_object;
897 static IMoniker Moniker;
898 static HRESULT WINAPI HlinkBrowseContext_GetObject(IHlinkBrowseContext *iface,
899 IMoniker *pimk, BOOL fBindIfRootRegistered, IUnknown **ppiunk)
901 IBindCtx *bctx;
902 WCHAR *name;
903 HRESULT hr;
905 CHECK_EXPECT(HBC_GetObject);
907 CreateBindCtx(0, &bctx);
908 hr = IMoniker_GetDisplayName(pimk, bctx, NULL, &name);
909 ok(hr == S_OK, "Failed to get display name, hr %#lx.\n", hr);
910 ok(!lstrcmpW(winehq_urlW, name) || !lstrcmpW(winehq_404W, name), "got unexpected url\n");
911 CoTaskMemFree(name);
912 IBindCtx_Release(bctx);
914 ok(fBindIfRootRegistered == 1, "fBindIfRootRegistered = %x\n", fBindIfRootRegistered);
916 *ppiunk = HBC_object;
917 return HBC_object ? S_OK : 0xdeadbeef;
920 static HRESULT WINAPI HlinkBrowseContext_Revoke(IHlinkBrowseContext *iface, DWORD dwRegister)
922 ok(0, "unexpected call\n");
923 return E_NOTIMPL;
926 static HRESULT WINAPI HlinkBrowseContext_SetBrowseWindowInfo(
927 IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
929 ok(0, "unexpected call\n");
930 return E_NOTIMPL;
933 static HRESULT WINAPI HlinkBrowseContext_GetBrowseWindowInfo(
934 IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
936 ok(0, "unexpected call\n");
937 return E_NOTIMPL;
940 static HRESULT WINAPI HlinkBrowseContext_SetInitialHlink(IHlinkBrowseContext *iface,
941 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
943 ok(0, "unexpected call\n");
944 return E_NOTIMPL;
947 static HRESULT WINAPI HlinkBrowseContext_OnNavigateHlink(IHlinkBrowseContext *iface, DWORD grfHLNF,
948 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, ULONG *puHLID)
950 ok(0, "unexpected call\n");
951 return E_NOTIMPL;
954 static HRESULT WINAPI HlinkBrowseContext_UpdateHlink(IHlinkBrowseContext *iface, ULONG uHLID,
955 IMoniker *pimkTarget, LPCWSTR location, LPCWSTR friendly_name)
957 CHECK_EXPECT(HBC_UpdateHlink);
958 return S_OK;
961 static HRESULT WINAPI HlinkBrowseContext_EnumNavigationStack(IHlinkBrowseContext *iface,
962 DWORD dwReserved, DWORD grfHLFNAMEF, IEnumHLITEM **ppienumhlitem)
964 ok(0, "unexpected call\n");
965 return E_NOTIMPL;
968 static HRESULT WINAPI HlinkBrowseContext_QueryHlink(IHlinkBrowseContext *iface,
969 DWORD grfHLQF, ULONG uHLID)
971 ok(0, "unexpected call\n");
972 return E_NOTIMPL;
975 static HRESULT WINAPI HlinkBrowseContext_GetHlink(IHlinkBrowseContext *iface,
976 ULONG uHLID, IHlink **ppihl)
978 ok(0, "unexpected call\n");
979 return E_NOTIMPL;
982 static HRESULT WINAPI HlinkBrowseContext_SetCurrentHlink(
983 IHlinkBrowseContext *iface, ULONG uHLID)
985 ok(0, "unexpected call\n");
986 return E_NOTIMPL;
989 static HRESULT WINAPI HlinkBrowseContext_Clone(IHlinkBrowseContext *iface,
990 IUnknown *piunkOuter, REFIID riid, IUnknown **ppiunkObj)
992 ok(0, "unexpected call\n");
993 return E_NOTIMPL;
996 static HRESULT WINAPI HlinkBrowseContext_Close(IHlinkBrowseContext *iface, DWORD reserved)
998 ok(0, "unexpected call\n");
999 return E_NOTIMPL;
1002 static IHlinkBrowseContextVtbl HlinkBrowseContextVtbl = {
1003 HlinkBrowseContext_QueryInterface,
1004 HlinkBrowseContext_AddRef,
1005 HlinkBrowseContext_Release,
1006 HlinkBrowseContext_Register,
1007 HlinkBrowseContext_GetObject,
1008 HlinkBrowseContext_Revoke,
1009 HlinkBrowseContext_SetBrowseWindowInfo,
1010 HlinkBrowseContext_GetBrowseWindowInfo,
1011 HlinkBrowseContext_SetInitialHlink,
1012 HlinkBrowseContext_OnNavigateHlink,
1013 HlinkBrowseContext_UpdateHlink,
1014 HlinkBrowseContext_EnumNavigationStack,
1015 HlinkBrowseContext_QueryHlink,
1016 HlinkBrowseContext_GetHlink,
1017 HlinkBrowseContext_SetCurrentHlink,
1018 HlinkBrowseContext_Clone,
1019 HlinkBrowseContext_Close
1022 static IHlinkBrowseContext HlinkBrowseContext = { &HlinkBrowseContextVtbl };
1024 static HRESULT WINAPI HlinkTarget_QueryInterface(IHlinkTarget *iface, REFIID riid, void **ppv)
1026 if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
1027 CHECK_EXPECT(HT_QueryInterface_IHlinkTarget);
1028 *ppv = iface;
1029 return S_OK;
1032 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
1033 return E_NOINTERFACE;
1036 static ULONG WINAPI HlinkTarget_AddRef(IHlinkTarget *iface)
1038 return 2;
1041 static ULONG WINAPI HlinkTarget_Release(IHlinkTarget *iface)
1043 return 1;
1046 static HRESULT WINAPI HlinkTarget_SetBrowseContext(IHlinkTarget *iface,
1047 IHlinkBrowseContext *pihlbc)
1049 CHECK_EXPECT(HT_SetBrowseContext);
1051 ok(pihlbc == &HlinkBrowseContext, "pihlbc != &HlinkBrowseContext (%p)\n", pihlbc);
1052 return S_OK;
1055 static HRESULT WINAPI HlinkTarget_GetBrowseContext(IHlinkTarget *iface,
1056 IHlinkBrowseContext **ppihlbc)
1058 CHECK_EXPECT(HT_GetBrowseContext);
1060 *ppihlbc = NULL;
1061 return S_OK;
1064 static HRESULT WINAPI HlinkTarget_Navigate(IHlinkTarget *iface,
1065 DWORD grfHLNF, LPCWSTR pwzJumpLocation)
1067 CHECK_EXPECT(HT_Navigate);
1069 ok(grfHLNF == 0, "grfHLNF = %lx\n", grfHLNF);
1070 ok(pwzJumpLocation == NULL, "pwzJumpLocation = %s\n", wine_dbgstr_w(pwzJumpLocation));
1071 return S_OK;
1074 static HRESULT WINAPI HlinkTarget_GetMoniker(IHlinkTarget *iface,
1075 LPCWSTR pwzLocation, DWORD dwAssign, IMoniker **ppimkLocation)
1077 ok(0, "unexpected call\n");
1078 return E_NOTIMPL;
1081 static HRESULT WINAPI HlinkTarget_GetFriendlyName(IHlinkTarget *iface,
1082 LPCWSTR pwzLocation, LPWSTR *ppwzFriendlyName)
1084 CHECK_EXPECT(HT_GetFriendlyName);
1085 return E_NOTIMPL;
1088 static IHlinkTargetVtbl HlinkTargetVtbl = {
1089 HlinkTarget_QueryInterface,
1090 HlinkTarget_AddRef,
1091 HlinkTarget_Release,
1092 HlinkTarget_SetBrowseContext,
1093 HlinkTarget_GetBrowseContext,
1094 HlinkTarget_Navigate,
1095 HlinkTarget_GetMoniker,
1096 HlinkTarget_GetFriendlyName
1099 static IHlinkTarget HlinkTarget = { &HlinkTargetVtbl };
1101 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
1103 *ppv = NULL;
1105 ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid));
1106 return E_NOINTERFACE;
1109 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
1111 return 2;
1114 static ULONG WINAPI Moniker_Release(IMoniker *iface)
1116 return 1;
1119 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
1121 CHECK_EXPECT(GetClassID);
1122 *pClassID = IID_IUnknown; /* not a valid CLSID */
1123 return S_OK;
1126 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
1128 ok(0, "unexpected call\n");
1129 return E_NOTIMPL;
1132 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
1134 ok(0, "unexpected call\n");
1135 return E_NOTIMPL;
1138 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
1140 CHECK_EXPECT(Save);
1141 return S_OK;
1144 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
1146 ok(0, "unexpected call\n");
1147 return E_NOTIMPL;
1150 static BOOL async_bind;
1151 static IBindStatusCallback *async_bind_callback;
1153 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1154 REFIID riid, void **ppv)
1156 static WCHAR bscb_holderW[] = {'_','B','S','C','B','_','H','o','l','d','e','r','_',0};
1157 IUnknown *bind_callback_holder;
1158 HRESULT hr;
1160 CHECK_EXPECT(BindToObject);
1162 ok(pbc != _bctx, "pbc != _bctx\n");
1163 ok(pmkToLeft == NULL, "pmkToLeft = %p\n", pmkToLeft);
1164 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1165 ok(ppv != NULL, "ppv == NULL\n");
1166 ok(*ppv == NULL, "*ppv = %p\n", *ppv);
1168 if (async_bind)
1170 hr = IBindCtx_GetObjectParam(pbc, bscb_holderW, &bind_callback_holder);
1171 ok(hr == S_OK, "Failed to get IBindStatusCallback holder, hr %#lx.\n", hr);
1172 hr = IUnknown_QueryInterface(bind_callback_holder, &IID_IBindStatusCallback,
1173 (void **)&async_bind_callback);
1174 ok(hr == S_OK, "Failed to get IBindStatusCallback interface, hr %#lx.\n", hr);
1175 IUnknown_Release(bind_callback_holder);
1176 return MK_S_ASYNCHRONOUS;
1179 *ppv = &HlinkTarget;
1180 return S_OK;
1183 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1184 REFIID riid, void **ppv)
1186 IUnknown *unk;
1187 HRESULT hres;
1189 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
1191 CHECK_EXPECT(BindToStorage);
1193 ok(pbc == _bctx, "pbc != _bctx\n");
1194 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1195 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1196 ok(ppv != NULL, "ppv == NULL\n");
1197 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
1199 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
1200 ok(hres == S_OK, "GetObjectParam failed: %08lx\n", hres);
1201 ok(unk != NULL, "unk == NULL\n");
1203 IUnknown_Release(unk);
1205 return S_OK;
1208 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
1209 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
1211 CHECK_EXPECT(Reduce);
1212 return E_NOTIMPL;
1215 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
1216 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
1218 ok(0, "unexpected call\n");
1219 return E_NOTIMPL;
1222 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
1224 CHECK_EXPECT(Enum);
1225 return E_NOTIMPL;
1228 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
1230 ok(0, "unexpected call\n");
1231 return E_NOTIMPL;
1234 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
1236 ok(0, "unexpected call\n");
1237 return E_NOTIMPL;
1240 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1241 IMoniker *pmkNewlyRunning)
1243 ok(0, "unexpected call\n");
1244 return E_NOTIMPL;
1247 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
1248 IMoniker *pmkToLeft, FILETIME *pFileTime)
1250 ok(0, "unexpected call\n");
1251 return E_NOTIMPL;
1254 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
1256 ok(0, "unexpected call\n");
1257 return E_NOTIMPL;
1260 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
1261 IMoniker **ppmkPrefix)
1263 ok(0, "unexpected call\n");
1264 return E_NOTIMPL;
1267 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
1268 IMoniker **pmkRelPath)
1270 ok(0, "unexpected call\n");
1271 return E_NOTIMPL;
1274 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
1275 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
1277 CHECK_EXPECT2(GetDisplayName);
1279 ok(pbc != NULL, "pbc == NULL\n");
1280 ok(pbc != _bctx, "pbc == _bctx\n");
1281 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1283 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
1284 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
1285 return S_OK;
1288 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
1289 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
1291 ok(0, "unexpected call\n");
1292 return E_NOTIMPL;
1295 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
1297 CHECK_EXPECT2(IsSystemMoniker);
1299 *pdwMksys = MKSYS_URLMONIKER;
1300 return S_OK;
1303 static IMonikerVtbl MonikerVtbl = {
1304 Moniker_QueryInterface,
1305 Moniker_AddRef,
1306 Moniker_Release,
1307 Moniker_GetClassID,
1308 Moniker_IsDirty,
1309 Moniker_Load,
1310 Moniker_Save,
1311 Moniker_GetSizeMax,
1312 Moniker_BindToObject,
1313 Moniker_BindToStorage,
1314 Moniker_Reduce,
1315 Moniker_ComposeWith,
1316 Moniker_Enum,
1317 Moniker_IsEqual,
1318 Moniker_Hash,
1319 Moniker_IsRunning,
1320 Moniker_GetTimeOfLastChange,
1321 Moniker_Inverse,
1322 Moniker_CommonPrefixWith,
1323 Moniker_RelativePathTo,
1324 Moniker_GetDisplayName,
1325 Moniker_ParseDisplayName,
1326 Moniker_IsSystemMoniker
1329 static IMoniker Moniker = { &MonikerVtbl };
1331 static void test_HlinkResolveMonikerForData(void)
1333 IBindCtx *bctx;
1334 HRESULT hres;
1336 CreateBindCtx(0, &bctx);
1337 _bctx = bctx;
1339 SET_EXPECT(IsSystemMoniker);
1340 SET_EXPECT(GetDisplayName);
1341 SET_EXPECT(BindToStorage);
1343 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1344 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08lx\n", hres);
1346 CHECK_CALLED(IsSystemMoniker);
1347 CHECK_CALLED(GetDisplayName);
1348 CHECK_CALLED(BindToStorage);
1350 IBindCtx_Release(bctx);
1351 _bctx = NULL;
1354 static void test_HlinkGetSetMonikerReference(void)
1356 IMoniker *found_trgt, *dummy, *dummy2;
1357 IHlink *hlink;
1358 HRESULT hres;
1359 const WCHAR one[] = {'1',0};
1360 const WCHAR two[] = {'2',0};
1361 const WCHAR name[] = {'a',0};
1362 WCHAR *found_loc;
1364 /* create two dummy monikers to use as targets */
1365 hres = CreateItemMoniker(one, one, &dummy);
1366 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08lx\n", hres);
1368 hres = CreateItemMoniker(two, two, &dummy2);
1369 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08lx\n", hres);
1371 /* create a new hlink: target => dummy, location => one */
1372 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1373 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08lx\n", hres);
1375 /* validate the target and location */
1376 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1377 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1378 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1379 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1380 IMoniker_Release(found_trgt);
1381 CoTaskMemFree(found_loc);
1383 /* set location => two */
1384 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1385 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08lx\n", hres);
1387 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1388 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1389 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1390 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1391 IMoniker_Release(found_trgt);
1392 CoTaskMemFree(found_loc);
1394 /* set target => dummy2 */
1395 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1396 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08lx\n", hres);
1398 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1399 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1400 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1401 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1402 IMoniker_Release(found_trgt);
1403 CoTaskMemFree(found_loc);
1405 /* set target => dummy, location => one */
1406 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1407 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08lx\n", hres);
1409 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1410 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1411 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1412 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1413 IMoniker_Release(found_trgt);
1414 CoTaskMemFree(found_loc);
1416 /* no HLINKSETF flags */
1417 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1418 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08lx), failed with 0x%08lx\n", E_INVALIDARG, hres);
1420 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1421 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1422 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1423 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1424 IMoniker_Release(found_trgt);
1425 CoTaskMemFree(found_loc);
1427 /* invalid HLINKSETF flags */
1428 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1429 if (0)
1430 IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1432 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1433 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1434 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1435 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1436 IMoniker_Release(found_trgt);
1437 CoTaskMemFree(found_loc);
1439 /* valid & invalid HLINKSETF flags */
1440 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1441 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08lx\n", hres);
1443 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1444 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1445 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1446 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1447 IMoniker_Release(found_trgt);
1448 CoTaskMemFree(found_loc);
1450 /* NULL args */
1451 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1452 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08lx\n", hres);
1454 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1455 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1456 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1457 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1458 if(found_trgt)
1459 IMoniker_Release(found_trgt);
1461 IHlink_Release(hlink);
1462 IMoniker_Release(dummy2);
1463 IMoniker_Release(dummy);
1465 SET_EXPECT(Reduce);
1466 SET_EXPECT(Enum);
1467 SET_EXPECT(IsSystemMoniker);
1468 SET_EXPECT(GetDisplayName);
1469 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL, 0, NULL,
1470 &IID_IHlink, (void **)&hlink);
1471 ok(hres == S_OK, "CreateFromMoniker failed: %08lx\n", hres);
1473 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_ABSOLUTE,
1474 &found_trgt, &found_loc);
1475 ok(hres == S_OK, "CreateFromMoniker failed: %08lx\n", hres);
1476 ok(found_trgt == &Moniker, "Got unexpected moniker: %p\n", found_trgt);
1477 ok(found_loc == NULL, "Got unexpected location: %p\n", found_loc);
1478 todo_wine CHECK_CALLED(Reduce);
1479 todo_wine CHECK_CALLED(Enum);
1480 CHECK_CALLED(IsSystemMoniker);
1481 CHECK_CALLED(GetDisplayName);
1483 IHlink_Release(hlink);
1486 static void test_HlinkGetSetStringReference(void)
1488 IHlink *link;
1489 static const WCHAR one[] = {'1',0};
1490 static const WCHAR two[] = {'2',0};
1491 static const WCHAR three[] = {'3',0};
1492 static const WCHAR empty[] = {0};
1493 WCHAR *fnd_tgt, *fnd_loc;
1494 HRESULT hres;
1496 /* create a new hlink: target => NULL, location => one */
1497 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1498 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08lx\n", hres);
1500 /* test setting/getting location */
1501 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1502 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1503 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1504 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1505 CoTaskMemFree(fnd_tgt);
1506 CoTaskMemFree(fnd_loc);
1508 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1509 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1511 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1512 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1513 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1514 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1515 CoTaskMemFree(fnd_tgt);
1516 CoTaskMemFree(fnd_loc);
1518 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1519 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1521 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1522 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1523 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1524 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1525 CoTaskMemFree(fnd_tgt);
1526 CoTaskMemFree(fnd_loc);
1528 /* test setting/getting target */
1529 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1530 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1532 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1533 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1534 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1535 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1536 CoTaskMemFree(fnd_tgt);
1537 CoTaskMemFree(fnd_loc);
1539 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1540 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1542 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1543 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1544 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1545 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1546 CoTaskMemFree(fnd_tgt);
1547 CoTaskMemFree(fnd_loc);
1549 /* test setting/getting both */
1550 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1551 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1553 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1554 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1555 ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1556 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1557 CoTaskMemFree(fnd_tgt);
1558 CoTaskMemFree(fnd_loc);
1560 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1561 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1563 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1564 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1565 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1566 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1567 CoTaskMemFree(fnd_tgt);
1568 CoTaskMemFree(fnd_loc);
1570 /* test invalid flags/params */
1571 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1572 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1573 "with E_INVALIDARG (0x%08lx), instead: 0x%08lx\n", E_INVALIDARG, hres);
1574 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1575 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1576 CoTaskMemFree(fnd_tgt);
1577 CoTaskMemFree(fnd_loc);
1579 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1580 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1581 "with E_FAIL (0x%08lx), instead: 0x%08lx\n", E_FAIL, hres);
1582 CoTaskMemFree(fnd_tgt);
1584 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1585 ok(hres == S_OK, "failed, hres=%08lx\n", hres);
1587 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1588 ok(hres == S_OK, "failed, hres=%08lx\n", hres);
1589 CoTaskMemFree(fnd_loc);
1591 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1592 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1593 "with E_FAIL (0x%08lx), instead: 0x%08lx\n", E_FAIL, hres);
1594 CoTaskMemFree(fnd_tgt);
1595 CoTaskMemFree(fnd_loc);
1597 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1598 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1599 "with E_INVALIDARG (0x%08lx), instead: 0x%08lx\n", E_INVALIDARG, hres);
1600 CoTaskMemFree(fnd_tgt);
1601 CoTaskMemFree(fnd_loc);
1603 if (0)
1605 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1606 IHlink_SetStringReference(link, 4, NULL, NULL);
1607 IHlink_SetStringReference(link, -4, NULL, NULL);
1610 IHlink_Release(link);
1613 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1614 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1616 HRESULT hres;
1617 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1618 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08lx\n", hres);
1621 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1622 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1624 HRESULT hres;
1625 WCHAR *fnd_tgt, *fnd_loc;
1627 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1628 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08lx\n", hres);
1630 if(exp_tgt)
1631 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));
1632 else
1633 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1635 if(exp_loc)
1636 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));
1637 else
1638 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1640 CoTaskMemFree(fnd_tgt);
1641 CoTaskMemFree(fnd_loc);
1644 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1645 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1647 HRESULT hres;
1648 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1649 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08lx\n", hres);
1652 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1653 #define getMonikerRef(h,t,l,r) r_getMonikerRef(__LINE__,h,t,l,r)
1654 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc, DWORD ref)
1656 HRESULT hres;
1657 IMoniker *fnd_tgt;
1658 WCHAR *fnd_loc;
1660 hres = IHlink_GetMonikerReference(hlink, ref, &fnd_tgt, &fnd_loc);
1661 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08lx\n", hres);
1663 if(exp_loc)
1664 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));
1665 else
1666 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1668 CoTaskMemFree(fnd_loc);
1670 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1671 return fnd_tgt;
1673 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1675 if(fnd_tgt)
1676 IMoniker_Release(fnd_tgt);
1678 return NULL;
1681 static void test_HlinkMoniker(void)
1683 IHlink *hlink;
1684 IMoniker *aMon, *file_mon;
1685 static const WCHAR emptyW[] = {0};
1686 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1687 static const WCHAR aW[] = {'a',0};
1688 static const WCHAR bW[] = {'b',0};
1689 HRESULT hres;
1691 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1692 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08lx\n", hres);
1693 getStringRef(hlink, NULL, NULL);
1694 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1696 /* setting a string target creates a moniker reference */
1697 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1698 getStringRef(hlink, aW, wordsW);
1699 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW, HLINKGETREF_RELATIVE);
1700 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1701 if(aMon)
1702 IMoniker_Release(aMon);
1704 /* setting target & location to the empty string deletes the moniker
1705 * reference */
1706 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1707 getStringRef(hlink, NULL, NULL);
1708 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1710 /* setting a moniker target also sets the target string to that moniker's
1711 * display name */
1712 hres = CreateFileMoniker(bW, &file_mon);
1713 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08lx\n", hres);
1715 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1716 getStringRef(hlink, bW, wordsW);
1717 getMonikerRef(hlink, file_mon, wordsW, HLINKGETREF_RELATIVE);
1719 IMoniker_Release(file_mon);
1721 IHlink_Release(hlink);
1724 static void test_HashLink(void)
1726 IHlink *hlink;
1727 IMoniker *pmk;
1728 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1729 const WCHAR two_hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1730 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1731 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1732 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1733 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1734 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1735 HRESULT hres;
1737 /* simple single hash test */
1738 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1739 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08lx\n", hres);
1740 ok(hlink != NULL, "Didn't get an hlink\n");
1742 if(hlink){
1743 getStringRef(hlink, tgt_partW, loc_partW);
1744 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1745 ok(pmk != NULL, "Found moniker should not be NULL\n");
1746 if(pmk)
1747 IMoniker_Release(pmk);
1749 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1750 getStringRef(hlink, hash_targetW, loc_partW);
1752 IHlink_Release(hlink);
1755 /* two hashes in the target */
1756 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1757 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08lx\n", hres);
1758 ok(hlink != NULL, "Didn't get an hlink\n");
1760 if(hlink){
1761 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1762 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW, HLINKGETREF_RELATIVE);
1763 ok(pmk != NULL, "Found moniker should not be NULL\n");
1764 if(pmk)
1765 IMoniker_Release(pmk);
1767 IHlink_Release(hlink);
1770 /* target with hash plus a location string */
1771 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1772 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08lx\n", hres);
1773 ok(hlink != NULL, "Didn't get an hlink\n");
1775 if(hlink){
1776 getStringRef(hlink, tgt_partW, test_locW);
1777 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW, HLINKGETREF_RELATIVE);
1778 ok(pmk != NULL, "Found moniker should not be NULL\n");
1779 if(pmk)
1780 IMoniker_Release(pmk);
1782 IHlink_Release(hlink);
1785 /* target with hash containing no "target part" */
1786 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1787 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08lx\n", hres);
1788 ok(hlink != NULL, "Didn't get an hlink\n");
1790 if(hlink){
1791 getStringRef(hlink, NULL, loc_partW);
1792 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1793 ok(pmk == NULL, "Found moniker should be NULL\n");
1794 if(pmk)
1795 IMoniker_Release(pmk);
1797 IHlink_Release(hlink);
1801 static const WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1802 static const WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1804 static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
1805 IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1807 ok(0, "BTS: %p %p %p %s %p\n", iface, pbc, toLeft, wine_dbgstr_guid(riid), obj);
1808 return E_NOTIMPL;
1811 static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
1812 IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1814 LPOLESTR rightName;
1815 HRESULT hres;
1817 ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1819 CHECK_EXPECT(ComposeWith);
1821 hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1822 ok(hres == S_OK, "GetDisplayName failed: %08lx\n", hres);
1823 ok(!lstrcmpW(rightName, ref_monikerW),
1824 "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1825 wine_dbgstr_w(rightName));
1826 CoTaskMemFree(rightName);
1828 *composite = NULL;
1830 /* unlikely error code to verify this return result is used */
1831 return E_OUTOFMEMORY;
1834 static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
1835 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1837 *displayName = CoTaskMemAlloc(sizeof(site_monikerW));
1838 memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
1839 return S_OK;
1842 static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
1843 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1845 *displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
1846 memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
1847 return S_OK;
1850 static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
1851 DWORD *mksys)
1853 return S_FALSE;
1856 static IMonikerVtbl hls_site_MonikerVtbl = {
1857 Moniker_QueryInterface,
1858 Moniker_AddRef,
1859 Moniker_Release,
1860 Moniker_GetClassID,
1861 Moniker_IsDirty,
1862 Moniker_Load,
1863 Moniker_Save,
1864 Moniker_GetSizeMax,
1865 Moniker_BindToObject,
1866 hls_test_Moniker_BindToStorage,
1867 Moniker_Reduce,
1868 hls_site_Moniker_ComposeWith,
1869 Moniker_Enum,
1870 Moniker_IsEqual,
1871 Moniker_Hash,
1872 Moniker_IsRunning,
1873 Moniker_GetTimeOfLastChange,
1874 Moniker_Inverse,
1875 Moniker_CommonPrefixWith,
1876 Moniker_RelativePathTo,
1877 hls_site_Moniker_GetDisplayName,
1878 Moniker_ParseDisplayName,
1879 hls_test_Moniker_IsSystemMoniker
1882 static IMonikerVtbl hls_ref_MonikerVtbl = {
1883 Moniker_QueryInterface,
1884 Moniker_AddRef,
1885 Moniker_Release,
1886 Moniker_GetClassID,
1887 Moniker_IsDirty,
1888 Moniker_Load,
1889 Moniker_Save,
1890 Moniker_GetSizeMax,
1891 Moniker_BindToObject,
1892 hls_test_Moniker_BindToStorage,
1893 Moniker_Reduce,
1894 Moniker_ComposeWith,
1895 Moniker_Enum,
1896 Moniker_IsEqual,
1897 Moniker_Hash,
1898 Moniker_IsRunning,
1899 Moniker_GetTimeOfLastChange,
1900 Moniker_Inverse,
1901 Moniker_CommonPrefixWith,
1902 Moniker_RelativePathTo,
1903 hls_ref_Moniker_GetDisplayName,
1904 Moniker_ParseDisplayName,
1905 hls_test_Moniker_IsSystemMoniker
1908 static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
1909 static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
1911 static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
1912 void **obj)
1914 ok(0, "QI: %p %s %p\n", iface, wine_dbgstr_guid(iid), obj);
1915 return E_NOTIMPL;
1918 static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
1920 return 2;
1923 static ULONG WINAPI hls_Release(IHlinkSite *iface)
1925 return 1;
1928 static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
1929 REFGUID service, REFIID riid, IUnknown **punk)
1931 ok(0, "QS: %p %lx %s %s %p\n", iface, siteData, wine_dbgstr_guid(service),
1932 wine_dbgstr_guid(riid), punk);
1933 return E_NOTIMPL;
1936 #define SITEDATA_SUCCESS 1
1937 #define SITEDATA_NOTIMPL 2
1939 static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
1940 DWORD assign, DWORD which, IMoniker **pmk)
1942 ok(siteData == SITEDATA_NOTIMPL ||
1943 siteData == SITEDATA_SUCCESS, "Unexpected site data: %lu\n", siteData);
1945 if(siteData == SITEDATA_SUCCESS){
1946 *pmk = &hls_site_Moniker;
1947 return S_OK;
1950 return E_NOTIMPL;
1953 static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
1954 DWORD reserved)
1956 ok(0, "RTN: %p %lx %lx\n", iface, siteData, reserved);
1957 return E_NOTIMPL;
1960 static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
1961 DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1963 CHECK_EXPECT(OnNavigationComplete);
1964 ok(siteData == SITEDATA_SUCCESS, "Unexpected site data: %lu\n", siteData);
1965 ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08lx\n", error);
1966 return E_NOTIMPL;
1969 static IHlinkSiteVtbl HlinkSiteVtbl = {
1970 hls_QueryInterface,
1971 hls_AddRef,
1972 hls_Release,
1973 hls_QueryService,
1974 hls_GetMoniker,
1975 hls_ReadyToNavigate,
1976 hls_OnNavigationComplete
1979 static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
1981 static void test_HlinkSite(void)
1983 IHlink *hl;
1984 IMoniker *mon_ref;
1985 IBindCtx *pbc;
1986 HRESULT hres;
1988 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1989 &IID_IHlink, (LPVOID*)&hl);
1990 ok(hres == S_OK, "HlinkCreateFromString failed: %08lx\n", hres);
1991 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1993 hres = IHlink_SetHlinkSite(hl, &HlinkSite, SITEDATA_SUCCESS);
1994 ok(hres == S_OK, "SetHlinkSite failed: %08lx\n", hres);
1995 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1996 getStringRef(hl, NULL, NULL);
1998 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1999 ok(hres == S_OK, "GetMonikerReference failed: %08lx\n", hres);
2000 ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
2002 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
2003 ok(hres == S_OK, "GetMonikerReference failed: %08lx\n", hres);
2004 ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
2006 SET_EXPECT(Reduce);
2007 SET_EXPECT(Enum);
2008 hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
2009 ok(hres == S_OK, "SetMonikerReference failed: %08lx\n", hres);
2010 todo_wine CHECK_CALLED(Reduce);
2011 todo_wine CHECK_CALLED(Enum);
2013 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
2015 SET_EXPECT(Enum);
2016 getStringRef(hl, ref_monikerW, NULL);
2017 todo_wine CHECK_CALLED(Enum);
2019 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
2020 ok(hres == S_OK, "GetMonikerReference failed: %08lx\n", hres);
2021 ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
2022 IMoniker_Release(mon_ref);
2024 SET_EXPECT(ComposeWith);
2025 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
2026 ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08lx\n", hres);
2027 ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
2028 CHECK_CALLED(ComposeWith);
2030 hres = CreateBindCtx(0, &pbc);
2031 ok(hres == S_OK, "CreateBindCtx failed: %08lx\n", hres);
2033 SET_EXPECT(ComposeWith);
2034 SET_EXPECT(OnNavigationComplete);
2035 hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
2036 ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08lx\n", hres);
2037 CHECK_CALLED(ComposeWith);
2038 CHECK_CALLED(OnNavigationComplete);
2040 IBindCtx_Release(pbc);
2041 IHlink_Release(hl);
2043 SET_EXPECT(Reduce);
2044 SET_EXPECT(Enum);
2045 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
2046 NULL, &IID_IHlink, (LPVOID*)&hl);
2047 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08lx\n", hres);
2048 todo_wine CHECK_CALLED(Reduce);
2049 todo_wine CHECK_CALLED(Enum);
2050 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
2051 IHlink_Release(hl);
2053 hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
2054 NULL, &IID_IHlink, (LPVOID*)&hl);
2055 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08lx\n", hres);
2056 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
2057 IHlink_Release(hl);
2059 SET_EXPECT(Reduce);
2060 SET_EXPECT(Enum);
2061 SET_EXPECT(IsSystemMoniker);
2062 SET_EXPECT(GetDisplayName);
2063 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, &HlinkSite, SITEDATA_NOTIMPL,
2064 NULL, &IID_IHlink, (LPVOID*)&hl);
2065 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08lx\n", hres);
2066 getMonikerRef(hl, &Moniker, NULL, HLINKGETREF_ABSOLUTE);
2067 IHlink_Release(hl);
2068 todo_wine CHECK_CALLED(Reduce);
2069 todo_wine CHECK_CALLED(Enum);
2070 CHECK_CALLED(IsSystemMoniker);
2071 CHECK_CALLED(GetDisplayName);
2074 static void test_HlinkClone(void)
2076 HRESULT hres;
2077 IHlink *hl, *cloned = NULL;
2078 IMoniker *dummy, *fnd_mk;
2079 IHlinkSite *fnd_site;
2080 WCHAR *fnd_name;
2081 DWORD fnd_data;
2082 const WCHAR one[] = {'1',0};
2083 const WCHAR two[] = {'2',0};
2084 const WCHAR name[] = {'a',0};
2086 hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
2087 ok(hres == E_INVALIDARG, "Got wrong failure code: %08lx\n", hres);
2089 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
2090 &IID_IHlink, (void**)&hl);
2091 ok(hres == S_OK, "HlinkCreateFromString failed: %08lx\n", hres);
2093 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
2094 ok(hres == E_INVALIDARG, "Got wrong failure code: %08lx\n", hres);
2096 if (0)
2098 /* crash on Windows XP */
2099 HlinkClone(hl, NULL, NULL, 0, NULL);
2101 HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
2104 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2105 ok(hres == S_OK, "HlinkClone failed: %08lx\n", hres);
2106 ok(cloned != NULL, "Didn't get a clone\n");
2107 getMonikerRef(cloned, NULL, NULL, HLINKGETREF_RELATIVE);
2108 IHlink_Release(cloned);
2110 IHlink_Release(hl);
2112 SET_EXPECT(Reduce);
2113 SET_EXPECT(Enum);
2114 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2115 todo_wine CHECK_CALLED(Reduce);
2116 todo_wine CHECK_CALLED(Enum);
2117 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08lx\n", hres);
2118 getMonikerRef(hl, &hls_ref_Moniker, two, HLINKGETREF_RELATIVE);
2120 SET_EXPECT(Save);
2121 SET_EXPECT(GetClassID);
2122 cloned = (IHlink*)0xdeadbeef;
2123 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2124 /* fails because of invalid CLSID given by Moniker_GetClassID */
2125 ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08lx\n", hres);
2126 ok(cloned == NULL, "Shouldn't have gotten a clone\n");
2127 CHECK_CALLED(Save);
2128 CHECK_CALLED(GetClassID);
2130 IHlink_Release(hl);
2132 hres = CreateItemMoniker(one, one, &dummy);
2133 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08lx\n", hres);
2135 hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, SITEDATA_SUCCESS, NULL, &IID_IHlink, (void**)&hl);
2136 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08lx\n", hres);
2137 getMonikerRef(hl, dummy, two, HLINKGETREF_RELATIVE);
2139 cloned = NULL;
2140 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2141 ok(hres == S_OK, "HlinkClone failed: %08lx\n", hres);
2142 ok(cloned != NULL, "Should have gotten a clone\n");
2144 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two, HLINKGETREF_RELATIVE);
2145 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2146 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2148 fnd_name = NULL;
2149 hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
2150 ok(hres == S_OK, "GetFriendlyName failed: %08lx\n", hres);
2151 ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
2152 ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
2153 wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
2154 CoTaskMemFree(fnd_name);
2156 fnd_site = (IHlinkSite*)0xdeadbeef;
2157 fnd_data = 4;
2158 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2159 ok(hres == S_OK, "GetHlinkSite failed: %08lx\n", hres);
2160 ok(fnd_site == NULL, "Expected NULL site\n");
2161 ok(fnd_data == 4, "Expected site data to be 4, was: %ld\n", fnd_data);
2163 IHlink_Release(cloned);
2164 IHlink_Release(hl);
2166 hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2167 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08lx\n", hres);
2168 getMonikerRef(hl, dummy, NULL, HLINKGETREF_RELATIVE);
2170 cloned = NULL;
2171 hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, SITEDATA_SUCCESS, (void**)&cloned);
2172 ok(hres == S_OK, "HlinkClone failed: %08lx\n", hres);
2173 ok(cloned != NULL, "Should have gotten a clone\n");
2175 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL, HLINKGETREF_RELATIVE);
2176 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2177 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2179 fnd_site = (IHlinkSite*)0xdeadbeef;
2180 fnd_data = 4;
2181 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2182 ok(hres == S_OK, "GetHlinkSite failed: %08lx\n", hres);
2183 ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
2184 ok(fnd_data == SITEDATA_SUCCESS, "Unexpected site data: %lu\n", fnd_data);
2186 IHlink_Release(cloned);
2187 IHlink_Release(hl);
2189 IMoniker_Release(dummy);
2192 static void test_StdHlink(void)
2194 IHlink *hlink;
2195 WCHAR *str;
2196 HRESULT hres;
2198 static const WCHAR testW[] = {'t','e','s','t',0};
2200 hres = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2201 &IID_IHlink, (void**)&hlink);
2202 ok(hres == S_OK, "CoCreateInstance failed: %08lx\n", hres);
2204 str = (void*)0xdeadbeef;
2205 hres = IHlink_GetTargetFrameName(hlink, &str);
2206 ok(hres == S_FALSE, "GetTargetFrameName failed: %08lx\n", hres);
2207 ok(!str, "str = %s\n", wine_dbgstr_w(str));
2209 hres = IHlink_SetTargetFrameName(hlink, testW);
2210 ok(hres == S_OK, "SetTargetFrameName failed: %08lx\n", hres);
2212 str = (void*)0xdeadbeef;
2213 hres = IHlink_GetTargetFrameName(hlink, &str);
2214 ok(hres == S_OK, "GetTargetFrameName failed: %08lx\n", hres);
2215 ok(!lstrcmpW(str, testW), "str = %s\n", wine_dbgstr_w(str));
2216 CoTaskMemFree(str);
2218 hres = IHlink_SetTargetFrameName(hlink, NULL);
2219 ok(hres == S_OK, "SetTargetFrameName failed: %08lx\n", hres);
2221 str = (void*)0xdeadbeef;
2222 hres = IHlink_GetTargetFrameName(hlink, &str);
2223 ok(hres == S_FALSE, "GetTargetFrameName failed: %08lx\n", hres);
2224 ok(!str, "str = %s\n", wine_dbgstr_w(str));
2226 IHlink_Release(hlink);
2229 static void test_Hlink_Navigate(void)
2231 BINDINFO bind_info = {sizeof(BINDINFO)};
2232 DWORD bind_flags;
2233 IHlink *hlink;
2234 IBindCtx *pbc;
2235 HRESULT hres;
2237 hres = CreateBindCtx(0, &pbc);
2238 ok(hres == S_OK, "CreateBindCtx failed: %08lx\n", hres);
2239 _bctx = pbc;
2241 HBC_object = NULL;
2243 SET_EXPECT(Reduce);
2244 SET_EXPECT(Enum);
2245 SET_EXPECT(IsSystemMoniker);
2246 SET_EXPECT(GetDisplayName);
2247 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL,
2248 0, NULL, &IID_IHlink, (void**)&hlink);
2249 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08lx\n", hres);
2250 todo_wine CHECK_CALLED(Reduce);
2251 todo_wine CHECK_CALLED(Enum);
2252 todo_wine CHECK_CALLED(IsSystemMoniker);
2253 CHECK_CALLED(GetDisplayName);
2255 SET_EXPECT(IsSystemMoniker);
2256 SET_EXPECT(GetDisplayName);
2257 SET_EXPECT(HBC_GetObject);
2258 SET_EXPECT(Reduce);
2259 SET_EXPECT(BindToObject);
2260 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2261 SET_EXPECT(HT_GetBrowseContext);
2262 SET_EXPECT(HT_SetBrowseContext);
2263 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2264 SET_EXPECT(HT_Navigate);
2265 SET_EXPECT(HT_GetFriendlyName);
2266 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2267 ok(hres == S_OK, "Navigate failed: %08lx\n", hres);
2268 CHECK_CALLED(IsSystemMoniker);
2269 CHECK_CALLED(GetDisplayName);
2270 CHECK_CALLED(HBC_GetObject);
2271 todo_wine CHECK_CALLED(Reduce);
2272 CHECK_CALLED(BindToObject);
2273 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2274 todo_wine CHECK_CALLED(HT_GetBrowseContext);
2275 CHECK_CALLED(HT_SetBrowseContext);
2276 todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2277 CHECK_CALLED(HT_Navigate);
2278 todo_wine CHECK_CALLED(HT_GetFriendlyName);
2280 /* Test with valid return from HlinkBrowseContext::GetObject */
2281 HBC_object = (IUnknown *)&HlinkTarget;
2283 SET_EXPECT(IsSystemMoniker);
2284 SET_EXPECT(GetDisplayName);
2285 SET_EXPECT(HBC_GetObject);
2286 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2287 SET_EXPECT(HT_Navigate);
2288 SET_EXPECT(HT_GetFriendlyName);
2289 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2290 ok(hres == S_OK, "Navigate failed: %08lx\n", hres);
2291 CHECK_CALLED(IsSystemMoniker);
2292 CHECK_CALLED(GetDisplayName);
2293 CHECK_CALLED(HBC_GetObject);
2294 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2295 CHECK_CALLED(HT_Navigate);
2296 todo_wine CHECK_CALLED(HT_GetFriendlyName);
2298 HBC_object = NULL;
2300 if (0) { /* these currently open a browser window on wine */
2301 /* Test from string */
2302 SET_EXPECT(HBC_GetObject);
2303 hres = HlinkNavigateToStringReference(winehq_404W, NULL, NULL, 0, NULL, 0, pbc, NULL, &HlinkBrowseContext);
2304 todo_wine ok(hres == INET_E_OBJECT_NOT_FOUND, "Expected INET_E_OBJECT_NOT_FOUND, got %08lx\n", hres);
2305 CHECK_CALLED(HBC_GetObject);
2307 /* MSDN claims browse context and bind context can't be null, but they can */
2308 SET_EXPECT(HBC_GetObject);
2309 hres = HlinkNavigateToStringReference(winehq_404W, NULL, NULL, 0, NULL, 0, NULL, NULL, &HlinkBrowseContext);
2310 todo_wine ok(hres == INET_E_OBJECT_NOT_FOUND, "Expected INET_E_OBJECT_NOT_FOUND, got %08lx\n", hres);
2311 CHECK_CALLED(HBC_GetObject);
2314 /* these open a browser window, so mark them interactive only */
2315 if (winetest_interactive)
2317 /* both parameters null */
2318 SET_EXPECT(IsSystemMoniker);
2319 SET_EXPECT(GetDisplayName);
2320 hres = IHlink_Navigate(hlink, 0, NULL, NULL, NULL);
2321 ok(hres == DRAGDROP_S_DROP, "Expected DRAGDROP_S_DROP, got %08lx\n", hres);
2322 CHECK_CALLED(IsSystemMoniker);
2323 CHECK_CALLED(GetDisplayName);
2325 /* same, from string */
2326 hres = HlinkNavigateToStringReference(winehq_404W, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL);
2327 ok(hres == DRAGDROP_S_DROP, "Expected DRAGDROP_S_DROP, got %08lx\n", hres);
2329 /* try basic test with valid URL */
2330 SET_EXPECT(HBC_GetObject);
2331 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2332 SET_EXPECT(HBC_QueryInterface_IMarshal);
2333 SET_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
2334 SET_EXPECT(HBC_QueryInterface_IUnknown);
2335 hres = HlinkNavigateToStringReference(winehq_urlW, NULL, NULL, 0, NULL, 0, pbc, NULL, &HlinkBrowseContext);
2336 ok(hres == S_OK, "Expected S_OK, got %08lx\n", hres);
2337 CHECK_CALLED(HBC_GetObject);
2338 todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2339 todo_wine CHECK_CALLED(HBC_QueryInterface_IMarshal);
2340 todo_wine CHECK_CALLED(HBC_QueryInterface_IdentityUnmarshal);
2341 todo_wine CHECK_CALLED(HBC_QueryInterface_IUnknown);
2343 else
2344 skip("interactive IHlink_Navigate tests\n");
2346 /* test binding callback */
2347 SET_EXPECT(IsSystemMoniker);
2348 SET_EXPECT(GetDisplayName);
2349 SET_EXPECT(BindStatusCallback_GetBindInfo);
2350 SET_EXPECT(HBC_GetObject);
2351 SET_EXPECT(Reduce);
2352 SET_EXPECT(BindToObject);
2353 SET_EXPECT(BindStatusCallback_OnStartBinding);
2354 SET_EXPECT(BindStatusCallback_OnObjectAvailable);
2355 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2356 SET_EXPECT(HT_GetBrowseContext);
2357 SET_EXPECT(HT_SetBrowseContext);
2358 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2359 SET_EXPECT(HT_Navigate);
2360 SET_EXPECT(HT_GetFriendlyName);
2361 SET_EXPECT(BindStatusCallback_OnStopBinding);
2362 hres = IHlink_Navigate(hlink, 0, pbc, &BindStatusCallback, &HlinkBrowseContext);
2363 ok(hres == S_OK, "Navigate failed: %#lx\n", hres);
2364 CHECK_CALLED(IsSystemMoniker);
2365 CHECK_CALLED(GetDisplayName);
2366 CHECK_CALLED(HBC_GetObject);
2367 todo_wine
2368 CHECK_CALLED(BindStatusCallback_GetBindInfo);
2369 todo_wine
2370 CHECK_CALLED(Reduce);
2371 CHECK_CALLED(BindToObject);
2372 todo_wine {
2373 CHECK_CALLED(BindStatusCallback_OnStartBinding);
2374 CHECK_CALLED(BindStatusCallback_OnObjectAvailable);
2376 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2377 todo_wine
2378 CHECK_CALLED(HT_GetBrowseContext);
2379 CHECK_CALLED(HT_SetBrowseContext);
2380 todo_wine
2381 CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2382 CHECK_CALLED(HT_Navigate);
2383 todo_wine
2384 CHECK_CALLED(HT_GetFriendlyName);
2385 todo_wine
2386 CHECK_CALLED(BindStatusCallback_OnStopBinding);
2388 ok(bind_callback_refs == 1, "Got unexpected refcount %ld.\n", bind_callback_refs);
2389 ok(browse_ctx_refs == 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2391 /* test asynchronous binding */
2392 async_bind = TRUE;
2393 SET_EXPECT(IsSystemMoniker);
2394 SET_EXPECT(GetDisplayName);
2395 SET_EXPECT(HBC_GetObject);
2396 SET_EXPECT(Reduce);
2397 SET_EXPECT(BindToObject);
2398 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2399 ok(hres == MK_S_ASYNCHRONOUS, "Navigate failed: %#lx\n", hres);
2400 CHECK_CALLED(IsSystemMoniker);
2401 CHECK_CALLED(GetDisplayName);
2402 CHECK_CALLED(HBC_GetObject);
2403 todo_wine
2404 CHECK_CALLED(Reduce);
2405 CHECK_CALLED(BindToObject);
2407 ok(browse_ctx_refs > 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2409 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2410 ok(hres == E_UNEXPECTED, "Got hr %#lx.\n", hres);
2412 hres = IBindStatusCallback_GetBindInfo(async_bind_callback, &bind_flags, &bind_info);
2413 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2415 hres = IBindStatusCallback_OnStartBinding(async_bind_callback, 0, NULL);
2416 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2418 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2419 SET_EXPECT(HT_GetBrowseContext);
2420 SET_EXPECT(HT_SetBrowseContext);
2421 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2422 SET_EXPECT(HT_Navigate);
2423 SET_EXPECT(HT_GetFriendlyName);
2424 hres = IBindStatusCallback_OnObjectAvailable(async_bind_callback, &IID_IUnknown,
2425 (IUnknown *)&HlinkTarget);
2426 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2427 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2428 todo_wine
2429 CHECK_CALLED(HT_GetBrowseContext);
2430 CHECK_CALLED(HT_SetBrowseContext);
2431 todo_wine
2432 CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2433 CHECK_CALLED(HT_Navigate);
2434 todo_wine
2435 CHECK_CALLED(HT_GetFriendlyName);
2437 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2438 ok(hres == E_UNEXPECTED, "Got hr %#lx.\n", hres);
2440 ok(browse_ctx_refs > 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2442 hres = IBindStatusCallback_OnStopBinding(async_bind_callback, S_OK, NULL);
2443 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2445 ok(browse_ctx_refs == 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2447 IBindStatusCallback_Release(async_bind_callback);
2449 SET_EXPECT(IsSystemMoniker);
2450 SET_EXPECT(GetDisplayName);
2451 SET_EXPECT(BindStatusCallback_GetBindInfo);
2452 SET_EXPECT(HBC_GetObject);
2453 SET_EXPECT(Reduce);
2454 SET_EXPECT(BindToObject);
2455 hres = IHlink_Navigate(hlink, 0, pbc, &BindStatusCallback, &HlinkBrowseContext);
2456 ok(hres == MK_S_ASYNCHRONOUS, "Navigate failed: %#lx\n", hres);
2457 CHECK_CALLED(IsSystemMoniker);
2458 CHECK_CALLED(GetDisplayName);
2459 todo_wine
2460 CHECK_CALLED(BindStatusCallback_GetBindInfo);
2461 CHECK_CALLED(HBC_GetObject);
2462 todo_wine
2463 CHECK_CALLED(Reduce);
2464 CHECK_CALLED(BindToObject);
2466 ok(bind_callback_refs > 1, "Got unexpected refcount %ld.\n", bind_callback_refs);
2467 ok(browse_ctx_refs > 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2469 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2470 ok(hres == E_UNEXPECTED, "Got hr %#lx.\n", hres);
2472 SET_EXPECT(BindStatusCallback_GetBindInfo);
2473 hres = IBindStatusCallback_GetBindInfo(async_bind_callback, &bind_flags, &bind_info);
2474 ok(hres == E_NOTIMPL, "Got hr %#lx.\n", hres);
2475 CHECK_CALLED(BindStatusCallback_GetBindInfo);
2477 SET_EXPECT(BindStatusCallback_OnStartBinding);
2478 hres = IBindStatusCallback_OnStartBinding(async_bind_callback, 0, NULL);
2479 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2480 CHECK_CALLED(BindStatusCallback_OnStartBinding);
2482 SET_EXPECT(BindStatusCallback_OnObjectAvailable);
2483 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2484 SET_EXPECT(HT_GetBrowseContext);
2485 SET_EXPECT(HT_SetBrowseContext);
2486 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2487 SET_EXPECT(HT_Navigate);
2488 SET_EXPECT(HT_GetFriendlyName);
2489 hres = IBindStatusCallback_OnObjectAvailable(async_bind_callback, &IID_IUnknown,
2490 (IUnknown *)&HlinkTarget);
2491 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2492 CHECK_CALLED(BindStatusCallback_OnObjectAvailable);
2493 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2494 todo_wine
2495 CHECK_CALLED(HT_GetBrowseContext);
2496 CHECK_CALLED(HT_SetBrowseContext);
2497 todo_wine
2498 CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2499 CHECK_CALLED(HT_Navigate);
2500 todo_wine
2501 CHECK_CALLED(HT_GetFriendlyName);
2503 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2504 ok(hres == E_UNEXPECTED, "Got hr %#lx.\n", hres);
2506 ok(bind_callback_refs > 1, "Got unexpected refcount %ld.\n", bind_callback_refs);
2507 ok(browse_ctx_refs > 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2509 SET_EXPECT(BindStatusCallback_OnStopBinding);
2510 hres = IBindStatusCallback_OnStopBinding(async_bind_callback, S_OK, NULL);
2511 ok(hres == S_OK, "Got hr %#lx.\n", hres);
2512 CHECK_CALLED(BindStatusCallback_OnStopBinding);
2514 ok(bind_callback_refs == 1, "Got unexpected refcount %ld.\n", bind_callback_refs);
2515 ok(browse_ctx_refs == 1, "Got unexpected refcount %ld.\n", browse_ctx_refs);
2517 IBindStatusCallback_Release(async_bind_callback);
2519 IHlink_Release(hlink);
2520 IBindCtx_Release(pbc);
2521 _bctx = NULL;
2524 static HRESULT WINAPI hlinkframe_QueryInterface(IHlinkFrame *iface, REFIID riid, void **obj)
2526 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IHlinkFrame))
2528 *obj = iface;
2529 return S_OK;
2532 *obj = NULL;
2533 return E_NOINTERFACE;
2536 static ULONG WINAPI hlinkframe_AddRef(IHlinkFrame *iface)
2538 return 2;
2541 static ULONG WINAPI hlinkframe_Release(IHlinkFrame *iface)
2543 return 1;
2546 static HRESULT WINAPI hlinkframe_SetBrowseContext(IHlinkFrame *iface, IHlinkBrowseContext *bc)
2548 ok(0, "unexpected %p\n", bc);
2549 return E_NOTIMPL;
2552 static HRESULT WINAPI hlinkframe_GetBrowseContext(IHlinkFrame *iface, IHlinkBrowseContext **bc)
2554 *bc = NULL;
2555 ok(0, "unexpected %p\n", bc);
2556 return E_NOTIMPL;
2559 static HRESULT WINAPI hlinkframe_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc, IBindStatusCallback *bsc, IHlink *navigate)
2561 ok(0, "unexpected\n");
2562 return E_NOTIMPL;
2565 static HRESULT WINAPI hlinkframe_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name,
2566 DWORD reserved)
2568 ok(0, "unexpected\n");
2569 return E_NOTIMPL;
2572 static HRESULT WINAPI hlinkframe_UpdateHlink(IHlinkFrame *iface, ULONG uHLID, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name)
2574 CHECK_EXPECT(HLF_UpdateHlink);
2575 return S_OK;
2578 static IHlinkFrameVtbl hlinkframevtbl = {
2579 hlinkframe_QueryInterface,
2580 hlinkframe_AddRef,
2581 hlinkframe_Release,
2582 hlinkframe_SetBrowseContext,
2583 hlinkframe_GetBrowseContext,
2584 hlinkframe_Navigate,
2585 hlinkframe_OnNavigate,
2586 hlinkframe_UpdateHlink
2589 static IHlinkFrame testframe = { &hlinkframevtbl };
2591 static void test_HlinkUpdateStackItem(void)
2593 static const WCHAR location[] = {'l','o','c','a','t','i','o','n',0};
2594 HRESULT hr;
2596 hr = HlinkUpdateStackItem(NULL, NULL, HLID_CURRENT, &Moniker, location, NULL);
2597 ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr);
2599 SET_EXPECT(HBC_UpdateHlink);
2600 hr = HlinkUpdateStackItem(NULL, &HlinkBrowseContext, HLID_CURRENT, &Moniker, location, NULL);
2601 ok(hr == S_OK, "got 0x%08lx\n", hr);
2602 CHECK_CALLED(HBC_UpdateHlink);
2604 SET_EXPECT(HLF_UpdateHlink);
2605 hr = HlinkUpdateStackItem(&testframe, &HlinkBrowseContext, HLID_CURRENT, &Moniker, location, NULL);
2606 ok(hr == S_OK, "got 0x%08lx\n", hr);
2607 CHECK_CALLED(HLF_UpdateHlink);
2610 static void test_HlinkCreateFromMoniker(void)
2612 IPersistStream *stream;
2613 IMoniker *moniker;
2614 HRESULT hr;
2616 hr = CreateItemMoniker(L"1", L"1", &moniker);
2617 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2619 hr = HlinkCreateFromMoniker(moniker, L"1", L"a", NULL, 0, NULL, &IID_IPersistStream, (void **)&stream);
2620 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2621 IPersistStream_Release(stream);
2623 IMoniker_Release(moniker);
2626 static void test_HlinkCreateFromString(void)
2628 IPersistStream *stream;
2629 HRESULT hr;
2631 hr = HlinkCreateFromString(L"http://winehq.org", NULL, NULL, NULL, 0, NULL, &IID_IPersistStream, (void **)&stream);
2632 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2633 IPersistStream_Release(stream);
2636 START_TEST(hlink)
2638 CoInitialize(NULL);
2640 test_HlinkIsShortcut();
2641 test_reference();
2642 test_persist();
2643 test_special_reference();
2644 test_HlinkCreateExtensionServices();
2645 test_HlinkParseDisplayName();
2646 test_HlinkResolveMonikerForData();
2647 test_HlinkGetSetMonikerReference();
2648 test_HlinkGetSetStringReference();
2649 test_HlinkMoniker();
2650 test_HashLink();
2651 test_HlinkSite();
2652 test_HlinkClone();
2653 test_StdHlink();
2654 test_Hlink_Navigate();
2655 test_HlinkUpdateStackItem();
2656 test_HlinkCreateFromMoniker();
2657 test_HlinkCreateFromString();
2659 CoUninitialize();