hlink/tests: Test skipped data.
[wine.git] / dlls / hlink / tests / hlink.c
blob22cfd10064e837b969e4a58b7a706abed84b4ec8
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_GetObject);
71 DEFINE_EXPECT(HBC_UpdateHlink);
73 DEFINE_EXPECT(HT_SetBrowseContext);
74 DEFINE_EXPECT(HT_GetBrowseContext);
75 DEFINE_EXPECT(HT_Navigate);
76 DEFINE_EXPECT(HT_GetFriendlyName);
78 DEFINE_EXPECT(HLF_UpdateHlink);
80 DEFINE_GUID(IID_IHlinkHistory,0x79eac9c8,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b);
82 static void test_HlinkIsShortcut(void)
84 UINT i;
85 HRESULT hres;
87 static const WCHAR file0[] = {'f','i','l','e',0};
88 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
89 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
90 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
91 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
92 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
93 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
94 static const WCHAR file7[] = {'.','u','r','l',0};
96 static struct {
97 LPCWSTR file;
98 HRESULT hres;
99 } shortcut_test[] = {
100 {file0, S_FALSE},
101 {file1, S_OK},
102 {file2, S_FALSE},
103 {file3, S_OK},
104 {file4, S_FALSE},
105 {file5, S_OK},
106 {file6, S_FALSE},
107 {file7, S_OK},
108 {NULL, E_INVALIDARG}
111 for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
112 hres = HlinkIsShortcut(shortcut_test[i].file);
113 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
114 i, hres, shortcut_test[i].hres);
118 static void test_reference(void)
120 HRESULT r;
121 IHlink *lnk = NULL;
122 IMoniker *mk = NULL;
123 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
124 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
125 LPWSTR str = NULL;
127 r = HlinkCreateFromString(url, NULL, NULL, NULL,
128 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
129 ok(r == S_OK, "failed to create link\n");
130 if (FAILED(r))
131 return;
133 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
134 ok(r == S_OK, "failed\n");
136 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
137 ok(r == S_OK, "failed\n");
138 ok(mk != NULL, "no moniker\n");
139 ok(str == NULL, "string should be null\n");
141 r = IMoniker_Release(mk);
142 ok( r == 1, "moniker refcount wrong\n");
144 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
145 ok(r == S_OK, "failed\n");
146 CoTaskMemFree(str);
148 r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
149 ok(r == S_OK, "failed, r=%08x\n", r);
151 r = IHlink_GetStringReference(lnk, -1, NULL, &str);
152 ok(r == S_OK, "failed, r=%08x\n", r);
153 ok(str == NULL, "string should be null\n");
155 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
156 ok(r == S_OK, "failed\n");
157 ok(!lstrcmpW(str, url2), "url wrong\n");
158 CoTaskMemFree(str);
160 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
161 ok(r == S_OK, "failed\n");
163 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
164 ok(r == S_OK, "failed\n");
165 ok(str == NULL, "string should be null\n");
167 /* Unimplented functions checks */
168 r = IHlink_GetAdditionalParams(lnk, NULL);
169 ok(r == E_NOTIMPL, "failed\n");
171 r = IHlink_SetAdditionalParams(lnk, NULL);
172 ok(r == E_NOTIMPL, "failed\n");
174 IHlink_Release(lnk);
177 /* url only */
178 static const unsigned char expected_hlink_data[] =
180 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
181 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
182 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
183 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
184 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
185 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
186 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
187 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
188 0x00,0x00,
191 /* url only (IE7) */
192 static const unsigned char expected_hlink_data_ie7[] =
194 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
195 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
196 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
197 0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
198 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
199 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
200 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
201 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
202 0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
203 0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
204 0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
205 0x00,0x00,
208 /* url + friendly name */
209 static const unsigned char expected_hlink_data2[] =
211 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
212 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
213 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
214 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
215 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
216 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
217 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
218 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
219 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
220 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
221 0x67,0x00,0x2f,0x00,0x00,0x00,
224 /* url + friendly name (IE7) */
225 static const unsigned char expected_hlink_data2_ie7[] =
227 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
228 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
229 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
230 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
231 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
232 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
233 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
234 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
235 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
236 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
237 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
238 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
239 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
240 0x00,0x00,0xa5,0xab,0x00,0x00,
243 /* url + friendly name + location */
244 static const unsigned char expected_hlink_data3[] =
246 0x02,0x00,0x00,0x00,0x1f,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,0x26,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,0x07,0x00,
257 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
258 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
261 /* url + friendly name + location (IE7) */
262 static const unsigned char expected_hlink_data3_ie7[] =
264 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
265 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
266 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
267 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
268 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
269 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
270 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
271 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
272 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
273 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
274 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
275 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
276 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
277 0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
278 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
279 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
282 /* relative url */
283 static const unsigned char expected_hlink_data4[] =
285 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
286 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
287 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
288 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
289 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
290 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
291 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
292 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
293 0x00,0x00,0x00,0x00,0x00,
296 /* url + target frame name */
297 static const unsigned char expected_hlink_data5[] =
299 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
300 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
301 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
302 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
303 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
304 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
305 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
306 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
307 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
308 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
309 0x2f,0x00,0x00,0x00,
312 /* url + target frame name (IE7) */
313 static const unsigned char expected_hlink_data5_ie7[] =
315 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
316 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
317 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
318 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
319 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
320 0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
321 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
322 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
323 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
324 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
325 0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
326 0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
327 0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
328 0xa5,0xab,0x00,0x00,
331 /* filename */
332 static const unsigned char expected_hlink_data6[] =
334 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
335 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
336 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
337 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
338 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
339 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
340 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
341 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
342 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
343 0x5c,0x00,
346 static void test_persist_save_data(const char *testname, IHlink *lnk,
347 const unsigned char *expected_data,
348 unsigned int expected_data_size,
349 const unsigned char *expected_data_alt,
350 unsigned int expected_data_alt_size)
352 HRESULT hr;
353 IStream *stream;
354 IPersistStream *ps;
355 HGLOBAL hglobal;
356 DWORD data_size;
357 const unsigned char *data;
358 DWORD i;
359 BOOL same;
361 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
362 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
364 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
365 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
367 hr = IPersistStream_Save(ps, stream, TRUE);
368 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
370 hr = GetHGlobalFromStream(stream, &hglobal);
371 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
373 data_size = GlobalSize(hglobal);
375 data = GlobalLock(hglobal);
377 /* first check we have the right amount of data */
378 ok((data_size == expected_data_size) ||
379 (data_size == expected_data_alt_size),
380 "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
381 testname, expected_data_size, expected_data_alt_size, data_size);
383 same = TRUE;
384 /* then do a byte-by-byte comparison */
385 for (i = 0; i < min(data_size, expected_data_size); i++)
387 if ((expected_data[i] != data[i]) &&
388 (((expected_data != expected_hlink_data2) &&
389 (expected_data != expected_hlink_data3)) ||
390 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
392 same = FALSE;
393 break;
397 if (!same && (expected_data_alt != expected_data))
399 /* then try the alternate data */
400 same = TRUE;
401 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
403 if ((expected_data_alt == expected_hlink_data_ie7 && i == 89) /* Win10 */ ||
404 (expected_data_alt == expected_hlink_data2_ie7 && i == 109) /* Win10 */ ||
405 (expected_data_alt == expected_hlink_data3_ie7 && i == 109) /* Win10 */ ||
406 (expected_data_alt == expected_hlink_data5_ie7 && i == 107) /* Win10 */)
408 ok(data[i] == 0 || broken(data[i] == 1), "Expected 0 or 1, got %d", data[i]);
409 continue;
411 if ((expected_data_alt[i] != data[i]) &&
412 (((expected_data_alt != expected_hlink_data2) &&
413 (expected_data_alt != expected_hlink_data3)) ||
414 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
416 same = FALSE;
417 break;
422 ok(same, "%s: Saved data differs\n", testname);
423 if (!same)
425 for (i = 0; i < data_size; i++)
427 if (i % 8 == 0) printf(" ");
428 printf("0x%02x,", data[i]);
429 if (i % 8 == 7) printf("\n");
431 printf("\n");
434 GlobalUnlock(hglobal);
436 IStream_Release(stream);
437 IPersistStream_Release(ps);
440 static void test_persist(void)
442 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
443 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
444 static const WCHAR filename[] = { 'c',':','\\',0 };
445 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
446 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
447 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
448 HRESULT hr;
449 IHlink *lnk;
451 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
452 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
453 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
454 if (!lnk) {
455 skip("Can't create lnk, skipping test_persist.\n");
456 return;
458 test_persist_save_data("url only", lnk,
459 expected_hlink_data, sizeof(expected_hlink_data),
460 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
461 IHlink_Release(lnk);
463 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
464 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
465 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
466 test_persist_save_data("url + friendly name", lnk,
467 expected_hlink_data2, sizeof(expected_hlink_data2),
468 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
469 IHlink_Release(lnk);
471 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
472 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
473 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
474 test_persist_save_data("url + friendly_name + location", lnk,
475 expected_hlink_data3, sizeof(expected_hlink_data3),
476 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
477 IHlink_Release(lnk);
479 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
480 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
481 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
482 test_persist_save_data("relative url", lnk,
483 expected_hlink_data4, sizeof(expected_hlink_data4),
484 expected_hlink_data4, sizeof(expected_hlink_data4));
485 IHlink_Release(lnk);
487 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
488 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
489 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
490 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
491 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
492 test_persist_save_data("url + target frame name", lnk,
493 expected_hlink_data5, sizeof(expected_hlink_data5),
494 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
495 IHlink_Release(lnk);
497 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
498 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
499 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
500 test_persist_save_data("filename", lnk,
501 expected_hlink_data6, sizeof(expected_hlink_data6),
502 expected_hlink_data6, sizeof(expected_hlink_data6));
503 IHlink_Release(lnk);
506 static void test_special_reference(void)
508 LPWSTR ref;
509 HRESULT hres;
511 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
512 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
513 ok(ref != NULL, "ref == NULL\n");
514 CoTaskMemFree(ref);
516 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
517 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
518 ok(ref != NULL, "ref == NULL\n");
519 CoTaskMemFree(ref);
521 ref = (void*)0xdeadbeef;
522 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
523 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
524 ok(ref == NULL, "ref=%p\n", ref);
526 ref = (void*)0xdeadbeef;
527 hres = HlinkGetSpecialReference(4, &ref);
528 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
529 ok(ref == NULL, "ref=%p\n", ref);
532 static void test_HlinkCreateExtensionServices(void)
534 IAuthenticate *authenticate;
535 IHttpNegotiate *http_negotiate;
536 LPWSTR password, username, headers;
537 HWND hwnd;
538 HRESULT hres;
540 static const WCHAR usernameW[] = {'u','s','e','r',0};
541 static const WCHAR passwordW[] = {'p','a','s','s',0};
542 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
543 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
545 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
546 NULL, &IID_IAuthenticate, (void**)&authenticate);
547 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
548 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
550 password = username = (void*)0xdeadbeef;
551 hwnd = (void*)0xdeadbeef;
552 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
553 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
554 ok(!hwnd, "hwnd != NULL\n");
555 ok(!username, "username != NULL\n");
556 ok(!password, "password != NULL\n");
558 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
559 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
561 headers = (void*)0xdeadbeef;
562 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
563 0, &headers);
564 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
565 ok(headers == NULL, "headers != NULL\n");
567 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
568 0, NULL);
569 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
571 headers = (void*)0xdeadbeef;
572 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
573 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
574 ok(headers == NULL, "headers != NULL\n");
576 IHttpNegotiate_Release(http_negotiate);
577 IAuthenticate_Release(authenticate);
580 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
581 NULL, &IID_IAuthenticate, (void**)&authenticate);
582 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
583 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
585 password = username = NULL;
586 hwnd = NULL;
587 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
588 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
589 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
590 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
591 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
592 CoTaskMemFree(username);
593 CoTaskMemFree(password);
595 password = username = (void*)0xdeadbeef;
596 hwnd = (void*)0xdeadbeef;
597 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
598 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
599 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
600 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
602 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
603 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
605 headers = (void*)0xdeadbeef;
606 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
607 0, &headers);
608 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
609 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
610 CoTaskMemFree(headers);
612 headers = (void*)0xdeadbeef;
613 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
614 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
615 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
617 IHttpNegotiate_Release(http_negotiate);
618 IAuthenticate_Release(authenticate);
621 static void test_HlinkParseDisplayName(void)
623 IMoniker *mon = NULL;
624 LPWSTR name;
625 DWORD issys;
626 ULONG eaten = 0;
627 IBindCtx *bctx;
628 HRESULT hres;
630 static const WCHAR winehq_urlW[] =
631 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
632 '/','s','i','t','e','/','a','b','o','u','t',0};
633 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
634 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
635 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
636 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
637 static const WCHAR file_urlW[] =
638 {'f','i','l','e',':','/','/','/','c',':','\\','f','i','l','e','.','t','x','t',0};
640 CreateBindCtx(0, &bctx);
642 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
643 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
644 ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
645 ok(mon != NULL, "mon == NULL\n");
647 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
648 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
649 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
650 CoTaskMemFree(name);
652 hres = IMoniker_IsSystemMoniker(mon, &issys);
653 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
654 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
656 IMoniker_Release(mon);
658 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
659 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
660 ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
661 ok(mon != NULL, "mon == NULL\n");
663 hres = IMoniker_IsSystemMoniker(mon, &issys);
664 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
665 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
667 IMoniker_Release(mon);
669 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
670 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
671 ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
672 ok(mon != NULL, "mon == NULL\n");
674 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
675 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
676 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
677 CoTaskMemFree(name);
679 hres = IMoniker_IsSystemMoniker(mon, &issys);
680 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
681 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
683 IMoniker_Release(mon);
685 hres = HlinkParseDisplayName(bctx, file_urlW, FALSE, &eaten, &mon);
686 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
687 ok(eaten == sizeof(file_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
688 ok(mon != NULL, "mon == NULL\n");
690 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
691 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
692 ok(!lstrcmpW(name, file_urlW+8), "wrong display name %s\n", wine_dbgstr_w(name));
693 CoTaskMemFree(name);
695 hres = IMoniker_IsSystemMoniker(mon, &issys);
696 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
697 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
699 IMoniker_Release(mon);
700 IBindCtx_Release(bctx);
703 static IBindCtx *_bctx;
705 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
707 ok(0, "unexpected call\n");
708 return E_NOINTERFACE;
711 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
713 return 2;
716 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
718 return 1;
721 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
722 REFGUID guidService, REFIID riid, void **ppv)
724 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
725 return E_NOINTERFACE;
728 static IServiceProviderVtbl ServiceProviderVtbl = {
729 ServiceProvider_QueryInterface,
730 ServiceProvider_AddRef,
731 ServiceProvider_Release,
732 ServiceProvider_QueryService
735 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
737 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
739 *ppv = NULL;
741 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
742 *ppv = &ServiceProvider;
743 return S_OK;
746 ok(0, "unexpected interface %s\n", wine_dbgstr_guid(riid));
747 return E_NOINTERFACE;
750 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
752 return 2;
755 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
757 return 1;
760 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
761 IBinding *pib)
763 ok(0, "unexpected call\n");
764 return E_NOTIMPL;
767 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
769 ok(0, "unexpected call\n");
770 return E_NOTIMPL;
773 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
775 ok(0, "unexpected call\n");
776 return E_NOTIMPL;
779 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
780 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
782 ok(0, "unexpected call\n");
783 return E_NOTIMPL;
786 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
788 ok(0, "unexpected call\n");
789 return E_NOTIMPL;
792 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
794 ok(0, "unexpected call\n");
795 return E_NOTIMPL;
798 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
799 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
801 ok(0, "unexpected call\n");
802 return E_NOTIMPL;
805 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
807 ok(0, "unexpected call\n");
808 return E_NOTIMPL;
811 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
812 BindStatusCallback_QueryInterface,
813 BindStatusCallback_AddRef,
814 BindStatusCallback_Release,
815 BindStatusCallback_OnStartBinding,
816 BindStatusCallback_GetPriority,
817 BindStatusCallback_OnLowResource,
818 BindStatusCallback_OnProgress,
819 BindStatusCallback_OnStopBinding,
820 BindStatusCallback_GetBindInfo,
821 BindStatusCallback_OnDataAvailable,
822 BindStatusCallback_OnObjectAvailable
825 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
827 static HRESULT WINAPI HlinkBrowseContext_QueryInterface(
828 IHlinkBrowseContext *iface, REFIID riid, void **ppv)
830 *ppv = NULL;
832 if(IsEqualGUID(&IID_IHlinkHistory, riid)) {
833 CHECK_EXPECT(HBC_QueryInterface_IHlinkHistory);
834 return E_NOINTERFACE;
837 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
838 return E_NOINTERFACE;
841 static ULONG WINAPI HlinkBrowseContext_AddRef(IHlinkBrowseContext *iface)
843 return 2;
846 static ULONG WINAPI HlinkBrowseContext_Release(IHlinkBrowseContext *iface)
848 return 1;
851 static HRESULT WINAPI HlinkBrowseContext_Register(IHlinkBrowseContext *iface,
852 DWORD reserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister)
854 ok(0, "unexpected call\n");
855 return E_NOTIMPL;
858 static IMoniker Moniker;
859 static HRESULT WINAPI HlinkBrowseContext_GetObject(IHlinkBrowseContext *iface,
860 IMoniker *pimk, BOOL fBindIfRootRegistered, IUnknown **ppiunk)
862 CHECK_EXPECT(HBC_GetObject);
864 ok(pimk == &Moniker, "pimk != &Moniker\n");
865 ok(fBindIfRootRegistered == 1, "fBindIfRootRegistered = %x\n", fBindIfRootRegistered);
866 *ppiunk = NULL;
867 return S_FALSE;
870 static HRESULT WINAPI HlinkBrowseContext_Revoke(IHlinkBrowseContext *iface, DWORD dwRegister)
872 ok(0, "unexpected call\n");
873 return E_NOTIMPL;
876 static HRESULT WINAPI HlinkBrowseContext_SetBrowseWindowInfo(
877 IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
879 ok(0, "unexpected call\n");
880 return E_NOTIMPL;
883 static HRESULT WINAPI HlinkBrowseContext_GetBrowseWindowInfo(
884 IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
886 ok(0, "unexpected call\n");
887 return E_NOTIMPL;
890 static HRESULT WINAPI HlinkBrowseContext_SetInitialHlink(IHlinkBrowseContext *iface,
891 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
893 ok(0, "unexpected call\n");
894 return E_NOTIMPL;
897 static HRESULT WINAPI HlinkBrowseContext_OnNavigateHlink(IHlinkBrowseContext *iface, DWORD grfHLNF,
898 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, ULONG *puHLID)
900 ok(0, "unexpected call\n");
901 return E_NOTIMPL;
904 static HRESULT WINAPI HlinkBrowseContext_UpdateHlink(IHlinkBrowseContext *iface, ULONG uHLID,
905 IMoniker *pimkTarget, LPCWSTR location, LPCWSTR friendly_name)
907 CHECK_EXPECT(HBC_UpdateHlink);
908 return S_OK;
911 static HRESULT WINAPI HlinkBrowseContext_EnumNavigationStack(IHlinkBrowseContext *iface,
912 DWORD dwReserved, DWORD grfHLFNAMEF, IEnumHLITEM **ppienumhlitem)
914 ok(0, "unexpected call\n");
915 return E_NOTIMPL;
918 static HRESULT WINAPI HlinkBrowseContext_QueryHlink(IHlinkBrowseContext *iface,
919 DWORD grfHLQF, ULONG uHLID)
921 ok(0, "unexpected call\n");
922 return E_NOTIMPL;
925 static HRESULT WINAPI HlinkBrowseContext_GetHlink(IHlinkBrowseContext *iface,
926 ULONG uHLID, IHlink **ppihl)
928 ok(0, "unexpected call\n");
929 return E_NOTIMPL;
932 static HRESULT WINAPI HlinkBrowseContext_SetCurrentHlink(
933 IHlinkBrowseContext *iface, ULONG uHLID)
935 ok(0, "unexpected call\n");
936 return E_NOTIMPL;
939 static HRESULT WINAPI HlinkBrowseContext_Clone(IHlinkBrowseContext *iface,
940 IUnknown *piunkOuter, REFIID riid, IUnknown **ppiunkObj)
942 ok(0, "unexpected call\n");
943 return E_NOTIMPL;
946 static HRESULT WINAPI HlinkBrowseContext_Close(IHlinkBrowseContext *iface, DWORD reserved)
948 ok(0, "unexpected call\n");
949 return E_NOTIMPL;
952 static IHlinkBrowseContextVtbl HlinkBrowseContextVtbl = {
953 HlinkBrowseContext_QueryInterface,
954 HlinkBrowseContext_AddRef,
955 HlinkBrowseContext_Release,
956 HlinkBrowseContext_Register,
957 HlinkBrowseContext_GetObject,
958 HlinkBrowseContext_Revoke,
959 HlinkBrowseContext_SetBrowseWindowInfo,
960 HlinkBrowseContext_GetBrowseWindowInfo,
961 HlinkBrowseContext_SetInitialHlink,
962 HlinkBrowseContext_OnNavigateHlink,
963 HlinkBrowseContext_UpdateHlink,
964 HlinkBrowseContext_EnumNavigationStack,
965 HlinkBrowseContext_QueryHlink,
966 HlinkBrowseContext_GetHlink,
967 HlinkBrowseContext_SetCurrentHlink,
968 HlinkBrowseContext_Clone,
969 HlinkBrowseContext_Close
972 static IHlinkBrowseContext HlinkBrowseContext = { &HlinkBrowseContextVtbl };
974 static HRESULT WINAPI HlinkTarget_QueryInterface(IHlinkTarget *iface, REFIID riid, void **ppv)
976 if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
977 *ppv = iface;
978 return S_OK;
981 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
982 return E_NOINTERFACE;
985 static ULONG WINAPI HlinkTarget_AddRef(IHlinkTarget *iface)
987 return 2;
990 static ULONG WINAPI HlinkTarget_Release(IHlinkTarget *iface)
992 return 1;
995 static HRESULT WINAPI HlinkTarget_SetBrowseContext(IHlinkTarget *iface,
996 IHlinkBrowseContext *pihlbc)
998 CHECK_EXPECT(HT_SetBrowseContext);
1000 ok(pihlbc == &HlinkBrowseContext, "pihlbc != &HlinkBrowseContext (%p)\n", pihlbc);
1001 return S_OK;
1004 static HRESULT WINAPI HlinkTarget_GetBrowseContext(IHlinkTarget *iface,
1005 IHlinkBrowseContext **ppihlbc)
1007 CHECK_EXPECT(HT_GetBrowseContext);
1009 *ppihlbc = NULL;
1010 return S_OK;
1013 static HRESULT WINAPI HlinkTarget_Navigate(IHlinkTarget *iface,
1014 DWORD grfHLNF, LPCWSTR pwzJumpLocation)
1016 CHECK_EXPECT(HT_Navigate);
1018 ok(grfHLNF == 0, "grfHLNF = %x\n", grfHLNF);
1019 ok(pwzJumpLocation == NULL, "pwzJumpLocation = %s\n", wine_dbgstr_w(pwzJumpLocation));
1020 return S_OK;
1023 static HRESULT WINAPI HlinkTarget_GetMoniker(IHlinkTarget *iface,
1024 LPCWSTR pwzLocation, DWORD dwAssign, IMoniker **ppimkLocation)
1026 ok(0, "unexpected call\n");
1027 return E_NOTIMPL;
1030 static HRESULT WINAPI HlinkTarget_GetFriendlyName(IHlinkTarget *iface,
1031 LPCWSTR pwzLocation, LPWSTR *ppwzFriendlyName)
1033 CHECK_EXPECT(HT_GetFriendlyName);
1034 return E_NOTIMPL;
1037 static IHlinkTargetVtbl HlinkTargetVtbl = {
1038 HlinkTarget_QueryInterface,
1039 HlinkTarget_AddRef,
1040 HlinkTarget_Release,
1041 HlinkTarget_SetBrowseContext,
1042 HlinkTarget_GetBrowseContext,
1043 HlinkTarget_Navigate,
1044 HlinkTarget_GetMoniker,
1045 HlinkTarget_GetFriendlyName
1048 static IHlinkTarget HlinkTarget = { &HlinkTargetVtbl };
1050 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
1052 *ppv = NULL;
1054 ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid));
1055 return E_NOINTERFACE;
1058 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
1060 return 2;
1063 static ULONG WINAPI Moniker_Release(IMoniker *iface)
1065 return 1;
1068 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
1070 CHECK_EXPECT(GetClassID);
1071 *pClassID = IID_IUnknown; /* not a valid CLSID */
1072 return S_OK;
1075 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
1077 ok(0, "unexpected call\n");
1078 return E_NOTIMPL;
1081 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
1083 ok(0, "unexpected call\n");
1084 return E_NOTIMPL;
1087 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
1089 CHECK_EXPECT(Save);
1090 return S_OK;
1093 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
1095 ok(0, "unexpected call\n");
1096 return E_NOTIMPL;
1099 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1100 REFIID riid, void **ppv)
1102 CHECK_EXPECT(BindToObject);
1104 ok(pbc != _bctx, "pbc != _bctx\n");
1105 ok(pmkToLeft == NULL, "pmkToLeft = %p\n", pmkToLeft);
1106 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1107 ok(ppv != NULL, "ppv == NULL\n");
1108 ok(*ppv == NULL, "*ppv = %p\n", *ppv);
1110 *ppv = &HlinkTarget;
1111 return S_OK;
1114 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1115 REFIID riid, void **ppv)
1117 IUnknown *unk;
1118 HRESULT hres;
1120 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
1122 CHECK_EXPECT(BindToStorage);
1124 ok(pbc == _bctx, "pbc != _bctx\n");
1125 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1126 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1127 ok(ppv != NULL, "ppv == NULL\n");
1128 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
1130 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
1131 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
1132 ok(unk != NULL, "unk == NULL\n");
1134 IUnknown_Release(unk);
1136 return S_OK;
1139 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
1140 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
1142 CHECK_EXPECT(Reduce);
1143 return E_NOTIMPL;
1146 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
1147 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
1149 ok(0, "unexpected call\n");
1150 return E_NOTIMPL;
1153 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
1155 CHECK_EXPECT(Enum);
1156 return E_NOTIMPL;
1159 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
1161 ok(0, "unexpected call\n");
1162 return E_NOTIMPL;
1165 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
1167 ok(0, "unexpected call\n");
1168 return E_NOTIMPL;
1171 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1172 IMoniker *pmkNewlyRunning)
1174 ok(0, "unexpected call\n");
1175 return E_NOTIMPL;
1178 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
1179 IMoniker *pmkToLeft, FILETIME *pFileTime)
1181 ok(0, "unexpected call\n");
1182 return E_NOTIMPL;
1185 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
1187 ok(0, "unexpected call\n");
1188 return E_NOTIMPL;
1191 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
1192 IMoniker **ppmkPrefix)
1194 ok(0, "unexpected call\n");
1195 return E_NOTIMPL;
1198 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
1199 IMoniker **pmkRelPath)
1201 ok(0, "unexpected call\n");
1202 return E_NOTIMPL;
1205 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
1206 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
1208 static const WCHAR winehq_urlW[] =
1209 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
1210 '/','s','i','t','e','/','a','b','o','u','t',0};
1212 CHECK_EXPECT2(GetDisplayName);
1214 ok(pbc != NULL, "pbc == NULL\n");
1215 ok(pbc != _bctx, "pbc == _bctx\n");
1216 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1218 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
1219 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
1220 return S_OK;
1223 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
1224 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
1226 ok(0, "unexpected call\n");
1227 return E_NOTIMPL;
1230 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
1232 CHECK_EXPECT2(IsSystemMoniker);
1234 *pdwMksys = MKSYS_URLMONIKER;
1235 return S_OK;
1238 static IMonikerVtbl MonikerVtbl = {
1239 Moniker_QueryInterface,
1240 Moniker_AddRef,
1241 Moniker_Release,
1242 Moniker_GetClassID,
1243 Moniker_IsDirty,
1244 Moniker_Load,
1245 Moniker_Save,
1246 Moniker_GetSizeMax,
1247 Moniker_BindToObject,
1248 Moniker_BindToStorage,
1249 Moniker_Reduce,
1250 Moniker_ComposeWith,
1251 Moniker_Enum,
1252 Moniker_IsEqual,
1253 Moniker_Hash,
1254 Moniker_IsRunning,
1255 Moniker_GetTimeOfLastChange,
1256 Moniker_Inverse,
1257 Moniker_CommonPrefixWith,
1258 Moniker_RelativePathTo,
1259 Moniker_GetDisplayName,
1260 Moniker_ParseDisplayName,
1261 Moniker_IsSystemMoniker
1264 static IMoniker Moniker = { &MonikerVtbl };
1266 static void test_HlinkResolveMonikerForData(void)
1268 IBindCtx *bctx;
1269 HRESULT hres;
1271 CreateBindCtx(0, &bctx);
1272 _bctx = bctx;
1274 SET_EXPECT(IsSystemMoniker);
1275 SET_EXPECT(GetDisplayName);
1276 SET_EXPECT(BindToStorage);
1278 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1279 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1281 CHECK_CALLED(IsSystemMoniker);
1282 CHECK_CALLED(GetDisplayName);
1283 CHECK_CALLED(BindToStorage);
1285 IBindCtx_Release(bctx);
1286 _bctx = NULL;
1289 static void test_HlinkGetSetMonikerReference(void)
1291 IMoniker *found_trgt, *dummy, *dummy2;
1292 IHlink *hlink;
1293 HRESULT hres;
1294 const WCHAR one[] = {'1',0};
1295 const WCHAR two[] = {'2',0};
1296 const WCHAR name[] = {'a',0};
1297 WCHAR *found_loc;
1299 /* create two dummy monikers to use as targets */
1300 hres = CreateItemMoniker(one, one, &dummy);
1301 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1303 hres = CreateItemMoniker(two, two, &dummy2);
1304 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1306 /* create a new hlink: target => dummy, location => one */
1307 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1308 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1310 /* validate the target and location */
1311 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1312 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1313 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1314 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1315 IMoniker_Release(found_trgt);
1316 CoTaskMemFree(found_loc);
1318 /* set location => two */
1319 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1320 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1322 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1323 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1324 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1325 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1326 IMoniker_Release(found_trgt);
1327 CoTaskMemFree(found_loc);
1329 /* set target => dummy2 */
1330 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1331 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1333 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1334 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1335 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1336 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1337 IMoniker_Release(found_trgt);
1338 CoTaskMemFree(found_loc);
1340 /* set target => dummy, location => one */
1341 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1342 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1344 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1345 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1346 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1347 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1348 IMoniker_Release(found_trgt);
1349 CoTaskMemFree(found_loc);
1351 /* no HLINKSETF flags */
1352 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1353 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1355 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1356 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1357 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1358 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1359 IMoniker_Release(found_trgt);
1360 CoTaskMemFree(found_loc);
1362 /* invalid HLINKSETF flags */
1363 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1364 if (0)
1365 IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1367 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1368 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1369 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1370 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1371 IMoniker_Release(found_trgt);
1372 CoTaskMemFree(found_loc);
1374 /* valid & invalid HLINKSETF flags */
1375 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1376 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1378 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1379 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1380 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1381 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1382 IMoniker_Release(found_trgt);
1383 CoTaskMemFree(found_loc);
1385 /* NULL args */
1386 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1387 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1389 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1390 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1391 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1392 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1393 if(found_trgt)
1394 IMoniker_Release(found_trgt);
1396 IHlink_Release(hlink);
1397 IMoniker_Release(dummy2);
1398 IMoniker_Release(dummy);
1400 SET_EXPECT(Reduce);
1401 SET_EXPECT(Enum);
1402 SET_EXPECT(IsSystemMoniker);
1403 SET_EXPECT(GetDisplayName);
1404 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL, 0, NULL,
1405 &IID_IHlink, (void **)&hlink);
1406 ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1408 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_ABSOLUTE,
1409 &found_trgt, &found_loc);
1410 ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1411 ok(found_trgt == &Moniker, "Got unexpected moniker: %p\n", found_trgt);
1412 ok(found_loc == NULL, "Got unexpected location: %p\n", found_loc);
1413 todo_wine CHECK_CALLED(Reduce);
1414 todo_wine CHECK_CALLED(Enum);
1415 CHECK_CALLED(IsSystemMoniker);
1416 CHECK_CALLED(GetDisplayName);
1418 IHlink_Release(hlink);
1421 static void test_HlinkGetSetStringReference(void)
1423 IHlink *link;
1424 static const WCHAR one[] = {'1',0};
1425 static const WCHAR two[] = {'2',0};
1426 static const WCHAR three[] = {'3',0};
1427 static const WCHAR empty[] = {0};
1428 WCHAR *fnd_tgt, *fnd_loc;
1429 HRESULT hres;
1431 /* create a new hlink: target => NULL, location => one */
1432 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1433 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1435 /* test setting/getting location */
1436 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1437 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1438 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1439 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1440 CoTaskMemFree(fnd_tgt);
1441 CoTaskMemFree(fnd_loc);
1443 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1444 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1446 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1447 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1448 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1449 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1450 CoTaskMemFree(fnd_tgt);
1451 CoTaskMemFree(fnd_loc);
1453 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1454 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1456 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1457 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1458 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1459 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1460 CoTaskMemFree(fnd_tgt);
1461 CoTaskMemFree(fnd_loc);
1463 /* test setting/getting target */
1464 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1465 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1467 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1468 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1469 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1470 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1471 CoTaskMemFree(fnd_tgt);
1472 CoTaskMemFree(fnd_loc);
1474 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1475 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1477 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1478 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1479 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1480 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1481 CoTaskMemFree(fnd_tgt);
1482 CoTaskMemFree(fnd_loc);
1484 /* test setting/getting both */
1485 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1486 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1488 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1489 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1490 ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1491 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1492 CoTaskMemFree(fnd_tgt);
1493 CoTaskMemFree(fnd_loc);
1495 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1496 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1498 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1499 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1500 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1501 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1502 CoTaskMemFree(fnd_tgt);
1503 CoTaskMemFree(fnd_loc);
1505 /* test invalid flags/params */
1506 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1507 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1508 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1509 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1510 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1511 CoTaskMemFree(fnd_tgt);
1512 CoTaskMemFree(fnd_loc);
1514 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1515 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1516 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1517 CoTaskMemFree(fnd_tgt);
1519 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1520 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1522 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1523 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1524 CoTaskMemFree(fnd_loc);
1526 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1527 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1528 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1529 CoTaskMemFree(fnd_tgt);
1530 CoTaskMemFree(fnd_loc);
1532 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1533 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1534 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1535 CoTaskMemFree(fnd_tgt);
1536 CoTaskMemFree(fnd_loc);
1538 if (0)
1540 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1541 IHlink_SetStringReference(link, 4, NULL, NULL);
1542 IHlink_SetStringReference(link, -4, NULL, NULL);
1545 IHlink_Release(link);
1548 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1549 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1551 HRESULT hres;
1552 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1553 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1556 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1557 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1559 HRESULT hres;
1560 WCHAR *fnd_tgt, *fnd_loc;
1562 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1563 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1565 if(exp_tgt)
1566 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));
1567 else
1568 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1570 if(exp_loc)
1571 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));
1572 else
1573 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1575 CoTaskMemFree(fnd_tgt);
1576 CoTaskMemFree(fnd_loc);
1579 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1580 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1582 HRESULT hres;
1583 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1584 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1587 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1588 #define getMonikerRef(h,t,l,r) r_getMonikerRef(__LINE__,h,t,l,r)
1589 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc, DWORD ref)
1591 HRESULT hres;
1592 IMoniker *fnd_tgt;
1593 WCHAR *fnd_loc;
1595 hres = IHlink_GetMonikerReference(hlink, ref, &fnd_tgt, &fnd_loc);
1596 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1598 if(exp_loc)
1599 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));
1600 else
1601 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1603 CoTaskMemFree(fnd_loc);
1605 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1606 return fnd_tgt;
1608 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1610 if(fnd_tgt)
1611 IMoniker_Release(fnd_tgt);
1613 return NULL;
1616 static void test_HlinkMoniker(void)
1618 IHlink *hlink;
1619 IMoniker *aMon, *file_mon;
1620 static const WCHAR emptyW[] = {0};
1621 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1622 static const WCHAR aW[] = {'a',0};
1623 static const WCHAR bW[] = {'b',0};
1624 HRESULT hres;
1626 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1627 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1628 getStringRef(hlink, NULL, NULL);
1629 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1631 /* setting a string target creates a moniker reference */
1632 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1633 getStringRef(hlink, aW, wordsW);
1634 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW, HLINKGETREF_RELATIVE);
1635 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1636 if(aMon)
1637 IMoniker_Release(aMon);
1639 /* setting target & location to the empty string deletes the moniker
1640 * reference */
1641 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1642 getStringRef(hlink, NULL, NULL);
1643 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1645 /* setting a moniker target also sets the target string to that moniker's
1646 * display name */
1647 hres = CreateFileMoniker(bW, &file_mon);
1648 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1650 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1651 getStringRef(hlink, bW, wordsW);
1652 getMonikerRef(hlink, file_mon, wordsW, HLINKGETREF_RELATIVE);
1654 IMoniker_Release(file_mon);
1656 IHlink_Release(hlink);
1659 static void test_HashLink(void)
1661 IHlink *hlink;
1662 IMoniker *pmk;
1663 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1664 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};
1665 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1666 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1667 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1668 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1669 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1670 HRESULT hres;
1672 /* simple single hash test */
1673 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1674 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1675 ok(hlink != NULL, "Didn't get an hlink\n");
1677 if(hlink){
1678 getStringRef(hlink, tgt_partW, loc_partW);
1679 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1680 ok(pmk != NULL, "Found moniker should not be NULL\n");
1681 if(pmk)
1682 IMoniker_Release(pmk);
1684 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1685 getStringRef(hlink, hash_targetW, loc_partW);
1687 IHlink_Release(hlink);
1690 /* two hashes in the target */
1691 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1692 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1693 ok(hlink != NULL, "Didn't get an hlink\n");
1695 if(hlink){
1696 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1697 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW, HLINKGETREF_RELATIVE);
1698 ok(pmk != NULL, "Found moniker should not be NULL\n");
1699 if(pmk)
1700 IMoniker_Release(pmk);
1702 IHlink_Release(hlink);
1705 /* target with hash plus a location string */
1706 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1707 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1708 ok(hlink != NULL, "Didn't get an hlink\n");
1710 if(hlink){
1711 getStringRef(hlink, tgt_partW, test_locW);
1712 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW, HLINKGETREF_RELATIVE);
1713 ok(pmk != NULL, "Found moniker should not be NULL\n");
1714 if(pmk)
1715 IMoniker_Release(pmk);
1717 IHlink_Release(hlink);
1720 /* target with hash containing no "target part" */
1721 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1722 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1723 ok(hlink != NULL, "Didn't get an hlink\n");
1725 if(hlink){
1726 getStringRef(hlink, NULL, loc_partW);
1727 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1728 ok(pmk == NULL, "Found moniker should be NULL\n");
1729 if(pmk)
1730 IMoniker_Release(pmk);
1732 IHlink_Release(hlink);
1736 static const WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1737 static const WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1739 static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
1740 IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1742 ok(0, "BTS: %p %p %p %s %p\n", iface, pbc, toLeft, wine_dbgstr_guid(riid), obj);
1743 return E_NOTIMPL;
1746 static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
1747 IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1749 LPOLESTR rightName;
1750 HRESULT hres;
1752 ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1754 CHECK_EXPECT(ComposeWith);
1756 hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1757 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1758 ok(!lstrcmpW(rightName, ref_monikerW),
1759 "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1760 wine_dbgstr_w(rightName));
1761 CoTaskMemFree(rightName);
1763 *composite = NULL;
1765 /* unlikely error code to verify this return result is used */
1766 return E_OUTOFMEMORY;
1769 static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
1770 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1772 *displayName = CoTaskMemAlloc(sizeof(site_monikerW));
1773 memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
1774 return S_OK;
1777 static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
1778 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1780 *displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
1781 memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
1782 return S_OK;
1785 static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
1786 DWORD *mksys)
1788 return S_FALSE;
1791 static IMonikerVtbl hls_site_MonikerVtbl = {
1792 Moniker_QueryInterface,
1793 Moniker_AddRef,
1794 Moniker_Release,
1795 Moniker_GetClassID,
1796 Moniker_IsDirty,
1797 Moniker_Load,
1798 Moniker_Save,
1799 Moniker_GetSizeMax,
1800 Moniker_BindToObject,
1801 hls_test_Moniker_BindToStorage,
1802 Moniker_Reduce,
1803 hls_site_Moniker_ComposeWith,
1804 Moniker_Enum,
1805 Moniker_IsEqual,
1806 Moniker_Hash,
1807 Moniker_IsRunning,
1808 Moniker_GetTimeOfLastChange,
1809 Moniker_Inverse,
1810 Moniker_CommonPrefixWith,
1811 Moniker_RelativePathTo,
1812 hls_site_Moniker_GetDisplayName,
1813 Moniker_ParseDisplayName,
1814 hls_test_Moniker_IsSystemMoniker
1817 static IMonikerVtbl hls_ref_MonikerVtbl = {
1818 Moniker_QueryInterface,
1819 Moniker_AddRef,
1820 Moniker_Release,
1821 Moniker_GetClassID,
1822 Moniker_IsDirty,
1823 Moniker_Load,
1824 Moniker_Save,
1825 Moniker_GetSizeMax,
1826 Moniker_BindToObject,
1827 hls_test_Moniker_BindToStorage,
1828 Moniker_Reduce,
1829 Moniker_ComposeWith,
1830 Moniker_Enum,
1831 Moniker_IsEqual,
1832 Moniker_Hash,
1833 Moniker_IsRunning,
1834 Moniker_GetTimeOfLastChange,
1835 Moniker_Inverse,
1836 Moniker_CommonPrefixWith,
1837 Moniker_RelativePathTo,
1838 hls_ref_Moniker_GetDisplayName,
1839 Moniker_ParseDisplayName,
1840 hls_test_Moniker_IsSystemMoniker
1843 static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
1844 static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
1846 static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
1847 void **obj)
1849 ok(0, "QI: %p %s %p\n", iface, wine_dbgstr_guid(iid), obj);
1850 return E_NOTIMPL;
1853 static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
1855 return 2;
1858 static ULONG WINAPI hls_Release(IHlinkSite *iface)
1860 return 1;
1863 static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
1864 REFGUID service, REFIID riid, IUnknown **punk)
1866 ok(0, "QS: %p %x %s %s %p\n", iface, siteData, wine_dbgstr_guid(service),
1867 wine_dbgstr_guid(riid), punk);
1868 return E_NOTIMPL;
1871 #define SITEDATA_SUCCESS 1
1872 #define SITEDATA_NOTIMPL 2
1874 static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
1875 DWORD assign, DWORD which, IMoniker **pmk)
1877 ok(siteData == SITEDATA_NOTIMPL ||
1878 siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1880 if(siteData == SITEDATA_SUCCESS){
1881 *pmk = &hls_site_Moniker;
1882 return S_OK;
1885 return E_NOTIMPL;
1888 static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
1889 DWORD reserved)
1891 ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
1892 return E_NOTIMPL;
1895 static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
1896 DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1898 CHECK_EXPECT(OnNavigationComplete);
1899 ok(siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1900 ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
1901 return E_NOTIMPL;
1904 static IHlinkSiteVtbl HlinkSiteVtbl = {
1905 hls_QueryInterface,
1906 hls_AddRef,
1907 hls_Release,
1908 hls_QueryService,
1909 hls_GetMoniker,
1910 hls_ReadyToNavigate,
1911 hls_OnNavigationComplete
1914 static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
1916 static void test_HlinkSite(void)
1918 IHlink *hl;
1919 IMoniker *mon_ref;
1920 IBindCtx *pbc;
1921 HRESULT hres;
1923 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1924 &IID_IHlink, (LPVOID*)&hl);
1925 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1926 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1928 hres = IHlink_SetHlinkSite(hl, &HlinkSite, SITEDATA_SUCCESS);
1929 ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
1930 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1931 getStringRef(hl, NULL, NULL);
1933 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1934 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1935 ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
1937 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1938 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1939 ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1941 SET_EXPECT(Reduce);
1942 SET_EXPECT(Enum);
1943 hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
1944 ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
1945 todo_wine CHECK_CALLED(Reduce);
1946 todo_wine CHECK_CALLED(Enum);
1948 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
1950 SET_EXPECT(Enum);
1951 getStringRef(hl, ref_monikerW, NULL);
1952 todo_wine CHECK_CALLED(Enum);
1954 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1955 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1956 ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1957 IMoniker_Release(mon_ref);
1959 SET_EXPECT(ComposeWith);
1960 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1961 ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
1962 ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
1963 CHECK_CALLED(ComposeWith);
1965 hres = CreateBindCtx(0, &pbc);
1966 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1968 SET_EXPECT(ComposeWith);
1969 SET_EXPECT(OnNavigationComplete);
1970 hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
1971 ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
1972 CHECK_CALLED(ComposeWith);
1973 CHECK_CALLED(OnNavigationComplete);
1975 IBindCtx_Release(pbc);
1976 IHlink_Release(hl);
1978 SET_EXPECT(Reduce);
1979 SET_EXPECT(Enum);
1980 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
1981 NULL, &IID_IHlink, (LPVOID*)&hl);
1982 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1983 todo_wine CHECK_CALLED(Reduce);
1984 todo_wine CHECK_CALLED(Enum);
1985 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
1986 IHlink_Release(hl);
1988 hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
1989 NULL, &IID_IHlink, (LPVOID*)&hl);
1990 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1991 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1992 IHlink_Release(hl);
1994 SET_EXPECT(Reduce);
1995 SET_EXPECT(Enum);
1996 SET_EXPECT(IsSystemMoniker);
1997 SET_EXPECT(GetDisplayName);
1998 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, &HlinkSite, SITEDATA_NOTIMPL,
1999 NULL, &IID_IHlink, (LPVOID*)&hl);
2000 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2001 getMonikerRef(hl, &Moniker, NULL, HLINKGETREF_ABSOLUTE);
2002 IHlink_Release(hl);
2003 todo_wine CHECK_CALLED(Reduce);
2004 todo_wine CHECK_CALLED(Enum);
2005 CHECK_CALLED(IsSystemMoniker);
2006 CHECK_CALLED(GetDisplayName);
2009 static void test_HlinkClone(void)
2011 HRESULT hres;
2012 IHlink *hl, *cloned = NULL;
2013 IMoniker *dummy, *fnd_mk;
2014 IHlinkSite *fnd_site;
2015 WCHAR *fnd_name;
2016 DWORD fnd_data;
2017 const WCHAR one[] = {'1',0};
2018 const WCHAR two[] = {'2',0};
2019 const WCHAR name[] = {'a',0};
2021 hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
2022 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
2024 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
2025 &IID_IHlink, (void**)&hl);
2026 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
2028 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
2029 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
2031 if (0)
2033 /* crash on Windows XP */
2034 HlinkClone(hl, NULL, NULL, 0, NULL);
2036 HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
2039 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2040 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2041 ok(cloned != NULL, "Didn't get a clone\n");
2042 getMonikerRef(cloned, NULL, NULL, HLINKGETREF_RELATIVE);
2043 IHlink_Release(cloned);
2045 IHlink_Release(hl);
2047 SET_EXPECT(Reduce);
2048 SET_EXPECT(Enum);
2049 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2050 todo_wine CHECK_CALLED(Reduce);
2051 todo_wine CHECK_CALLED(Enum);
2052 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2053 getMonikerRef(hl, &hls_ref_Moniker, two, HLINKGETREF_RELATIVE);
2055 SET_EXPECT(Save);
2056 SET_EXPECT(GetClassID);
2057 cloned = (IHlink*)0xdeadbeef;
2058 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2059 /* fails because of invalid CLSID given by Moniker_GetClassID */
2060 ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08x\n", hres);
2061 ok(cloned == NULL, "Shouldn't have gotten a clone\n");
2062 CHECK_CALLED(Save);
2063 CHECK_CALLED(GetClassID);
2065 IHlink_Release(hl);
2067 hres = CreateItemMoniker(one, one, &dummy);
2068 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
2070 hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, SITEDATA_SUCCESS, NULL, &IID_IHlink, (void**)&hl);
2071 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2072 getMonikerRef(hl, dummy, two, HLINKGETREF_RELATIVE);
2074 cloned = NULL;
2075 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2076 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2077 ok(cloned != NULL, "Should have gotten a clone\n");
2079 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two, HLINKGETREF_RELATIVE);
2080 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2081 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2083 fnd_name = NULL;
2084 hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
2085 ok(hres == S_OK, "GetFriendlyName failed: %08x\n", hres);
2086 ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
2087 ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
2088 wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
2089 CoTaskMemFree(fnd_name);
2091 fnd_site = (IHlinkSite*)0xdeadbeef;
2092 fnd_data = 4;
2093 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2094 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
2095 ok(fnd_site == NULL, "Expected NULL site\n");
2096 ok(fnd_data == 4, "Expected site data to be 4, was: %d\n", fnd_data);
2098 IHlink_Release(cloned);
2099 IHlink_Release(hl);
2101 hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2102 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2103 getMonikerRef(hl, dummy, NULL, HLINKGETREF_RELATIVE);
2105 cloned = NULL;
2106 hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, SITEDATA_SUCCESS, (void**)&cloned);
2107 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2108 ok(cloned != NULL, "Should have gotten a clone\n");
2110 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL, HLINKGETREF_RELATIVE);
2111 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2112 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2114 fnd_site = (IHlinkSite*)0xdeadbeef;
2115 fnd_data = 4;
2116 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2117 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
2118 ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
2119 ok(fnd_data == SITEDATA_SUCCESS, "Unexpected site data: %u\n", fnd_data);
2121 IHlink_Release(cloned);
2122 IHlink_Release(hl);
2124 IMoniker_Release(dummy);
2127 static void test_StdHlink(void)
2129 IHlink *hlink;
2130 WCHAR *str;
2131 HRESULT hres;
2133 static const WCHAR testW[] = {'t','e','s','t',0};
2135 hres = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2136 &IID_IHlink, (void**)&hlink);
2137 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2139 str = (void*)0xdeadbeef;
2140 hres = IHlink_GetTargetFrameName(hlink, &str);
2141 ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
2142 ok(!str, "str = %s\n", wine_dbgstr_w(str));
2144 hres = IHlink_SetTargetFrameName(hlink, testW);
2145 ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
2147 str = (void*)0xdeadbeef;
2148 hres = IHlink_GetTargetFrameName(hlink, &str);
2149 ok(hres == S_OK, "GetTargetFrameName failed: %08x\n", hres);
2150 ok(!lstrcmpW(str, testW), "str = %s\n", wine_dbgstr_w(str));
2151 CoTaskMemFree(str);
2153 hres = IHlink_SetTargetFrameName(hlink, NULL);
2154 ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
2156 str = (void*)0xdeadbeef;
2157 hres = IHlink_GetTargetFrameName(hlink, &str);
2158 ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
2159 ok(!str, "str = %s\n", wine_dbgstr_w(str));
2161 IHlink_Release(hlink);
2164 static void test_Hlink_Navigate(void)
2166 IHlink *hlink;
2167 IBindCtx *pbc;
2168 HRESULT hres;
2170 hres = CreateBindCtx(0, &pbc);
2171 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2172 _bctx = pbc;
2174 SET_EXPECT(Reduce);
2175 SET_EXPECT(Enum);
2176 SET_EXPECT(IsSystemMoniker);
2177 SET_EXPECT(GetDisplayName);
2178 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL,
2179 0, NULL, &IID_IHlink, (void**)&hlink);
2180 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2181 todo_wine CHECK_CALLED(Reduce);
2182 todo_wine CHECK_CALLED(Enum);
2183 todo_wine CHECK_CALLED(IsSystemMoniker);
2184 CHECK_CALLED(GetDisplayName);
2186 SET_EXPECT(IsSystemMoniker);
2187 SET_EXPECT(GetDisplayName);
2188 SET_EXPECT(HBC_GetObject);
2189 SET_EXPECT(Reduce);
2190 SET_EXPECT(BindToObject);
2191 SET_EXPECT(HT_GetBrowseContext);
2192 SET_EXPECT(HT_SetBrowseContext);
2193 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2194 SET_EXPECT(HT_Navigate);
2195 SET_EXPECT(HT_GetFriendlyName);
2196 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2197 ok(hres == S_OK, "Navigate failed: %08x\n", hres);
2198 CHECK_CALLED(IsSystemMoniker);
2199 todo_wine CHECK_CALLED(GetDisplayName);
2200 todo_wine CHECK_CALLED(HBC_GetObject);
2201 todo_wine CHECK_CALLED(Reduce);
2202 CHECK_CALLED(BindToObject);
2203 todo_wine CHECK_CALLED(HT_GetBrowseContext);
2204 CHECK_CALLED(HT_SetBrowseContext);
2205 todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2206 CHECK_CALLED(HT_Navigate);
2207 todo_wine CHECK_CALLED(HT_GetFriendlyName);
2209 IHlink_Release(hlink);
2210 IBindCtx_Release(pbc);
2211 _bctx = NULL;
2214 static HRESULT WINAPI hlinkframe_QueryInterface(IHlinkFrame *iface, REFIID riid, void **obj)
2216 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IHlinkFrame))
2218 *obj = iface;
2219 return S_OK;
2222 *obj = NULL;
2223 return E_NOINTERFACE;
2226 static ULONG WINAPI hlinkframe_AddRef(IHlinkFrame *iface)
2228 return 2;
2231 static ULONG WINAPI hlinkframe_Release(IHlinkFrame *iface)
2233 return 1;
2236 static HRESULT WINAPI hlinkframe_SetBrowseContext(IHlinkFrame *iface, IHlinkBrowseContext *bc)
2238 ok(0, "unexpected %p\n", bc);
2239 return E_NOTIMPL;
2242 static HRESULT WINAPI hlinkframe_GetBrowseContext(IHlinkFrame *iface, IHlinkBrowseContext **bc)
2244 *bc = NULL;
2245 ok(0, "unexpected %p\n", bc);
2246 return E_NOTIMPL;
2249 static HRESULT WINAPI hlinkframe_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc, IBindStatusCallback *bsc, IHlink *navigate)
2251 ok(0, "unexpected\n");
2252 return E_NOTIMPL;
2255 static HRESULT WINAPI hlinkframe_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name,
2256 DWORD reserved)
2258 ok(0, "unexpected\n");
2259 return E_NOTIMPL;
2262 static HRESULT WINAPI hlinkframe_UpdateHlink(IHlinkFrame *iface, ULONG uHLID, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name)
2264 CHECK_EXPECT(HLF_UpdateHlink);
2265 return S_OK;
2268 static IHlinkFrameVtbl hlinkframevtbl = {
2269 hlinkframe_QueryInterface,
2270 hlinkframe_AddRef,
2271 hlinkframe_Release,
2272 hlinkframe_SetBrowseContext,
2273 hlinkframe_GetBrowseContext,
2274 hlinkframe_Navigate,
2275 hlinkframe_OnNavigate,
2276 hlinkframe_UpdateHlink
2279 static IHlinkFrame testframe = { &hlinkframevtbl };
2281 static void test_HlinkUpdateStackItem(void)
2283 static const WCHAR location[] = {'l','o','c','a','t','i','o','n',0};
2284 HRESULT hr;
2286 hr = HlinkUpdateStackItem(NULL, NULL, HLID_CURRENT, &Moniker, location, NULL);
2287 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2289 SET_EXPECT(HBC_UpdateHlink);
2290 hr = HlinkUpdateStackItem(NULL, &HlinkBrowseContext, HLID_CURRENT, &Moniker, location, NULL);
2291 ok(hr == S_OK, "got 0x%08x\n", hr);
2292 CHECK_CALLED(HBC_UpdateHlink);
2294 SET_EXPECT(HLF_UpdateHlink);
2295 hr = HlinkUpdateStackItem(&testframe, &HlinkBrowseContext, HLID_CURRENT, &Moniker, location, NULL);
2296 ok(hr == S_OK, "got 0x%08x\n", hr);
2297 CHECK_CALLED(HLF_UpdateHlink);
2300 START_TEST(hlink)
2302 CoInitialize(NULL);
2304 test_HlinkIsShortcut();
2305 test_reference();
2306 test_persist();
2307 test_special_reference();
2308 test_HlinkCreateExtensionServices();
2309 test_HlinkParseDisplayName();
2310 test_HlinkResolveMonikerForData();
2311 test_HlinkGetSetMonikerReference();
2312 test_HlinkGetSetStringReference();
2313 test_HlinkMoniker();
2314 test_HashLink();
2315 test_HlinkSite();
2316 test_HlinkClone();
2317 test_StdHlink();
2318 test_Hlink_Navigate();
2319 test_HlinkUpdateStackItem();
2321 CoUninitialize();