wer: Add new stubbed wer.dll.
[wine/hramrach.git] / dlls / hlink / tests / hlink.c
blob61b9498fb01b311210911b8fbc5caa87d4eca398
1 /*
2 * Implementation of hyperlinking (hlink.dll)
4 * Copyright 2006 Mike McCormack
5 * Copyright 2007-2008 Jacek Caban for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include <stdio.h>
26 #include <initguid.h>
27 #include <hlink.h>
28 #include <hlguids.h>
30 #include "wine/test.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT2(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
42 }while(0)
44 #define CHECK_EXPECT(func) \
45 do { \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
48 }while(0)
50 #define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
54 }while(0)
56 DEFINE_EXPECT(IsSystemMoniker);
57 DEFINE_EXPECT(BindToStorage);
58 DEFINE_EXPECT(GetDisplayName);
60 DEFINE_EXPECT(ComposeWith);
61 DEFINE_EXPECT(OnNavigationComplete);
62 DEFINE_EXPECT(Enum);
63 DEFINE_EXPECT(Reduce);
65 static const char *debugstr_guid(REFIID riid)
67 static char buf[50];
69 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
70 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
71 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
72 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
74 return buf;
77 static void test_HlinkIsShortcut(void)
79 UINT i;
80 HRESULT hres;
82 static const WCHAR file0[] = {'f','i','l','e',0};
83 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
84 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
85 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
86 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
87 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
88 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
89 static const WCHAR file7[] = {'.','u','r','l',0};
91 static struct {
92 LPCWSTR file;
93 HRESULT hres;
94 } shortcut_test[] = {
95 {file0, S_FALSE},
96 {file1, S_OK},
97 {file2, S_FALSE},
98 {file3, S_OK},
99 {file4, S_FALSE},
100 {file5, S_OK},
101 {file6, S_FALSE},
102 {file7, S_OK},
103 {NULL, E_INVALIDARG}
106 for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
107 hres = HlinkIsShortcut(shortcut_test[i].file);
108 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
109 i, hres, shortcut_test[i].hres);
113 static void test_reference(void)
115 HRESULT r;
116 IHlink *lnk = NULL;
117 IMoniker *mk = NULL;
118 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
119 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
120 LPWSTR str = NULL;
122 r = HlinkCreateFromString(url, NULL, NULL, NULL,
123 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
124 ok(r == S_OK, "failed to create link\n");
125 if (FAILED(r))
126 return;
128 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
129 ok(r == S_OK, "failed\n");
131 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
132 ok(r == S_OK, "failed\n");
133 ok(mk != NULL, "no moniker\n");
134 ok(str == NULL, "string should be null\n");
136 r = IMoniker_Release(mk);
137 ok( r == 1, "moniker refcount wrong\n");
139 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
140 ok(r == S_OK, "failed\n");
141 CoTaskMemFree(str);
143 r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
144 ok(r == S_OK, "failed, r=%08x\n", r);
146 r = IHlink_GetStringReference(lnk, -1, NULL, &str);
147 ok(r == S_OK, "failed, r=%08x\n", r);
148 ok(str == NULL, "string should be null\n");
150 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
151 ok(r == S_OK, "failed\n");
152 ok(!lstrcmpW(str, url2), "url wrong\n");
153 CoTaskMemFree(str);
155 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
156 ok(r == S_OK, "failed\n");
158 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
159 ok(r == S_OK, "failed\n");
160 ok(str == NULL, "string should be null\n");
162 /* Unimplented functions checks */
163 r = IHlink_GetAdditionalParams(lnk, NULL);
164 ok(r == E_NOTIMPL, "failed\n");
166 r = IHlink_SetAdditionalParams(lnk, NULL);
167 ok(r == E_NOTIMPL, "failed\n");
169 IHlink_Release(lnk);
172 /* url only */
173 static const unsigned char expected_hlink_data[] =
175 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
176 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
177 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
178 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
179 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
180 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
181 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
182 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
183 0x00,0x00,
186 /* url only (IE7) */
187 static const unsigned char expected_hlink_data_ie7[] =
189 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
190 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
191 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
192 0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
193 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
194 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
195 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
196 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
197 0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
198 0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
199 0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
200 0x00,0x00,
203 /* url + friendly name */
204 static const unsigned char expected_hlink_data2[] =
206 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
207 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
208 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
209 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
210 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
211 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
212 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
213 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
214 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
215 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
216 0x67,0x00,0x2f,0x00,0x00,0x00,
219 /* url + friendly name (IE7) */
220 static const unsigned char expected_hlink_data2_ie7[] =
222 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
223 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
224 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
225 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
226 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
227 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
228 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
229 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
230 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
231 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
232 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
233 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
234 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
235 0x00,0x00,0xa5,0xab,0x00,0x00,
238 /* url + friendly name + location */
239 static const unsigned char expected_hlink_data3[] =
241 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
242 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
243 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
244 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
245 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
246 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
247 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
248 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
249 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
250 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
251 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
252 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
253 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
256 /* url + friendly name + location (IE7) */
257 static const unsigned char expected_hlink_data3_ie7[] =
259 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
260 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
261 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
262 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
263 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
264 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
265 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
266 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
267 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
268 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
269 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
270 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
271 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
272 0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
273 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
274 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
277 /* relative url */
278 static const unsigned char expected_hlink_data4[] =
280 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
281 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
282 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
283 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
284 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
285 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
286 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
287 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
288 0x00,0x00,0x00,0x00,0x00,
291 /* url + target frame name */
292 static const unsigned char expected_hlink_data5[] =
294 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
295 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
296 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
297 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
298 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
299 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
300 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
301 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
302 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
303 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
304 0x2f,0x00,0x00,0x00,
307 /* url + target frame name (IE7) */
308 static const unsigned char expected_hlink_data5_ie7[] =
310 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
311 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
312 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
313 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
314 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
315 0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
316 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
317 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
318 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
319 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
320 0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
321 0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
322 0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
323 0xa5,0xab,0x00,0x00,
326 /* filename */
327 static const unsigned char expected_hlink_data6[] =
329 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
330 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
331 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
332 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
333 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
334 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
335 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
336 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
337 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
338 0x5c,0x00,
341 static void test_persist_save_data(const char *testname, IHlink *lnk,
342 const unsigned char *expected_data,
343 unsigned int expected_data_size,
344 const unsigned char *expected_data_alt,
345 unsigned int expected_data_alt_size)
347 HRESULT hr;
348 IStream *stream;
349 IPersistStream *ps;
350 HGLOBAL hglobal;
351 DWORD data_size;
352 const unsigned char *data;
353 DWORD i;
354 BOOL same;
355 unsigned int expected_data_win9x_size = 0;
357 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
358 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
360 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
361 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
363 hr = IPersistStream_Save(ps, stream, TRUE);
364 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
366 hr = GetHGlobalFromStream(stream, &hglobal);
367 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
369 data_size = GlobalSize(hglobal);
371 data = GlobalLock(hglobal);
373 if (expected_data_size % 4)
374 expected_data_win9x_size = 4 * ((expected_data_size / 4) + 1);
376 /* first check we have the right amount of data */
377 ok((data_size == expected_data_size) ||
378 (data_size == expected_data_alt_size) ||
379 broken(data_size == expected_data_win9x_size), /* Win9x and WinMe */
380 "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
381 testname, expected_data_size, expected_data_alt_size, data_size);
383 same = TRUE;
384 /* then do a byte-by-byte comparison */
385 for (i = 0; i < min(data_size, expected_data_size); i++)
387 if ((expected_data[i] != data[i]) &&
388 (((expected_data != expected_hlink_data2) &&
389 (expected_data != expected_hlink_data3)) ||
390 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
392 same = FALSE;
393 break;
397 if (!same && (expected_data_alt != expected_data))
399 /* then try the alternate data */
400 same = TRUE;
401 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
403 if ((expected_data_alt[i] != data[i]) &&
404 (((expected_data_alt != expected_hlink_data2) &&
405 (expected_data_alt != expected_hlink_data3)) ||
406 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
408 same = FALSE;
409 break;
414 ok(same, "%s: Saved data differs\n", testname);
415 if (!same)
417 for (i = 0; i < data_size; i++)
419 if (i % 8 == 0) printf(" ");
420 printf("0x%02x,", data[i]);
421 if (i % 8 == 7) printf("\n");
423 printf("\n");
426 GlobalUnlock(hglobal);
428 IStream_Release(stream);
429 IPersistStream_Release(ps);
432 static void test_persist(void)
434 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
435 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
436 static const WCHAR filename[] = { 'c',':','\\',0 };
437 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
438 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
439 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
440 HRESULT hr;
441 IHlink *lnk;
443 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
444 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
445 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
446 if (!lnk) {
447 skip("Can't create lnk, skipping test_persist.\n");
448 return;
450 test_persist_save_data("url only", lnk,
451 expected_hlink_data, sizeof(expected_hlink_data),
452 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
453 IHlink_Release(lnk);
455 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
456 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
457 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
458 test_persist_save_data("url + friendly name", lnk,
459 expected_hlink_data2, sizeof(expected_hlink_data2),
460 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
461 IHlink_Release(lnk);
463 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
464 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
465 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
466 test_persist_save_data("url + friendly_name + location", lnk,
467 expected_hlink_data3, sizeof(expected_hlink_data3),
468 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
469 IHlink_Release(lnk);
471 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
472 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
473 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
474 test_persist_save_data("relative url", lnk,
475 expected_hlink_data4, sizeof(expected_hlink_data4),
476 expected_hlink_data4, sizeof(expected_hlink_data4));
477 IHlink_Release(lnk);
479 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
480 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
481 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
482 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
483 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
484 test_persist_save_data("url + target frame name", lnk,
485 expected_hlink_data5, sizeof(expected_hlink_data5),
486 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
487 IHlink_Release(lnk);
489 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
490 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
491 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
492 test_persist_save_data("filename", lnk,
493 expected_hlink_data6, sizeof(expected_hlink_data6),
494 expected_hlink_data6, sizeof(expected_hlink_data6));
495 IHlink_Release(lnk);
498 static void test_special_reference(void)
500 LPWSTR ref;
501 HRESULT hres;
503 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
504 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
505 ok(ref != NULL, "ref == NULL\n");
506 CoTaskMemFree(ref);
508 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
509 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
510 ok(ref != NULL, "ref == NULL\n");
511 CoTaskMemFree(ref);
513 ref = (void*)0xdeadbeef;
514 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
515 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
516 ok(ref == NULL, "ref=%p\n", ref);
518 ref = (void*)0xdeadbeef;
519 hres = HlinkGetSpecialReference(4, &ref);
520 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
521 ok(ref == NULL, "ref=%p\n", ref);
524 static void test_HlinkCreateExtensionServices(void)
526 IAuthenticate *authenticate;
527 IHttpNegotiate *http_negotiate;
528 LPWSTR password, username, headers;
529 HWND hwnd;
530 HRESULT hres;
532 static const WCHAR usernameW[] = {'u','s','e','r',0};
533 static const WCHAR passwordW[] = {'p','a','s','s',0};
534 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
535 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
537 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
538 NULL, &IID_IAuthenticate, (void**)&authenticate);
539 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
540 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
542 password = username = (void*)0xdeadbeef;
543 hwnd = (void*)0xdeadbeef;
544 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
545 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
546 ok(!hwnd, "hwnd != NULL\n");
547 ok(!username, "username != NULL\n");
548 ok(!password, "password != NULL\n");
550 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
551 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
553 headers = (void*)0xdeadbeef;
554 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
555 0, &headers);
556 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
557 ok(headers == NULL, "headers != NULL\n");
559 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
560 0, NULL);
561 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
563 headers = (void*)0xdeadbeef;
564 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
565 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
566 ok(headers == NULL, "headers != NULL\n");
568 IHttpNegotiate_Release(http_negotiate);
569 IAuthenticate_Release(authenticate);
572 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
573 NULL, &IID_IAuthenticate, (void**)&authenticate);
574 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
575 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
577 password = username = NULL;
578 hwnd = NULL;
579 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
580 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
581 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
582 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
583 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
584 CoTaskMemFree(username);
585 CoTaskMemFree(password);
587 password = username = (void*)0xdeadbeef;
588 hwnd = (void*)0xdeadbeef;
589 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
590 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
591 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
592 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
594 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
595 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
597 headers = (void*)0xdeadbeef;
598 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
599 0, &headers);
600 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
601 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
602 CoTaskMemFree(headers);
604 headers = (void*)0xdeadbeef;
605 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
606 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
607 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
609 IHttpNegotiate_Release(http_negotiate);
610 IAuthenticate_Release(authenticate);
613 static void test_HlinkParseDisplayName(void)
615 IMoniker *mon = NULL;
616 LPWSTR name;
617 DWORD issys;
618 ULONG eaten = 0;
619 IBindCtx *bctx;
620 HRESULT hres;
622 static const WCHAR winehq_urlW[] =
623 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
624 '/','s','i','t','e','/','a','b','o','u','t',0};
625 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
626 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
627 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
628 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
630 CreateBindCtx(0, &bctx);
632 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
633 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
634 ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
635 ok(mon != NULL, "mon == NULL\n");
637 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
638 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
639 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
640 CoTaskMemFree(name);
642 hres = IMoniker_IsSystemMoniker(mon, &issys);
643 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
644 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
646 IMoniker_Release(mon);
648 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
649 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
650 ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
651 ok(mon != NULL, "mon == NULL\n");
653 hres = IMoniker_IsSystemMoniker(mon, &issys);
654 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
655 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
657 IMoniker_Release(mon);
659 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
660 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
661 ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
662 ok(mon != NULL, "mon == NULL\n");
664 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
665 ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
666 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
667 CoTaskMemFree(name);
669 hres = IMoniker_IsSystemMoniker(mon, &issys);
670 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
671 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
673 IMoniker_Release(mon);
674 IBindCtx_Release(bctx);
677 static IBindCtx *_bctx;
679 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
681 ok(0, "unexpected call\n");
682 return E_NOINTERFACE;
685 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
687 return 2;
690 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
692 return 1;
695 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
696 REFGUID guidService, REFIID riid, void **ppv)
698 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
699 return E_NOINTERFACE;
702 static IServiceProviderVtbl ServiceProviderVtbl = {
703 ServiceProvider_QueryInterface,
704 ServiceProvider_AddRef,
705 ServiceProvider_Release,
706 ServiceProvider_QueryService
709 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
711 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
713 *ppv = NULL;
715 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
716 *ppv = &ServiceProvider;
717 return S_OK;
720 ok(0, "unexpected interface %s\n", debugstr_guid(riid));
721 return E_NOINTERFACE;
724 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
726 return 2;
729 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
731 return 1;
734 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
735 IBinding *pib)
737 ok(0, "unexpected call\n");
738 return E_NOTIMPL;
741 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
743 ok(0, "unexpected call\n");
744 return E_NOTIMPL;
747 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
749 ok(0, "unexpected call\n");
750 return E_NOTIMPL;
753 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
754 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
756 ok(0, "unexpected call\n");
757 return E_NOTIMPL;
760 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
762 ok(0, "unexpected call\n");
763 return E_NOTIMPL;
766 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
768 ok(0, "unexpected call\n");
769 return E_NOTIMPL;
772 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
773 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
775 ok(0, "unexpected call\n");
776 return E_NOTIMPL;
779 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
781 ok(0, "unexpected call\n");
782 return E_NOTIMPL;
785 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
786 BindStatusCallback_QueryInterface,
787 BindStatusCallback_AddRef,
788 BindStatusCallback_Release,
789 BindStatusCallback_OnStartBinding,
790 BindStatusCallback_GetPriority,
791 BindStatusCallback_OnLowResource,
792 BindStatusCallback_OnProgress,
793 BindStatusCallback_OnStopBinding,
794 BindStatusCallback_GetBindInfo,
795 BindStatusCallback_OnDataAvailable,
796 BindStatusCallback_OnObjectAvailable
799 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
801 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
803 *ppv = NULL;
805 ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
806 return E_NOINTERFACE;
809 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
811 return 2;
814 static ULONG WINAPI Moniker_Release(IMoniker *iface)
816 return 1;
819 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
821 ok(0, "unexpected call\n");
822 return E_NOTIMPL;
825 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
827 ok(0, "unexpected call\n");
828 return E_NOTIMPL;
831 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
833 ok(0, "unexpected call\n");
834 return E_NOTIMPL;
837 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
839 ok(0, "unexpected call\n");
840 return E_NOTIMPL;
843 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
845 ok(0, "unexpected call\n");
846 return E_NOTIMPL;
849 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
850 REFIID riidResult, void **ppvResult)
852 ok(0, "unexpected call\n");
853 return E_NOTIMPL;
856 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
857 REFIID riid, void **ppv)
859 IUnknown *unk;
860 HRESULT hres;
862 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
864 CHECK_EXPECT(BindToStorage);
866 ok(pbc == _bctx, "pbc != _bctx\n");
867 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
868 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
869 ok(ppv != NULL, "ppv == NULL\n");
870 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
872 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
873 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
874 ok(unk != NULL, "unk == NULL\n");
876 IUnknown_Release(unk);
878 return S_OK;
881 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
882 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
884 CHECK_EXPECT(Reduce);
885 return E_NOTIMPL;
888 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
889 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
891 ok(0, "unexpected call\n");
892 return E_NOTIMPL;
895 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
897 CHECK_EXPECT(Enum);
898 return E_NOTIMPL;
901 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
903 ok(0, "unexpected call\n");
904 return E_NOTIMPL;
907 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
909 ok(0, "unexpected call\n");
910 return E_NOTIMPL;
913 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
914 IMoniker *pmkNewlyRunning)
916 ok(0, "unexpected call\n");
917 return E_NOTIMPL;
920 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
921 IMoniker *pmkToLeft, FILETIME *pFileTime)
923 ok(0, "unexpected call\n");
924 return E_NOTIMPL;
927 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
929 ok(0, "unexpected call\n");
930 return E_NOTIMPL;
933 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
934 IMoniker **ppmkPrefix)
936 ok(0, "unexpected call\n");
937 return E_NOTIMPL;
940 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
941 IMoniker **pmkRelPath)
943 ok(0, "unexpected call\n");
944 return E_NOTIMPL;
947 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
948 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
950 static const WCHAR winehq_urlW[] =
951 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
952 '/','s','i','t','e','/','a','b','o','u','t',0};
954 CHECK_EXPECT(GetDisplayName);
956 ok(pbc != NULL, "pbc == NULL\n");
957 ok(pbc != _bctx, "pbc == _bctx\n");
958 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
960 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
961 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
962 return S_OK;
965 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
966 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
968 ok(0, "unexpected call\n");
969 return E_NOTIMPL;
972 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
974 CHECK_EXPECT2(IsSystemMoniker);
976 *pdwMksys = MKSYS_URLMONIKER;
977 return S_OK;
980 static IMonikerVtbl MonikerVtbl = {
981 Moniker_QueryInterface,
982 Moniker_AddRef,
983 Moniker_Release,
984 Moniker_GetClassID,
985 Moniker_IsDirty,
986 Moniker_Load,
987 Moniker_Save,
988 Moniker_GetSizeMax,
989 Moniker_BindToObject,
990 Moniker_BindToStorage,
991 Moniker_Reduce,
992 Moniker_ComposeWith,
993 Moniker_Enum,
994 Moniker_IsEqual,
995 Moniker_Hash,
996 Moniker_IsRunning,
997 Moniker_GetTimeOfLastChange,
998 Moniker_Inverse,
999 Moniker_CommonPrefixWith,
1000 Moniker_RelativePathTo,
1001 Moniker_GetDisplayName,
1002 Moniker_ParseDisplayName,
1003 Moniker_IsSystemMoniker
1006 static IMoniker Moniker = { &MonikerVtbl };
1008 static void test_HlinkResolveMonikerForData(void)
1010 IBindCtx *bctx;
1011 HRESULT hres;
1013 CreateBindCtx(0, &bctx);
1014 _bctx = bctx;
1016 SET_EXPECT(IsSystemMoniker);
1017 SET_EXPECT(GetDisplayName);
1018 SET_EXPECT(BindToStorage);
1020 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1021 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1023 CHECK_CALLED(IsSystemMoniker);
1024 CHECK_CALLED(GetDisplayName);
1025 CHECK_CALLED(BindToStorage);
1027 IBindCtx_Release(bctx);
1030 static void test_HlinkGetSetMonikerReference(void)
1032 IMoniker *found_trgt, *dummy, *dummy2;
1033 IHlink *hlink;
1034 HRESULT hres;
1035 const WCHAR one[] = {'1',0};
1036 const WCHAR two[] = {'2',0};
1037 const WCHAR name[] = {'a',0};
1038 WCHAR *found_loc;
1040 /* create two dummy monikers to use as targets */
1041 hres = CreateItemMoniker(one, one, &dummy);
1042 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1044 hres = CreateItemMoniker(two, two, &dummy2);
1045 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1047 /* create a new hlink: target => dummy, location => one */
1048 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1049 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1051 /* validate the target and location */
1052 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1053 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1054 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1055 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1056 IMoniker_Release(found_trgt);
1057 CoTaskMemFree(found_loc);
1059 /* set location => two */
1060 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1061 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1063 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1064 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1065 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1066 IMoniker_Release(found_trgt);
1067 CoTaskMemFree(found_loc);
1069 /* set target => dummy2 */
1070 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1071 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1073 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1074 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1075 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1076 IMoniker_Release(found_trgt);
1077 CoTaskMemFree(found_loc);
1079 /* set target => dummy, location => one */
1080 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1081 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1083 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1084 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1085 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1086 IMoniker_Release(found_trgt);
1087 CoTaskMemFree(found_loc);
1089 /* no HLINKSETF flags */
1090 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1091 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1093 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1094 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1095 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1096 IMoniker_Release(found_trgt);
1097 CoTaskMemFree(found_loc);
1099 /* invalid HLINKSETF flags */
1100 hres = IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1101 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1102 if (0) ok(hres == 12, "IHlink_SetMonikerReference should've failed with 0x%08x, failed with 0x%08x\n", 12, hres);
1104 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1105 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1106 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1107 IMoniker_Release(found_trgt);
1108 CoTaskMemFree(found_loc);
1110 /* valid & invalid HLINKSETF flags */
1111 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1112 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1114 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1115 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1116 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1117 IMoniker_Release(found_trgt);
1118 CoTaskMemFree(found_loc);
1120 /* NULL args */
1121 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1122 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1124 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1125 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1126 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1127 if(found_trgt)
1128 IMoniker_Release(found_trgt);
1130 IHlink_Release(hlink);
1131 IMoniker_Release(dummy2);
1132 IMoniker_Release(dummy);
1135 static void test_HlinkGetSetStringReference(void)
1137 IHlink *link;
1138 static const WCHAR one[] = {'1',0};
1139 static const WCHAR two[] = {'2',0};
1140 static const WCHAR three[] = {'3',0};
1141 static const WCHAR empty[] = {0};
1142 WCHAR *fnd_tgt, *fnd_loc;
1143 HRESULT hres;
1145 /* create a new hlink: target => NULL, location => one */
1146 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1147 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1149 /* test setting/getting location */
1150 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1151 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1152 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1153 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1154 CoTaskMemFree(fnd_tgt);
1155 CoTaskMemFree(fnd_loc);
1157 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1158 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1160 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1161 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1162 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1163 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1164 CoTaskMemFree(fnd_tgt);
1165 CoTaskMemFree(fnd_loc);
1167 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1168 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1170 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1171 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1172 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1173 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1174 CoTaskMemFree(fnd_tgt);
1175 CoTaskMemFree(fnd_loc);
1177 /* test setting/getting target */
1178 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1179 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1181 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1182 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1183 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1184 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1185 CoTaskMemFree(fnd_tgt);
1186 CoTaskMemFree(fnd_loc);
1188 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1189 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1191 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1192 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1193 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1194 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1195 CoTaskMemFree(fnd_tgt);
1196 CoTaskMemFree(fnd_loc);
1198 /* test setting/getting both */
1199 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1200 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1202 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1203 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1204 ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1205 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1206 CoTaskMemFree(fnd_tgt);
1207 CoTaskMemFree(fnd_loc);
1209 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1210 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1212 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1213 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1214 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1215 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1216 CoTaskMemFree(fnd_tgt);
1217 CoTaskMemFree(fnd_loc);
1219 /* test invalid flags/params */
1220 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1221 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1222 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1223 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1224 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1225 CoTaskMemFree(fnd_tgt);
1226 CoTaskMemFree(fnd_loc);
1228 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1229 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1230 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1231 CoTaskMemFree(fnd_tgt);
1233 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1234 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1236 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1237 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1238 CoTaskMemFree(fnd_loc);
1240 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1241 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1242 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1243 CoTaskMemFree(fnd_tgt);
1244 CoTaskMemFree(fnd_loc);
1246 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1247 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1248 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1249 CoTaskMemFree(fnd_tgt);
1250 CoTaskMemFree(fnd_loc);
1252 hres = IHlink_SetStringReference(link, 4, NULL, NULL);
1253 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1254 if (0) ok(hres == 4, "IHlink_SetStringReference should have failed with 0x4, instead: 0x%08x\n", hres);
1256 hres = IHlink_SetStringReference(link, -4, NULL, NULL);
1257 if (0) ok(hres == -4, "IHlink_SetStringReference should have failed with 0xFFFFFFFC, instead: 0x%08x\n", hres);
1259 IHlink_Release(link);
1262 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1263 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1265 HRESULT hres;
1266 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1267 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1270 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1271 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1273 HRESULT hres;
1274 WCHAR *fnd_tgt, *fnd_loc;
1276 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1277 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1279 if(exp_tgt)
1280 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));
1281 else
1282 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1284 if(exp_loc)
1285 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));
1286 else
1287 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1289 CoTaskMemFree(fnd_tgt);
1290 CoTaskMemFree(fnd_loc);
1293 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1294 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1296 HRESULT hres;
1297 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1298 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1301 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1302 #define getMonikerRef(h,t,l) r_getMonikerRef(__LINE__,h,t,l)
1303 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc)
1305 HRESULT hres;
1306 IMoniker *fnd_tgt;
1307 WCHAR *fnd_loc;
1309 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1310 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1312 if(exp_loc)
1313 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));
1314 else
1315 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1317 CoTaskMemFree(fnd_loc);
1319 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1320 return fnd_tgt;
1322 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1324 if(fnd_tgt)
1325 IMoniker_Release(fnd_tgt);
1327 return NULL;
1330 static void test_HlinkMoniker(void)
1332 IHlink *hlink;
1333 IMoniker *aMon, *file_mon;
1334 static const WCHAR emptyW[] = {0};
1335 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1336 static const WCHAR aW[] = {'a',0};
1337 static const WCHAR bW[] = {'b',0};
1338 HRESULT hres;
1340 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1341 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1342 getStringRef(hlink, NULL, NULL);
1343 getMonikerRef(hlink, NULL, NULL);
1345 /* setting a string target creates a moniker reference */
1346 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1347 getStringRef(hlink, aW, wordsW);
1348 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW);
1349 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1350 if(aMon)
1351 IMoniker_Release(aMon);
1353 /* setting target & location to the empty string deletes the moniker
1354 * reference */
1355 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1356 getStringRef(hlink, NULL, NULL);
1357 getMonikerRef(hlink, NULL, NULL);
1359 /* setting a moniker target also sets the target string to that moniker's
1360 * display name */
1361 hres = CreateFileMoniker(bW, &file_mon);
1362 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1364 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1365 getStringRef(hlink, bW, wordsW);
1366 getMonikerRef(hlink, file_mon, wordsW);
1368 IMoniker_Release(file_mon);
1370 IHlink_Release(hlink);
1373 static void test_HashLink(void)
1375 IHlink *hlink;
1376 IMoniker *pmk;
1377 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1378 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};
1379 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1380 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1381 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1382 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1383 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1384 HRESULT hres;
1386 /* simple single hash test */
1387 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1388 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1389 ok(hlink != NULL, "Didn't get an hlink\n");
1391 if(hlink){
1392 getStringRef(hlink, tgt_partW, loc_partW);
1393 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
1394 ok(pmk != NULL, "Found moniker should not be NULL\n");
1395 if(pmk)
1396 IMoniker_Release(pmk);
1398 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1399 getStringRef(hlink, hash_targetW, loc_partW);
1401 IHlink_Release(hlink);
1404 /* two hashes in the target */
1405 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1406 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1407 ok(hlink != NULL, "Didn't get an hlink\n");
1409 if(hlink){
1410 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1411 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW);
1412 ok(pmk != NULL, "Found moniker should not be NULL\n");
1413 if(pmk)
1414 IMoniker_Release(pmk);
1416 IHlink_Release(hlink);
1419 /* target with hash plus a location string */
1420 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1421 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1422 ok(hlink != NULL, "Didn't get an hlink\n");
1424 if(hlink){
1425 getStringRef(hlink, tgt_partW, test_locW);
1426 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW);
1427 ok(pmk != NULL, "Found moniker should not be NULL\n");
1428 if(pmk)
1429 IMoniker_Release(pmk);
1431 IHlink_Release(hlink);
1434 /* target with hash containing no "target part" */
1435 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1436 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1437 ok(hlink != NULL, "Didn't get an hlink\n");
1439 if(hlink){
1440 getStringRef(hlink, NULL, loc_partW);
1441 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
1442 ok(pmk == NULL, "Found moniker should be NULL\n");
1443 if(pmk)
1444 IMoniker_Release(pmk);
1446 IHlink_Release(hlink);
1450 static WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1451 static WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1453 static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
1454 IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1456 ok(0, "BTS: %p %p %p %p %p\n", iface, pbc, toLeft, riid, obj);
1457 return E_NOTIMPL;
1460 static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
1461 IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1463 LPOLESTR rightName;
1464 HRESULT hres;
1466 ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1468 CHECK_EXPECT(ComposeWith);
1470 hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1471 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1472 ok(!lstrcmpW(rightName, ref_monikerW),
1473 "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1474 wine_dbgstr_w(rightName));
1475 CoTaskMemFree(rightName);
1477 *composite = NULL;
1479 /* unlikely error code to verify this return result is used */
1480 return E_OUTOFMEMORY;
1483 static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
1484 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1486 *displayName = CoTaskMemAlloc(sizeof(site_monikerW));
1487 memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
1488 return S_OK;
1491 static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
1492 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1494 *displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
1495 memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
1496 return S_OK;
1499 static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
1500 DWORD *mksys)
1502 return S_FALSE;
1505 static IMonikerVtbl hls_site_MonikerVtbl = {
1506 Moniker_QueryInterface,
1507 Moniker_AddRef,
1508 Moniker_Release,
1509 Moniker_GetClassID,
1510 Moniker_IsDirty,
1511 Moniker_Load,
1512 Moniker_Save,
1513 Moniker_GetSizeMax,
1514 Moniker_BindToObject,
1515 hls_test_Moniker_BindToStorage,
1516 Moniker_Reduce,
1517 hls_site_Moniker_ComposeWith,
1518 Moniker_Enum,
1519 Moniker_IsEqual,
1520 Moniker_Hash,
1521 Moniker_IsRunning,
1522 Moniker_GetTimeOfLastChange,
1523 Moniker_Inverse,
1524 Moniker_CommonPrefixWith,
1525 Moniker_RelativePathTo,
1526 hls_site_Moniker_GetDisplayName,
1527 Moniker_ParseDisplayName,
1528 hls_test_Moniker_IsSystemMoniker
1531 static IMonikerVtbl hls_ref_MonikerVtbl = {
1532 Moniker_QueryInterface,
1533 Moniker_AddRef,
1534 Moniker_Release,
1535 Moniker_GetClassID,
1536 Moniker_IsDirty,
1537 Moniker_Load,
1538 Moniker_Save,
1539 Moniker_GetSizeMax,
1540 Moniker_BindToObject,
1541 hls_test_Moniker_BindToStorage,
1542 Moniker_Reduce,
1543 Moniker_ComposeWith,
1544 Moniker_Enum,
1545 Moniker_IsEqual,
1546 Moniker_Hash,
1547 Moniker_IsRunning,
1548 Moniker_GetTimeOfLastChange,
1549 Moniker_Inverse,
1550 Moniker_CommonPrefixWith,
1551 Moniker_RelativePathTo,
1552 hls_ref_Moniker_GetDisplayName,
1553 Moniker_ParseDisplayName,
1554 hls_test_Moniker_IsSystemMoniker
1557 static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
1558 static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
1560 static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
1561 void **obj)
1563 ok(0, "QI: %p %s %p\n", iface, debugstr_guid(iid), obj);
1564 return E_NOTIMPL;
1567 static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
1569 return 2;
1572 static ULONG WINAPI hls_Release(IHlinkSite *iface)
1574 return 1;
1577 static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
1578 REFGUID service, REFIID riid, IUnknown **punk)
1580 ok(0, "QS: %p %x %s %s %p\n", iface, siteData, debugstr_guid(service),
1581 debugstr_guid(riid), punk);
1582 return E_NOTIMPL;
1585 static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
1586 DWORD assign, DWORD which, IMoniker **pmk)
1588 ok(siteData == 17, "Expected siteData == 17, got: %d\n", siteData);
1589 *pmk = &hls_site_Moniker;
1590 return S_OK;
1593 static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
1594 DWORD reserved)
1596 ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
1597 return E_NOTIMPL;
1600 static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
1601 DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1603 CHECK_EXPECT(OnNavigationComplete);
1604 ok(siteData == 17, "Expected siteData == 17, got: %d\n", siteData);
1605 ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
1606 return E_NOTIMPL;
1609 static IHlinkSiteVtbl HlinkSiteVtbl = {
1610 hls_QueryInterface,
1611 hls_AddRef,
1612 hls_Release,
1613 hls_QueryService,
1614 hls_GetMoniker,
1615 hls_ReadyToNavigate,
1616 hls_OnNavigationComplete
1619 static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
1621 static void test_HlinkSite(void)
1623 IHlink *hl;
1624 IMoniker *mon_ref;
1625 IBindCtx *pbc;
1626 HRESULT hres;
1628 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1629 &IID_IHlink, (LPVOID*)&hl);
1630 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1631 getMonikerRef(hl, NULL, NULL);
1633 hres = IHlink_SetHlinkSite(hl, &HlinkSite, 17);
1634 ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
1635 getMonikerRef(hl, NULL, NULL);
1636 getStringRef(hl, NULL, NULL);
1638 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1639 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1640 ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
1642 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1643 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1644 ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1646 SET_EXPECT(Reduce);
1647 SET_EXPECT(Enum);
1648 hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
1649 ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
1650 todo_wine CHECK_CALLED(Reduce);
1651 todo_wine CHECK_CALLED(Enum);
1653 getMonikerRef(hl, &hls_ref_Moniker, NULL);
1655 SET_EXPECT(Enum);
1656 getStringRef(hl, ref_monikerW, NULL);
1657 todo_wine CHECK_CALLED(Enum);
1659 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1660 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1661 ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1662 IMoniker_Release(mon_ref);
1664 SET_EXPECT(ComposeWith);
1665 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1666 ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
1667 ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
1668 CHECK_CALLED(ComposeWith);
1670 hres = CreateBindCtx(0, &pbc);
1671 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1673 SET_EXPECT(ComposeWith);
1674 SET_EXPECT(OnNavigationComplete);
1675 hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
1676 ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
1677 CHECK_CALLED(ComposeWith);
1678 CHECK_CALLED(OnNavigationComplete);
1680 IBindCtx_Release(pbc);
1681 IHlink_Release(hl);
1683 SET_EXPECT(Reduce);
1684 SET_EXPECT(Enum);
1685 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, 17,
1686 NULL, &IID_IHlink, (LPVOID*)&hl);
1687 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1688 todo_wine CHECK_CALLED(Reduce);
1689 todo_wine CHECK_CALLED(Enum);
1690 getMonikerRef(hl, &hls_ref_Moniker, NULL);
1691 IHlink_Release(hl);
1693 hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, 17,
1694 NULL, &IID_IHlink, (LPVOID*)&hl);
1695 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
1696 getMonikerRef(hl, NULL, NULL);
1697 IHlink_Release(hl);
1700 START_TEST(hlink)
1702 CoInitialize(NULL);
1704 test_HlinkIsShortcut();
1705 test_reference();
1706 test_persist();
1707 test_special_reference();
1708 test_HlinkCreateExtensionServices();
1709 test_HlinkParseDisplayName();
1710 test_HlinkResolveMonikerForData();
1711 test_HlinkGetSetMonikerReference();
1712 test_HlinkGetSetStringReference();
1713 test_HlinkMoniker();
1714 test_HashLink();
1715 test_HlinkSite();
1717 CoUninitialize();