hlink: Don't query the IHlinkSite if the IMoniker is a system moniker.
[wine/multimedia.git] / dlls / hlink / tests / hlink.c
blob4a8eb44fe1d48933a632f29e895323ea7fd3719d
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(GetDisplayName);
60 DEFINE_EXPECT(ComposeWith);
61 DEFINE_EXPECT(OnNavigationComplete);
62 DEFINE_EXPECT(Enum);
63 DEFINE_EXPECT(Reduce);
65 DEFINE_EXPECT(GetClassID);
66 DEFINE_EXPECT(Save);
68 static const char *debugstr_guid(REFIID riid)
70 static char buf[50];
72 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
73 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
74 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
75 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
77 return buf;
80 static void test_HlinkIsShortcut(void)
82 UINT i;
83 HRESULT hres;
85 static const WCHAR file0[] = {'f','i','l','e',0};
86 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
87 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
88 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
89 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
90 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
91 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
92 static const WCHAR file7[] = {'.','u','r','l',0};
94 static struct {
95 LPCWSTR file;
96 HRESULT hres;
97 } shortcut_test[] = {
98 {file0, S_FALSE},
99 {file1, S_OK},
100 {file2, S_FALSE},
101 {file3, S_OK},
102 {file4, S_FALSE},
103 {file5, S_OK},
104 {file6, S_FALSE},
105 {file7, S_OK},
106 {NULL, E_INVALIDARG}
109 for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
110 hres = HlinkIsShortcut(shortcut_test[i].file);
111 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
112 i, hres, shortcut_test[i].hres);
116 static void test_reference(void)
118 HRESULT r;
119 IHlink *lnk = NULL;
120 IMoniker *mk = NULL;
121 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
122 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
123 LPWSTR str = NULL;
125 r = HlinkCreateFromString(url, NULL, NULL, NULL,
126 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
127 ok(r == S_OK, "failed to create link\n");
128 if (FAILED(r))
129 return;
131 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
132 ok(r == S_OK, "failed\n");
134 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
135 ok(r == S_OK, "failed\n");
136 ok(mk != NULL, "no moniker\n");
137 ok(str == NULL, "string should be null\n");
139 r = IMoniker_Release(mk);
140 ok( r == 1, "moniker refcount wrong\n");
142 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
143 ok(r == S_OK, "failed\n");
144 CoTaskMemFree(str);
146 r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
147 ok(r == S_OK, "failed, r=%08x\n", r);
149 r = IHlink_GetStringReference(lnk, -1, NULL, &str);
150 ok(r == S_OK, "failed, r=%08x\n", r);
151 ok(str == NULL, "string should be null\n");
153 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
154 ok(r == S_OK, "failed\n");
155 ok(!lstrcmpW(str, url2), "url wrong\n");
156 CoTaskMemFree(str);
158 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
159 ok(r == S_OK, "failed\n");
161 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
162 ok(r == S_OK, "failed\n");
163 ok(str == NULL, "string should be null\n");
165 /* Unimplented functions checks */
166 r = IHlink_GetAdditionalParams(lnk, NULL);
167 ok(r == E_NOTIMPL, "failed\n");
169 r = IHlink_SetAdditionalParams(lnk, NULL);
170 ok(r == E_NOTIMPL, "failed\n");
172 IHlink_Release(lnk);
175 /* url only */
176 static const unsigned char expected_hlink_data[] =
178 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
179 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
180 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
181 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
182 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
183 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
184 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
185 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
186 0x00,0x00,
189 /* url only (IE7) */
190 static const unsigned char expected_hlink_data_ie7[] =
192 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
193 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
194 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
195 0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
196 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
197 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
198 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
199 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
200 0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
201 0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
202 0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
203 0x00,0x00,
206 /* url + friendly name */
207 static const unsigned char expected_hlink_data2[] =
209 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
210 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
211 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
212 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
213 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
214 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
215 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
216 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
217 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
218 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
219 0x67,0x00,0x2f,0x00,0x00,0x00,
222 /* url + friendly name (IE7) */
223 static const unsigned char expected_hlink_data2_ie7[] =
225 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
226 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
227 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
228 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
229 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
230 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
231 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
232 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
233 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
234 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
235 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
236 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
237 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
238 0x00,0x00,0xa5,0xab,0x00,0x00,
241 /* url + friendly name + location */
242 static const unsigned char expected_hlink_data3[] =
244 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
245 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
246 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
247 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
248 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
249 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
250 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
251 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
252 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
253 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
254 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
255 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
256 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
259 /* url + friendly name + location (IE7) */
260 static const unsigned char expected_hlink_data3_ie7[] =
262 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
263 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
264 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
265 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
266 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
267 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
268 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
269 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
270 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
271 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
272 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
273 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
274 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
275 0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
276 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
277 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
280 /* relative url */
281 static const unsigned char expected_hlink_data4[] =
283 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
284 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
285 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
286 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
287 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
288 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
289 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
290 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
291 0x00,0x00,0x00,0x00,0x00,
294 /* url + target frame name */
295 static const unsigned char expected_hlink_data5[] =
297 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
298 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
299 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
300 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
301 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
302 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
303 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
304 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
305 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
306 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
307 0x2f,0x00,0x00,0x00,
310 /* url + target frame name (IE7) */
311 static const unsigned char expected_hlink_data5_ie7[] =
313 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
314 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
315 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
316 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
317 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
318 0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
319 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
320 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
321 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
322 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
323 0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
324 0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
325 0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
326 0xa5,0xab,0x00,0x00,
329 /* filename */
330 static const unsigned char expected_hlink_data6[] =
332 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
333 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
334 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
335 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
336 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
337 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
338 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
339 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
340 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
341 0x5c,0x00,
344 static void test_persist_save_data(const char *testname, IHlink *lnk,
345 const unsigned char *expected_data,
346 unsigned int expected_data_size,
347 const unsigned char *expected_data_alt,
348 unsigned int expected_data_alt_size)
350 HRESULT hr;
351 IStream *stream;
352 IPersistStream *ps;
353 HGLOBAL hglobal;
354 DWORD data_size;
355 const unsigned char *data;
356 DWORD i;
357 BOOL same;
359 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
360 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
362 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
363 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
365 hr = IPersistStream_Save(ps, stream, TRUE);
366 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
368 hr = GetHGlobalFromStream(stream, &hglobal);
369 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
371 data_size = GlobalSize(hglobal);
373 data = GlobalLock(hglobal);
375 /* first check we have the right amount of data */
376 ok((data_size == expected_data_size) ||
377 (data_size == expected_data_alt_size),
378 "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
379 testname, expected_data_size, expected_data_alt_size, data_size);
381 same = TRUE;
382 /* then do a byte-by-byte comparison */
383 for (i = 0; i < min(data_size, expected_data_size); i++)
385 if ((expected_data[i] != data[i]) &&
386 (((expected_data != expected_hlink_data2) &&
387 (expected_data != expected_hlink_data3)) ||
388 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
390 same = FALSE;
391 break;
395 if (!same && (expected_data_alt != expected_data))
397 /* then try the alternate data */
398 same = TRUE;
399 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
401 if ((expected_data_alt[i] != data[i]) &&
402 (((expected_data_alt != expected_hlink_data2) &&
403 (expected_data_alt != expected_hlink_data3)) ||
404 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
406 same = FALSE;
407 break;
412 ok(same, "%s: Saved data differs\n", testname);
413 if (!same)
415 for (i = 0; i < data_size; i++)
417 if (i % 8 == 0) printf(" ");
418 printf("0x%02x,", data[i]);
419 if (i % 8 == 7) printf("\n");
421 printf("\n");
424 GlobalUnlock(hglobal);
426 IStream_Release(stream);
427 IPersistStream_Release(ps);
430 static void test_persist(void)
432 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
433 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
434 static const WCHAR filename[] = { 'c',':','\\',0 };
435 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
436 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
437 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
438 HRESULT hr;
439 IHlink *lnk;
441 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
442 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
443 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
444 if (!lnk) {
445 skip("Can't create lnk, skipping test_persist.\n");
446 return;
448 test_persist_save_data("url only", lnk,
449 expected_hlink_data, sizeof(expected_hlink_data),
450 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
451 IHlink_Release(lnk);
453 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
454 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
455 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
456 test_persist_save_data("url + friendly name", lnk,
457 expected_hlink_data2, sizeof(expected_hlink_data2),
458 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
459 IHlink_Release(lnk);
461 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
462 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
463 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
464 test_persist_save_data("url + friendly_name + location", lnk,
465 expected_hlink_data3, sizeof(expected_hlink_data3),
466 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
467 IHlink_Release(lnk);
469 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
470 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
471 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
472 test_persist_save_data("relative url", lnk,
473 expected_hlink_data4, sizeof(expected_hlink_data4),
474 expected_hlink_data4, sizeof(expected_hlink_data4));
475 IHlink_Release(lnk);
477 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
478 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
479 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
480 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
481 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
482 test_persist_save_data("url + target frame name", lnk,
483 expected_hlink_data5, sizeof(expected_hlink_data5),
484 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
485 IHlink_Release(lnk);
487 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
488 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
489 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
490 test_persist_save_data("filename", lnk,
491 expected_hlink_data6, sizeof(expected_hlink_data6),
492 expected_hlink_data6, sizeof(expected_hlink_data6));
493 IHlink_Release(lnk);
496 static void test_special_reference(void)
498 LPWSTR ref;
499 HRESULT hres;
501 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
502 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
503 ok(ref != NULL, "ref == NULL\n");
504 CoTaskMemFree(ref);
506 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
507 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
508 ok(ref != NULL, "ref == NULL\n");
509 CoTaskMemFree(ref);
511 ref = (void*)0xdeadbeef;
512 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
513 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
514 ok(ref == NULL, "ref=%p\n", ref);
516 ref = (void*)0xdeadbeef;
517 hres = HlinkGetSpecialReference(4, &ref);
518 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
519 ok(ref == NULL, "ref=%p\n", ref);
522 static void test_HlinkCreateExtensionServices(void)
524 IAuthenticate *authenticate;
525 IHttpNegotiate *http_negotiate;
526 LPWSTR password, username, headers;
527 HWND hwnd;
528 HRESULT hres;
530 static const WCHAR usernameW[] = {'u','s','e','r',0};
531 static const WCHAR passwordW[] = {'p','a','s','s',0};
532 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
533 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
535 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
536 NULL, &IID_IAuthenticate, (void**)&authenticate);
537 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
538 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
540 password = username = (void*)0xdeadbeef;
541 hwnd = (void*)0xdeadbeef;
542 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
543 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
544 ok(!hwnd, "hwnd != NULL\n");
545 ok(!username, "username != NULL\n");
546 ok(!password, "password != NULL\n");
548 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
549 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
551 headers = (void*)0xdeadbeef;
552 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
553 0, &headers);
554 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
555 ok(headers == NULL, "headers != NULL\n");
557 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
558 0, NULL);
559 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
561 headers = (void*)0xdeadbeef;
562 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
563 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
564 ok(headers == NULL, "headers != NULL\n");
566 IHttpNegotiate_Release(http_negotiate);
567 IAuthenticate_Release(authenticate);
570 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
571 NULL, &IID_IAuthenticate, (void**)&authenticate);
572 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
573 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
575 password = username = NULL;
576 hwnd = NULL;
577 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
578 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
579 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
580 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
581 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
582 CoTaskMemFree(username);
583 CoTaskMemFree(password);
585 password = username = (void*)0xdeadbeef;
586 hwnd = (void*)0xdeadbeef;
587 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
588 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
589 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
590 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
592 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
593 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
595 headers = (void*)0xdeadbeef;
596 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
597 0, &headers);
598 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
599 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
600 CoTaskMemFree(headers);
602 headers = (void*)0xdeadbeef;
603 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
604 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
605 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
607 IHttpNegotiate_Release(http_negotiate);
608 IAuthenticate_Release(authenticate);
611 static void test_HlinkParseDisplayName(void)
613 IMoniker *mon = NULL;
614 LPWSTR name;
615 DWORD issys;
616 ULONG eaten = 0;
617 IBindCtx *bctx;
618 HRESULT hres;
620 static const WCHAR winehq_urlW[] =
621 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
622 '/','s','i','t','e','/','a','b','o','u','t',0};
623 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
624 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
625 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
626 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
628 CreateBindCtx(0, &bctx);
630 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
631 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
632 ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
633 ok(mon != NULL, "mon == NULL\n");
635 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
636 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
637 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
638 CoTaskMemFree(name);
640 hres = IMoniker_IsSystemMoniker(mon, &issys);
641 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
642 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
644 IMoniker_Release(mon);
646 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
647 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
648 ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
649 ok(mon != NULL, "mon == NULL\n");
651 hres = IMoniker_IsSystemMoniker(mon, &issys);
652 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
653 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
655 IMoniker_Release(mon);
657 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
658 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
659 ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
660 ok(mon != NULL, "mon == NULL\n");
662 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
663 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
664 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
665 CoTaskMemFree(name);
667 hres = IMoniker_IsSystemMoniker(mon, &issys);
668 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
669 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
671 IMoniker_Release(mon);
672 IBindCtx_Release(bctx);
675 static IBindCtx *_bctx;
677 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
679 ok(0, "unexpected call\n");
680 return E_NOINTERFACE;
683 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
685 return 2;
688 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
690 return 1;
693 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
694 REFGUID guidService, REFIID riid, void **ppv)
696 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
697 return E_NOINTERFACE;
700 static IServiceProviderVtbl ServiceProviderVtbl = {
701 ServiceProvider_QueryInterface,
702 ServiceProvider_AddRef,
703 ServiceProvider_Release,
704 ServiceProvider_QueryService
707 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
709 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
711 *ppv = NULL;
713 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
714 *ppv = &ServiceProvider;
715 return S_OK;
718 ok(0, "unexpected interface %s\n", debugstr_guid(riid));
719 return E_NOINTERFACE;
722 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
724 return 2;
727 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
729 return 1;
732 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
733 IBinding *pib)
735 ok(0, "unexpected call\n");
736 return E_NOTIMPL;
739 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
741 ok(0, "unexpected call\n");
742 return E_NOTIMPL;
745 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
747 ok(0, "unexpected call\n");
748 return E_NOTIMPL;
751 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
752 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
754 ok(0, "unexpected call\n");
755 return E_NOTIMPL;
758 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
760 ok(0, "unexpected call\n");
761 return E_NOTIMPL;
764 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
766 ok(0, "unexpected call\n");
767 return E_NOTIMPL;
770 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
771 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
773 ok(0, "unexpected call\n");
774 return E_NOTIMPL;
777 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
779 ok(0, "unexpected call\n");
780 return E_NOTIMPL;
783 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
784 BindStatusCallback_QueryInterface,
785 BindStatusCallback_AddRef,
786 BindStatusCallback_Release,
787 BindStatusCallback_OnStartBinding,
788 BindStatusCallback_GetPriority,
789 BindStatusCallback_OnLowResource,
790 BindStatusCallback_OnProgress,
791 BindStatusCallback_OnStopBinding,
792 BindStatusCallback_GetBindInfo,
793 BindStatusCallback_OnDataAvailable,
794 BindStatusCallback_OnObjectAvailable
797 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
799 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
801 *ppv = NULL;
803 ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
804 return E_NOINTERFACE;
807 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
809 return 2;
812 static ULONG WINAPI Moniker_Release(IMoniker *iface)
814 return 1;
817 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
819 CHECK_EXPECT(GetClassID);
820 *pClassID = IID_IUnknown; /* not a valid CLSID */
821 return S_OK;
824 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
826 ok(0, "unexpected call\n");
827 return E_NOTIMPL;
830 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
832 ok(0, "unexpected call\n");
833 return E_NOTIMPL;
836 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
838 CHECK_EXPECT(Save);
839 return S_OK;
842 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
844 ok(0, "unexpected call\n");
845 return E_NOTIMPL;
848 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
849 REFIID riidResult, void **ppvResult)
851 ok(0, "unexpected call\n");
852 return E_NOTIMPL;
855 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
856 REFIID riid, void **ppv)
858 IUnknown *unk;
859 HRESULT hres;
861 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
863 CHECK_EXPECT(BindToStorage);
865 ok(pbc == _bctx, "pbc != _bctx\n");
866 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
867 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
868 ok(ppv != NULL, "ppv == NULL\n");
869 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
871 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
872 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
873 ok(unk != NULL, "unk == NULL\n");
875 IUnknown_Release(unk);
877 return S_OK;
880 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
881 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
883 CHECK_EXPECT(Reduce);
884 return E_NOTIMPL;
887 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
888 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
890 ok(0, "unexpected call\n");
891 return E_NOTIMPL;
894 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
896 CHECK_EXPECT(Enum);
897 return E_NOTIMPL;
900 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
902 ok(0, "unexpected call\n");
903 return E_NOTIMPL;
906 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
908 ok(0, "unexpected call\n");
909 return E_NOTIMPL;
912 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
913 IMoniker *pmkNewlyRunning)
915 ok(0, "unexpected call\n");
916 return E_NOTIMPL;
919 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
920 IMoniker *pmkToLeft, FILETIME *pFileTime)
922 ok(0, "unexpected call\n");
923 return E_NOTIMPL;
926 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
928 ok(0, "unexpected call\n");
929 return E_NOTIMPL;
932 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
933 IMoniker **ppmkPrefix)
935 ok(0, "unexpected call\n");
936 return E_NOTIMPL;
939 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
940 IMoniker **pmkRelPath)
942 ok(0, "unexpected call\n");
943 return E_NOTIMPL;
946 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
947 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
949 static const WCHAR winehq_urlW[] =
950 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
951 '/','s','i','t','e','/','a','b','o','u','t',0};
953 CHECK_EXPECT(GetDisplayName);
955 ok(pbc != NULL, "pbc == NULL\n");
956 ok(pbc != _bctx, "pbc == _bctx\n");
957 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
959 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
960 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
961 return S_OK;
964 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
965 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
967 ok(0, "unexpected call\n");
968 return E_NOTIMPL;
971 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
973 CHECK_EXPECT2(IsSystemMoniker);
975 *pdwMksys = MKSYS_URLMONIKER;
976 return S_OK;
979 static IMonikerVtbl MonikerVtbl = {
980 Moniker_QueryInterface,
981 Moniker_AddRef,
982 Moniker_Release,
983 Moniker_GetClassID,
984 Moniker_IsDirty,
985 Moniker_Load,
986 Moniker_Save,
987 Moniker_GetSizeMax,
988 Moniker_BindToObject,
989 Moniker_BindToStorage,
990 Moniker_Reduce,
991 Moniker_ComposeWith,
992 Moniker_Enum,
993 Moniker_IsEqual,
994 Moniker_Hash,
995 Moniker_IsRunning,
996 Moniker_GetTimeOfLastChange,
997 Moniker_Inverse,
998 Moniker_CommonPrefixWith,
999 Moniker_RelativePathTo,
1000 Moniker_GetDisplayName,
1001 Moniker_ParseDisplayName,
1002 Moniker_IsSystemMoniker
1005 static IMoniker Moniker = { &MonikerVtbl };
1007 static void test_HlinkResolveMonikerForData(void)
1009 IBindCtx *bctx;
1010 HRESULT hres;
1012 CreateBindCtx(0, &bctx);
1013 _bctx = bctx;
1015 SET_EXPECT(IsSystemMoniker);
1016 SET_EXPECT(GetDisplayName);
1017 SET_EXPECT(BindToStorage);
1019 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1020 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1022 CHECK_CALLED(IsSystemMoniker);
1023 CHECK_CALLED(GetDisplayName);
1024 CHECK_CALLED(BindToStorage);
1026 IBindCtx_Release(bctx);
1027 _bctx = NULL;
1030 static void test_HlinkGetSetMonikerReference(void)
1032 IMoniker *found_trgt, *dummy, *dummy2;
1033 IHlink *hlink;
1034 HRESULT hres;
1035 const WCHAR one[] = {'1',0};
1036 const WCHAR two[] = {'2',0};
1037 const WCHAR name[] = {'a',0};
1038 WCHAR *found_loc;
1040 /* create two dummy monikers to use as targets */
1041 hres = CreateItemMoniker(one, one, &dummy);
1042 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1044 hres = CreateItemMoniker(two, two, &dummy2);
1045 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1047 /* create a new hlink: target => dummy, location => one */
1048 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1049 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1051 /* validate the target and location */
1052 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1053 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1054 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1055 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1056 IMoniker_Release(found_trgt);
1057 CoTaskMemFree(found_loc);
1059 /* set location => two */
1060 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1061 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1063 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1064 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1065 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1066 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1067 IMoniker_Release(found_trgt);
1068 CoTaskMemFree(found_loc);
1070 /* set target => dummy2 */
1071 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1072 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1074 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1075 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1076 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1077 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1078 IMoniker_Release(found_trgt);
1079 CoTaskMemFree(found_loc);
1081 /* set target => dummy, location => one */
1082 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1083 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1085 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1086 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1087 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1088 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1089 IMoniker_Release(found_trgt);
1090 CoTaskMemFree(found_loc);
1092 /* no HLINKSETF flags */
1093 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1094 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1096 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1097 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1098 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1099 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1100 IMoniker_Release(found_trgt);
1101 CoTaskMemFree(found_loc);
1103 /* invalid HLINKSETF flags */
1104 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1105 if (0)
1106 IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1108 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1109 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1110 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1111 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1112 IMoniker_Release(found_trgt);
1113 CoTaskMemFree(found_loc);
1115 /* valid & invalid HLINKSETF flags */
1116 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1117 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1119 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1120 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1121 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1122 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1123 IMoniker_Release(found_trgt);
1124 CoTaskMemFree(found_loc);
1126 /* NULL args */
1127 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1128 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1130 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1131 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1132 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1133 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1134 if(found_trgt)
1135 IMoniker_Release(found_trgt);
1137 IHlink_Release(hlink);
1138 IMoniker_Release(dummy2);
1139 IMoniker_Release(dummy);
1141 SET_EXPECT(Reduce);
1142 SET_EXPECT(Enum);
1143 SET_EXPECT(IsSystemMoniker);
1144 SET_EXPECT(GetDisplayName);
1145 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL, 0, NULL,
1146 &IID_IHlink, (void **)&hlink);
1147 ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1149 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_ABSOLUTE,
1150 &found_trgt, &found_loc);
1151 ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1152 ok(found_trgt == &Moniker, "Got unexpected moniker: %p\n", found_trgt);
1153 ok(found_loc == NULL, "Got unexpected location: %p\n", found_loc);
1154 todo_wine CHECK_CALLED(Reduce);
1155 todo_wine CHECK_CALLED(Enum);
1156 CHECK_CALLED(IsSystemMoniker);
1157 CHECK_CALLED(GetDisplayName);
1159 IHlink_Release(hlink);
1162 static void test_HlinkGetSetStringReference(void)
1164 IHlink *link;
1165 static const WCHAR one[] = {'1',0};
1166 static const WCHAR two[] = {'2',0};
1167 static const WCHAR three[] = {'3',0};
1168 static const WCHAR empty[] = {0};
1169 WCHAR *fnd_tgt, *fnd_loc;
1170 HRESULT hres;
1172 /* create a new hlink: target => NULL, location => one */
1173 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1174 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1176 /* test setting/getting location */
1177 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1178 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1179 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1180 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1181 CoTaskMemFree(fnd_tgt);
1182 CoTaskMemFree(fnd_loc);
1184 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1185 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1187 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1188 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1189 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1190 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1191 CoTaskMemFree(fnd_tgt);
1192 CoTaskMemFree(fnd_loc);
1194 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1195 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1197 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1198 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1199 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1200 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1201 CoTaskMemFree(fnd_tgt);
1202 CoTaskMemFree(fnd_loc);
1204 /* test setting/getting target */
1205 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1206 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1208 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1209 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1210 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1211 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1212 CoTaskMemFree(fnd_tgt);
1213 CoTaskMemFree(fnd_loc);
1215 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1216 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1218 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1219 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1220 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1221 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1222 CoTaskMemFree(fnd_tgt);
1223 CoTaskMemFree(fnd_loc);
1225 /* test setting/getting both */
1226 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1227 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1229 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1230 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1231 ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1232 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1233 CoTaskMemFree(fnd_tgt);
1234 CoTaskMemFree(fnd_loc);
1236 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1237 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1239 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1240 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1241 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1242 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1243 CoTaskMemFree(fnd_tgt);
1244 CoTaskMemFree(fnd_loc);
1246 /* test invalid flags/params */
1247 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1248 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1249 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1250 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1251 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1252 CoTaskMemFree(fnd_tgt);
1253 CoTaskMemFree(fnd_loc);
1255 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1256 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1257 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1258 CoTaskMemFree(fnd_tgt);
1260 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1261 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1263 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1264 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1265 CoTaskMemFree(fnd_loc);
1267 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1268 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1269 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1270 CoTaskMemFree(fnd_tgt);
1271 CoTaskMemFree(fnd_loc);
1273 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1274 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1275 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1276 CoTaskMemFree(fnd_tgt);
1277 CoTaskMemFree(fnd_loc);
1279 if (0)
1281 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1282 IHlink_SetStringReference(link, 4, NULL, NULL);
1283 IHlink_SetStringReference(link, -4, NULL, NULL);
1286 IHlink_Release(link);
1289 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1290 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1292 HRESULT hres;
1293 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1294 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1297 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1298 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1300 HRESULT hres;
1301 WCHAR *fnd_tgt, *fnd_loc;
1303 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1304 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1306 if(exp_tgt)
1307 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));
1308 else
1309 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1311 if(exp_loc)
1312 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));
1313 else
1314 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1316 CoTaskMemFree(fnd_tgt);
1317 CoTaskMemFree(fnd_loc);
1320 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1321 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1323 HRESULT hres;
1324 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1325 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1328 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1329 #define getMonikerRef(h,t,l,r) r_getMonikerRef(__LINE__,h,t,l,r)
1330 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc, DWORD ref)
1332 HRESULT hres;
1333 IMoniker *fnd_tgt;
1334 WCHAR *fnd_loc;
1336 hres = IHlink_GetMonikerReference(hlink, ref, &fnd_tgt, &fnd_loc);
1337 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1339 if(exp_loc)
1340 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));
1341 else
1342 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1344 CoTaskMemFree(fnd_loc);
1346 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1347 return fnd_tgt;
1349 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1351 if(fnd_tgt)
1352 IMoniker_Release(fnd_tgt);
1354 return NULL;
1357 static void test_HlinkMoniker(void)
1359 IHlink *hlink;
1360 IMoniker *aMon, *file_mon;
1361 static const WCHAR emptyW[] = {0};
1362 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1363 static const WCHAR aW[] = {'a',0};
1364 static const WCHAR bW[] = {'b',0};
1365 HRESULT hres;
1367 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1368 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1369 getStringRef(hlink, NULL, NULL);
1370 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1372 /* setting a string target creates a moniker reference */
1373 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1374 getStringRef(hlink, aW, wordsW);
1375 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW, HLINKGETREF_RELATIVE);
1376 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1377 if(aMon)
1378 IMoniker_Release(aMon);
1380 /* setting target & location to the empty string deletes the moniker
1381 * reference */
1382 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1383 getStringRef(hlink, NULL, NULL);
1384 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1386 /* setting a moniker target also sets the target string to that moniker's
1387 * display name */
1388 hres = CreateFileMoniker(bW, &file_mon);
1389 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1391 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1392 getStringRef(hlink, bW, wordsW);
1393 getMonikerRef(hlink, file_mon, wordsW, HLINKGETREF_RELATIVE);
1395 IMoniker_Release(file_mon);
1397 IHlink_Release(hlink);
1400 static void test_HashLink(void)
1402 IHlink *hlink;
1403 IMoniker *pmk;
1404 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1405 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};
1406 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1407 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1408 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1409 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1410 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1411 HRESULT hres;
1413 /* simple single hash test */
1414 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1415 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1416 ok(hlink != NULL, "Didn't get an hlink\n");
1418 if(hlink){
1419 getStringRef(hlink, tgt_partW, loc_partW);
1420 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1421 ok(pmk != NULL, "Found moniker should not be NULL\n");
1422 if(pmk)
1423 IMoniker_Release(pmk);
1425 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1426 getStringRef(hlink, hash_targetW, loc_partW);
1428 IHlink_Release(hlink);
1431 /* two hashes in the target */
1432 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1433 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1434 ok(hlink != NULL, "Didn't get an hlink\n");
1436 if(hlink){
1437 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1438 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW, HLINKGETREF_RELATIVE);
1439 ok(pmk != NULL, "Found moniker should not be NULL\n");
1440 if(pmk)
1441 IMoniker_Release(pmk);
1443 IHlink_Release(hlink);
1446 /* target with hash plus a location string */
1447 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1448 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1449 ok(hlink != NULL, "Didn't get an hlink\n");
1451 if(hlink){
1452 getStringRef(hlink, tgt_partW, test_locW);
1453 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW, HLINKGETREF_RELATIVE);
1454 ok(pmk != NULL, "Found moniker should not be NULL\n");
1455 if(pmk)
1456 IMoniker_Release(pmk);
1458 IHlink_Release(hlink);
1461 /* target with hash containing no "target part" */
1462 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1463 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1464 ok(hlink != NULL, "Didn't get an hlink\n");
1466 if(hlink){
1467 getStringRef(hlink, NULL, loc_partW);
1468 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1469 ok(pmk == NULL, "Found moniker should be NULL\n");
1470 if(pmk)
1471 IMoniker_Release(pmk);
1473 IHlink_Release(hlink);
1477 static WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1478 static WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1480 static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
1481 IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1483 ok(0, "BTS: %p %p %p %p %p\n", iface, pbc, toLeft, riid, obj);
1484 return E_NOTIMPL;
1487 static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
1488 IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1490 LPOLESTR rightName;
1491 HRESULT hres;
1493 ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1495 CHECK_EXPECT(ComposeWith);
1497 hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1498 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1499 ok(!lstrcmpW(rightName, ref_monikerW),
1500 "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1501 wine_dbgstr_w(rightName));
1502 CoTaskMemFree(rightName);
1504 *composite = NULL;
1506 /* unlikely error code to verify this return result is used */
1507 return E_OUTOFMEMORY;
1510 static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
1511 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1513 *displayName = CoTaskMemAlloc(sizeof(site_monikerW));
1514 memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
1515 return S_OK;
1518 static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
1519 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1521 *displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
1522 memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
1523 return S_OK;
1526 static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
1527 DWORD *mksys)
1529 return S_FALSE;
1532 static IMonikerVtbl hls_site_MonikerVtbl = {
1533 Moniker_QueryInterface,
1534 Moniker_AddRef,
1535 Moniker_Release,
1536 Moniker_GetClassID,
1537 Moniker_IsDirty,
1538 Moniker_Load,
1539 Moniker_Save,
1540 Moniker_GetSizeMax,
1541 Moniker_BindToObject,
1542 hls_test_Moniker_BindToStorage,
1543 Moniker_Reduce,
1544 hls_site_Moniker_ComposeWith,
1545 Moniker_Enum,
1546 Moniker_IsEqual,
1547 Moniker_Hash,
1548 Moniker_IsRunning,
1549 Moniker_GetTimeOfLastChange,
1550 Moniker_Inverse,
1551 Moniker_CommonPrefixWith,
1552 Moniker_RelativePathTo,
1553 hls_site_Moniker_GetDisplayName,
1554 Moniker_ParseDisplayName,
1555 hls_test_Moniker_IsSystemMoniker
1558 static IMonikerVtbl hls_ref_MonikerVtbl = {
1559 Moniker_QueryInterface,
1560 Moniker_AddRef,
1561 Moniker_Release,
1562 Moniker_GetClassID,
1563 Moniker_IsDirty,
1564 Moniker_Load,
1565 Moniker_Save,
1566 Moniker_GetSizeMax,
1567 Moniker_BindToObject,
1568 hls_test_Moniker_BindToStorage,
1569 Moniker_Reduce,
1570 Moniker_ComposeWith,
1571 Moniker_Enum,
1572 Moniker_IsEqual,
1573 Moniker_Hash,
1574 Moniker_IsRunning,
1575 Moniker_GetTimeOfLastChange,
1576 Moniker_Inverse,
1577 Moniker_CommonPrefixWith,
1578 Moniker_RelativePathTo,
1579 hls_ref_Moniker_GetDisplayName,
1580 Moniker_ParseDisplayName,
1581 hls_test_Moniker_IsSystemMoniker
1584 static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
1585 static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
1587 static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
1588 void **obj)
1590 ok(0, "QI: %p %s %p\n", iface, debugstr_guid(iid), obj);
1591 return E_NOTIMPL;
1594 static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
1596 return 2;
1599 static ULONG WINAPI hls_Release(IHlinkSite *iface)
1601 return 1;
1604 static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
1605 REFGUID service, REFIID riid, IUnknown **punk)
1607 ok(0, "QS: %p %x %s %s %p\n", iface, siteData, debugstr_guid(service),
1608 debugstr_guid(riid), punk);
1609 return E_NOTIMPL;
1612 #define SITEDATA_SUCCESS 1
1613 #define SITEDATA_NOTIMPL 2
1615 static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
1616 DWORD assign, DWORD which, IMoniker **pmk)
1618 ok(siteData == SITEDATA_NOTIMPL ||
1619 siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1621 if(siteData == SITEDATA_SUCCESS){
1622 *pmk = &hls_site_Moniker;
1623 return S_OK;
1626 return E_NOTIMPL;
1629 static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
1630 DWORD reserved)
1632 ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
1633 return E_NOTIMPL;
1636 static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
1637 DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1639 CHECK_EXPECT(OnNavigationComplete);
1640 ok(siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1641 ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
1642 return E_NOTIMPL;
1645 static IHlinkSiteVtbl HlinkSiteVtbl = {
1646 hls_QueryInterface,
1647 hls_AddRef,
1648 hls_Release,
1649 hls_QueryService,
1650 hls_GetMoniker,
1651 hls_ReadyToNavigate,
1652 hls_OnNavigationComplete
1655 static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
1657 static void test_HlinkSite(void)
1659 IHlink *hl;
1660 IMoniker *mon_ref;
1661 IBindCtx *pbc;
1662 HRESULT hres;
1664 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1665 &IID_IHlink, (LPVOID*)&hl);
1666 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1667 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1669 hres = IHlink_SetHlinkSite(hl, &HlinkSite, SITEDATA_SUCCESS);
1670 ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
1671 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1672 getStringRef(hl, NULL, NULL);
1674 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1675 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1676 ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
1678 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1679 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1680 ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1682 SET_EXPECT(Reduce);
1683 SET_EXPECT(Enum);
1684 hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
1685 ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
1686 todo_wine CHECK_CALLED(Reduce);
1687 todo_wine CHECK_CALLED(Enum);
1689 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
1691 SET_EXPECT(Enum);
1692 getStringRef(hl, ref_monikerW, NULL);
1693 todo_wine CHECK_CALLED(Enum);
1695 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1696 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1697 ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1698 IMoniker_Release(mon_ref);
1700 SET_EXPECT(ComposeWith);
1701 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1702 ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
1703 ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
1704 CHECK_CALLED(ComposeWith);
1706 hres = CreateBindCtx(0, &pbc);
1707 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1709 SET_EXPECT(ComposeWith);
1710 SET_EXPECT(OnNavigationComplete);
1711 hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
1712 ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
1713 CHECK_CALLED(ComposeWith);
1714 CHECK_CALLED(OnNavigationComplete);
1716 IBindCtx_Release(pbc);
1717 IHlink_Release(hl);
1719 SET_EXPECT(Reduce);
1720 SET_EXPECT(Enum);
1721 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
1722 NULL, &IID_IHlink, (LPVOID*)&hl);
1723 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1724 todo_wine CHECK_CALLED(Reduce);
1725 todo_wine CHECK_CALLED(Enum);
1726 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
1727 IHlink_Release(hl);
1729 hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
1730 NULL, &IID_IHlink, (LPVOID*)&hl);
1731 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1732 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1733 IHlink_Release(hl);
1735 SET_EXPECT(Reduce);
1736 SET_EXPECT(Enum);
1737 SET_EXPECT(IsSystemMoniker);
1738 SET_EXPECT(GetDisplayName);
1739 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, &HlinkSite, SITEDATA_NOTIMPL,
1740 NULL, &IID_IHlink, (LPVOID*)&hl);
1741 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1742 getMonikerRef(hl, &Moniker, NULL, HLINKGETREF_ABSOLUTE);
1743 IHlink_Release(hl);
1744 todo_wine CHECK_CALLED(Reduce);
1745 todo_wine CHECK_CALLED(Enum);
1746 CHECK_CALLED(IsSystemMoniker);
1747 CHECK_CALLED(GetDisplayName);
1750 static void test_HlinkClone(void)
1752 HRESULT hres;
1753 IHlink *hl, *cloned = NULL;
1754 IMoniker *dummy, *fnd_mk;
1755 IHlinkSite *fnd_site;
1756 WCHAR *fnd_name;
1757 DWORD fnd_data;
1758 const WCHAR one[] = {'1',0};
1759 const WCHAR two[] = {'2',0};
1760 const WCHAR name[] = {'a',0};
1762 hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
1763 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
1765 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1766 &IID_IHlink, (void**)&hl);
1767 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1769 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
1770 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
1772 if (0)
1774 /* crash on Windows XP */
1775 HlinkClone(hl, NULL, NULL, 0, NULL);
1777 HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
1780 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
1781 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
1782 ok(cloned != NULL, "Didn't get a clone\n");
1783 getMonikerRef(cloned, NULL, NULL, HLINKGETREF_RELATIVE);
1784 IHlink_Release(cloned);
1786 IHlink_Release(hl);
1788 SET_EXPECT(Reduce);
1789 SET_EXPECT(Enum);
1790 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
1791 todo_wine CHECK_CALLED(Reduce);
1792 todo_wine CHECK_CALLED(Enum);
1793 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1794 getMonikerRef(hl, &hls_ref_Moniker, two, HLINKGETREF_RELATIVE);
1796 SET_EXPECT(Save);
1797 SET_EXPECT(GetClassID);
1798 cloned = (IHlink*)0xdeadbeef;
1799 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
1800 /* fails because of invalid CLSID given by Moniker_GetClassID */
1801 ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08x\n", hres);
1802 ok(cloned == NULL, "Shouldn't have gotten a clone\n");
1803 CHECK_CALLED(Save);
1804 CHECK_CALLED(GetClassID);
1806 IHlink_Release(hl);
1808 hres = CreateItemMoniker(one, one, &dummy);
1809 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1811 hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, SITEDATA_SUCCESS, NULL, &IID_IHlink, (void**)&hl);
1812 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1813 getMonikerRef(hl, dummy, two, HLINKGETREF_RELATIVE);
1815 cloned = NULL;
1816 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
1817 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
1818 ok(cloned != NULL, "Should have gotten a clone\n");
1820 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two, HLINKGETREF_RELATIVE);
1821 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
1822 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
1824 fnd_name = NULL;
1825 hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
1826 ok(hres == S_OK, "GetFriendlyName failed: %08x\n", hres);
1827 ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
1828 ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
1829 wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
1830 CoTaskMemFree(fnd_name);
1832 fnd_site = (IHlinkSite*)0xdeadbeef;
1833 fnd_data = 4;
1834 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
1835 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
1836 ok(fnd_site == NULL, "Expected NULL site\n");
1837 ok(fnd_data == 4, "Expected site data to be 4, was: %d\n", fnd_data);
1839 IHlink_Release(cloned);
1840 IHlink_Release(hl);
1842 hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
1843 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1844 getMonikerRef(hl, dummy, NULL, HLINKGETREF_RELATIVE);
1846 cloned = NULL;
1847 hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, SITEDATA_SUCCESS, (void**)&cloned);
1848 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
1849 ok(cloned != NULL, "Should have gotten a clone\n");
1851 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL, HLINKGETREF_RELATIVE);
1852 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
1853 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
1855 fnd_site = (IHlinkSite*)0xdeadbeef;
1856 fnd_data = 4;
1857 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
1858 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
1859 ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
1860 ok(fnd_data == SITEDATA_SUCCESS, "Unexpected site data: %u\n", fnd_data);
1862 IHlink_Release(cloned);
1863 IHlink_Release(hl);
1865 IMoniker_Release(dummy);
1868 static void test_StdHlink(void)
1870 IHlink *hlink;
1871 WCHAR *str;
1872 HRESULT hres;
1874 static const WCHAR testW[] = {'t','e','s','t',0};
1876 hres = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1877 &IID_IHlink, (void**)&hlink);
1878 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1880 str = (void*)0xdeadbeef;
1881 hres = IHlink_GetTargetFrameName(hlink, &str);
1882 ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
1883 ok(!str, "str = %s\n", wine_dbgstr_w(str));
1885 hres = IHlink_SetTargetFrameName(hlink, testW);
1886 ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
1888 str = (void*)0xdeadbeef;
1889 hres = IHlink_GetTargetFrameName(hlink, &str);
1890 ok(hres == S_OK, "GetTargetFrameName failed: %08x\n", hres);
1891 ok(!lstrcmpW(str, testW), "str = %s\n", wine_dbgstr_w(str));
1892 CoTaskMemFree(str);
1894 hres = IHlink_SetTargetFrameName(hlink, NULL);
1895 ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
1897 str = (void*)0xdeadbeef;
1898 hres = IHlink_GetTargetFrameName(hlink, &str);
1899 ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
1900 ok(!str, "str = %s\n", wine_dbgstr_w(str));
1902 IHlink_Release(hlink);
1905 START_TEST(hlink)
1907 CoInitialize(NULL);
1909 test_HlinkIsShortcut();
1910 test_reference();
1911 test_persist();
1912 test_special_reference();
1913 test_HlinkCreateExtensionServices();
1914 test_HlinkParseDisplayName();
1915 test_HlinkResolveMonikerForData();
1916 test_HlinkGetSetMonikerReference();
1917 test_HlinkGetSetStringReference();
1918 test_HlinkMoniker();
1919 test_HashLink();
1920 test_HlinkSite();
1921 test_HlinkClone();
1922 test_StdHlink();
1924 CoUninitialize();