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
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) \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
44 #define CHECK_EXPECT(func) \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
50 #define CHECK_CALLED(func) \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
56 DEFINE_EXPECT(IsSystemMoniker
);
57 DEFINE_EXPECT(BindToStorage
);
58 DEFINE_EXPECT(GetDisplayName
);
60 static const char *debugstr_guid(REFIID riid
)
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]);
72 static void test_HlinkIsShortcut(void)
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};
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
);
108 static void test_reference(void)
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 };
117 r
= HlinkCreateFromString(url
, NULL
, NULL
, NULL
,
118 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
119 ok(r
== S_OK
, "failed to create link\n");
123 r
= IHlink_GetMonikerReference(lnk
, HLINKGETREF_DEFAULT
, NULL
, NULL
);
124 ok(r
== S_OK
, "failed\n");
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");
131 r
= IMoniker_Release(mk
);
132 ok( r
== 1, "moniker refcount wrong\n");
134 r
= IHlink_GetStringReference(lnk
, -1, &str
, NULL
);
135 ok(r
== S_OK
, "failed\n");
138 r
= IHlink_GetStringReference(lnk
, -1, NULL
, NULL
);
139 ok(r
== S_OK
, "failed, r=%08x\n", r
);
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");
145 r
= IHlink_GetStringReference(lnk
, HLINKGETREF_DEFAULT
, &str
, NULL
);
146 ok(r
== S_OK
, "failed\n");
147 ok(!lstrcmpW(str
, url2
), "url wrong\n");
150 r
= IHlink_GetStringReference(lnk
, HLINKGETREF_DEFAULT
, NULL
, NULL
);
151 ok(r
== S_OK
, "failed\n");
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");
157 /* Unimplented functions checks */
158 r
= IHlink_GetAdditionalParams(lnk
, NULL
);
159 ok(r
== E_NOTIMPL
, "failed\n");
161 r
= IHlink_SetAdditionalParams(lnk
, NULL
);
162 ok(r
== E_NOTIMPL
, "failed\n");
168 static const unsigned char expected_hlink_data
[] =
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,
182 static const unsigned char expected_hlink_data_ie7
[] =
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,
198 /* url + friendly name */
199 static const unsigned char expected_hlink_data2
[] =
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,
214 /* url + friendly name (IE7) */
215 static const unsigned char expected_hlink_data2_ie7
[] =
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,
233 /* url + friendly name + location */
234 static const unsigned char expected_hlink_data3
[] =
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,
251 /* url + friendly name + location (IE7) */
252 static const unsigned char expected_hlink_data3_ie7
[] =
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,
273 static const unsigned char expected_hlink_data4
[] =
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,
286 /* url + target frame name */
287 static const unsigned char expected_hlink_data5
[] =
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,
302 /* url + target frame name (IE7) */
303 static const unsigned char expected_hlink_data5_ie7
[] =
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,
322 static const unsigned char expected_hlink_data6
[] =
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,
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
)
347 const unsigned char *data
;
350 unsigned int expected_data_win9x_size
= 0;
352 hr
= IHlink_QueryInterface(lnk
, &IID_IPersistStream
, (void **)&ps
);
353 ok(hr
== S_OK
, "IHlink_QueryInterface failed with error 0x%08x\n", hr
);
355 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
356 ok(hr
== S_OK
, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr
);
358 hr
= IPersistStream_Save(ps
, stream
, TRUE
);
359 ok(hr
== S_OK
, "IPersistStream_Save failed with error 0x%08x\n", hr
);
361 hr
= GetHGlobalFromStream(stream
, &hglobal
);
362 ok(hr
== S_OK
, "GetHGlobalFromStream failed with error 0x%08x\n", hr
);
364 data_size
= GlobalSize(hglobal
);
366 data
= GlobalLock(hglobal
);
368 if (expected_data_size
% 4)
369 expected_data_win9x_size
= 4 * ((expected_data_size
/ 4) + 1);
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
);
379 /* then do a byte-by-byte comparison */
380 for (i
= 0; i
< min(data_size
, expected_data_size
); i
++)
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))))
392 if (!same
&& (expected_data_alt
!= expected_data
))
394 /* then try the alternate data */
396 for (i
= 0; i
< min(data_size
, expected_data_alt_size
); i
++)
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))))
409 ok(same
, "%s: Saved data differs\n", testname
);
412 for (i
= 0; i
< data_size
; i
++)
414 if (i
% 8 == 0) printf(" ");
415 printf("0x%02x,", data
[i
]);
416 if (i
% 8 == 7) printf("\n");
421 GlobalUnlock(hglobal
);
423 IStream_Release(stream
);
424 IPersistStream_Release(ps
);
427 static void test_persist(void)
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 };
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
);
442 skip("Can't create lnk, skipping test_persist. Was wineprefixcreate run properly?\n");
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
));
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
));
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
));
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
));
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
));
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
));
493 static void test_special_reference(void)
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");
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");
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
);
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
);
519 static void test_HlinkCreateExtensionServices(void)
521 IAuthenticate
*authenticate
;
522 IHttpNegotiate
*http_negotiate
;
523 LPWSTR password
, username
, headers
;
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};
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");
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");
545 hres
= IAuthenticate_QueryInterface(authenticate
, &IID_IHttpNegotiate
, (void**)&http_negotiate
);
546 ok(hres
== S_OK
, "Could not get IHttpNegotiate interface: %08x\n", hres
);
548 headers
= (void*)0xdeadbeef;
549 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, (void*)0xdeadbeef, (void*)0xdeadbeef,
551 ok(hres
== S_OK
, "BeginningTransaction failed: %08x\n", hres
);
552 ok(headers
== NULL
, "headers != NULL\n");
554 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, (void*)0xdeadbeef, (void*)0xdeadbeef,
556 ok(hres
== E_INVALIDARG
, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres
);
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");
563 IHttpNegotiate_Release(http_negotiate
);
564 IAuthenticate_Release(authenticate
);
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");
572 password
= username
= 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
);
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
);
589 hres
= IAuthenticate_QueryInterface(authenticate
, &IID_IHttpNegotiate
, (void**)&http_negotiate
);
590 ok(hres
== S_OK
, "Could not get IHttpNegotiate interface: %08x\n", hres
);
592 headers
= (void*)0xdeadbeef;
593 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, (void*)0xdeadbeef, (void*)0xdeadbeef,
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
);
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
));
604 IHttpNegotiate_Release(http_negotiate
);
605 IAuthenticate_Release(authenticate
);
608 static void test_HlinkParseDisplayName(void)
610 IMoniker
*mon
= NULL
;
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};
625 CreateBindCtx(0, &bctx
);
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");
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
));
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
);
641 IMoniker_Release(mon
);
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");
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
);
652 IMoniker_Release(mon
);
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");
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
));
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
);
668 IMoniker_Release(mon
);
669 IBindCtx_Release(bctx
);
672 static IBindCtx
*_bctx
;
674 static HRESULT WINAPI
ServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
676 ok(0, "unexpected call\n");
677 return E_NOINTERFACE
;
680 static ULONG WINAPI
ServiceProvider_AddRef(IServiceProvider
*iface
)
685 static ULONG WINAPI
ServiceProvider_Release(IServiceProvider
*iface
)
690 static HRESULT WINAPI
ServiceProvider_QueryService(IServiceProvider
*iface
,
691 REFGUID guidService
, REFIID riid
, void **ppv
)
693 ok(0, "unexpected service %s\n", debugstr_guid(guidService
));
694 return E_NOINTERFACE
;
697 static IServiceProviderVtbl ServiceProviderVtbl
= {
698 ServiceProvider_QueryInterface
,
699 ServiceProvider_AddRef
,
700 ServiceProvider_Release
,
701 ServiceProvider_QueryService
704 static IServiceProvider ServiceProvider
= { &ServiceProviderVtbl
};
706 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
, REFIID riid
, void **ppv
)
710 if(IsEqualGUID(riid
, &IID_IServiceProvider
)) {
711 *ppv
= &ServiceProvider
;
715 ok(0, "unexpected interface %s\n", debugstr_guid(riid
));
716 return E_NOINTERFACE
;
719 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
724 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
729 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
, DWORD dwReserved
,
732 ok(0, "unexpected call\n");
736 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
738 ok(0, "unexpected call\n");
742 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
744 ok(0, "unexpected call\n");
748 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
749 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
751 ok(0, "unexpected call\n");
755 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
, HRESULT hresult
, LPCWSTR szError
)
757 ok(0, "unexpected call\n");
761 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
763 ok(0, "unexpected call\n");
767 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
768 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
770 ok(0, "unexpected call\n");
774 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
, REFIID riid
, IUnknown
*punk
)
776 ok(0, "unexpected call\n");
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
794 static IBindStatusCallback BindStatusCallback
= { &BindStatusCallbackVtbl
};
796 static HRESULT WINAPI
Moniker_QueryInterface(IMoniker
*iface
, REFIID riid
, void **ppv
)
800 ok(0, "unexpected riid: %s\n", debugstr_guid(riid
));
801 return E_NOINTERFACE
;
804 static ULONG WINAPI
Moniker_AddRef(IMoniker
*iface
)
809 static ULONG WINAPI
Moniker_Release(IMoniker
*iface
)
814 static HRESULT WINAPI
Moniker_GetClassID(IMoniker
*iface
, CLSID
*pClassID
)
816 ok(0, "unexpected call\n");
820 static HRESULT WINAPI
Moniker_IsDirty(IMoniker
*iface
)
822 ok(0, "unexpected call\n");
826 static HRESULT WINAPI
Moniker_Load(IMoniker
*iface
, IStream
*pStm
)
828 ok(0, "unexpected call\n");
832 static HRESULT WINAPI
Moniker_Save(IMoniker
*iface
, IStream
*pStm
, BOOL fClearDirty
)
834 ok(0, "unexpected call\n");
838 static HRESULT WINAPI
Moniker_GetSizeMax(IMoniker
*iface
, ULARGE_INTEGER
*pcbSize
)
840 ok(0, "unexpected call\n");
844 static HRESULT WINAPI
Moniker_BindToObject(IMoniker
*iface
, IBindCtx
*pcb
, IMoniker
*pmkToLeft
,
845 REFIID riidResult
, void **ppvResult
)
847 ok(0, "unexpected call\n");
851 static HRESULT WINAPI
Moniker_BindToStorage(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
852 REFIID riid
, void **ppv
)
857 static OLECHAR BSCBHolder
[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
859 CHECK_EXPECT(BindToStorage
);
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
);
867 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
868 ok(hres
== S_OK
, "GetObjectParam failed: %08x\n", hres
);
869 ok(unk
!= NULL
, "unk == NULL\n");
871 IUnknown_Release(unk
);
876 static HRESULT WINAPI
Moniker_Reduce(IMoniker
*iface
, IBindCtx
*pbc
, DWORD dwReduceHowFar
,
877 IMoniker
**ppmkToLeft
, IMoniker
**ppmkReduced
)
879 ok(0, "unexpected call\n");
883 static HRESULT WINAPI
Moniker_ComposeWith(IMoniker
*iface
, IMoniker
*pmkRight
,
884 BOOL fOnlyIfNotGeneric
, IMoniker
**ppnkComposite
)
886 ok(0, "unexpected call\n");
890 static HRESULT WINAPI
Moniker_Enum(IMoniker
*iface
, BOOL fForwrd
, IEnumMoniker
**ppenumMoniker
)
892 ok(0, "unexpected call\n");
896 static HRESULT WINAPI
Moniker_IsEqual(IMoniker
*iface
, IMoniker
*pmkOtherMoniker
)
898 ok(0, "unexpected call\n");
902 static HRESULT WINAPI
Moniker_Hash(IMoniker
*iface
, DWORD
*pdwHash
)
904 ok(0, "unexpected call\n");
908 static HRESULT WINAPI
Moniker_IsRunning(IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
,
909 IMoniker
*pmkNewlyRunning
)
911 ok(0, "unexpected call\n");
915 static HRESULT WINAPI
Moniker_GetTimeOfLastChange(IMoniker
*iface
, IBindCtx
*pbc
,
916 IMoniker
*pmkToLeft
, FILETIME
*pFileTime
)
918 ok(0, "unexpected call\n");
922 static HRESULT WINAPI
Moniker_Inverse(IMoniker
*iface
, IMoniker
**ppmk
)
924 ok(0, "unexpected call\n");
928 static HRESULT WINAPI
Moniker_CommonPrefixWith(IMoniker
*iface
, IMoniker
*pmkOther
,
929 IMoniker
**ppmkPrefix
)
931 ok(0, "unexpected call\n");
935 static HRESULT WINAPI
Moniker_RelativePathTo(IMoniker
*iface
, IMoniker
*pmkOther
,
936 IMoniker
**pmkRelPath
)
938 ok(0, "unexpected call\n");
942 static HRESULT WINAPI
Moniker_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
,
943 IMoniker
*pmkToLeft
, LPOLESTR
*ppszDisplayName
)
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};
949 CHECK_EXPECT(GetDisplayName
);
951 ok(pbc
!= NULL
, "pbc == NULL\n");
952 ok(pbc
!= _bctx
, "pbc == _bctx\n");
953 ok(pmkToLeft
== NULL
, "pmkToLeft=%p\n", pmkToLeft
);
955 *ppszDisplayName
= CoTaskMemAlloc(sizeof(winehq_urlW
));
956 memcpy(*ppszDisplayName
, winehq_urlW
, sizeof(winehq_urlW
));
960 static HRESULT WINAPI
Moniker_ParseDisplayName(IMoniker
*iface
, IBindCtx
*pbc
,
961 IMoniker
*pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
*pchEaten
, IMoniker
**ppmkOut
)
963 ok(0, "unexpected call\n");
967 static HRESULT WINAPI
Moniker_IsSystemMoniker(IMoniker
*iface
, DWORD
*pdwMksys
)
969 CHECK_EXPECT2(IsSystemMoniker
);
971 *pdwMksys
= MKSYS_URLMONIKER
;
975 static IMonikerVtbl MonikerVtbl
= {
976 Moniker_QueryInterface
,
984 Moniker_BindToObject
,
985 Moniker_BindToStorage
,
992 Moniker_GetTimeOfLastChange
,
994 Moniker_CommonPrefixWith
,
995 Moniker_RelativePathTo
,
996 Moniker_GetDisplayName
,
997 Moniker_ParseDisplayName
,
998 Moniker_IsSystemMoniker
1001 static IMoniker Moniker
= { &MonikerVtbl
};
1003 static void test_HlinkResolveMonikerForData(void)
1008 CreateBindCtx(0, &bctx
);
1011 SET_EXPECT(IsSystemMoniker
);
1012 SET_EXPECT(GetDisplayName
);
1013 SET_EXPECT(BindToStorage
);
1015 hres
= HlinkResolveMonikerForData(&Moniker
, 0, bctx
, 0, NULL
, &BindStatusCallback
, NULL
);
1016 ok(hres
== S_OK
, "HlinkResolveMonikerForData failed: %08x\n", hres
);
1018 CHECK_CALLED(IsSystemMoniker
);
1019 CHECK_CALLED(GetDisplayName
);
1020 CHECK_CALLED(BindToStorage
);
1022 IBindCtx_Release(bctx
);
1025 static void test_HlinkGetSetMonikerReference(void)
1027 IMoniker
*found_trgt
, *dummy
, *dummy2
;
1030 const WCHAR one
[] = {'1',0};
1031 const WCHAR two
[] = {'2',0};
1032 const WCHAR name
[] = {'a',0};
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
);
1039 hres
= CreateItemMoniker(two
, two
, &dummy2
);
1040 ok(hres
== S_OK
, "CreateItemMoniker failed: 0x%08x\n", hres
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1116 hres
= IHlink_SetMonikerReference(hlink
, HLINKSETF_TARGET
| HLINKSETF_LOCATION
, NULL
, NULL
);
1117 ok(hres
== S_OK
, "IHlink_SetMonikerReference failed: 0x%08x\n", hres
);
1119 hres
= IHlink_GetMonikerReference(hlink
, HLINKGETREF_DEFAULT
, &found_trgt
, &found_loc
);
1120 ok(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
));
1123 IMoniker_Release(found_trgt
);
1125 IHlink_Release(hlink
);
1126 IMoniker_Release(dummy2
);
1127 IMoniker_Release(dummy
);
1130 static void test_HlinkGetSetStringReference(void)
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
;
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
);
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
);
1152 hres
= IHlink_SetStringReference(link
, HLINKSETF_LOCATION
, one
, two
);
1153 ok(hres
== S_OK
, "IHlink_SetStringReference failed: 0x%08x\n", hres
);
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
);
1162 hres
= IHlink_SetStringReference(link
, -HLINKSETF_LOCATION
, two
, one
);
1163 ok(hres
== S_OK
, "IHlink_SetStringReference failed: 0x%08x\n", hres
);
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
);
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
);
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
);
1183 hres
= IHlink_SetStringReference(link
, -HLINKSETF_TARGET
, three
, two
);
1184 ok(hres
== S_OK
, "IHlink_SetStringReference failed: 0x%08x\n", hres
);
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
);
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
);
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
);
1204 hres
= IHlink_SetStringReference(link
, -(HLINKSETF_TARGET
| HLINKSETF_LOCATION
), three
, one
);
1205 ok(hres
== S_OK
, "IHlink_SetStringReference failed: 0x%08x\n", hres
);
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
);
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
);
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
);
1228 hres
= IHlink_GetStringReference(link
, -1, NULL
, NULL
);
1229 ok(hres
== S_OK
, "failed, hres=%08x\n", hres
);
1231 hres
= IHlink_GetStringReference(link
, -1, NULL
, &fnd_loc
);
1232 ok(hres
== S_OK
, "failed, hres=%08x\n", hres
);
1233 CoTaskMemFree(fnd_loc
);
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
);
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
);
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
);
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
);
1254 IHlink_Release(link
);
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
)
1261 hres
= IHlink_SetStringReference(hlink
, flags
, tgt
, loc
);
1262 ok_(__FILE__
,line
) (hres
== S_OK
, "IHlink_SetStringReference failed: 0x%08x\n", hres
);
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
)
1269 WCHAR
*fnd_tgt
, *fnd_loc
;
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
);
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
));
1277 ok_(__FILE__
,line
) (fnd_tgt
== NULL
, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt
));
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
));
1282 ok_(__FILE__
,line
) (fnd_loc
== NULL
, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc
));
1284 CoTaskMemFree(fnd_tgt
);
1285 CoTaskMemFree(fnd_loc
);
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
)
1292 hres
= IHlink_SetMonikerReference(hlink
, flags
, tgt
, loc
);
1293 ok_(__FILE__
,line
) (hres
== S_OK
, "IHlink_SetMonikerReference failed: 0x%08x\n", hres
);
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
)
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
);
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
));
1310 ok_(__FILE__
,line
) (fnd_loc
== NULL
, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc
));
1312 CoTaskMemFree(fnd_loc
);
1314 if(exp_tgt
== (IMoniker
*)0xFFFFFFFF)
1317 ok_(__FILE__
,line
) (fnd_tgt
== exp_tgt
, "Found moniker target should have been %p, was: %p\n", exp_tgt
, fnd_tgt
);
1320 IMoniker_Release(fnd_tgt
);
1325 static void test_HlinkMoniker(void)
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};
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
);
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
));
1346 IMoniker_Release(aMon
);
1348 /* setting target & location to the empty string deletes the moniker
1350 setStringRef(hlink
, HLINKSETF_TARGET
| HLINKSETF_LOCATION
, emptyW
, emptyW
);
1351 getStringRef(hlink
, NULL
, NULL
);
1352 getMonikerRef(hlink
, NULL
, NULL
);
1354 /* setting a moniker target also sets the target string to that moniker's
1356 hres
= CreateFileMoniker(bW
, &file_mon
);
1357 ok(hres
== S_OK
, "CreateFileMoniker failed: 0x%08x\n", hres
);
1359 setMonikerRef(hlink
, HLINKSETF_TARGET
| HLINKSETF_LOCATION
, file_mon
, wordsW
);
1360 getStringRef(hlink
, bW
, wordsW
);
1361 getMonikerRef(hlink
, file_mon
, wordsW
);
1363 IMoniker_Release(file_mon
);
1365 IHlink_Release(hlink
);
1368 static void test_HashLink(void)
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};
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");
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");
1391 IMoniker_Release(pmk
);
1393 setStringRef(hlink
, HLINKSETF_TARGET
, hash_targetW
, NULL
);
1394 getStringRef(hlink
, hash_targetW
, loc_partW
);
1396 IHlink_Release(hlink
);
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");
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");
1409 IMoniker_Release(pmk
);
1411 IHlink_Release(hlink
);
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");
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");
1424 IMoniker_Release(pmk
);
1426 IHlink_Release(hlink
);
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");
1435 getStringRef(hlink
, NULL
, loc_partW
);
1436 pmk
= getMonikerRef(hlink
, (IMoniker
*)0xFFFFFFFF, loc_partW
);
1437 ok(pmk
== NULL
, "Found moniker should be NULL\n");
1439 IMoniker_Release(pmk
);
1441 IHlink_Release(hlink
);
1449 test_HlinkIsShortcut();
1452 test_special_reference();
1453 test_HlinkCreateExtensionServices();
1454 test_HlinkParseDisplayName();
1455 test_HlinkResolveMonikerForData();
1456 test_HlinkGetSetMonikerReference();
1457 test_HlinkGetSetStringReference();
1458 test_HlinkMoniker();