Sync advapi32, comctl32, crypt32, cryptui, cryptnet, fusion, gdi32, gdiplus, hlink...
[reactos.git] / rostests / winetests / hlink / hlink.c
1 /*
2 * Implementation of hyperlinking (hlink.dll)
3 *
4 * Copyright 2006 Mike McCormack
5 * Copyright 2007-2008 Jacek Caban for CodeWeavers
6 *
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.
11 *
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.
16 *
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
20 */
21
22 #define COBJMACROS
23
24 #include <stdio.h>
25
26 #include <initguid.h>
27 #include <hlink.h>
28 #include <hlguids.h>
29
30 #include "wine/test.h"
31
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
34
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
37
38 #define CHECK_EXPECT2(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
42 }while(0)
43
44 #define CHECK_EXPECT(func) \
45 do { \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
48 }while(0)
49
50 #define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
54 }while(0)
55
56 DEFINE_EXPECT(IsSystemMoniker);
57 DEFINE_EXPECT(BindToStorage);
58 DEFINE_EXPECT(GetDisplayName);
59
60 static const char *debugstr_guid(REFIID riid)
61 {
62 static char buf[50];
63
64 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
65 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
66 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
67 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
68
69 return buf;
70 }
71
72 static void test_HlinkIsShortcut(void)
73 {
74 UINT i;
75 HRESULT hres;
76
77 static const WCHAR file0[] = {'f','i','l','e',0};
78 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
79 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
80 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
81 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
82 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
83 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
84 static const WCHAR file7[] = {'.','u','r','l',0};
85
86 static struct {
87 LPCWSTR file;
88 HRESULT hres;
89 } shortcut_test[] = {
90 {file0, S_FALSE},
91 {file1, S_OK},
92 {file2, S_FALSE},
93 {file3, S_OK},
94 {file4, S_FALSE},
95 {file5, S_OK},
96 {file6, S_FALSE},
97 {file7, S_OK},
98 {NULL, E_INVALIDARG}
99 };
100
101 for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
102 hres = HlinkIsShortcut(shortcut_test[i].file);
103 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
104 i, hres, shortcut_test[i].hres);
105 }
106 }
107
108 static void test_reference(void)
109 {
110 HRESULT r;
111 IHlink *lnk = NULL;
112 IMoniker *mk = NULL;
113 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
114 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
115 LPWSTR str = NULL;
116
117 r = HlinkCreateFromString(url, NULL, NULL, NULL,
118 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
119 ok(r == S_OK, "failed to create link\n");
120 if (FAILED(r))
121 return;
122
123 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
124 ok(r == S_OK, "failed\n");
125
126 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
127 ok(r == S_OK, "failed\n");
128 ok(mk != NULL, "no moniker\n");
129 ok(str == NULL, "string should be null\n");
130
131 r = IMoniker_Release(mk);
132 ok( r == 1, "moniker refcount wrong\n");
133
134 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
135 ok(r == S_OK, "failed\n");
136 CoTaskMemFree(str);
137
138 r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
139 ok(r == S_OK, "failed, r=%08x\n", r);
140
141 r = IHlink_GetStringReference(lnk, -1, NULL, &str);
142 ok(r == S_OK, "failed, r=%08x\n", r);
143 ok(str == NULL, "string should be null\n");
144
145 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
146 ok(r == S_OK, "failed\n");
147 ok(!lstrcmpW(str, url2), "url wrong\n");
148 CoTaskMemFree(str);
149
150 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
151 ok(r == S_OK, "failed\n");
152
153 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
154 ok(r == S_OK, "failed\n");
155 ok(str == NULL, "string should be null\n");
156
157 /* Unimplented functions checks */
158 r = IHlink_GetAdditionalParams(lnk, NULL);
159 ok(r == E_NOTIMPL, "failed\n");
160
161 r = IHlink_SetAdditionalParams(lnk, NULL);
162 ok(r == E_NOTIMPL, "failed\n");
163
164 IHlink_Release(lnk);
165 }
166
167 /* url only */
168 static const unsigned char expected_hlink_data[] =
169 {
170 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
171 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
172 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
173 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
174 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
175 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
176 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
177 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
178 0x00,0x00,
179 };
180
181 /* url only (IE7) */
182 static const unsigned char expected_hlink_data_ie7[] =
183 {
184 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
185 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
186 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
187 0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
188 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
189 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
190 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
191 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
192 0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
193 0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
194 0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
195 0x00,0x00,
196 };
197
198 /* url + friendly name */
199 static const unsigned char expected_hlink_data2[] =
200 {
201 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
202 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
203 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
204 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
205 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
206 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
207 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
208 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
209 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
210 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
211 0x67,0x00,0x2f,0x00,0x00,0x00,
212 };
213
214 /* url + friendly name (IE7) */
215 static const unsigned char expected_hlink_data2_ie7[] =
216 {
217 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
218 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
219 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
220 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
221 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
222 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
223 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
224 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
225 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
226 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
227 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
228 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
229 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
230 0x00,0x00,0xa5,0xab,0x00,0x00,
231 };
232
233 /* url + friendly name + location */
234 static const unsigned char expected_hlink_data3[] =
235 {
236 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
237 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
238 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
239 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
240 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
241 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
242 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
243 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
244 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
245 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
246 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
247 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
248 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
249 };
250
251 /* url + friendly name + location (IE7) */
252 static const unsigned char expected_hlink_data3_ie7[] =
253 {
254 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
255 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
256 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
257 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
258 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
259 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
260 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
261 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
262 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
263 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
264 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
265 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
266 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
267 0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
268 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
269 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
270 };
271
272 /* relative url */
273 static const unsigned char expected_hlink_data4[] =
274 {
275 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
276 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
277 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
278 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
279 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
280 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
281 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
282 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
283 0x00,0x00,0x00,0x00,0x00,
284 };
285
286 /* url + target frame name */
287 static const unsigned char expected_hlink_data5[] =
288 {
289 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
290 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
291 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
292 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
293 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
294 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
295 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
296 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
297 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
298 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
299 0x2f,0x00,0x00,0x00,
300 };
301
302 /* url + target frame name (IE7) */
303 static const unsigned char expected_hlink_data5_ie7[] =
304 {
305 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
306 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
307 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
308 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
309 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
310 0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
311 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
312 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
313 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
314 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
315 0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
316 0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
317 0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
318 0xa5,0xab,0x00,0x00,
319 };
320
321 /* filename */
322 static const unsigned char expected_hlink_data6[] =
323 {
324 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
325 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
326 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
327 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
328 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
329 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
330 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
331 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
332 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
333 0x5c,0x00,
334 };
335
336 static void test_persist_save_data(const char *testname, IHlink *lnk,
337 const unsigned char *expected_data,
338 unsigned int expected_data_size,
339 const unsigned char *expected_data_alt,
340 unsigned int expected_data_alt_size)
341 {
342 HRESULT hr;
343 IStream *stream;
344 IPersistStream *ps;
345 HGLOBAL hglobal;
346 DWORD data_size;
347 const unsigned char *data;
348 DWORD i;
349 BOOL same;
350 unsigned int expected_data_win9x_size = 0;
351
352 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
353 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
354
355 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
356 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
357
358 hr = IPersistStream_Save(ps, stream, TRUE);
359 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
360
361 hr = GetHGlobalFromStream(stream, &hglobal);
362 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
363
364 data_size = GlobalSize(hglobal);
365
366 data = GlobalLock(hglobal);
367
368 if (expected_data_size % 4)
369 expected_data_win9x_size = 4 * ((expected_data_size / 4) + 1);
370
371 /* first check we have the right amount of data */
372 ok((data_size == expected_data_size) ||
373 (data_size == expected_data_alt_size) ||
374 broken(data_size == expected_data_win9x_size), /* Win9x and WinMe */
375 "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
376 testname, expected_data_size, expected_data_alt_size, data_size);
377
378 same = TRUE;
379 /* then do a byte-by-byte comparison */
380 for (i = 0; i < min(data_size, expected_data_size); i++)
381 {
382 if ((expected_data[i] != data[i]) &&
383 (((expected_data != expected_hlink_data2) &&
384 (expected_data != expected_hlink_data3)) ||
385 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
386 {
387 same = FALSE;
388 break;
389 }
390 }
391
392 if (!same && (expected_data_alt != expected_data))
393 {
394 /* then try the alternate data */
395 same = TRUE;
396 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
397 {
398 if ((expected_data_alt[i] != data[i]) &&
399 (((expected_data_alt != expected_hlink_data2) &&
400 (expected_data_alt != expected_hlink_data3)) ||
401 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
402 {
403 same = FALSE;
404 break;
405 }
406 }
407 }
408
409 ok(same, "%s: Saved data differs\n", testname);
410 if (!same)
411 {
412 for (i = 0; i < data_size; i++)
413 {
414 if (i % 8 == 0) printf(" ");
415 printf("0x%02x,", data[i]);
416 if (i % 8 == 7) printf("\n");
417 }
418 printf("\n");
419 }
420
421 GlobalUnlock(hglobal);
422
423 IStream_Release(stream);
424 IPersistStream_Release(ps);
425 }
426
427 static void test_persist(void)
428 {
429 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
430 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
431 static const WCHAR filename[] = { 'c',':','\\',0 };
432 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
433 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
434 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
435 HRESULT hr;
436 IHlink *lnk;
437
438 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
439 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
440 ok(hr == S_OK, "IHlinkCreateFromString failed with error 0x%08x\n", hr);
441 if (!lnk) {
442 skip("Can't create lnk, skipping test_persist. Was wineprefixcreate run properly?\n");
443 return;
444 }
445 test_persist_save_data("url only", lnk,
446 expected_hlink_data, sizeof(expected_hlink_data),
447 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
448 IHlink_Release(lnk);
449
450 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
451 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
452 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
453 test_persist_save_data("url + friendly name", lnk,
454 expected_hlink_data2, sizeof(expected_hlink_data2),
455 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
456 IHlink_Release(lnk);
457
458 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
459 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
460 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
461 test_persist_save_data("url + friendly_name + location", lnk,
462 expected_hlink_data3, sizeof(expected_hlink_data3),
463 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
464 IHlink_Release(lnk);
465
466 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
467 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
468 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
469 test_persist_save_data("relative url", lnk,
470 expected_hlink_data4, sizeof(expected_hlink_data4),
471 expected_hlink_data4, sizeof(expected_hlink_data4));
472 IHlink_Release(lnk);
473
474 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
475 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
476 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
477 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
478 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
479 test_persist_save_data("url + target frame name", lnk,
480 expected_hlink_data5, sizeof(expected_hlink_data5),
481 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
482 IHlink_Release(lnk);
483
484 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
485 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
486 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
487 test_persist_save_data("filename", lnk,
488 expected_hlink_data6, sizeof(expected_hlink_data6),
489 expected_hlink_data6, sizeof(expected_hlink_data6));
490 IHlink_Release(lnk);
491 }
492
493 static void test_special_reference(void)
494 {
495 LPWSTR ref;
496 HRESULT hres;
497
498 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
499 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
500 ok(ref != NULL, "ref == NULL\n");
501 CoTaskMemFree(ref);
502
503 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
504 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
505 ok(ref != NULL, "ref == NULL\n");
506 CoTaskMemFree(ref);
507
508 ref = (void*)0xdeadbeef;
509 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
510 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
511 ok(ref == NULL, "ref=%p\n", ref);
512
513 ref = (void*)0xdeadbeef;
514 hres = HlinkGetSpecialReference(4, &ref);
515 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
516 ok(ref == NULL, "ref=%p\n", ref);
517 }
518
519 static void test_HlinkCreateExtensionServices(void)
520 {
521 IAuthenticate *authenticate;
522 IHttpNegotiate *http_negotiate;
523 LPWSTR password, username, headers;
524 HWND hwnd;
525 HRESULT hres;
526
527 static const WCHAR usernameW[] = {'u','s','e','r',0};
528 static const WCHAR passwordW[] = {'p','a','s','s',0};
529 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
530 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
531
532 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
533 NULL, &IID_IAuthenticate, (void**)&authenticate);
534 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
535 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
536
537 password = username = (void*)0xdeadbeef;
538 hwnd = (void*)0xdeadbeef;
539 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
540 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
541 ok(!hwnd, "hwnd != NULL\n");
542 ok(!username, "username != NULL\n");
543 ok(!password, "password != NULL\n");
544
545 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
546 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
547
548 headers = (void*)0xdeadbeef;
549 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
550 0, &headers);
551 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
552 ok(headers == NULL, "headers != NULL\n");
553
554 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
555 0, NULL);
556 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
557
558 headers = (void*)0xdeadbeef;
559 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
560 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
561 ok(headers == NULL, "headers != NULL\n");
562
563 IHttpNegotiate_Release(http_negotiate);
564 IAuthenticate_Release(authenticate);
565
566
567 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
568 NULL, &IID_IAuthenticate, (void**)&authenticate);
569 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
570 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
571
572 password = username = NULL;
573 hwnd = NULL;
574 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
575 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
576 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
577 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
578 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
579 CoTaskMemFree(username);
580 CoTaskMemFree(password);
581
582 password = username = (void*)0xdeadbeef;
583 hwnd = (void*)0xdeadbeef;
584 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
585 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
586 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
587 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
588
589 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
590 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
591
592 headers = (void*)0xdeadbeef;
593 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
594 0, &headers);
595 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
596 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
597 CoTaskMemFree(headers);
598
599 headers = (void*)0xdeadbeef;
600 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
601 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
602 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
603
604 IHttpNegotiate_Release(http_negotiate);
605 IAuthenticate_Release(authenticate);
606 }
607
608 static void test_HlinkParseDisplayName(void)
609 {
610 IMoniker *mon = NULL;
611 LPWSTR name;
612 DWORD issys;
613 ULONG eaten = 0;
614 IBindCtx *bctx;
615 HRESULT hres;
616
617 static const WCHAR winehq_urlW[] =
618 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
619 '/','s','i','t','e','/','a','b','o','u','t',0};
620 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
621 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
622 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
623 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
624
625 CreateBindCtx(0, &bctx);
626
627 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
628 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
629 ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
630 ok(mon != NULL, "mon == NULL\n");
631
632 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
633 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
634 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
635 CoTaskMemFree(name);
636
637 hres = IMoniker_IsSystemMoniker(mon, &issys);
638 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
639 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
640
641 IMoniker_Release(mon);
642
643 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
644 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
645 ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
646 ok(mon != NULL, "mon == NULL\n");
647
648 hres = IMoniker_IsSystemMoniker(mon, &issys);
649 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
650 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
651
652 IMoniker_Release(mon);
653
654 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
655 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
656 ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
657 ok(mon != NULL, "mon == NULL\n");
658
659 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
660 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
661 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
662 CoTaskMemFree(name);
663
664 hres = IMoniker_IsSystemMoniker(mon, &issys);
665 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
666 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
667
668 IMoniker_Release(mon);
669 IBindCtx_Release(bctx);
670 }
671
672 static IBindCtx *_bctx;
673
674 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
675 {
676 ok(0, "unexpected call\n");
677 return E_NOINTERFACE;
678 }
679
680 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
681 {
682 return 2;
683 }
684
685 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
686 {
687 return 1;
688 }
689
690 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
691 REFGUID guidService, REFIID riid, void **ppv)
692 {
693 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
694 return E_NOINTERFACE;
695 }
696
697 static IServiceProviderVtbl ServiceProviderVtbl = {
698 ServiceProvider_QueryInterface,
699 ServiceProvider_AddRef,
700 ServiceProvider_Release,
701 ServiceProvider_QueryService
702 };
703
704 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
705
706 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
707 {
708 *ppv = NULL;
709
710 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
711 *ppv = &ServiceProvider;
712 return S_OK;
713 }
714
715 ok(0, "unexpected interface %s\n", debugstr_guid(riid));
716 return E_NOINTERFACE;
717 }
718
719 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
720 {
721 return 2;
722 }
723
724 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
725 {
726 return 1;
727 }
728
729 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
730 IBinding *pib)
731 {
732 ok(0, "unexpected call\n");
733 return E_NOTIMPL;
734 }
735
736 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
737 {
738 ok(0, "unexpected call\n");
739 return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
743 {
744 ok(0, "unexpected call\n");
745 return E_NOTIMPL;
746 }
747
748 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
749 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
750 {
751 ok(0, "unexpected call\n");
752 return E_NOTIMPL;
753 }
754
755 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
756 {
757 ok(0, "unexpected call\n");
758 return E_NOTIMPL;
759 }
760
761 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
762 {
763 ok(0, "unexpected call\n");
764 return E_NOTIMPL;
765 }
766
767 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
768 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
769 {
770 ok(0, "unexpected call\n");
771 return E_NOTIMPL;
772 }
773
774 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
775 {
776 ok(0, "unexpected call\n");
777 return E_NOTIMPL;
778 }
779
780 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
781 BindStatusCallback_QueryInterface,
782 BindStatusCallback_AddRef,
783 BindStatusCallback_Release,
784 BindStatusCallback_OnStartBinding,
785 BindStatusCallback_GetPriority,
786 BindStatusCallback_OnLowResource,
787 BindStatusCallback_OnProgress,
788 BindStatusCallback_OnStopBinding,
789 BindStatusCallback_GetBindInfo,
790 BindStatusCallback_OnDataAvailable,
791 BindStatusCallback_OnObjectAvailable
792 };
793
794 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
795
796 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
797 {
798 *ppv = NULL;
799
800 ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
801 return E_NOINTERFACE;
802 }
803
804 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
805 {
806 return 2;
807 }
808
809 static ULONG WINAPI Moniker_Release(IMoniker *iface)
810 {
811 return 1;
812 }
813
814 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
815 {
816 ok(0, "unexpected call\n");
817 return E_NOTIMPL;
818 }
819
820 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
821 {
822 ok(0, "unexpected call\n");
823 return E_NOTIMPL;
824 }
825
826 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
827 {
828 ok(0, "unexpected call\n");
829 return E_NOTIMPL;
830 }
831
832 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
833 {
834 ok(0, "unexpected call\n");
835 return E_NOTIMPL;
836 }
837
838 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
839 {
840 ok(0, "unexpected call\n");
841 return E_NOTIMPL;
842 }
843
844 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
845 REFIID riidResult, void **ppvResult)
846 {
847 ok(0, "unexpected call\n");
848 return E_NOTIMPL;
849 }
850
851 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
852 REFIID riid, void **ppv)
853 {
854 IUnknown *unk;
855 HRESULT hres;
856
857 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
858
859 CHECK_EXPECT(BindToStorage);
860
861 ok(pbc == _bctx, "pbc != _bctx\n");
862 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
863 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
864 ok(ppv != NULL, "ppv == NULL\n");
865 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
866
867 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
868 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
869 ok(unk != NULL, "unk == NULL\n");
870
871 IUnknown_Release(unk);
872
873 return S_OK;
874 }
875
876 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
877 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
878 {
879 ok(0, "unexpected call\n");
880 return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
884 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
885 {
886 ok(0, "unexpected call\n");
887 return E_NOTIMPL;
888 }
889
890 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
891 {
892 ok(0, "unexpected call\n");
893 return E_NOTIMPL;
894 }
895
896 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
897 {
898 ok(0, "unexpected call\n");
899 return E_NOTIMPL;
900 }
901
902 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
903 {
904 ok(0, "unexpected call\n");
905 return E_NOTIMPL;
906 }
907
908 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
909 IMoniker *pmkNewlyRunning)
910 {
911 ok(0, "unexpected call\n");
912 return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
916 IMoniker *pmkToLeft, FILETIME *pFileTime)
917 {
918 ok(0, "unexpected call\n");
919 return E_NOTIMPL;
920 }
921
922 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
923 {
924 ok(0, "unexpected call\n");
925 return E_NOTIMPL;
926 }
927
928 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
929 IMoniker **ppmkPrefix)
930 {
931 ok(0, "unexpected call\n");
932 return E_NOTIMPL;
933 }
934
935 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
936 IMoniker **pmkRelPath)
937 {
938 ok(0, "unexpected call\n");
939 return E_NOTIMPL;
940 }
941
942 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
943 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
944 {
945 static const WCHAR winehq_urlW[] =
946 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
947 '/','s','i','t','e','/','a','b','o','u','t',0};
948
949 CHECK_EXPECT(GetDisplayName);
950
951 ok(pbc != NULL, "pbc == NULL\n");
952 ok(pbc != _bctx, "pbc == _bctx\n");
953 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
954
955 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
956 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
957 return S_OK;
958 }
959
960 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
961 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
962 {
963 ok(0, "unexpected call\n");
964 return E_NOTIMPL;
965 }
966
967 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
968 {
969 CHECK_EXPECT2(IsSystemMoniker);
970
971 *pdwMksys = MKSYS_URLMONIKER;
972 return S_OK;
973 }
974
975 static IMonikerVtbl MonikerVtbl = {
976 Moniker_QueryInterface,
977 Moniker_AddRef,
978 Moniker_Release,
979 Moniker_GetClassID,
980 Moniker_IsDirty,
981 Moniker_Load,
982 Moniker_Save,
983 Moniker_GetSizeMax,
984 Moniker_BindToObject,
985 Moniker_BindToStorage,
986 Moniker_Reduce,
987 Moniker_ComposeWith,
988 Moniker_Enum,
989 Moniker_IsEqual,
990 Moniker_Hash,
991 Moniker_IsRunning,
992 Moniker_GetTimeOfLastChange,
993 Moniker_Inverse,
994 Moniker_CommonPrefixWith,
995 Moniker_RelativePathTo,
996 Moniker_GetDisplayName,
997 Moniker_ParseDisplayName,
998 Moniker_IsSystemMoniker
999 };
1000
1001 static IMoniker Moniker = { &MonikerVtbl };
1002
1003 static void test_HlinkResolveMonikerForData(void)
1004 {
1005 IBindCtx *bctx;
1006 HRESULT hres;
1007
1008 CreateBindCtx(0, &bctx);
1009 _bctx = bctx;
1010
1011 SET_EXPECT(IsSystemMoniker);
1012 SET_EXPECT(GetDisplayName);
1013 SET_EXPECT(BindToStorage);
1014
1015 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1016 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1017
1018 CHECK_CALLED(IsSystemMoniker);
1019 CHECK_CALLED(GetDisplayName);
1020 CHECK_CALLED(BindToStorage);
1021
1022 IBindCtx_Release(bctx);
1023 }
1024
1025 static void test_HlinkGetSetMonikerReference(void)
1026 {
1027 IMoniker *found_trgt, *dummy, *dummy2;
1028 IHlink *hlink;
1029 HRESULT hres;
1030 const WCHAR one[] = {'1',0};
1031 const WCHAR two[] = {'2',0};
1032 const WCHAR name[] = {'a',0};
1033 WCHAR *found_loc;
1034
1035 /* create two dummy monikers to use as targets */
1036 hres = CreateItemMoniker(one, one, &dummy);
1037 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1038
1039 hres = CreateItemMoniker(two, two, &dummy2);
1040 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1041
1042 /* create a new hlink: target => dummy, location => one */
1043 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1044 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1045
1046 /* validate the target and location */
1047 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1048 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1049 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1050 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1051 IMoniker_Release(found_trgt);
1052 CoTaskMemFree(found_loc);
1053
1054 /* set location => two */
1055 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1056 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1057
1058 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1059 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1060 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1061 IMoniker_Release(found_trgt);
1062 CoTaskMemFree(found_loc);
1063
1064 /* set target => dummy2 */
1065 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1066 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1067
1068 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1069 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1070 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1071 IMoniker_Release(found_trgt);
1072 CoTaskMemFree(found_loc);
1073
1074 /* set target => dummy, location => one */
1075 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1076 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1077
1078 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1079 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1080 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1081 IMoniker_Release(found_trgt);
1082 CoTaskMemFree(found_loc);
1083
1084 /* no HLINKSETF flags */
1085 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1086 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1087
1088 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1089 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1090 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1091 IMoniker_Release(found_trgt);
1092 CoTaskMemFree(found_loc);
1093
1094 /* invalid HLINKSETF flags */
1095 hres = IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1096 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1097 if (0) ok(hres == 12, "IHlink_SetMonikerReference should've failed with 0x%08x, failed with 0x%08x\n", 12, hres);
1098
1099 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1100 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1101 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1102 IMoniker_Release(found_trgt);
1103 CoTaskMemFree(found_loc);
1104
1105 /* valid & invalid HLINKSETF flags */
1106 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1107 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1108
1109 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1110 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, 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);
1114
1115 /* NULL args */
1116 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1117 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1118
1119 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1120 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1121 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1122 if(found_trgt)
1123 IMoniker_Release(found_trgt);
1124
1125 IHlink_Release(hlink);
1126 IMoniker_Release(dummy2);
1127 IMoniker_Release(dummy);
1128 }
1129
1130 static void test_HlinkGetSetStringReference(void)
1131 {
1132 IHlink *link;
1133 static const WCHAR one[] = {'1',0};
1134 static const WCHAR two[] = {'2',0};
1135 static const WCHAR three[] = {'3',0};
1136 static const WCHAR empty[] = {0};
1137 WCHAR *fnd_tgt, *fnd_loc;
1138 HRESULT hres;
1139
1140 /* create a new hlink: target => NULL, location => one */
1141 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1142 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1143
1144 /* test setting/getting location */
1145 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1146 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1147 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1148 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1149 CoTaskMemFree(fnd_tgt);
1150 CoTaskMemFree(fnd_loc);
1151
1152 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1153 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1154
1155 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1156 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1157 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1158 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1159 CoTaskMemFree(fnd_tgt);
1160 CoTaskMemFree(fnd_loc);
1161
1162 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1163 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1164
1165 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1166 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1167 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1168 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1169 CoTaskMemFree(fnd_tgt);
1170 CoTaskMemFree(fnd_loc);
1171
1172 /* test setting/getting target */
1173 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1174 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1175
1176 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1177 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1178 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1179 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1180 CoTaskMemFree(fnd_tgt);
1181 CoTaskMemFree(fnd_loc);
1182
1183 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1184 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1185
1186 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1187 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1188 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1189 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1190 CoTaskMemFree(fnd_tgt);
1191 CoTaskMemFree(fnd_loc);
1192
1193 /* test setting/getting both */
1194 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1195 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1196
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(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1200 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1201 CoTaskMemFree(fnd_tgt);
1202 CoTaskMemFree(fnd_loc);
1203
1204 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1205 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1206
1207 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1208 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1209 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1210 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1211 CoTaskMemFree(fnd_tgt);
1212 CoTaskMemFree(fnd_loc);
1213
1214 /* test invalid flags/params */
1215 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1216 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1217 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1218 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1219 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1220 CoTaskMemFree(fnd_tgt);
1221 CoTaskMemFree(fnd_loc);
1222
1223 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1224 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1225 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1226 CoTaskMemFree(fnd_tgt);
1227
1228 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1229 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1230
1231 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1232 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1233 CoTaskMemFree(fnd_loc);
1234
1235 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1236 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1237 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1238 CoTaskMemFree(fnd_tgt);
1239 CoTaskMemFree(fnd_loc);
1240
1241 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1242 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1243 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1244 CoTaskMemFree(fnd_tgt);
1245 CoTaskMemFree(fnd_loc);
1246
1247 hres = IHlink_SetStringReference(link, 4, NULL, NULL);
1248 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1249 if (0) ok(hres == 4, "IHlink_SetStringReference should have failed with 0x4, instead: 0x%08x\n", hres);
1250
1251 hres = IHlink_SetStringReference(link, -4, NULL, NULL);
1252 if (0) ok(hres == -4, "IHlink_SetStringReference should have failed with 0xFFFFFFFC, instead: 0x%08x\n", hres);
1253
1254 IHlink_Release(link);
1255 }
1256
1257 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1258 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1259 {
1260 HRESULT hres;
1261 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1262 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1263 }
1264
1265 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1266 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1267 {
1268 HRESULT hres;
1269 WCHAR *fnd_tgt, *fnd_loc;
1270
1271 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1272 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1273
1274 if(exp_tgt)
1275 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));
1276 else
1277 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1278
1279 if(exp_loc)
1280 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));
1281 else
1282 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1283
1284 CoTaskMemFree(fnd_tgt);
1285 CoTaskMemFree(fnd_loc);
1286 }
1287
1288 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1289 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1290 {
1291 HRESULT hres;
1292 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1293 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1294 }
1295
1296 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1297 #define getMonikerRef(h,t,l) r_getMonikerRef(__LINE__,h,t,l)
1298 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc)
1299 {
1300 HRESULT hres;
1301 IMoniker *fnd_tgt;
1302 WCHAR *fnd_loc;
1303
1304 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1305 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1306
1307 if(exp_loc)
1308 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));
1309 else
1310 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1311
1312 CoTaskMemFree(fnd_loc);
1313
1314 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1315 return fnd_tgt;
1316
1317 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1318
1319 if(fnd_tgt)
1320 IMoniker_Release(fnd_tgt);
1321
1322 return NULL;
1323 }
1324
1325 static void test_HlinkMoniker(void)
1326 {
1327 IHlink *hlink;
1328 IMoniker *aMon, *file_mon;
1329 static const WCHAR emptyW[] = {0};
1330 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1331 static const WCHAR aW[] = {'a',0};
1332 static const WCHAR bW[] = {'b',0};
1333 HRESULT hres;
1334
1335 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1336 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1337 getStringRef(hlink, NULL, NULL);
1338 getMonikerRef(hlink, NULL, NULL);
1339
1340 /* setting a string target creates a moniker reference */
1341 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1342 getStringRef(hlink, aW, wordsW);
1343 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW);
1344 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1345 if(aMon)
1346 IMoniker_Release(aMon);
1347
1348 /* setting target & location to the empty string deletes the moniker
1349 * reference */
1350 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1351 getStringRef(hlink, NULL, NULL);
1352 getMonikerRef(hlink, NULL, NULL);
1353
1354 /* setting a moniker target also sets the target string to that moniker's
1355 * display name */
1356 hres = CreateFileMoniker(bW, &file_mon);
1357 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1358
1359 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1360 getStringRef(hlink, bW, wordsW);
1361 getMonikerRef(hlink, file_mon, wordsW);
1362
1363 IMoniker_Release(file_mon);
1364
1365 IHlink_Release(hlink);
1366 }
1367
1368 static void test_HashLink(void)
1369 {
1370 IHlink *hlink;
1371 IMoniker *pmk;
1372 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1373 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};
1374 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1375 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1376 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1377 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1378 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1379 HRESULT hres;
1380
1381 /* simple single hash test */
1382 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1383 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1384 ok(hlink != NULL, "Didn't get an hlink\n");
1385
1386 if(hlink){
1387 getStringRef(hlink, tgt_partW, loc_partW);
1388 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
1389 ok(pmk != NULL, "Found moniker should not be NULL\n");
1390 if(pmk)
1391 IMoniker_Release(pmk);
1392
1393 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1394 getStringRef(hlink, hash_targetW, loc_partW);
1395
1396 IHlink_Release(hlink);
1397 }
1398
1399 /* two hashes in the target */
1400 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1401 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1402 ok(hlink != NULL, "Didn't get an hlink\n");
1403
1404 if(hlink){
1405 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1406 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW);
1407 ok(pmk != NULL, "Found moniker should not be NULL\n");
1408 if(pmk)
1409 IMoniker_Release(pmk);
1410
1411 IHlink_Release(hlink);
1412 }
1413
1414 /* target with hash plus a location string */
1415 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1416 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1417 ok(hlink != NULL, "Didn't get an hlink\n");
1418
1419 if(hlink){
1420 getStringRef(hlink, tgt_partW, test_locW);
1421 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW);
1422 ok(pmk != NULL, "Found moniker should not be NULL\n");
1423 if(pmk)
1424 IMoniker_Release(pmk);
1425
1426 IHlink_Release(hlink);
1427 }
1428
1429 /* target with hash containing no "target part" */
1430 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1431 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1432 ok(hlink != NULL, "Didn't get an hlink\n");
1433
1434 if(hlink){
1435 getStringRef(hlink, NULL, loc_partW);
1436 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
1437 ok(pmk == NULL, "Found moniker should be NULL\n");
1438 if(pmk)
1439 IMoniker_Release(pmk);
1440
1441 IHlink_Release(hlink);
1442 }
1443 }
1444
1445 START_TEST(hlink)
1446 {
1447 CoInitialize(NULL);
1448
1449 test_HlinkIsShortcut();
1450 test_reference();
1451 test_persist();
1452 test_special_reference();
1453 test_HlinkCreateExtensionServices();
1454 test_HlinkParseDisplayName();
1455 test_HlinkResolveMonikerForData();
1456 test_HlinkGetSetMonikerReference();
1457 test_HlinkGetSetStringReference();
1458 test_HlinkMoniker();
1459 test_HashLink();
1460
1461 CoUninitialize();
1462 }