Release 1.3.7.
[wine/gsoc-2012-control.git] / dlls / hlink / tests / hlink.c
blob3cb6db44a6a0278fd953521afa08cae9bcf0fc7a
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;
358 unsigned int expected_data_win9x_size = 0;
360 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
361 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
363 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
364 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
366 hr = IPersistStream_Save(ps, stream, TRUE);
367 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
369 hr = GetHGlobalFromStream(stream, &hglobal);
370 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
372 data_size = GlobalSize(hglobal);
374 data = GlobalLock(hglobal);
376 if (expected_data_size % 4)
377 expected_data_win9x_size = 4 * ((expected_data_size / 4) + 1);
379 /* first check we have the right amount of data */
380 ok((data_size == expected_data_size) ||
381 (data_size == expected_data_alt_size) ||
382 broken(data_size == expected_data_win9x_size), /* Win9x and WinMe */
383 "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
384 testname, expected_data_size, expected_data_alt_size, data_size);
386 same = TRUE;
387 /* then do a byte-by-byte comparison */
388 for (i = 0; i < min(data_size, expected_data_size); i++)
390 if ((expected_data[i] != data[i]) &&
391 (((expected_data != expected_hlink_data2) &&
392 (expected_data != expected_hlink_data3)) ||
393 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
395 same = FALSE;
396 break;
400 if (!same && (expected_data_alt != expected_data))
402 /* then try the alternate data */
403 same = TRUE;
404 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
406 if ((expected_data_alt[i] != data[i]) &&
407 (((expected_data_alt != expected_hlink_data2) &&
408 (expected_data_alt != expected_hlink_data3)) ||
409 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
411 same = FALSE;
412 break;
417 ok(same, "%s: Saved data differs\n", testname);
418 if (!same)
420 for (i = 0; i < data_size; i++)
422 if (i % 8 == 0) printf(" ");
423 printf("0x%02x,", data[i]);
424 if (i % 8 == 7) printf("\n");
426 printf("\n");
429 GlobalUnlock(hglobal);
431 IStream_Release(stream);
432 IPersistStream_Release(ps);
435 static void test_persist(void)
437 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
438 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
439 static const WCHAR filename[] = { 'c',':','\\',0 };
440 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
441 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
442 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
443 HRESULT hr;
444 IHlink *lnk;
446 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
447 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
448 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
449 if (!lnk) {
450 skip("Can't create lnk, skipping test_persist.\n");
451 return;
453 test_persist_save_data("url only", lnk,
454 expected_hlink_data, sizeof(expected_hlink_data),
455 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
456 IHlink_Release(lnk);
458 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
459 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
460 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
461 test_persist_save_data("url + friendly name", lnk,
462 expected_hlink_data2, sizeof(expected_hlink_data2),
463 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
464 IHlink_Release(lnk);
466 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
467 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
468 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
469 test_persist_save_data("url + friendly_name + location", lnk,
470 expected_hlink_data3, sizeof(expected_hlink_data3),
471 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
472 IHlink_Release(lnk);
474 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
475 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
476 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
477 test_persist_save_data("relative url", lnk,
478 expected_hlink_data4, sizeof(expected_hlink_data4),
479 expected_hlink_data4, sizeof(expected_hlink_data4));
480 IHlink_Release(lnk);
482 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
483 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
484 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
485 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
486 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
487 test_persist_save_data("url + target frame name", lnk,
488 expected_hlink_data5, sizeof(expected_hlink_data5),
489 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
490 IHlink_Release(lnk);
492 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
493 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
494 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
495 test_persist_save_data("filename", lnk,
496 expected_hlink_data6, sizeof(expected_hlink_data6),
497 expected_hlink_data6, sizeof(expected_hlink_data6));
498 IHlink_Release(lnk);
501 static void test_special_reference(void)
503 LPWSTR ref;
504 HRESULT hres;
506 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
507 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
508 ok(ref != NULL, "ref == NULL\n");
509 CoTaskMemFree(ref);
511 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
512 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
513 ok(ref != NULL, "ref == NULL\n");
514 CoTaskMemFree(ref);
516 ref = (void*)0xdeadbeef;
517 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
518 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
519 ok(ref == NULL, "ref=%p\n", ref);
521 ref = (void*)0xdeadbeef;
522 hres = HlinkGetSpecialReference(4, &ref);
523 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
524 ok(ref == NULL, "ref=%p\n", ref);
527 static void test_HlinkCreateExtensionServices(void)
529 IAuthenticate *authenticate;
530 IHttpNegotiate *http_negotiate;
531 LPWSTR password, username, headers;
532 HWND hwnd;
533 HRESULT hres;
535 static const WCHAR usernameW[] = {'u','s','e','r',0};
536 static const WCHAR passwordW[] = {'p','a','s','s',0};
537 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
538 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
540 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
541 NULL, &IID_IAuthenticate, (void**)&authenticate);
542 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
543 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
545 password = username = (void*)0xdeadbeef;
546 hwnd = (void*)0xdeadbeef;
547 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
548 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
549 ok(!hwnd, "hwnd != NULL\n");
550 ok(!username, "username != NULL\n");
551 ok(!password, "password != NULL\n");
553 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
554 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
556 headers = (void*)0xdeadbeef;
557 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
558 0, &headers);
559 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
560 ok(headers == NULL, "headers != NULL\n");
562 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
563 0, NULL);
564 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
566 headers = (void*)0xdeadbeef;
567 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
568 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
569 ok(headers == NULL, "headers != NULL\n");
571 IHttpNegotiate_Release(http_negotiate);
572 IAuthenticate_Release(authenticate);
575 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
576 NULL, &IID_IAuthenticate, (void**)&authenticate);
577 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
578 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
580 password = username = NULL;
581 hwnd = NULL;
582 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
583 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
584 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
585 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
586 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
587 CoTaskMemFree(username);
588 CoTaskMemFree(password);
590 password = username = (void*)0xdeadbeef;
591 hwnd = (void*)0xdeadbeef;
592 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
593 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
594 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
595 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
597 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
598 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
600 headers = (void*)0xdeadbeef;
601 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
602 0, &headers);
603 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
604 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
605 CoTaskMemFree(headers);
607 headers = (void*)0xdeadbeef;
608 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
609 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
610 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
612 IHttpNegotiate_Release(http_negotiate);
613 IAuthenticate_Release(authenticate);
616 static void test_HlinkParseDisplayName(void)
618 IMoniker *mon = NULL;
619 LPWSTR name;
620 DWORD issys;
621 ULONG eaten = 0;
622 IBindCtx *bctx;
623 HRESULT hres;
625 static const WCHAR winehq_urlW[] =
626 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
627 '/','s','i','t','e','/','a','b','o','u','t',0};
628 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
629 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
630 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
631 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
633 CreateBindCtx(0, &bctx);
635 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
636 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
637 ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
638 ok(mon != NULL, "mon == NULL\n");
640 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
641 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
642 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
643 CoTaskMemFree(name);
645 hres = IMoniker_IsSystemMoniker(mon, &issys);
646 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
647 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
649 IMoniker_Release(mon);
651 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
652 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
653 ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
654 ok(mon != NULL, "mon == NULL\n");
656 hres = IMoniker_IsSystemMoniker(mon, &issys);
657 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
658 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
660 IMoniker_Release(mon);
662 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
663 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
664 ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
665 ok(mon != NULL, "mon == NULL\n");
667 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
668 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
669 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
670 CoTaskMemFree(name);
672 hres = IMoniker_IsSystemMoniker(mon, &issys);
673 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
674 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
676 IMoniker_Release(mon);
677 IBindCtx_Release(bctx);
680 static IBindCtx *_bctx;
682 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
684 ok(0, "unexpected call\n");
685 return E_NOINTERFACE;
688 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
690 return 2;
693 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
695 return 1;
698 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
699 REFGUID guidService, REFIID riid, void **ppv)
701 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
702 return E_NOINTERFACE;
705 static IServiceProviderVtbl ServiceProviderVtbl = {
706 ServiceProvider_QueryInterface,
707 ServiceProvider_AddRef,
708 ServiceProvider_Release,
709 ServiceProvider_QueryService
712 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
714 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
716 *ppv = NULL;
718 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
719 *ppv = &ServiceProvider;
720 return S_OK;
723 ok(0, "unexpected interface %s\n", debugstr_guid(riid));
724 return E_NOINTERFACE;
727 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
729 return 2;
732 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
734 return 1;
737 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
738 IBinding *pib)
740 ok(0, "unexpected call\n");
741 return E_NOTIMPL;
744 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
746 ok(0, "unexpected call\n");
747 return E_NOTIMPL;
750 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
752 ok(0, "unexpected call\n");
753 return E_NOTIMPL;
756 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
757 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
759 ok(0, "unexpected call\n");
760 return E_NOTIMPL;
763 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
765 ok(0, "unexpected call\n");
766 return E_NOTIMPL;
769 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
771 ok(0, "unexpected call\n");
772 return E_NOTIMPL;
775 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
776 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
778 ok(0, "unexpected call\n");
779 return E_NOTIMPL;
782 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
784 ok(0, "unexpected call\n");
785 return E_NOTIMPL;
788 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
789 BindStatusCallback_QueryInterface,
790 BindStatusCallback_AddRef,
791 BindStatusCallback_Release,
792 BindStatusCallback_OnStartBinding,
793 BindStatusCallback_GetPriority,
794 BindStatusCallback_OnLowResource,
795 BindStatusCallback_OnProgress,
796 BindStatusCallback_OnStopBinding,
797 BindStatusCallback_GetBindInfo,
798 BindStatusCallback_OnDataAvailable,
799 BindStatusCallback_OnObjectAvailable
802 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
804 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
806 *ppv = NULL;
808 ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
809 return E_NOINTERFACE;
812 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
814 return 2;
817 static ULONG WINAPI Moniker_Release(IMoniker *iface)
819 return 1;
822 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
824 CHECK_EXPECT(GetClassID);
825 *pClassID = IID_IUnknown; /* not a valid CLSID */
826 return S_OK;
829 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
831 ok(0, "unexpected call\n");
832 return E_NOTIMPL;
835 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
837 ok(0, "unexpected call\n");
838 return E_NOTIMPL;
841 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
843 CHECK_EXPECT(Save);
844 return S_OK;
847 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
849 ok(0, "unexpected call\n");
850 return E_NOTIMPL;
853 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
854 REFIID riidResult, void **ppvResult)
856 ok(0, "unexpected call\n");
857 return E_NOTIMPL;
860 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
861 REFIID riid, void **ppv)
863 IUnknown *unk;
864 HRESULT hres;
866 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
868 CHECK_EXPECT(BindToStorage);
870 ok(pbc == _bctx, "pbc != _bctx\n");
871 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
872 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
873 ok(ppv != NULL, "ppv == NULL\n");
874 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
876 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
877 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
878 ok(unk != NULL, "unk == NULL\n");
880 IUnknown_Release(unk);
882 return S_OK;
885 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
886 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
888 CHECK_EXPECT(Reduce);
889 return E_NOTIMPL;
892 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
893 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
895 ok(0, "unexpected call\n");
896 return E_NOTIMPL;
899 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
901 CHECK_EXPECT(Enum);
902 return E_NOTIMPL;
905 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
907 ok(0, "unexpected call\n");
908 return E_NOTIMPL;
911 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
913 ok(0, "unexpected call\n");
914 return E_NOTIMPL;
917 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
918 IMoniker *pmkNewlyRunning)
920 ok(0, "unexpected call\n");
921 return E_NOTIMPL;
924 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
925 IMoniker *pmkToLeft, FILETIME *pFileTime)
927 ok(0, "unexpected call\n");
928 return E_NOTIMPL;
931 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
933 ok(0, "unexpected call\n");
934 return E_NOTIMPL;
937 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
938 IMoniker **ppmkPrefix)
940 ok(0, "unexpected call\n");
941 return E_NOTIMPL;
944 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
945 IMoniker **pmkRelPath)
947 ok(0, "unexpected call\n");
948 return E_NOTIMPL;
951 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
952 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
954 static const WCHAR winehq_urlW[] =
955 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
956 '/','s','i','t','e','/','a','b','o','u','t',0};
958 CHECK_EXPECT(GetDisplayName);
960 ok(pbc != NULL, "pbc == NULL\n");
961 ok(pbc != _bctx, "pbc == _bctx\n");
962 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
964 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
965 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
966 return S_OK;
969 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
970 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
972 ok(0, "unexpected call\n");
973 return E_NOTIMPL;
976 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
978 CHECK_EXPECT2(IsSystemMoniker);
980 *pdwMksys = MKSYS_URLMONIKER;
981 return S_OK;
984 static IMonikerVtbl MonikerVtbl = {
985 Moniker_QueryInterface,
986 Moniker_AddRef,
987 Moniker_Release,
988 Moniker_GetClassID,
989 Moniker_IsDirty,
990 Moniker_Load,
991 Moniker_Save,
992 Moniker_GetSizeMax,
993 Moniker_BindToObject,
994 Moniker_BindToStorage,
995 Moniker_Reduce,
996 Moniker_ComposeWith,
997 Moniker_Enum,
998 Moniker_IsEqual,
999 Moniker_Hash,
1000 Moniker_IsRunning,
1001 Moniker_GetTimeOfLastChange,
1002 Moniker_Inverse,
1003 Moniker_CommonPrefixWith,
1004 Moniker_RelativePathTo,
1005 Moniker_GetDisplayName,
1006 Moniker_ParseDisplayName,
1007 Moniker_IsSystemMoniker
1010 static IMoniker Moniker = { &MonikerVtbl };
1012 static void test_HlinkResolveMonikerForData(void)
1014 IBindCtx *bctx;
1015 HRESULT hres;
1017 CreateBindCtx(0, &bctx);
1018 _bctx = bctx;
1020 SET_EXPECT(IsSystemMoniker);
1021 SET_EXPECT(GetDisplayName);
1022 SET_EXPECT(BindToStorage);
1024 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1025 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1027 CHECK_CALLED(IsSystemMoniker);
1028 CHECK_CALLED(GetDisplayName);
1029 CHECK_CALLED(BindToStorage);
1031 IBindCtx_Release(bctx);
1034 static void test_HlinkGetSetMonikerReference(void)
1036 IMoniker *found_trgt, *dummy, *dummy2;
1037 IHlink *hlink;
1038 HRESULT hres;
1039 const WCHAR one[] = {'1',0};
1040 const WCHAR two[] = {'2',0};
1041 const WCHAR name[] = {'a',0};
1042 WCHAR *found_loc;
1044 /* create two dummy monikers to use as targets */
1045 hres = CreateItemMoniker(one, one, &dummy);
1046 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1048 hres = CreateItemMoniker(two, two, &dummy2);
1049 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1051 /* create a new hlink: target => dummy, location => one */
1052 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1053 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1055 /* validate the target and location */
1056 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1057 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1058 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1059 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1060 IMoniker_Release(found_trgt);
1061 CoTaskMemFree(found_loc);
1063 /* set location => two */
1064 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1065 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1067 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1068 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1069 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1070 IMoniker_Release(found_trgt);
1071 CoTaskMemFree(found_loc);
1073 /* set target => dummy2 */
1074 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1075 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1077 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1078 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1079 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1080 IMoniker_Release(found_trgt);
1081 CoTaskMemFree(found_loc);
1083 /* set target => dummy, location => one */
1084 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1085 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1087 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1088 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1089 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1090 IMoniker_Release(found_trgt);
1091 CoTaskMemFree(found_loc);
1093 /* no HLINKSETF flags */
1094 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1095 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1097 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
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 hres = IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1105 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1106 if (0) ok(hres == 12, "IHlink_SetMonikerReference should've failed with 0x%08x, failed with 0x%08x\n", 12, hres);
1108 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1109 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1110 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1111 IMoniker_Release(found_trgt);
1112 CoTaskMemFree(found_loc);
1114 /* valid & invalid HLINKSETF flags */
1115 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1116 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1118 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1119 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1120 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1121 IMoniker_Release(found_trgt);
1122 CoTaskMemFree(found_loc);
1124 /* NULL args */
1125 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1126 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1128 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1129 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1130 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1131 if(found_trgt)
1132 IMoniker_Release(found_trgt);
1134 IHlink_Release(hlink);
1135 IMoniker_Release(dummy2);
1136 IMoniker_Release(dummy);
1139 static void test_HlinkGetSetStringReference(void)
1141 IHlink *link;
1142 static const WCHAR one[] = {'1',0};
1143 static const WCHAR two[] = {'2',0};
1144 static const WCHAR three[] = {'3',0};
1145 static const WCHAR empty[] = {0};
1146 WCHAR *fnd_tgt, *fnd_loc;
1147 HRESULT hres;
1149 /* create a new hlink: target => NULL, location => one */
1150 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1151 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1153 /* test setting/getting location */
1154 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1155 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1156 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1157 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1158 CoTaskMemFree(fnd_tgt);
1159 CoTaskMemFree(fnd_loc);
1161 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1162 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1164 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1165 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1166 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1167 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1168 CoTaskMemFree(fnd_tgt);
1169 CoTaskMemFree(fnd_loc);
1171 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1172 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1174 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1175 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1176 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1177 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1178 CoTaskMemFree(fnd_tgt);
1179 CoTaskMemFree(fnd_loc);
1181 /* test setting/getting target */
1182 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1183 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1185 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1186 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1187 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1188 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1189 CoTaskMemFree(fnd_tgt);
1190 CoTaskMemFree(fnd_loc);
1192 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1193 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1195 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1196 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1197 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1198 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1199 CoTaskMemFree(fnd_tgt);
1200 CoTaskMemFree(fnd_loc);
1202 /* test setting/getting both */
1203 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1204 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1206 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1207 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1208 ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1209 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1210 CoTaskMemFree(fnd_tgt);
1211 CoTaskMemFree(fnd_loc);
1213 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1214 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1216 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1217 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1218 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1219 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1220 CoTaskMemFree(fnd_tgt);
1221 CoTaskMemFree(fnd_loc);
1223 /* test invalid flags/params */
1224 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1225 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1226 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1227 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1228 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1229 CoTaskMemFree(fnd_tgt);
1230 CoTaskMemFree(fnd_loc);
1232 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1233 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1234 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1235 CoTaskMemFree(fnd_tgt);
1237 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1238 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1240 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1241 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1242 CoTaskMemFree(fnd_loc);
1244 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1245 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1246 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1247 CoTaskMemFree(fnd_tgt);
1248 CoTaskMemFree(fnd_loc);
1250 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1251 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1252 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1253 CoTaskMemFree(fnd_tgt);
1254 CoTaskMemFree(fnd_loc);
1256 hres = IHlink_SetStringReference(link, 4, NULL, NULL);
1257 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1258 if (0) ok(hres == 4, "IHlink_SetStringReference should have failed with 0x4, instead: 0x%08x\n", hres);
1260 hres = IHlink_SetStringReference(link, -4, NULL, NULL);
1261 if (0) ok(hres == -4, "IHlink_SetStringReference should have failed with 0xFFFFFFFC, instead: 0x%08x\n", hres);
1263 IHlink_Release(link);
1266 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1267 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1269 HRESULT hres;
1270 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1271 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1274 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1275 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1277 HRESULT hres;
1278 WCHAR *fnd_tgt, *fnd_loc;
1280 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1281 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1283 if(exp_tgt)
1284 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));
1285 else
1286 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1288 if(exp_loc)
1289 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));
1290 else
1291 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1293 CoTaskMemFree(fnd_tgt);
1294 CoTaskMemFree(fnd_loc);
1297 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1298 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1300 HRESULT hres;
1301 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1302 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1305 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1306 #define getMonikerRef(h,t,l) r_getMonikerRef(__LINE__,h,t,l)
1307 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc)
1309 HRESULT hres;
1310 IMoniker *fnd_tgt;
1311 WCHAR *fnd_loc;
1313 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1314 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1316 if(exp_loc)
1317 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));
1318 else
1319 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1321 CoTaskMemFree(fnd_loc);
1323 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1324 return fnd_tgt;
1326 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1328 if(fnd_tgt)
1329 IMoniker_Release(fnd_tgt);
1331 return NULL;
1334 static void test_HlinkMoniker(void)
1336 IHlink *hlink;
1337 IMoniker *aMon, *file_mon;
1338 static const WCHAR emptyW[] = {0};
1339 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1340 static const WCHAR aW[] = {'a',0};
1341 static const WCHAR bW[] = {'b',0};
1342 HRESULT hres;
1344 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1345 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1346 getStringRef(hlink, NULL, NULL);
1347 getMonikerRef(hlink, NULL, NULL);
1349 /* setting a string target creates a moniker reference */
1350 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1351 getStringRef(hlink, aW, wordsW);
1352 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW);
1353 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1354 if(aMon)
1355 IMoniker_Release(aMon);
1357 /* setting target & location to the empty string deletes the moniker
1358 * reference */
1359 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1360 getStringRef(hlink, NULL, NULL);
1361 getMonikerRef(hlink, NULL, NULL);
1363 /* setting a moniker target also sets the target string to that moniker's
1364 * display name */
1365 hres = CreateFileMoniker(bW, &file_mon);
1366 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1368 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1369 getStringRef(hlink, bW, wordsW);
1370 getMonikerRef(hlink, file_mon, wordsW);
1372 IMoniker_Release(file_mon);
1374 IHlink_Release(hlink);
1377 static void test_HashLink(void)
1379 IHlink *hlink;
1380 IMoniker *pmk;
1381 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1382 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};
1383 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1384 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1385 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1386 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1387 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1388 HRESULT hres;
1390 /* simple single hash test */
1391 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1392 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1393 ok(hlink != NULL, "Didn't get an hlink\n");
1395 if(hlink){
1396 getStringRef(hlink, tgt_partW, loc_partW);
1397 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
1398 ok(pmk != NULL, "Found moniker should not be NULL\n");
1399 if(pmk)
1400 IMoniker_Release(pmk);
1402 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1403 getStringRef(hlink, hash_targetW, loc_partW);
1405 IHlink_Release(hlink);
1408 /* two hashes in the target */
1409 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1410 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1411 ok(hlink != NULL, "Didn't get an hlink\n");
1413 if(hlink){
1414 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1415 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW);
1416 ok(pmk != NULL, "Found moniker should not be NULL\n");
1417 if(pmk)
1418 IMoniker_Release(pmk);
1420 IHlink_Release(hlink);
1423 /* target with hash plus a location string */
1424 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1425 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1426 ok(hlink != NULL, "Didn't get an hlink\n");
1428 if(hlink){
1429 getStringRef(hlink, tgt_partW, test_locW);
1430 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW);
1431 ok(pmk != NULL, "Found moniker should not be NULL\n");
1432 if(pmk)
1433 IMoniker_Release(pmk);
1435 IHlink_Release(hlink);
1438 /* target with hash containing no "target part" */
1439 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1440 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1441 ok(hlink != NULL, "Didn't get an hlink\n");
1443 if(hlink){
1444 getStringRef(hlink, NULL, loc_partW);
1445 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
1446 ok(pmk == NULL, "Found moniker should be NULL\n");
1447 if(pmk)
1448 IMoniker_Release(pmk);
1450 IHlink_Release(hlink);
1454 static WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1455 static WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1457 static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
1458 IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1460 ok(0, "BTS: %p %p %p %p %p\n", iface, pbc, toLeft, riid, obj);
1461 return E_NOTIMPL;
1464 static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
1465 IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1467 LPOLESTR rightName;
1468 HRESULT hres;
1470 ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1472 CHECK_EXPECT(ComposeWith);
1474 hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1475 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1476 ok(!lstrcmpW(rightName, ref_monikerW),
1477 "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1478 wine_dbgstr_w(rightName));
1479 CoTaskMemFree(rightName);
1481 *composite = NULL;
1483 /* unlikely error code to verify this return result is used */
1484 return E_OUTOFMEMORY;
1487 static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
1488 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1490 *displayName = CoTaskMemAlloc(sizeof(site_monikerW));
1491 memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
1492 return S_OK;
1495 static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
1496 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1498 *displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
1499 memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
1500 return S_OK;
1503 static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
1504 DWORD *mksys)
1506 return S_FALSE;
1509 static IMonikerVtbl hls_site_MonikerVtbl = {
1510 Moniker_QueryInterface,
1511 Moniker_AddRef,
1512 Moniker_Release,
1513 Moniker_GetClassID,
1514 Moniker_IsDirty,
1515 Moniker_Load,
1516 Moniker_Save,
1517 Moniker_GetSizeMax,
1518 Moniker_BindToObject,
1519 hls_test_Moniker_BindToStorage,
1520 Moniker_Reduce,
1521 hls_site_Moniker_ComposeWith,
1522 Moniker_Enum,
1523 Moniker_IsEqual,
1524 Moniker_Hash,
1525 Moniker_IsRunning,
1526 Moniker_GetTimeOfLastChange,
1527 Moniker_Inverse,
1528 Moniker_CommonPrefixWith,
1529 Moniker_RelativePathTo,
1530 hls_site_Moniker_GetDisplayName,
1531 Moniker_ParseDisplayName,
1532 hls_test_Moniker_IsSystemMoniker
1535 static IMonikerVtbl hls_ref_MonikerVtbl = {
1536 Moniker_QueryInterface,
1537 Moniker_AddRef,
1538 Moniker_Release,
1539 Moniker_GetClassID,
1540 Moniker_IsDirty,
1541 Moniker_Load,
1542 Moniker_Save,
1543 Moniker_GetSizeMax,
1544 Moniker_BindToObject,
1545 hls_test_Moniker_BindToStorage,
1546 Moniker_Reduce,
1547 Moniker_ComposeWith,
1548 Moniker_Enum,
1549 Moniker_IsEqual,
1550 Moniker_Hash,
1551 Moniker_IsRunning,
1552 Moniker_GetTimeOfLastChange,
1553 Moniker_Inverse,
1554 Moniker_CommonPrefixWith,
1555 Moniker_RelativePathTo,
1556 hls_ref_Moniker_GetDisplayName,
1557 Moniker_ParseDisplayName,
1558 hls_test_Moniker_IsSystemMoniker
1561 static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
1562 static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
1564 static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
1565 void **obj)
1567 ok(0, "QI: %p %s %p\n", iface, debugstr_guid(iid), obj);
1568 return E_NOTIMPL;
1571 static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
1573 return 2;
1576 static ULONG WINAPI hls_Release(IHlinkSite *iface)
1578 return 1;
1581 static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
1582 REFGUID service, REFIID riid, IUnknown **punk)
1584 ok(0, "QS: %p %x %s %s %p\n", iface, siteData, debugstr_guid(service),
1585 debugstr_guid(riid), punk);
1586 return E_NOTIMPL;
1589 static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
1590 DWORD assign, DWORD which, IMoniker **pmk)
1592 ok(siteData == 17, "Expected siteData == 17, got: %d\n", siteData);
1593 *pmk = &hls_site_Moniker;
1594 return S_OK;
1597 static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
1598 DWORD reserved)
1600 ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
1601 return E_NOTIMPL;
1604 static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
1605 DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1607 CHECK_EXPECT(OnNavigationComplete);
1608 ok(siteData == 17, "Expected siteData == 17, got: %d\n", siteData);
1609 ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
1610 return E_NOTIMPL;
1613 static IHlinkSiteVtbl HlinkSiteVtbl = {
1614 hls_QueryInterface,
1615 hls_AddRef,
1616 hls_Release,
1617 hls_QueryService,
1618 hls_GetMoniker,
1619 hls_ReadyToNavigate,
1620 hls_OnNavigationComplete
1623 static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
1625 static void test_HlinkSite(void)
1627 IHlink *hl;
1628 IMoniker *mon_ref;
1629 IBindCtx *pbc;
1630 HRESULT hres;
1632 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1633 &IID_IHlink, (LPVOID*)&hl);
1634 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1635 getMonikerRef(hl, NULL, NULL);
1637 hres = IHlink_SetHlinkSite(hl, &HlinkSite, 17);
1638 ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
1639 getMonikerRef(hl, NULL, NULL);
1640 getStringRef(hl, NULL, NULL);
1642 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1643 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1644 ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
1646 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1647 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1648 ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1650 SET_EXPECT(Reduce);
1651 SET_EXPECT(Enum);
1652 hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
1653 ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
1654 todo_wine CHECK_CALLED(Reduce);
1655 todo_wine CHECK_CALLED(Enum);
1657 getMonikerRef(hl, &hls_ref_Moniker, NULL);
1659 SET_EXPECT(Enum);
1660 getStringRef(hl, ref_monikerW, NULL);
1661 todo_wine CHECK_CALLED(Enum);
1663 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1664 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1665 ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1666 IMoniker_Release(mon_ref);
1668 SET_EXPECT(ComposeWith);
1669 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1670 ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
1671 ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
1672 CHECK_CALLED(ComposeWith);
1674 hres = CreateBindCtx(0, &pbc);
1675 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1677 SET_EXPECT(ComposeWith);
1678 SET_EXPECT(OnNavigationComplete);
1679 hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
1680 ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
1681 CHECK_CALLED(ComposeWith);
1682 CHECK_CALLED(OnNavigationComplete);
1684 IBindCtx_Release(pbc);
1685 IHlink_Release(hl);
1687 SET_EXPECT(Reduce);
1688 SET_EXPECT(Enum);
1689 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, 17,
1690 NULL, &IID_IHlink, (LPVOID*)&hl);
1691 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1692 todo_wine CHECK_CALLED(Reduce);
1693 todo_wine CHECK_CALLED(Enum);
1694 getMonikerRef(hl, &hls_ref_Moniker, NULL);
1695 IHlink_Release(hl);
1697 hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, 17,
1698 NULL, &IID_IHlink, (LPVOID*)&hl);
1699 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1700 getMonikerRef(hl, NULL, NULL);
1701 IHlink_Release(hl);
1704 static void test_HlinkClone(void)
1706 HRESULT hres;
1707 IHlink *hl, *cloned = NULL;
1708 IMoniker *dummy, *fnd_mk;
1709 IHlinkSite *fnd_site;
1710 WCHAR *fnd_name;
1711 DWORD fnd_data;
1712 const WCHAR one[] = {'1',0};
1713 const WCHAR two[] = {'2',0};
1714 const WCHAR name[] = {'a',0};
1716 hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
1717 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
1719 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1720 &IID_IHlink, (void**)&hl);
1721 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1723 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
1724 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
1726 if(0){ /* crash on Windows XP */
1727 hres = HlinkClone(hl, NULL, NULL, 0, NULL);
1728 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
1730 hres = HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
1731 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
1734 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
1735 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
1736 ok(cloned != NULL, "Didn't get a clone\n");
1737 getMonikerRef(cloned, NULL, NULL);
1738 IHlink_Release(cloned);
1740 IHlink_Release(hl);
1742 SET_EXPECT(Reduce);
1743 SET_EXPECT(Enum);
1744 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
1745 todo_wine CHECK_CALLED(Reduce);
1746 todo_wine CHECK_CALLED(Enum);
1747 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1748 getMonikerRef(hl, &hls_ref_Moniker, two);
1750 SET_EXPECT(Save);
1751 SET_EXPECT(GetClassID);
1752 cloned = (IHlink*)0xdeadbeef;
1753 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
1754 /* fails because of invalid CLSID given by Moniker_GetClassID */
1755 ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08x\n", hres);
1756 ok(cloned == NULL, "Shouldn't have gotten a clone\n");
1757 CHECK_CALLED(Save);
1758 CHECK_CALLED(GetClassID);
1760 IHlink_Release(hl);
1762 hres = CreateItemMoniker(one, one, &dummy);
1763 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1765 hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, 17, NULL, &IID_IHlink, (void**)&hl);
1766 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1767 getMonikerRef(hl, dummy, two);
1769 cloned = NULL;
1770 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
1771 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
1772 ok(cloned != NULL, "Should have gotten a clone\n");
1774 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two);
1775 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
1776 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
1778 fnd_name = NULL;
1779 hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
1780 ok(hres == S_OK, "GetFriendlyName failed: %08x\n", hres);
1781 ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
1782 ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
1783 wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
1784 CoTaskMemFree(fnd_name);
1786 fnd_site = (IHlinkSite*)0xdeadbeef;
1787 fnd_data = 4;
1788 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
1789 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
1790 ok(fnd_site == NULL, "Expected NULL site\n");
1791 ok(fnd_data == 4, "Expected site data to be 4, was: %d\n", fnd_data);
1793 IHlink_Release(cloned);
1794 IHlink_Release(hl);
1796 hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
1797 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1798 getMonikerRef(hl, dummy, NULL);
1800 cloned = NULL;
1801 hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, 17, (void**)&cloned);
1802 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
1803 ok(cloned != NULL, "Should have gotten a clone\n");
1805 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL);
1806 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
1807 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
1809 fnd_site = (IHlinkSite*)0xdeadbeef;
1810 fnd_data = 4;
1811 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
1812 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
1813 ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
1814 ok(fnd_data == 17, "Expected site data to be 17, was: %d\n", fnd_data);
1816 IHlink_Release(cloned);
1817 IHlink_Release(hl);
1819 IMoniker_Release(dummy);
1822 START_TEST(hlink)
1824 CoInitialize(NULL);
1826 test_HlinkIsShortcut();
1827 test_reference();
1828 test_persist();
1829 test_special_reference();
1830 test_HlinkCreateExtensionServices();
1831 test_HlinkParseDisplayName();
1832 test_HlinkResolveMonikerForData();
1833 test_HlinkGetSetMonikerReference();
1834 test_HlinkGetSetStringReference();
1835 test_HlinkMoniker();
1836 test_HashLink();
1837 test_HlinkSite();
1838 test_HlinkClone();
1840 CoUninitialize();