1 /*
2 * Implementation of hyperlinking (hlink.dll)
3 *
4 * Copyright 2006 Mike McCormack
5 * Copyright 2007-2008 Jacek Caban for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #define COBJMACROS
23
24 #include <stdio.h>
25
26 #include <initguid.h>
27 #include <hlink.h>
28 #include <hlguids.h>
29
30 #include "wine/test.h"
31
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
34
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
37
38 #define CHECK_EXPECT2(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
42 }while(0)
43
44 #define CHECK_EXPECT(func) \
45 do { \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
48 }while(0)
49
50 #define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
54 }while(0)
55
56 DEFINE_EXPECT(IsSystemMoniker);
57 DEFINE_EXPECT(BindToStorage);
58 DEFINE_EXPECT(BindToObject);
59 DEFINE_EXPECT(GetDisplayName);
60
61 DEFINE_EXPECT(ComposeWith);
62 DEFINE_EXPECT(OnNavigationComplete);
63 DEFINE_EXPECT(Enum);
64 DEFINE_EXPECT(Reduce);
65
66 DEFINE_EXPECT(GetClassID);
67 DEFINE_EXPECT(Save);
68
69 DEFINE_EXPECT(HBC_QueryInterface_IHlinkHistory);
70 DEFINE_EXPECT(HBC_QueryInterface_IMarshal);
71 DEFINE_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
72 DEFINE_EXPECT(HBC_QueryInterface_IUnknown);
73 DEFINE_EXPECT(HBC_GetObject);
74 DEFINE_EXPECT(HBC_UpdateHlink);
75
76 DEFINE_EXPECT(HT_QueryInterface_IHlinkTarget);
77 DEFINE_EXPECT(HT_SetBrowseContext);
78 DEFINE_EXPECT(HT_GetBrowseContext);
79 DEFINE_EXPECT(HT_Navigate);
80 DEFINE_EXPECT(HT_GetFriendlyName);
81
82 DEFINE_EXPECT(HLF_UpdateHlink);
83
84 DEFINE_EXPECT(BindStatusCallback_GetBindInfo);
85 DEFINE_EXPECT(BindStatusCallback_OnObjectAvailable);
86 DEFINE_EXPECT(BindStatusCallback_OnStartBinding);
87 DEFINE_EXPECT(BindStatusCallback_OnStopBinding);
88
89 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
90 DEFINE_GUID(IID_IHlinkHistory,0x79eac9c8,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b);
91
92 static IHlinkTarget HlinkTarget;
93
94 static const WCHAR winehq_urlW[] =
95 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
96 '/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
97 static const WCHAR winehq_404W[] =
98 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
99 '/','t','e','s','t','s','/','f','a','k','e','u','r','l',0};
100
test_HlinkIsShortcut(void)101 static void test_HlinkIsShortcut(void)
102 {
103 UINT i;
104 HRESULT hres;
105
106 static const WCHAR file0[] = {'f','i','l','e',0};
107 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
108 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
109 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
110 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
111 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
112 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
113 static const WCHAR file7[] = {'.','u','r','l',0};
114
115 static struct {
116 LPCWSTR file;
117 HRESULT hres;
118 } shortcut_test[] = {
119 {file0, S_FALSE},
120 {file1, S_OK},
121 {file2, S_FALSE},
122 {file3, S_OK},
123 {file4, S_FALSE},
124 {file5, S_OK},
125 {file6, S_FALSE},
126 {file7, S_OK},
127 {NULL, E_INVALIDARG}
128 };
129
130 for (i=0; i < ARRAY_SIZE(shortcut_test); i++) {
131 hres = HlinkIsShortcut(shortcut_test[i].file);
132 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
133 i, hres, shortcut_test[i].hres);
134 }
135 }
136
test_reference(void)137 static void test_reference(void)
138 {
139 HRESULT r;
140 IHlink *lnk = NULL;
141 IMoniker *mk = NULL;
142 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
143 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
144 LPWSTR str = NULL;
145
146 r = HlinkCreateFromString(url, NULL, NULL, NULL,
147 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
148 ok(r == S_OK, "failed to create link\n");
149 if (FAILED(r))
150 return;
151
152 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
153 ok(r == S_OK, "failed\n");
154
155 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
156 ok(r == S_OK, "failed\n");
157 ok(mk != NULL, "no moniker\n");
158 ok(str == NULL, "string should be null\n");
159
160 r = IMoniker_Release(mk);
161 ok( r == 1, "moniker refcount wrong\n");
162
163 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
164 ok(r == S_OK, "failed\n");
165 CoTaskMemFree(str);
166
167 r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
168 ok(r == S_OK, "failed, r=%08x\n", r);
169
170 r = IHlink_GetStringReference(lnk, -1, NULL, &str);
171 ok(r == S_OK, "failed, r=%08x\n", r);
172 ok(str == NULL, "string should be null\n");
173
174 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
175 ok(r == S_OK, "failed\n");
176 ok(!lstrcmpW(str, url2), "url wrong\n");
177 CoTaskMemFree(str);
178
179 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
180 ok(r == S_OK, "failed\n");
181
182 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
183 ok(r == S_OK, "failed\n");
184 ok(str == NULL, "string should be null\n");
185
186 /* Unimplented functions checks */
187 r = IHlink_GetAdditionalParams(lnk, NULL);
188 ok(r == E_NOTIMPL, "failed\n");
189
190 r = IHlink_SetAdditionalParams(lnk, NULL);
191 ok(r == E_NOTIMPL, "failed\n");
192
193 IHlink_Release(lnk);
194 }
195
196 /* url only */
197 static const unsigned char expected_hlink_data[] =
198 {
199 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
200 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
201 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
202 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
203 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
204 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
205 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
206 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
207 0x00,0x00,
208 };
209
210 /* url only (IE7) */
211 static const unsigned char expected_hlink_data_ie7[] =
212 {
213 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
214 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
215 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
216 0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
217 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
218 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
219 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
220 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
221 0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
222 0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
223 0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
224 0x00,0x00,
225 };
226
227 /* url + friendly name */
228 static const unsigned char expected_hlink_data2[] =
229 {
230 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
231 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
232 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
233 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
234 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
235 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
236 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
237 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
238 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
239 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
240 0x67,0x00,0x2f,0x00,0x00,0x00,
241 };
242
243 /* url + friendly name (IE7) */
244 static const unsigned char expected_hlink_data2_ie7[] =
245 {
246 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
247 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
248 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
249 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
250 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
251 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
252 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
253 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
254 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
255 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
256 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
257 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
258 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
259 0x00,0x00,0xa5,0xab,0x00,0x00,
260 };
261
262 /* url + friendly name + location */
263 static const unsigned char expected_hlink_data3[] =
264 {
265 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
266 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
267 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
268 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
269 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
270 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
271 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
272 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
273 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
274 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
275 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
276 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
277 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
278 };
279
280 /* url + friendly name + location (IE7) */
281 static const unsigned char expected_hlink_data3_ie7[] =
282 {
283 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
284 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
285 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
286 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
287 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
288 0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
289 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
290 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
291 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
292 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
293 0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
294 0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
295 0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
296 0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
297 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
298 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
299 };
300
301 /* relative url */
302 static const unsigned char expected_hlink_data4[] =
303 {
304 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
305 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
306 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
307 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
308 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
309 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
310 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
311 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
312 0x00,0x00,0x00,0x00,0x00,
313 };
314
315 /* url + target frame name */
316 static const unsigned char expected_hlink_data5[] =
317 {
318 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
319 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
320 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
321 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
322 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
323 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
324 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
325 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
326 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
327 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
328 0x2f,0x00,0x00,0x00,
329 };
330
331 /* url + target frame name (IE7) */
332 static const unsigned char expected_hlink_data5_ie7[] =
333 {
334 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
335 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
336 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
337 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
338 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
339 0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
340 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
341 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
342 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
343 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
344 0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
345 0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
346 0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
347 0xa5,0xab,0x00,0x00,
348 };
349
350 /* filename */
351 static const unsigned char expected_hlink_data6[] =
352 {
353 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
354 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
355 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
356 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
357 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
358 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
359 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
360 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
361 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
362 0x5c,0x00,
363 };
364
test_persist_save_data(const char * testname,IHlink * lnk,const unsigned char * expected_data,unsigned int expected_data_size,const unsigned char * expected_data_alt,unsigned int expected_data_alt_size)365 static void test_persist_save_data(const char *testname, IHlink *lnk,
366 const unsigned char *expected_data,
367 unsigned int expected_data_size,
368 const unsigned char *expected_data_alt,
369 unsigned int expected_data_alt_size)
370 {
371 HRESULT hr;
372 IStream *stream;
373 IPersistStream *ps;
374 HGLOBAL hglobal;
375 DWORD data_size;
376 const unsigned char *data;
377 DWORD i;
378 BOOL same;
379
380 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
381 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
382
383 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
384 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
385
386 hr = IPersistStream_Save(ps, stream, TRUE);
387 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
388
389 hr = GetHGlobalFromStream(stream, &hglobal);
390 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
391
392 data_size = GlobalSize(hglobal);
393
394 data = GlobalLock(hglobal);
395
396 /* first check we have the right amount of data */
397 ok((data_size == expected_data_size) ||
398 (data_size == expected_data_alt_size),
399 "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
400 testname, expected_data_size, expected_data_alt_size, data_size);
401
402 same = TRUE;
403 /* then do a byte-by-byte comparison */
404 for (i = 0; i < min(data_size, expected_data_size); i++)
405 {
406 if ((expected_data[i] != data[i]) &&
407 (((expected_data != expected_hlink_data2) &&
408 (expected_data != expected_hlink_data3)) ||
409 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
410 {
411 same = FALSE;
412 break;
413 }
414 }
415
416 if (!same && (expected_data_alt != expected_data))
417 {
418 /* then try the alternate data */
419 same = TRUE;
420 for (i = 0; i < min(data_size, expected_data_alt_size); i++)
421 {
422 if ((expected_data_alt == expected_hlink_data_ie7 && i == 89) /* Win10 */ ||
423 (expected_data_alt == expected_hlink_data2_ie7 && i == 109) /* Win10 */ ||
424 (expected_data_alt == expected_hlink_data3_ie7 && i == 109) /* Win10 */ ||
425 (expected_data_alt == expected_hlink_data5_ie7 && i == 107) /* Win10 */)
426 {
427 ok(data[i] == 0 || broken(data[i] == 1) || broken(data[i] == 3),
428 "Expected 0 or 1, got %d\n", data[i]);
429 continue;
430 }
431 if ((expected_data_alt[i] != data[i]) &&
432 (((expected_data_alt != expected_hlink_data2) &&
433 (expected_data_alt != expected_hlink_data3)) ||
434 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
435 {
436 same = FALSE;
437 break;
438 }
439 }
440 }
441
442 ok(same, "%s: Saved data differs\n", testname);
443 if (!same)
444 {
445 for (i = 0; i < data_size; i++)
446 {
447 if (i % 8 == 0) printf(" ");
448 printf("0x%02x,", data[i]);
449 if (i % 8 == 7) printf("\n");
450 }
451 printf("\n");
452 }
453
454 GlobalUnlock(hglobal);
455
456 IStream_Release(stream);
457 IPersistStream_Release(ps);
458 }
459
test_persist(void)460 static void test_persist(void)
461 {
462 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
463 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
464 static const WCHAR filename[] = { 'c',':','\\',0 };
465 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
466 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
467 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
468 HRESULT hr;
469 IHlink *lnk;
470
471 hr = HlinkCreateFromString(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 if (!lnk) {
475 skip("Can't create lnk, skipping test_persist.\n");
476 return;
477 }
478 test_persist_save_data("url only", lnk,
479 expected_hlink_data, sizeof(expected_hlink_data),
480 expected_hlink_data_ie7, sizeof(expected_hlink_data_ie7));
481 IHlink_Release(lnk);
482
483 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
484 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
485 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
486 test_persist_save_data("url + friendly name", lnk,
487 expected_hlink_data2, sizeof(expected_hlink_data2),
488 expected_hlink_data2_ie7, sizeof(expected_hlink_data2_ie7));
489 IHlink_Release(lnk);
490
491 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
492 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
493 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
494 test_persist_save_data("url + friendly_name + location", lnk,
495 expected_hlink_data3, sizeof(expected_hlink_data3),
496 expected_hlink_data3_ie7, sizeof(expected_hlink_data3_ie7));
497 IHlink_Release(lnk);
498
499 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
500 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
501 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
502 test_persist_save_data("relative url", lnk,
503 expected_hlink_data4, sizeof(expected_hlink_data4),
504 expected_hlink_data4, sizeof(expected_hlink_data4));
505 IHlink_Release(lnk);
506
507 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
508 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
509 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
510 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
511 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
512 test_persist_save_data("url + target frame name", lnk,
513 expected_hlink_data5, sizeof(expected_hlink_data5),
514 expected_hlink_data5_ie7, sizeof(expected_hlink_data5_ie7));
515 IHlink_Release(lnk);
516
517 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
518 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
519 ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
520 test_persist_save_data("filename", lnk,
521 expected_hlink_data6, sizeof(expected_hlink_data6),
522 expected_hlink_data6, sizeof(expected_hlink_data6));
523 IHlink_Release(lnk);
524 }
525
test_special_reference(void)526 static void test_special_reference(void)
527 {
528 LPWSTR ref;
529 HRESULT hres;
530
531 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
532 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
533 ok(ref != NULL, "ref == NULL\n");
534 CoTaskMemFree(ref);
535
536 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
537 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
538 ok(ref != NULL, "ref == NULL\n");
539 CoTaskMemFree(ref);
540
541 ref = (void*)0xdeadbeef;
542 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
543 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
544 ok(ref == NULL, "ref=%p\n", ref);
545
546 ref = (void*)0xdeadbeef;
547 hres = HlinkGetSpecialReference(4, &ref);
548 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
549 ok(ref == NULL, "ref=%p\n", ref);
550 }
551
test_HlinkCreateExtensionServices(void)552 static void test_HlinkCreateExtensionServices(void)
553 {
554 IAuthenticate *authenticate;
555 IHttpNegotiate *http_negotiate;
556 LPWSTR password, username, headers;
557 HWND hwnd;
558 HRESULT hres;
559
560 static const WCHAR usernameW[] = {'u','s','e','r',0};
561 static const WCHAR passwordW[] = {'p','a','s','s',0};
562 static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
563 static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
564
565 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
566 NULL, &IID_IAuthenticate, (void**)&authenticate);
567 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
568 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
569
570 password = username = (void*)0xdeadbeef;
571 hwnd = (void*)0xdeadbeef;
572 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
573 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
574 ok(!hwnd, "hwnd != NULL\n");
575 ok(!username, "username != NULL\n");
576 ok(!password, "password != NULL\n");
577
578 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
579 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
580
581 headers = (void*)0xdeadbeef;
582 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
583 0, &headers);
584 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
585 ok(headers == NULL, "headers != NULL\n");
586
587 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
588 0, NULL);
589 ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
590
591 headers = (void*)0xdeadbeef;
592 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
593 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
594 ok(headers == NULL, "headers != NULL\n");
595
596 IHttpNegotiate_Release(http_negotiate);
597 IAuthenticate_Release(authenticate);
598
599
600 hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
601 NULL, &IID_IAuthenticate, (void**)&authenticate);
602 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
603 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
604
605 password = username = NULL;
606 hwnd = NULL;
607 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
608 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
609 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
610 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
611 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
612 CoTaskMemFree(username);
613 CoTaskMemFree(password);
614
615 password = username = (void*)0xdeadbeef;
616 hwnd = (void*)0xdeadbeef;
617 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
618 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
619 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
620 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
621
622 hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
623 ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
624
625 headers = (void*)0xdeadbeef;
626 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
627 0, &headers);
628 ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
629 ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
630 CoTaskMemFree(headers);
631
632 headers = (void*)0xdeadbeef;
633 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
634 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
635 ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
636
637 IHttpNegotiate_Release(http_negotiate);
638 IAuthenticate_Release(authenticate);
639 }
640
test_HlinkParseDisplayName(void)641 static void test_HlinkParseDisplayName(void)
642 {
643 IMoniker *mon = NULL;
644 LPWSTR name;
645 DWORD issys;
646 ULONG eaten = 0;
647 IBindCtx *bctx;
648 HRESULT hres;
649
650 static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
651 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
652 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
653 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
654 static const WCHAR file_urlW[] =
655 {'f','i','l','e',':','/','/','/','c',':','\\','f','i','l','e','.','t','x','t',0};
656
657 CreateBindCtx(0, &bctx);
658
659 hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
660 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
661 ok(eaten == ARRAY_SIZE(winehq_urlW)-1, "eaten=%d\n", eaten);
662 ok(mon != NULL, "mon == NULL\n");
663
664 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
665 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
666 ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
667 CoTaskMemFree(name);
668
669 hres = IMoniker_IsSystemMoniker(mon, &issys);
670 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
671 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
672
673 IMoniker_Release(mon);
674
675 hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
676 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
677 ok(eaten == ARRAY_SIZE(clsid_nameW)-1, "eaten=%d\n", eaten);
678 ok(mon != NULL, "mon == NULL\n");
679
680 hres = IMoniker_IsSystemMoniker(mon, &issys);
681 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
682 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
683
684 IMoniker_Release(mon);
685
686 hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
687 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
688 ok(eaten == ARRAY_SIZE(invalid_urlW)-1, "eaten=%d\n", eaten);
689 ok(mon != NULL, "mon == NULL\n");
690
691 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
692 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
693 ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
694 CoTaskMemFree(name);
695
696 hres = IMoniker_IsSystemMoniker(mon, &issys);
697 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
698 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
699
700 IMoniker_Release(mon);
701
702 hres = HlinkParseDisplayName(bctx, file_urlW, FALSE, &eaten, &mon);
703 ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
704 ok(eaten == ARRAY_SIZE(file_urlW)-1, "eaten=%d\n", eaten);
705 ok(mon != NULL, "mon == NULL\n");
706
707 hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
708 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
709 ok(!lstrcmpW(name, file_urlW+8), "wrong display name %s\n", wine_dbgstr_w(name));
710 CoTaskMemFree(name);
711
712 hres = IMoniker_IsSystemMoniker(mon, &issys);
713 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
714 ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
715
716 IMoniker_Release(mon);
717 IBindCtx_Release(bctx);
718 }
719
720 static IBindCtx *_bctx;
721
ServiceProvider_QueryInterface(IServiceProvider * iface,REFIID riid,void ** ppv)722 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
723 {
724 ok(0, "unexpected call\n");
725 return E_NOINTERFACE;
726 }
727
ServiceProvider_AddRef(IServiceProvider * iface)728 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
729 {
730 return 2;
731 }
732
ServiceProvider_Release(IServiceProvider * iface)733 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
734 {
735 return 1;
736 }
737
ServiceProvider_QueryService(IServiceProvider * iface,REFGUID guidService,REFIID riid,void ** ppv)738 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
739 REFGUID guidService, REFIID riid, void **ppv)
740 {
741 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
742 return E_NOINTERFACE;
743 }
744
745 static IServiceProviderVtbl ServiceProviderVtbl = {
746 ServiceProvider_QueryInterface,
747 ServiceProvider_AddRef,
748 ServiceProvider_Release,
749 ServiceProvider_QueryService
750 };
751
752 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
753
BindStatusCallback_QueryInterface(IBindStatusCallback * iface,REFIID riid,void ** ppv)754 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
755 {
756 *ppv = NULL;
757
758 if(IsEqualGUID(riid, &IID_IServiceProvider)) {
759 *ppv = &ServiceProvider;
760 return S_OK;
761 }
762
763 ok(0, "unexpected interface %s\n", wine_dbgstr_guid(riid));
764 return E_NOINTERFACE;
765 }
766
767 static LONG bind_callback_refs = 1;
768
BindStatusCallback_AddRef(IBindStatusCallback * iface)769 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
770 {
771 return ++bind_callback_refs;
772 }
773
BindStatusCallback_Release(IBindStatusCallback * iface)774 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
775 {
776 return --bind_callback_refs;
777 }
778
BindStatusCallback_OnStartBinding(IBindStatusCallback * iface,DWORD reserved,IBinding * binding)779 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
780 DWORD reserved, IBinding *binding)
781 {
782 CHECK_EXPECT(BindStatusCallback_OnStartBinding);
783
784 ok(!binding, "binding = %p\n", binding);
785 return S_OK;
786 }
787
BindStatusCallback_GetPriority(IBindStatusCallback * iface,LONG * pnPriority)788 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
789 {
790 ok(0, "unexpected call\n");
791 return E_NOTIMPL;
792 }
793
BindStatusCallback_OnLowResource(IBindStatusCallback * iface,DWORD reserved)794 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
795 {
796 ok(0, "unexpected call\n");
797 return E_NOTIMPL;
798 }
799
BindStatusCallback_OnProgress(IBindStatusCallback * iface,ULONG ulProgress,ULONG ulProgressMax,ULONG ulStatusCode,LPCWSTR szStatusText)800 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
801 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
802 {
803 ok(0, "unexpected call\n");
804 return E_NOTIMPL;
805 }
806
BindStatusCallback_OnStopBinding(IBindStatusCallback * iface,HRESULT hr,const WCHAR * error)807 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hr, const WCHAR *error)
808 {
809 CHECK_EXPECT(BindStatusCallback_OnStopBinding);
810
811 ok(hr == S_OK, "got hr %#x\n", hr);
812 ok(!error, "got error %s\n", wine_dbgstr_w(error));
813
814 return 0xdeadbeef;
815 }
816
BindStatusCallback_GetBindInfo(IBindStatusCallback * iface,DWORD * bind_flags,BINDINFO * bind_info)817 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *bind_flags, BINDINFO *bind_info)
818 {
819 CHECK_EXPECT(BindStatusCallback_GetBindInfo);
820
821 return E_NOTIMPL;
822 }
823
BindStatusCallback_OnDataAvailable(IBindStatusCallback * iface,DWORD grfBSCF,DWORD dwSize,FORMATETC * pformatetc,STGMEDIUM * pstgmed)824 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
825 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
826 {
827 ok(0, "unexpected call\n");
828 return E_NOTIMPL;
829 }
830
BindStatusCallback_OnObjectAvailable(IBindStatusCallback * iface,REFIID iid,IUnknown * out)831 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID iid, IUnknown *out)
832 {
833 CHECK_EXPECT(BindStatusCallback_OnObjectAvailable);
834
835 ok(IsEqualGUID(iid, &IID_IUnknown), "iid = %s\n", wine_dbgstr_guid(iid));
836 ok(out == (IUnknown *)&HlinkTarget, "out = %p\n", out);
837
838 return 0xdeadbeef;
839 }
840
841 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
842 BindStatusCallback_QueryInterface,
843 BindStatusCallback_AddRef,
844 BindStatusCallback_Release,
845 BindStatusCallback_OnStartBinding,
846 BindStatusCallback_GetPriority,
847 BindStatusCallback_OnLowResource,
848 BindStatusCallback_OnProgress,
849 BindStatusCallback_OnStopBinding,
850 BindStatusCallback_GetBindInfo,
851 BindStatusCallback_OnDataAvailable,
852 BindStatusCallback_OnObjectAvailable
853 };
854
855 static IBindStatusCallback BindStatusCallback = { &BindStatusCallbackVtbl };
856
HlinkBrowseContext_QueryInterface(IHlinkBrowseContext * iface,REFIID riid,void ** ppv)857 static HRESULT WINAPI HlinkBrowseContext_QueryInterface(
858 IHlinkBrowseContext *iface, REFIID riid, void **ppv)
859 {
860 *ppv = NULL;
861
862 if (IsEqualGUID(&IID_IHlinkHistory, riid))
863 CHECK_EXPECT(HBC_QueryInterface_IHlinkHistory);
864 else if (IsEqualGUID(&IID_IMarshal, riid))
865 CHECK_EXPECT2(HBC_QueryInterface_IMarshal);
866 else if (IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
867 CHECK_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
868 else if (IsEqualGUID(&IID_IUnknown, riid))
869 CHECK_EXPECT(HBC_QueryInterface_IUnknown);
870 else
871 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
872
873 return E_NOINTERFACE;
874 }
875
876 static LONG browse_ctx_refs = 1;
877
HlinkBrowseContext_AddRef(IHlinkBrowseContext * iface)878 static ULONG WINAPI HlinkBrowseContext_AddRef(IHlinkBrowseContext *iface)
879 {
880 return ++browse_ctx_refs;
881 }
882
HlinkBrowseContext_Release(IHlinkBrowseContext * iface)883 static ULONG WINAPI HlinkBrowseContext_Release(IHlinkBrowseContext *iface)
884 {
885 return --browse_ctx_refs;
886 }
887
HlinkBrowseContext_Register(IHlinkBrowseContext * iface,DWORD reserved,IUnknown * piunk,IMoniker * pimk,DWORD * pdwRegister)888 static HRESULT WINAPI HlinkBrowseContext_Register(IHlinkBrowseContext *iface,
889 DWORD reserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister)
890 {
891 ok(0, "unexpected call\n");
892 return E_NOTIMPL;
893 }
894
895 static IUnknown *HBC_object;
896
897 static IMoniker Moniker;
HlinkBrowseContext_GetObject(IHlinkBrowseContext * iface,IMoniker * pimk,BOOL fBindIfRootRegistered,IUnknown ** ppiunk)898 static HRESULT WINAPI HlinkBrowseContext_GetObject(IHlinkBrowseContext *iface,
899 IMoniker *pimk, BOOL fBindIfRootRegistered, IUnknown **ppiunk)
900 {
901 IBindCtx *bctx;
902 WCHAR *name;
903 HRESULT hr;
904
905 CHECK_EXPECT(HBC_GetObject);
906
907 CreateBindCtx(0, &bctx);
908 hr = IMoniker_GetDisplayName(pimk, bctx, NULL, &name);
909 ok(hr == S_OK, "Failed to get display name, hr %#x.\n", hr);
910 ok(!lstrcmpW(winehq_urlW, name) || !lstrcmpW(winehq_404W, name), "got unexpected url\n");
911 CoTaskMemFree(name);
912 IBindCtx_Release(bctx);
913
914 ok(fBindIfRootRegistered == 1, "fBindIfRootRegistered = %x\n", fBindIfRootRegistered);
915
916 *ppiunk = HBC_object;
917 return HBC_object ? S_OK : 0xdeadbeef;
918 }
919
HlinkBrowseContext_Revoke(IHlinkBrowseContext * iface,DWORD dwRegister)920 static HRESULT WINAPI HlinkBrowseContext_Revoke(IHlinkBrowseContext *iface, DWORD dwRegister)
921 {
922 ok(0, "unexpected call\n");
923 return E_NOTIMPL;
924 }
925
HlinkBrowseContext_SetBrowseWindowInfo(IHlinkBrowseContext * iface,HLBWINFO * phlbwi)926 static HRESULT WINAPI HlinkBrowseContext_SetBrowseWindowInfo(
927 IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
928 {
929 ok(0, "unexpected call\n");
930 return E_NOTIMPL;
931 }
932
HlinkBrowseContext_GetBrowseWindowInfo(IHlinkBrowseContext * iface,HLBWINFO * phlbwi)933 static HRESULT WINAPI HlinkBrowseContext_GetBrowseWindowInfo(
934 IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
935 {
936 ok(0, "unexpected call\n");
937 return E_NOTIMPL;
938 }
939
HlinkBrowseContext_SetInitialHlink(IHlinkBrowseContext * iface,IMoniker * pimkTarget,LPCWSTR pwzLocation,LPCWSTR pwzFriendlyName)940 static HRESULT WINAPI HlinkBrowseContext_SetInitialHlink(IHlinkBrowseContext *iface,
941 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
942 {
943 ok(0, "unexpected call\n");
944 return E_NOTIMPL;
945 }
946
HlinkBrowseContext_OnNavigateHlink(IHlinkBrowseContext * iface,DWORD grfHLNF,IMoniker * pimkTarget,LPCWSTR pwzLocation,LPCWSTR pwzFriendlyName,ULONG * puHLID)947 static HRESULT WINAPI HlinkBrowseContext_OnNavigateHlink(IHlinkBrowseContext *iface, DWORD grfHLNF,
948 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, ULONG *puHLID)
949 {
950 ok(0, "unexpected call\n");
951 return E_NOTIMPL;
952 }
953
HlinkBrowseContext_UpdateHlink(IHlinkBrowseContext * iface,ULONG uHLID,IMoniker * pimkTarget,LPCWSTR location,LPCWSTR friendly_name)954 static HRESULT WINAPI HlinkBrowseContext_UpdateHlink(IHlinkBrowseContext *iface, ULONG uHLID,
955 IMoniker *pimkTarget, LPCWSTR location, LPCWSTR friendly_name)
956 {
957 CHECK_EXPECT(HBC_UpdateHlink);
958 return S_OK;
959 }
960
HlinkBrowseContext_EnumNavigationStack(IHlinkBrowseContext * iface,DWORD dwReserved,DWORD grfHLFNAMEF,IEnumHLITEM ** ppienumhlitem)961 static HRESULT WINAPI HlinkBrowseContext_EnumNavigationStack(IHlinkBrowseContext *iface,
962 DWORD dwReserved, DWORD grfHLFNAMEF, IEnumHLITEM **ppienumhlitem)
963 {
964 ok(0, "unexpected call\n");
965 return E_NOTIMPL;
966 }
967
HlinkBrowseContext_QueryHlink(IHlinkBrowseContext * iface,DWORD grfHLQF,ULONG uHLID)968 static HRESULT WINAPI HlinkBrowseContext_QueryHlink(IHlinkBrowseContext *iface,
969 DWORD grfHLQF, ULONG uHLID)
970 {
971 ok(0, "unexpected call\n");
972 return E_NOTIMPL;
973 }
974
HlinkBrowseContext_GetHlink(IHlinkBrowseContext * iface,ULONG uHLID,IHlink ** ppihl)975 static HRESULT WINAPI HlinkBrowseContext_GetHlink(IHlinkBrowseContext *iface,
976 ULONG uHLID, IHlink **ppihl)
977 {
978 ok(0, "unexpected call\n");
979 return E_NOTIMPL;
980 }
981
HlinkBrowseContext_SetCurrentHlink(IHlinkBrowseContext * iface,ULONG uHLID)982 static HRESULT WINAPI HlinkBrowseContext_SetCurrentHlink(
983 IHlinkBrowseContext *iface, ULONG uHLID)
984 {
985 ok(0, "unexpected call\n");
986 return E_NOTIMPL;
987 }
988
HlinkBrowseContext_Clone(IHlinkBrowseContext * iface,IUnknown * piunkOuter,REFIID riid,IUnknown ** ppiunkObj)989 static HRESULT WINAPI HlinkBrowseContext_Clone(IHlinkBrowseContext *iface,
990 IUnknown *piunkOuter, REFIID riid, IUnknown **ppiunkObj)
991 {
992 ok(0, "unexpected call\n");
993 return E_NOTIMPL;
994 }
995
HlinkBrowseContext_Close(IHlinkBrowseContext * iface,DWORD reserved)996 static HRESULT WINAPI HlinkBrowseContext_Close(IHlinkBrowseContext *iface, DWORD reserved)
997 {
998 ok(0, "unexpected call\n");
999 return E_NOTIMPL;
1000 }
1001
1002 static IHlinkBrowseContextVtbl HlinkBrowseContextVtbl = {
1003 HlinkBrowseContext_QueryInterface,
1004 HlinkBrowseContext_AddRef,
1005 HlinkBrowseContext_Release,
1006 HlinkBrowseContext_Register,
1007 HlinkBrowseContext_GetObject,
1008 HlinkBrowseContext_Revoke,
1009 HlinkBrowseContext_SetBrowseWindowInfo,
1010 HlinkBrowseContext_GetBrowseWindowInfo,
1011 HlinkBrowseContext_SetInitialHlink,
1012 HlinkBrowseContext_OnNavigateHlink,
1013 HlinkBrowseContext_UpdateHlink,
1014 HlinkBrowseContext_EnumNavigationStack,
1015 HlinkBrowseContext_QueryHlink,
1016 HlinkBrowseContext_GetHlink,
1017 HlinkBrowseContext_SetCurrentHlink,
1018 HlinkBrowseContext_Clone,
1019 HlinkBrowseContext_Close
1020 };
1021
1022 static IHlinkBrowseContext HlinkBrowseContext = { &HlinkBrowseContextVtbl };
1023
HlinkTarget_QueryInterface(IHlinkTarget * iface,REFIID riid,void ** ppv)1024 static HRESULT WINAPI HlinkTarget_QueryInterface(IHlinkTarget *iface, REFIID riid, void **ppv)
1025 {
1026 if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
1027 CHECK_EXPECT(HT_QueryInterface_IHlinkTarget);
1028 *ppv = iface;
1029 return S_OK;
1030 }
1031
1032 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
1033 return E_NOINTERFACE;
1034 }
1035
HlinkTarget_AddRef(IHlinkTarget * iface)1036 static ULONG WINAPI HlinkTarget_AddRef(IHlinkTarget *iface)
1037 {
1038 return 2;
1039 }
1040
HlinkTarget_Release(IHlinkTarget * iface)1041 static ULONG WINAPI HlinkTarget_Release(IHlinkTarget *iface)
1042 {
1043 return 1;
1044 }
1045
HlinkTarget_SetBrowseContext(IHlinkTarget * iface,IHlinkBrowseContext * pihlbc)1046 static HRESULT WINAPI HlinkTarget_SetBrowseContext(IHlinkTarget *iface,
1047 IHlinkBrowseContext *pihlbc)
1048 {
1049 CHECK_EXPECT(HT_SetBrowseContext);
1050
1051 ok(pihlbc == &HlinkBrowseContext, "pihlbc != &HlinkBrowseContext (%p)\n", pihlbc);
1052 return S_OK;
1053 }
1054
HlinkTarget_GetBrowseContext(IHlinkTarget * iface,IHlinkBrowseContext ** ppihlbc)1055 static HRESULT WINAPI HlinkTarget_GetBrowseContext(IHlinkTarget *iface,
1056 IHlinkBrowseContext **ppihlbc)
1057 {
1058 CHECK_EXPECT(HT_GetBrowseContext);
1059
1060 *ppihlbc = NULL;
1061 return S_OK;
1062 }
1063
HlinkTarget_Navigate(IHlinkTarget * iface,DWORD grfHLNF,LPCWSTR pwzJumpLocation)1064 static HRESULT WINAPI HlinkTarget_Navigate(IHlinkTarget *iface,
1065 DWORD grfHLNF, LPCWSTR pwzJumpLocation)
1066 {
1067 CHECK_EXPECT(HT_Navigate);
1068
1069 ok(grfHLNF == 0, "grfHLNF = %x\n", grfHLNF);
1070 ok(pwzJumpLocation == NULL, "pwzJumpLocation = %s\n", wine_dbgstr_w(pwzJumpLocation));
1071 return S_OK;
1072 }
1073
HlinkTarget_GetMoniker(IHlinkTarget * iface,LPCWSTR pwzLocation,DWORD dwAssign,IMoniker ** ppimkLocation)1074 static HRESULT WINAPI HlinkTarget_GetMoniker(IHlinkTarget *iface,
1075 LPCWSTR pwzLocation, DWORD dwAssign, IMoniker **ppimkLocation)
1076 {
1077 ok(0, "unexpected call\n");
1078 return E_NOTIMPL;
1079 }
1080
HlinkTarget_GetFriendlyName(IHlinkTarget * iface,LPCWSTR pwzLocation,LPWSTR * ppwzFriendlyName)1081 static HRESULT WINAPI HlinkTarget_GetFriendlyName(IHlinkTarget *iface,
1082 LPCWSTR pwzLocation, LPWSTR *ppwzFriendlyName)
1083 {
1084 CHECK_EXPECT(HT_GetFriendlyName);
1085 return E_NOTIMPL;
1086 }
1087
1088 static IHlinkTargetVtbl HlinkTargetVtbl = {
1089 HlinkTarget_QueryInterface,
1090 HlinkTarget_AddRef,
1091 HlinkTarget_Release,
1092 HlinkTarget_SetBrowseContext,
1093 HlinkTarget_GetBrowseContext,
1094 HlinkTarget_Navigate,
1095 HlinkTarget_GetMoniker,
1096 HlinkTarget_GetFriendlyName
1097 };
1098
1099 static IHlinkTarget HlinkTarget = { &HlinkTargetVtbl };
1100
Moniker_QueryInterface(IMoniker * iface,REFIID riid,void ** ppv)1101 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
1102 {
1103 *ppv = NULL;
1104
1105 ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid));
1106 return E_NOINTERFACE;
1107 }
1108
Moniker_AddRef(IMoniker * iface)1109 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
1110 {
1111 return 2;
1112 }
1113
Moniker_Release(IMoniker * iface)1114 static ULONG WINAPI Moniker_Release(IMoniker *iface)
1115 {
1116 return 1;
1117 }
1118
Moniker_GetClassID(IMoniker * iface,CLSID * pClassID)1119 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
1120 {
1121 CHECK_EXPECT(GetClassID);
1122 *pClassID = IID_IUnknown; /* not a valid CLSID */
1123 return S_OK;
1124 }
1125
Moniker_IsDirty(IMoniker * iface)1126 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
1127 {
1128 ok(0, "unexpected call\n");
1129 return E_NOTIMPL;
1130 }
1131
Moniker_Load(IMoniker * iface,IStream * pStm)1132 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
1133 {
1134 ok(0, "unexpected call\n");
1135 return E_NOTIMPL;
1136 }
1137
Moniker_Save(IMoniker * iface,IStream * pStm,BOOL fClearDirty)1138 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
1139 {
1140 CHECK_EXPECT(Save);
1141 return S_OK;
1142 }
1143
Moniker_GetSizeMax(IMoniker * iface,ULARGE_INTEGER * pcbSize)1144 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
1145 {
1146 ok(0, "unexpected call\n");
1147 return E_NOTIMPL;
1148 }
1149
1150 static BOOL async_bind;
1151 static IBindStatusCallback *async_bind_callback;
1152
Moniker_BindToObject(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,REFIID riid,void ** ppv)1153 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1154 REFIID riid, void **ppv)
1155 {
1156 static WCHAR bscb_holderW[] = {'_','B','S','C','B','_','H','o','l','d','e','r','_',0};
1157 IUnknown *bind_callback_holder;
1158 HRESULT hr;
1159
1160 CHECK_EXPECT(BindToObject);
1161
1162 ok(pbc != _bctx, "pbc != _bctx\n");
1163 ok(pmkToLeft == NULL, "pmkToLeft = %p\n", pmkToLeft);
1164 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1165 ok(ppv != NULL, "ppv == NULL\n");
1166 ok(*ppv == NULL, "*ppv = %p\n", *ppv);
1167
1168 if (async_bind)
1169 {
1170 hr = IBindCtx_GetObjectParam(pbc, bscb_holderW, &bind_callback_holder);
1171 ok(hr == S_OK, "Failed to get IBindStatusCallback holder, hr %#x.\n", hr);
1172 hr = IUnknown_QueryInterface(bind_callback_holder, &IID_IBindStatusCallback,
1173 (void **)&async_bind_callback);
1174 ok(hr == S_OK, "Failed to get IBindStatusCallback interface, hr %#x.\n", hr);
1175 IUnknown_Release(bind_callback_holder);
1176 return MK_S_ASYNCHRONOUS;
1177 }
1178
1179 *ppv = &HlinkTarget;
1180 return S_OK;
1181 }
1182
Moniker_BindToStorage(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,REFIID riid,void ** ppv)1183 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1184 REFIID riid, void **ppv)
1185 {
1186 IUnknown *unk;
1187 HRESULT hres;
1188
1189 static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
1190
1191 CHECK_EXPECT(BindToStorage);
1192
1193 ok(pbc == _bctx, "pbc != _bctx\n");
1194 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1195 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1196 ok(ppv != NULL, "ppv == NULL\n");
1197 ok(*ppv == NULL, "*ppv=%p\n", *ppv);
1198
1199 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
1200 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
1201 ok(unk != NULL, "unk == NULL\n");
1202
1203 IUnknown_Release(unk);
1204
1205 return S_OK;
1206 }
1207
Moniker_Reduce(IMoniker * iface,IBindCtx * pbc,DWORD dwReduceHowFar,IMoniker ** ppmkToLeft,IMoniker ** ppmkReduced)1208 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
1209 IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
1210 {
1211 CHECK_EXPECT(Reduce);
1212 return E_NOTIMPL;
1213 }
1214
Moniker_ComposeWith(IMoniker * iface,IMoniker * pmkRight,BOOL fOnlyIfNotGeneric,IMoniker ** ppnkComposite)1215 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
1216 BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
1217 {
1218 ok(0, "unexpected call\n");
1219 return E_NOTIMPL;
1220 }
1221
Moniker_Enum(IMoniker * iface,BOOL fForwrd,IEnumMoniker ** ppenumMoniker)1222 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
1223 {
1224 CHECK_EXPECT(Enum);
1225 return E_NOTIMPL;
1226 }
1227
Moniker_IsEqual(IMoniker * iface,IMoniker * pmkOtherMoniker)1228 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
1229 {
1230 ok(0, "unexpected call\n");
1231 return E_NOTIMPL;
1232 }
1233
Moniker_Hash(IMoniker * iface,DWORD * pdwHash)1234 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
1235 {
1236 ok(0, "unexpected call\n");
1237 return E_NOTIMPL;
1238 }
1239
Moniker_IsRunning(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,IMoniker * pmkNewlyRunning)1240 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1241 IMoniker *pmkNewlyRunning)
1242 {
1243 ok(0, "unexpected call\n");
1244 return E_NOTIMPL;
1245 }
1246
Moniker_GetTimeOfLastChange(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,FILETIME * pFileTime)1247 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
1248 IMoniker *pmkToLeft, FILETIME *pFileTime)
1249 {
1250 ok(0, "unexpected call\n");
1251 return E_NOTIMPL;
1252 }
1253
Moniker_Inverse(IMoniker * iface,IMoniker ** ppmk)1254 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
1255 {
1256 ok(0, "unexpected call\n");
1257 return E_NOTIMPL;
1258 }
1259
Moniker_CommonPrefixWith(IMoniker * iface,IMoniker * pmkOther,IMoniker ** ppmkPrefix)1260 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
1261 IMoniker **ppmkPrefix)
1262 {
1263 ok(0, "unexpected call\n");
1264 return E_NOTIMPL;
1265 }
1266
Moniker_RelativePathTo(IMoniker * iface,IMoniker * pmkOther,IMoniker ** pmkRelPath)1267 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
1268 IMoniker **pmkRelPath)
1269 {
1270 ok(0, "unexpected call\n");
1271 return E_NOTIMPL;
1272 }
1273
Moniker_GetDisplayName(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,LPOLESTR * ppszDisplayName)1274 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
1275 IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
1276 {
1277 CHECK_EXPECT2(GetDisplayName);
1278
1279 ok(pbc != NULL, "pbc == NULL\n");
1280 ok(pbc != _bctx, "pbc == _bctx\n");
1281 ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1282
1283 *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
1284 memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
1285 return S_OK;
1286 }
1287
Moniker_ParseDisplayName(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,LPOLESTR pszDisplayName,ULONG * pchEaten,IMoniker ** ppmkOut)1288 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
1289 IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
1290 {
1291 ok(0, "unexpected call\n");
1292 return E_NOTIMPL;
1293 }
1294
Moniker_IsSystemMoniker(IMoniker * iface,DWORD * pdwMksys)1295 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
1296 {
1297 CHECK_EXPECT2(IsSystemMoniker);
1298
1299 *pdwMksys = MKSYS_URLMONIKER;
1300 return S_OK;
1301 }
1302
1303 static IMonikerVtbl MonikerVtbl = {
1304 Moniker_QueryInterface,
1305 Moniker_AddRef,
1306 Moniker_Release,
1307 Moniker_GetClassID,
1308 Moniker_IsDirty,
1309 Moniker_Load,
1310 Moniker_Save,
1311 Moniker_GetSizeMax,
1312 Moniker_BindToObject,
1313 Moniker_BindToStorage,
1314 Moniker_Reduce,
1315 Moniker_ComposeWith,
1316 Moniker_Enum,
1317 Moniker_IsEqual,
1318 Moniker_Hash,
1319 Moniker_IsRunning,
1320 Moniker_GetTimeOfLastChange,
1321 Moniker_Inverse,
1322 Moniker_CommonPrefixWith,
1323 Moniker_RelativePathTo,
1324 Moniker_GetDisplayName,
1325 Moniker_ParseDisplayName,
1326 Moniker_IsSystemMoniker
1327 };
1328
1329 static IMoniker Moniker = { &MonikerVtbl };
1330
test_HlinkResolveMonikerForData(void)1331 static void test_HlinkResolveMonikerForData(void)
1332 {
1333 IBindCtx *bctx;
1334 HRESULT hres;
1335
1336 CreateBindCtx(0, &bctx);
1337 _bctx = bctx;
1338
1339 SET_EXPECT(IsSystemMoniker);
1340 SET_EXPECT(GetDisplayName);
1341 SET_EXPECT(BindToStorage);
1342
1343 hres = HlinkResolveMonikerForData(&Moniker, 0, bctx, 0, NULL, &BindStatusCallback, NULL);
1344 ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1345
1346 CHECK_CALLED(IsSystemMoniker);
1347 CHECK_CALLED(GetDisplayName);
1348 CHECK_CALLED(BindToStorage);
1349
1350 IBindCtx_Release(bctx);
1351 _bctx = NULL;
1352 }
1353
test_HlinkGetSetMonikerReference(void)1354 static void test_HlinkGetSetMonikerReference(void)
1355 {
1356 IMoniker *found_trgt, *dummy, *dummy2;
1357 IHlink *hlink;
1358 HRESULT hres;
1359 const WCHAR one[] = {'1',0};
1360 const WCHAR two[] = {'2',0};
1361 const WCHAR name[] = {'a',0};
1362 WCHAR *found_loc;
1363
1364 /* create two dummy monikers to use as targets */
1365 hres = CreateItemMoniker(one, one, &dummy);
1366 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1367
1368 hres = CreateItemMoniker(two, two, &dummy2);
1369 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1370
1371 /* create a new hlink: target => dummy, location => one */
1372 hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1373 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1374
1375 /* validate the target and location */
1376 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1377 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1378 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1379 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1380 IMoniker_Release(found_trgt);
1381 CoTaskMemFree(found_loc);
1382
1383 /* set location => two */
1384 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1385 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1386
1387 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1388 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1389 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1390 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1391 IMoniker_Release(found_trgt);
1392 CoTaskMemFree(found_loc);
1393
1394 /* set target => dummy2 */
1395 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1396 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1397
1398 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1399 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1400 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1401 ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1402 IMoniker_Release(found_trgt);
1403 CoTaskMemFree(found_loc);
1404
1405 /* set target => dummy, location => one */
1406 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1407 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1408
1409 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1410 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1411 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1412 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1413 IMoniker_Release(found_trgt);
1414 CoTaskMemFree(found_loc);
1415
1416 /* no HLINKSETF flags */
1417 hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1418 ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1419
1420 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1421 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1422 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1423 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1424 IMoniker_Release(found_trgt);
1425 CoTaskMemFree(found_loc);
1426
1427 /* invalid HLINKSETF flags */
1428 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1429 if (0)
1430 IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1431
1432 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1433 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1434 ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1435 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1436 IMoniker_Release(found_trgt);
1437 CoTaskMemFree(found_loc);
1438
1439 /* valid & invalid HLINKSETF flags */
1440 hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1441 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1442
1443 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1444 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1445 ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1446 ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1447 IMoniker_Release(found_trgt);
1448 CoTaskMemFree(found_loc);
1449
1450 /* NULL args */
1451 hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1452 ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1453
1454 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1455 ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1456 ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1457 ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1458 if(found_trgt)
1459 IMoniker_Release(found_trgt);
1460
1461 IHlink_Release(hlink);
1462 IMoniker_Release(dummy2);
1463 IMoniker_Release(dummy);
1464
1465 SET_EXPECT(Reduce);
1466 SET_EXPECT(Enum);
1467 SET_EXPECT(IsSystemMoniker);
1468 SET_EXPECT(GetDisplayName);
1469 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL, 0, NULL,
1470 &IID_IHlink, (void **)&hlink);
1471 ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1472
1473 hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_ABSOLUTE,
1474 &found_trgt, &found_loc);
1475 ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1476 ok(found_trgt == &Moniker, "Got unexpected moniker: %p\n", found_trgt);
1477 ok(found_loc == NULL, "Got unexpected location: %p\n", found_loc);
1478 todo_wine CHECK_CALLED(Reduce);
1479 todo_wine CHECK_CALLED(Enum);
1480 CHECK_CALLED(IsSystemMoniker);
1481 CHECK_CALLED(GetDisplayName);
1482
1483 IHlink_Release(hlink);
1484 }
1485
test_HlinkGetSetStringReference(void)1486 static void test_HlinkGetSetStringReference(void)
1487 {
1488 IHlink *link;
1489 static const WCHAR one[] = {'1',0};
1490 static const WCHAR two[] = {'2',0};
1491 static const WCHAR three[] = {'3',0};
1492 static const WCHAR empty[] = {0};
1493 WCHAR *fnd_tgt, *fnd_loc;
1494 HRESULT hres;
1495
1496 /* create a new hlink: target => NULL, location => one */
1497 hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1498 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1499
1500 /* test setting/getting location */
1501 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1502 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1503 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1504 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1505 CoTaskMemFree(fnd_tgt);
1506 CoTaskMemFree(fnd_loc);
1507
1508 hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1509 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1510
1511 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1512 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1513 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1514 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1515 CoTaskMemFree(fnd_tgt);
1516 CoTaskMemFree(fnd_loc);
1517
1518 hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1519 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1520
1521 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1522 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1523 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1524 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1525 CoTaskMemFree(fnd_tgt);
1526 CoTaskMemFree(fnd_loc);
1527
1528 /* test setting/getting target */
1529 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1530 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1531
1532 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1533 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1534 ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1535 ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1536 CoTaskMemFree(fnd_tgt);
1537 CoTaskMemFree(fnd_loc);
1538
1539 hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1540 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1541
1542 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1543 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1544 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1545 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1546 CoTaskMemFree(fnd_tgt);
1547 CoTaskMemFree(fnd_loc);
1548
1549 /* test setting/getting both */
1550 hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1551 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1552
1553 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1554 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1555 ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1556 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1557 CoTaskMemFree(fnd_tgt);
1558 CoTaskMemFree(fnd_loc);
1559
1560 hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1561 ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1562
1563 hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1564 ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1565 ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1566 ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1567 CoTaskMemFree(fnd_tgt);
1568 CoTaskMemFree(fnd_loc);
1569
1570 /* test invalid flags/params */
1571 hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1572 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1573 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1574 ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1575 ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1576 CoTaskMemFree(fnd_tgt);
1577 CoTaskMemFree(fnd_loc);
1578
1579 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1580 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1581 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1582 CoTaskMemFree(fnd_tgt);
1583
1584 hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1585 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1586
1587 hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1588 ok(hres == S_OK, "failed, hres=%08x\n", hres);
1589 CoTaskMemFree(fnd_loc);
1590
1591 hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1592 todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1593 "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1594 CoTaskMemFree(fnd_tgt);
1595 CoTaskMemFree(fnd_loc);
1596
1597 hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1598 ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1599 "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1600 CoTaskMemFree(fnd_tgt);
1601 CoTaskMemFree(fnd_loc);
1602
1603 if (0)
1604 {
1605 /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1606 IHlink_SetStringReference(link, 4, NULL, NULL);
1607 IHlink_SetStringReference(link, -4, NULL, NULL);
1608 }
1609
1610 IHlink_Release(link);
1611 }
1612
1613 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
r_setStringRef(unsigned line,IHlink * hlink,DWORD flags,const WCHAR * tgt,const WCHAR * loc)1614 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1615 {
1616 HRESULT hres;
1617 hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1618 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1619 }
1620
1621 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
r_getStringRef(unsigned line,IHlink * hlink,const WCHAR * exp_tgt,const WCHAR * exp_loc)1622 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1623 {
1624 HRESULT hres;
1625 WCHAR *fnd_tgt, *fnd_loc;
1626
1627 hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1628 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1629
1630 if(exp_tgt)
1631 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));
1632 else
1633 ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1634
1635 if(exp_loc)
1636 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));
1637 else
1638 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1639
1640 CoTaskMemFree(fnd_tgt);
1641 CoTaskMemFree(fnd_loc);
1642 }
1643
1644 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
r_setMonikerRef(unsigned line,IHlink * hlink,DWORD flags,IMoniker * tgt,const WCHAR * loc)1645 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1646 {
1647 HRESULT hres;
1648 hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1649 ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1650 }
1651
1652 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1653 #define getMonikerRef(h,t,l,r) r_getMonikerRef(__LINE__,h,t,l,r)
r_getMonikerRef(unsigned line,IHlink * hlink,IMoniker * exp_tgt,const WCHAR * exp_loc,DWORD ref)1654 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc, DWORD ref)
1655 {
1656 HRESULT hres;
1657 IMoniker *fnd_tgt;
1658 WCHAR *fnd_loc;
1659
1660 hres = IHlink_GetMonikerReference(hlink, ref, &fnd_tgt, &fnd_loc);
1661 ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1662
1663 if(exp_loc)
1664 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));
1665 else
1666 ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1667
1668 CoTaskMemFree(fnd_loc);
1669
1670 if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1671 return fnd_tgt;
1672
1673 ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1674
1675 if(fnd_tgt)
1676 IMoniker_Release(fnd_tgt);
1677
1678 return NULL;
1679 }
1680
test_HlinkMoniker(void)1681 static void test_HlinkMoniker(void)
1682 {
1683 IHlink *hlink;
1684 IMoniker *aMon, *file_mon;
1685 static const WCHAR emptyW[] = {0};
1686 static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1687 static const WCHAR aW[] = {'a',0};
1688 static const WCHAR bW[] = {'b',0};
1689 HRESULT hres;
1690
1691 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1692 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1693 getStringRef(hlink, NULL, NULL);
1694 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1695
1696 /* setting a string target creates a moniker reference */
1697 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1698 getStringRef(hlink, aW, wordsW);
1699 aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW, HLINKGETREF_RELATIVE);
1700 ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1701 if(aMon)
1702 IMoniker_Release(aMon);
1703
1704 /* setting target & location to the empty string deletes the moniker
1705 * reference */
1706 setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1707 getStringRef(hlink, NULL, NULL);
1708 getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1709
1710 /* setting a moniker target also sets the target string to that moniker's
1711 * display name */
1712 hres = CreateFileMoniker(bW, &file_mon);
1713 ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1714
1715 setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1716 getStringRef(hlink, bW, wordsW);
1717 getMonikerRef(hlink, file_mon, wordsW, HLINKGETREF_RELATIVE);
1718
1719 IMoniker_Release(file_mon);
1720
1721 IHlink_Release(hlink);
1722 }
1723
test_HashLink(void)1724 static void test_HashLink(void)
1725 {
1726 IHlink *hlink;
1727 IMoniker *pmk;
1728 const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1729 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};
1730 const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1731 const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1732 const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1733 const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1734 const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1735 HRESULT hres;
1736
1737 /* simple single hash test */
1738 hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1739 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1740 ok(hlink != NULL, "Didn't get an hlink\n");
1741
1742 if(hlink){
1743 getStringRef(hlink, tgt_partW, loc_partW);
1744 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1745 ok(pmk != NULL, "Found moniker should not be NULL\n");
1746 if(pmk)
1747 IMoniker_Release(pmk);
1748
1749 setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1750 getStringRef(hlink, hash_targetW, loc_partW);
1751
1752 IHlink_Release(hlink);
1753 }
1754
1755 /* two hashes in the target */
1756 hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1757 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1758 ok(hlink != NULL, "Didn't get an hlink\n");
1759
1760 if(hlink){
1761 getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1762 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW, HLINKGETREF_RELATIVE);
1763 ok(pmk != NULL, "Found moniker should not be NULL\n");
1764 if(pmk)
1765 IMoniker_Release(pmk);
1766
1767 IHlink_Release(hlink);
1768 }
1769
1770 /* target with hash plus a location string */
1771 hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1772 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1773 ok(hlink != NULL, "Didn't get an hlink\n");
1774
1775 if(hlink){
1776 getStringRef(hlink, tgt_partW, test_locW);
1777 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW, HLINKGETREF_RELATIVE);
1778 ok(pmk != NULL, "Found moniker should not be NULL\n");
1779 if(pmk)
1780 IMoniker_Release(pmk);
1781
1782 IHlink_Release(hlink);
1783 }
1784
1785 /* target with hash containing no "target part" */
1786 hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1787 ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1788 ok(hlink != NULL, "Didn't get an hlink\n");
1789
1790 if(hlink){
1791 getStringRef(hlink, NULL, loc_partW);
1792 pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1793 ok(pmk == NULL, "Found moniker should be NULL\n");
1794 if(pmk)
1795 IMoniker_Release(pmk);
1796
1797 IHlink_Release(hlink);
1798 }
1799 }
1800
1801 static const WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1802 static const WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1803
hls_test_Moniker_BindToStorage(IMoniker * iface,IBindCtx * pbc,IMoniker * toLeft,REFIID riid,void ** obj)1804 static HRESULT WINAPI hls_test_Moniker_BindToStorage(IMoniker *iface,
1805 IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1806 {
1807 ok(0, "BTS: %p %p %p %s %p\n", iface, pbc, toLeft, wine_dbgstr_guid(riid), obj);
1808 return E_NOTIMPL;
1809 }
1810
hls_site_Moniker_ComposeWith(IMoniker * iface,IMoniker * right,BOOL onlyIfNotGeneric,IMoniker ** composite)1811 static HRESULT WINAPI hls_site_Moniker_ComposeWith(IMoniker *iface,
1812 IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1813 {
1814 LPOLESTR rightName;
1815 HRESULT hres;
1816
1817 ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1818
1819 CHECK_EXPECT(ComposeWith);
1820
1821 hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1822 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1823 ok(!lstrcmpW(rightName, ref_monikerW),
1824 "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1825 wine_dbgstr_w(rightName));
1826 CoTaskMemFree(rightName);
1827
1828 *composite = NULL;
1829
1830 /* unlikely error code to verify this return result is used */
1831 return E_OUTOFMEMORY;
1832 }
1833
hls_site_Moniker_GetDisplayName(IMoniker * iface,IBindCtx * pbc,IMoniker * toLeft,LPOLESTR * displayName)1834 static HRESULT WINAPI hls_site_Moniker_GetDisplayName(IMoniker *iface,
1835 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1836 {
1837 *displayName = CoTaskMemAlloc(sizeof(site_monikerW));
1838 memcpy(*displayName, site_monikerW, sizeof(site_monikerW));
1839 return S_OK;
1840 }
1841
hls_ref_Moniker_GetDisplayName(IMoniker * iface,IBindCtx * pbc,IMoniker * toLeft,LPOLESTR * displayName)1842 static HRESULT WINAPI hls_ref_Moniker_GetDisplayName(IMoniker *iface,
1843 IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1844 {
1845 *displayName = CoTaskMemAlloc(sizeof(ref_monikerW));
1846 memcpy(*displayName, ref_monikerW, sizeof(ref_monikerW));
1847 return S_OK;
1848 }
1849
hls_test_Moniker_IsSystemMoniker(IMoniker * iface,DWORD * mksys)1850 static HRESULT WINAPI hls_test_Moniker_IsSystemMoniker(IMoniker *iface,
1851 DWORD *mksys)
1852 {
1853 return S_FALSE;
1854 }
1855
1856 static IMonikerVtbl hls_site_MonikerVtbl = {
1857 Moniker_QueryInterface,
1858 Moniker_AddRef,
1859 Moniker_Release,
1860 Moniker_GetClassID,
1861 Moniker_IsDirty,
1862 Moniker_Load,
1863 Moniker_Save,
1864 Moniker_GetSizeMax,
1865 Moniker_BindToObject,
1866 hls_test_Moniker_BindToStorage,
1867 Moniker_Reduce,
1868 hls_site_Moniker_ComposeWith,
1869 Moniker_Enum,
1870 Moniker_IsEqual,
1871 Moniker_Hash,
1872 Moniker_IsRunning,
1873 Moniker_GetTimeOfLastChange,
1874 Moniker_Inverse,
1875 Moniker_CommonPrefixWith,
1876 Moniker_RelativePathTo,
1877 hls_site_Moniker_GetDisplayName,
1878 Moniker_ParseDisplayName,
1879 hls_test_Moniker_IsSystemMoniker
1880 };
1881
1882 static IMonikerVtbl hls_ref_MonikerVtbl = {
1883 Moniker_QueryInterface,
1884 Moniker_AddRef,
1885 Moniker_Release,
1886 Moniker_GetClassID,
1887 Moniker_IsDirty,
1888 Moniker_Load,
1889 Moniker_Save,
1890 Moniker_GetSizeMax,
1891 Moniker_BindToObject,
1892 hls_test_Moniker_BindToStorage,
1893 Moniker_Reduce,
1894 Moniker_ComposeWith,
1895 Moniker_Enum,
1896 Moniker_IsEqual,
1897 Moniker_Hash,
1898 Moniker_IsRunning,
1899 Moniker_GetTimeOfLastChange,
1900 Moniker_Inverse,
1901 Moniker_CommonPrefixWith,
1902 Moniker_RelativePathTo,
1903 hls_ref_Moniker_GetDisplayName,
1904 Moniker_ParseDisplayName,
1905 hls_test_Moniker_IsSystemMoniker
1906 };
1907
1908 static IMoniker hls_site_Moniker = { &hls_site_MonikerVtbl };
1909 static IMoniker hls_ref_Moniker = { &hls_ref_MonikerVtbl };
1910
hls_QueryInterface(IHlinkSite * iface,REFGUID iid,void ** obj)1911 static HRESULT WINAPI hls_QueryInterface(IHlinkSite *iface, REFGUID iid,
1912 void **obj)
1913 {
1914 ok(0, "QI: %p %s %p\n", iface, wine_dbgstr_guid(iid), obj);
1915 return E_NOTIMPL;
1916 }
1917
hls_AddRef(IHlinkSite * iface)1918 static ULONG WINAPI hls_AddRef(IHlinkSite *iface)
1919 {
1920 return 2;
1921 }
1922
hls_Release(IHlinkSite * iface)1923 static ULONG WINAPI hls_Release(IHlinkSite *iface)
1924 {
1925 return 1;
1926 }
1927
hls_QueryService(IHlinkSite * iface,DWORD siteData,REFGUID service,REFIID riid,IUnknown ** punk)1928 static HRESULT WINAPI hls_QueryService(IHlinkSite *iface, DWORD siteData,
1929 REFGUID service, REFIID riid, IUnknown **punk)
1930 {
1931 ok(0, "QS: %p %x %s %s %p\n", iface, siteData, wine_dbgstr_guid(service),
1932 wine_dbgstr_guid(riid), punk);
1933 return E_NOTIMPL;
1934 }
1935
1936 #define SITEDATA_SUCCESS 1
1937 #define SITEDATA_NOTIMPL 2
1938
hls_GetMoniker(IHlinkSite * iface,DWORD siteData,DWORD assign,DWORD which,IMoniker ** pmk)1939 static HRESULT WINAPI hls_GetMoniker(IHlinkSite *iface, DWORD siteData,
1940 DWORD assign, DWORD which, IMoniker **pmk)
1941 {
1942 ok(siteData == SITEDATA_NOTIMPL ||
1943 siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1944
1945 if(siteData == SITEDATA_SUCCESS){
1946 *pmk = &hls_site_Moniker;
1947 return S_OK;
1948 }
1949
1950 return E_NOTIMPL;
1951 }
1952
hls_ReadyToNavigate(IHlinkSite * iface,DWORD siteData,DWORD reserved)1953 static HRESULT WINAPI hls_ReadyToNavigate(IHlinkSite *iface, DWORD siteData,
1954 DWORD reserved)
1955 {
1956 ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
1957 return E_NOTIMPL;
1958 }
1959
hls_OnNavigationComplete(IHlinkSite * iface,DWORD siteData,DWORD reserved,HRESULT error,LPCWSTR errorStr)1960 static HRESULT WINAPI hls_OnNavigationComplete(IHlinkSite *iface,
1961 DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1962 {
1963 CHECK_EXPECT(OnNavigationComplete);
1964 ok(siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1965 ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
1966 return E_NOTIMPL;
1967 }
1968
1969 static IHlinkSiteVtbl HlinkSiteVtbl = {
1970 hls_QueryInterface,
1971 hls_AddRef,
1972 hls_Release,
1973 hls_QueryService,
1974 hls_GetMoniker,
1975 hls_ReadyToNavigate,
1976 hls_OnNavigationComplete
1977 };
1978
1979 static IHlinkSite HlinkSite = { &HlinkSiteVtbl };
1980
test_HlinkSite(void)1981 static void test_HlinkSite(void)
1982 {
1983 IHlink *hl;
1984 IMoniker *mon_ref;
1985 IBindCtx *pbc;
1986 HRESULT hres;
1987
1988 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
1989 &IID_IHlink, (LPVOID*)&hl);
1990 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1991 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1992
1993 hres = IHlink_SetHlinkSite(hl, &HlinkSite, SITEDATA_SUCCESS);
1994 ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
1995 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1996 getStringRef(hl, NULL, NULL);
1997
1998 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1999 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
2000 ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
2001
2002 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
2003 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
2004 ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
2005
2006 SET_EXPECT(Reduce);
2007 SET_EXPECT(Enum);
2008 hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
2009 ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
2010 todo_wine CHECK_CALLED(Reduce);
2011 todo_wine CHECK_CALLED(Enum);
2012
2013 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
2014
2015 SET_EXPECT(Enum);
2016 getStringRef(hl, ref_monikerW, NULL);
2017 todo_wine CHECK_CALLED(Enum);
2018
2019 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
2020 ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
2021 ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
2022 IMoniker_Release(mon_ref);
2023
2024 SET_EXPECT(ComposeWith);
2025 hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
2026 ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
2027 ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
2028 CHECK_CALLED(ComposeWith);
2029
2030 hres = CreateBindCtx(0, &pbc);
2031 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2032
2033 SET_EXPECT(ComposeWith);
2034 SET_EXPECT(OnNavigationComplete);
2035 hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
2036 ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
2037 CHECK_CALLED(ComposeWith);
2038 CHECK_CALLED(OnNavigationComplete);
2039
2040 IBindCtx_Release(pbc);
2041 IHlink_Release(hl);
2042
2043 SET_EXPECT(Reduce);
2044 SET_EXPECT(Enum);
2045 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
2046 NULL, &IID_IHlink, (LPVOID*)&hl);
2047 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2048 todo_wine CHECK_CALLED(Reduce);
2049 todo_wine CHECK_CALLED(Enum);
2050 getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
2051 IHlink_Release(hl);
2052
2053 hres = HlinkCreateFromMoniker(NULL, NULL, NULL, &HlinkSite, SITEDATA_SUCCESS,
2054 NULL, &IID_IHlink, (LPVOID*)&hl);
2055 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2056 getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
2057 IHlink_Release(hl);
2058
2059 SET_EXPECT(Reduce);
2060 SET_EXPECT(Enum);
2061 SET_EXPECT(IsSystemMoniker);
2062 SET_EXPECT(GetDisplayName);
2063 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, &HlinkSite, SITEDATA_NOTIMPL,
2064 NULL, &IID_IHlink, (LPVOID*)&hl);
2065 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2066 getMonikerRef(hl, &Moniker, NULL, HLINKGETREF_ABSOLUTE);
2067 IHlink_Release(hl);
2068 todo_wine CHECK_CALLED(Reduce);
2069 todo_wine CHECK_CALLED(Enum);
2070 CHECK_CALLED(IsSystemMoniker);
2071 CHECK_CALLED(GetDisplayName);
2072 }
2073
test_HlinkClone(void)2074 static void test_HlinkClone(void)
2075 {
2076 HRESULT hres;
2077 IHlink *hl, *cloned = NULL;
2078 IMoniker *dummy, *fnd_mk;
2079 IHlinkSite *fnd_site;
2080 WCHAR *fnd_name;
2081 DWORD fnd_data;
2082 const WCHAR one[] = {'1',0};
2083 const WCHAR two[] = {'2',0};
2084 const WCHAR name[] = {'a',0};
2085
2086 hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
2087 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
2088
2089 hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL,
2090 &IID_IHlink, (void**)&hl);
2091 ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
2092
2093 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
2094 ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
2095
2096 if (0)
2097 {
2098 /* crash on Windows XP */
2099 HlinkClone(hl, NULL, NULL, 0, NULL);
2100
2101 HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
2102 }
2103
2104 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2105 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2106 ok(cloned != NULL, "Didn't get a clone\n");
2107 getMonikerRef(cloned, NULL, NULL, HLINKGETREF_RELATIVE);
2108 IHlink_Release(cloned);
2109
2110 IHlink_Release(hl);
2111
2112 SET_EXPECT(Reduce);
2113 SET_EXPECT(Enum);
2114 hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2115 todo_wine CHECK_CALLED(Reduce);
2116 todo_wine CHECK_CALLED(Enum);
2117 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2118 getMonikerRef(hl, &hls_ref_Moniker, two, HLINKGETREF_RELATIVE);
2119
2120 SET_EXPECT(Save);
2121 SET_EXPECT(GetClassID);
2122 cloned = (IHlink*)0xdeadbeef;
2123 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2124 /* fails because of invalid CLSID given by Moniker_GetClassID */
2125 ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08x\n", hres);
2126 ok(cloned == NULL, "Shouldn't have gotten a clone\n");
2127 CHECK_CALLED(Save);
2128 CHECK_CALLED(GetClassID);
2129
2130 IHlink_Release(hl);
2131
2132 hres = CreateItemMoniker(one, one, &dummy);
2133 ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
2134
2135 hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, SITEDATA_SUCCESS, NULL, &IID_IHlink, (void**)&hl);
2136 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2137 getMonikerRef(hl, dummy, two, HLINKGETREF_RELATIVE);
2138
2139 cloned = NULL;
2140 hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2141 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2142 ok(cloned != NULL, "Should have gotten a clone\n");
2143
2144 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two, HLINKGETREF_RELATIVE);
2145 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2146 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2147
2148 fnd_name = NULL;
2149 hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
2150 ok(hres == S_OK, "GetFriendlyName failed: %08x\n", hres);
2151 ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
2152 ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
2153 wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
2154 CoTaskMemFree(fnd_name);
2155
2156 fnd_site = (IHlinkSite*)0xdeadbeef;
2157 fnd_data = 4;
2158 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2159 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
2160 ok(fnd_site == NULL, "Expected NULL site\n");
2161 ok(fnd_data == 4, "Expected site data to be 4, was: %d\n", fnd_data);
2162
2163 IHlink_Release(cloned);
2164 IHlink_Release(hl);
2165
2166 hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2167 ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2168 getMonikerRef(hl, dummy, NULL, HLINKGETREF_RELATIVE);
2169
2170 cloned = NULL;
2171 hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, SITEDATA_SUCCESS, (void**)&cloned);
2172 ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2173 ok(cloned != NULL, "Should have gotten a clone\n");
2174
2175 fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL, HLINKGETREF_RELATIVE);
2176 ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2177 ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2178
2179 fnd_site = (IHlinkSite*)0xdeadbeef;
2180 fnd_data = 4;
2181 hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2182 ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
2183 ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
2184 ok(fnd_data == SITEDATA_SUCCESS, "Unexpected site data: %u\n", fnd_data);
2185
2186 IHlink_Release(cloned);
2187 IHlink_Release(hl);
2188
2189 IMoniker_Release(dummy);
2190 }
2191
test_StdHlink(void)2192 static void test_StdHlink(void)
2193 {
2194 IHlink *hlink;
2195 WCHAR *str;
2196 HRESULT hres;
2197
2198 static const WCHAR testW[] = {'t','e','s','t',0};
2199
2200 hres = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2201 &IID_IHlink, (void**)&hlink);
2202 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2203
2204 str = (void*)0xdeadbeef;
2205 hres = IHlink_GetTargetFrameName(hlink, &str);
2206 ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
2207 ok(!str, "str = %s\n", wine_dbgstr_w(str));
2208
2209 hres = IHlink_SetTargetFrameName(hlink, testW);
2210 ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
2211
2212 str = (void*)0xdeadbeef;
2213 hres = IHlink_GetTargetFrameName(hlink, &str);
2214 ok(hres == S_OK, "GetTargetFrameName failed: %08x\n", hres);
2215 ok(!lstrcmpW(str, testW), "str = %s\n", wine_dbgstr_w(str));
2216 CoTaskMemFree(str);
2217
2218 hres = IHlink_SetTargetFrameName(hlink, NULL);
2219 ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
2220
2221 str = (void*)0xdeadbeef;
2222 hres = IHlink_GetTargetFrameName(hlink, &str);
2223 ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
2224 ok(!str, "str = %s\n", wine_dbgstr_w(str));
2225
2226 IHlink_Release(hlink);
2227 }
2228
test_Hlink_Navigate(void)2229 static void test_Hlink_Navigate(void)
2230 {
2231 BINDINFO bind_info = {sizeof(BINDINFO)};
2232 DWORD bind_flags;
2233 IHlink *hlink;
2234 IBindCtx *pbc;
2235 HRESULT hres;
2236
2237 hres = CreateBindCtx(0, &pbc);
2238 ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2239 _bctx = pbc;
2240
2241 HBC_object = NULL;
2242
2243 SET_EXPECT(Reduce);
2244 SET_EXPECT(Enum);
2245 SET_EXPECT(IsSystemMoniker);
2246 SET_EXPECT(GetDisplayName);
2247 hres = HlinkCreateFromMoniker(&Moniker, NULL, NULL, NULL,
2248 0, NULL, &IID_IHlink, (void**)&hlink);
2249 ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2250 todo_wine CHECK_CALLED(Reduce);
2251 todo_wine CHECK_CALLED(Enum);
2252 todo_wine CHECK_CALLED(IsSystemMoniker);
2253 CHECK_CALLED(GetDisplayName);
2254
2255 SET_EXPECT(IsSystemMoniker);
2256 SET_EXPECT(GetDisplayName);
2257 SET_EXPECT(HBC_GetObject);
2258 SET_EXPECT(Reduce);
2259 SET_EXPECT(BindToObject);
2260 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2261 SET_EXPECT(HT_GetBrowseContext);
2262 SET_EXPECT(HT_SetBrowseContext);
2263 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2264 SET_EXPECT(HT_Navigate);
2265 SET_EXPECT(HT_GetFriendlyName);
2266 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2267 ok(hres == S_OK, "Navigate failed: %08x\n", hres);
2268 CHECK_CALLED(IsSystemMoniker);
2269 CHECK_CALLED(GetDisplayName);
2270 CHECK_CALLED(HBC_GetObject);
2271 todo_wine CHECK_CALLED(Reduce);
2272 CHECK_CALLED(BindToObject);
2273 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2274 todo_wine CHECK_CALLED(HT_GetBrowseContext);
2275 CHECK_CALLED(HT_SetBrowseContext);
2276 todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2277 CHECK_CALLED(HT_Navigate);
2278 todo_wine CHECK_CALLED(HT_GetFriendlyName);
2279
2280 /* Test with valid return from HlinkBrowseContext::GetObject */
2281 HBC_object = (IUnknown *)&HlinkTarget;
2282
2283 SET_EXPECT(IsSystemMoniker);
2284 SET_EXPECT(GetDisplayName);
2285 SET_EXPECT(HBC_GetObject);
2286 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2287 SET_EXPECT(HT_Navigate);
2288 SET_EXPECT(HT_GetFriendlyName);
2289 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2290 ok(hres == S_OK, "Navigate failed: %08x\n", hres);
2291 CHECK_CALLED(IsSystemMoniker);
2292 CHECK_CALLED(GetDisplayName);
2293 CHECK_CALLED(HBC_GetObject);
2294 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2295 CHECK_CALLED(HT_Navigate);
2296 todo_wine CHECK_CALLED(HT_GetFriendlyName);
2297
2298 HBC_object = NULL;
2299
2300 if (0) { /* these currently open a browser window on wine */
2301 /* Test from string */
2302 SET_EXPECT(HBC_GetObject);
2303 hres = HlinkNavigateToStringReference(winehq_404W, NULL, NULL, 0, NULL, 0, pbc, NULL, &HlinkBrowseContext);
2304 todo_wine ok(hres == INET_E_OBJECT_NOT_FOUND, "Expected INET_E_OBJECT_NOT_FOUND, got %08x\n", hres);
2305 CHECK_CALLED(HBC_GetObject);
2306
2307 /* MSDN claims browse context and bind context can't be null, but they can */
2308 SET_EXPECT(HBC_GetObject);
2309 hres = HlinkNavigateToStringReference(winehq_404W, NULL, NULL, 0, NULL, 0, NULL, NULL, &HlinkBrowseContext);
2310 todo_wine ok(hres == INET_E_OBJECT_NOT_FOUND, "Expected INET_E_OBJECT_NOT_FOUND, got %08x\n", hres);
2311 CHECK_CALLED(HBC_GetObject);
2312 }
2313
2314 /* these open a browser window, so mark them interactive only */
2315 if (winetest_interactive)
2316 {
2317 /* both parameters null */
2318 SET_EXPECT(IsSystemMoniker);
2319 SET_EXPECT(GetDisplayName);
2320 hres = IHlink_Navigate(hlink, 0, NULL, NULL, NULL);
2321 ok(hres == DRAGDROP_S_DROP, "Expected DRAGDROP_S_DROP, got %08x\n", hres);
2322 CHECK_CALLED(IsSystemMoniker);
2323 CHECK_CALLED(GetDisplayName);
2324
2325 /* same, from string */
2326 hres = HlinkNavigateToStringReference(winehq_404W, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL);
2327 ok(hres == DRAGDROP_S_DROP, "Expected DRAGDROP_S_DROP, got %08x\n", hres);
2328
2329 /* try basic test with valid URL */
2330 SET_EXPECT(HBC_GetObject);
2331 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2332 SET_EXPECT(HBC_QueryInterface_IMarshal);
2333 SET_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
2334 SET_EXPECT(HBC_QueryInterface_IUnknown);
2335 hres = HlinkNavigateToStringReference(winehq_urlW, NULL, NULL, 0, NULL, 0, pbc, NULL, &HlinkBrowseContext);
2336 ok(hres == S_OK, "Expected S_OK, got %08x\n", hres);
2337 CHECK_CALLED(HBC_GetObject);
2338 todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2339 todo_wine CHECK_CALLED(HBC_QueryInterface_IMarshal);
2340 todo_wine CHECK_CALLED(HBC_QueryInterface_IdentityUnmarshal);
2341 todo_wine CHECK_CALLED(HBC_QueryInterface_IUnknown);
2342 }
2343 else
2344 skip("interactive IHlink_Navigate tests\n");
2345
2346 /* test binding callback */
2347 SET_EXPECT(IsSystemMoniker);
2348 SET_EXPECT(GetDisplayName);
2349 SET_EXPECT(BindStatusCallback_GetBindInfo);
2350 SET_EXPECT(HBC_GetObject);
2351 SET_EXPECT(Reduce);
2352 SET_EXPECT(BindToObject);
2353 SET_EXPECT(BindStatusCallback_OnStartBinding);
2354 SET_EXPECT(BindStatusCallback_OnObjectAvailable);
2355 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2356 SET_EXPECT(HT_GetBrowseContext);
2357 SET_EXPECT(HT_SetBrowseContext);
2358 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2359 SET_EXPECT(HT_Navigate);
2360 SET_EXPECT(HT_GetFriendlyName);
2361 SET_EXPECT(BindStatusCallback_OnStopBinding);
2362 hres = IHlink_Navigate(hlink, 0, pbc, &BindStatusCallback, &HlinkBrowseContext);
2363 ok(hres == S_OK, "Navigate failed: %#x\n", hres);
2364 CHECK_CALLED(IsSystemMoniker);
2365 CHECK_CALLED(GetDisplayName);
2366 CHECK_CALLED(HBC_GetObject);
2367 todo_wine
2368 CHECK_CALLED(BindStatusCallback_GetBindInfo);
2369 todo_wine
2370 CHECK_CALLED(Reduce);
2371 CHECK_CALLED(BindToObject);
2372 todo_wine {
2373 CHECK_CALLED(BindStatusCallback_OnStartBinding);
2374 CHECK_CALLED(BindStatusCallback_OnObjectAvailable);
2375 }
2376 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2377 todo_wine
2378 CHECK_CALLED(HT_GetBrowseContext);
2379 CHECK_CALLED(HT_SetBrowseContext);
2380 todo_wine
2381 CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2382 CHECK_CALLED(HT_Navigate);
2383 todo_wine
2384 CHECK_CALLED(HT_GetFriendlyName);
2385 todo_wine
2386 CHECK_CALLED(BindStatusCallback_OnStopBinding);
2387
2388 ok(bind_callback_refs == 1, "Got unexpected refcount %d.\n", bind_callback_refs);
2389 ok(browse_ctx_refs == 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2390
2391 /* test asynchronous binding */
2392 async_bind = TRUE;
2393 SET_EXPECT(IsSystemMoniker);
2394 SET_EXPECT(GetDisplayName);
2395 SET_EXPECT(HBC_GetObject);
2396 SET_EXPECT(Reduce);
2397 SET_EXPECT(BindToObject);
2398 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2399 ok(hres == MK_S_ASYNCHRONOUS, "Navigate failed: %#x\n", hres);
2400 CHECK_CALLED(IsSystemMoniker);
2401 CHECK_CALLED(GetDisplayName);
2402 CHECK_CALLED(HBC_GetObject);
2403 todo_wine
2404 CHECK_CALLED(Reduce);
2405 CHECK_CALLED(BindToObject);
2406
2407 ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2408
2409 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2410 ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
2411
2412 hres = IBindStatusCallback_GetBindInfo(async_bind_callback, &bind_flags, &bind_info);
2413 ok(hres == S_OK, "Got hr %#x.\n", hres);
2414
2415 hres = IBindStatusCallback_OnStartBinding(async_bind_callback, 0, NULL);
2416 ok(hres == S_OK, "Got hr %#x.\n", hres);
2417
2418 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2419 SET_EXPECT(HT_GetBrowseContext);
2420 SET_EXPECT(HT_SetBrowseContext);
2421 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2422 SET_EXPECT(HT_Navigate);
2423 SET_EXPECT(HT_GetFriendlyName);
2424 hres = IBindStatusCallback_OnObjectAvailable(async_bind_callback, &IID_IUnknown,
2425 (IUnknown *)&HlinkTarget);
2426 ok(hres == S_OK, "Got hr %#x.\n", hres);
2427 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2428 todo_wine
2429 CHECK_CALLED(HT_GetBrowseContext);
2430 CHECK_CALLED(HT_SetBrowseContext);
2431 todo_wine
2432 CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2433 CHECK_CALLED(HT_Navigate);
2434 todo_wine
2435 CHECK_CALLED(HT_GetFriendlyName);
2436
2437 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2438 ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
2439
2440 ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2441
2442 hres = IBindStatusCallback_OnStopBinding(async_bind_callback, S_OK, NULL);
2443 ok(hres == S_OK, "Got hr %#x.\n", hres);
2444
2445 ok(browse_ctx_refs == 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2446
2447 IBindStatusCallback_Release(async_bind_callback);
2448
2449 SET_EXPECT(IsSystemMoniker);
2450 SET_EXPECT(GetDisplayName);
2451 SET_EXPECT(BindStatusCallback_GetBindInfo);
2452 SET_EXPECT(HBC_GetObject);
2453 SET_EXPECT(Reduce);
2454 SET_EXPECT(BindToObject);
2455 hres = IHlink_Navigate(hlink, 0, pbc, &BindStatusCallback, &HlinkBrowseContext);
2456 ok(hres == MK_S_ASYNCHRONOUS, "Navigate failed: %#x\n", hres);
2457 CHECK_CALLED(IsSystemMoniker);
2458 CHECK_CALLED(GetDisplayName);
2459 todo_wine
2460 CHECK_CALLED(BindStatusCallback_GetBindInfo);
2461 CHECK_CALLED(HBC_GetObject);
2462 todo_wine
2463 CHECK_CALLED(Reduce);
2464 CHECK_CALLED(BindToObject);
2465
2466 ok(bind_callback_refs > 1, "Got unexpected refcount %d.\n", bind_callback_refs);
2467 ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2468
2469 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2470 ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
2471
2472 SET_EXPECT(BindStatusCallback_GetBindInfo);
2473 hres = IBindStatusCallback_GetBindInfo(async_bind_callback, &bind_flags, &bind_info);
2474 ok(hres == E_NOTIMPL, "Got hr %#x.\n", hres);
2475 CHECK_CALLED(BindStatusCallback_GetBindInfo);
2476
2477 SET_EXPECT(BindStatusCallback_OnStartBinding);
2478 hres = IBindStatusCallback_OnStartBinding(async_bind_callback, 0, NULL);
2479 ok(hres == S_OK, "Got hr %#x.\n", hres);
2480 CHECK_CALLED(BindStatusCallback_OnStartBinding);
2481
2482 SET_EXPECT(BindStatusCallback_OnObjectAvailable);
2483 SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2484 SET_EXPECT(HT_GetBrowseContext);
2485 SET_EXPECT(HT_SetBrowseContext);
2486 SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2487 SET_EXPECT(HT_Navigate);
2488 SET_EXPECT(HT_GetFriendlyName);
2489 hres = IBindStatusCallback_OnObjectAvailable(async_bind_callback, &IID_IUnknown,
2490 (IUnknown *)&HlinkTarget);
2491 ok(hres == S_OK, "Got hr %#x.\n", hres);
2492 CHECK_CALLED(BindStatusCallback_OnObjectAvailable);
2493 CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2494 todo_wine
2495 CHECK_CALLED(HT_GetBrowseContext);
2496 CHECK_CALLED(HT_SetBrowseContext);
2497 todo_wine
2498 CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2499 CHECK_CALLED(HT_Navigate);
2500 todo_wine
2501 CHECK_CALLED(HT_GetFriendlyName);
2502
2503 hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2504 ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
2505
2506 ok(bind_callback_refs > 1, "Got unexpected refcount %d.\n", bind_callback_refs);
2507 ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2508
2509 SET_EXPECT(BindStatusCallback_OnStopBinding);
2510 hres = IBindStatusCallback_OnStopBinding(async_bind_callback, S_OK, NULL);
2511 ok(hres == S_OK, "Got hr %#x.\n", hres);
2512 CHECK_CALLED(BindStatusCallback_OnStopBinding);
2513
2514 ok(bind_callback_refs == 1, "Got unexpected refcount %d.\n", bind_callback_refs);
2515 ok(browse_ctx_refs == 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
2516
2517 IBindStatusCallback_Release(async_bind_callback);
2518
2519 IHlink_Release(hlink);
2520 IBindCtx_Release(pbc);
2521 _bctx = NULL;
2522 }
2523
hlinkframe_QueryInterface(IHlinkFrame * iface,REFIID riid,void ** obj)2524 static HRESULT WINAPI hlinkframe_QueryInterface(IHlinkFrame *iface, REFIID riid, void **obj)
2525 {
2526 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IHlinkFrame))
2527 {
2528 *obj = iface;
2529 return S_OK;
2530 }
2531
2532 *obj = NULL;
2533 return E_NOINTERFACE;
2534 }
2535
hlinkframe_AddRef(IHlinkFrame * iface)2536 static ULONG WINAPI hlinkframe_AddRef(IHlinkFrame *iface)
2537 {
2538 return 2;
2539 }
2540
hlinkframe_Release(IHlinkFrame * iface)2541 static ULONG WINAPI hlinkframe_Release(IHlinkFrame *iface)
2542 {
2543 return 1;
2544 }
2545
hlinkframe_SetBrowseContext(IHlinkFrame * iface,IHlinkBrowseContext * bc)2546 static HRESULT WINAPI hlinkframe_SetBrowseContext(IHlinkFrame *iface, IHlinkBrowseContext *bc)
2547 {
2548 ok(0, "unexpected %p\n", bc);
2549 return E_NOTIMPL;
2550 }
2551
hlinkframe_GetBrowseContext(IHlinkFrame * iface,IHlinkBrowseContext ** bc)2552 static HRESULT WINAPI hlinkframe_GetBrowseContext(IHlinkFrame *iface, IHlinkBrowseContext **bc)
2553 {
2554 *bc = NULL;
2555 ok(0, "unexpected %p\n", bc);
2556 return E_NOTIMPL;
2557 }
2558
hlinkframe_Navigate(IHlinkFrame * iface,DWORD grfHLNF,LPBC pbc,IBindStatusCallback * bsc,IHlink * navigate)2559 static HRESULT WINAPI hlinkframe_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc, IBindStatusCallback *bsc, IHlink *navigate)
2560 {
2561 ok(0, "unexpected\n");
2562 return E_NOTIMPL;
2563 }
2564
hlinkframe_OnNavigate(IHlinkFrame * iface,DWORD grfHLNF,IMoniker * target,LPCWSTR location,LPCWSTR friendly_name,DWORD reserved)2565 static HRESULT WINAPI hlinkframe_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name,
2566 DWORD reserved)
2567 {
2568 ok(0, "unexpected\n");
2569 return E_NOTIMPL;
2570 }
2571
hlinkframe_UpdateHlink(IHlinkFrame * iface,ULONG uHLID,IMoniker * target,LPCWSTR location,LPCWSTR friendly_name)2572 static HRESULT WINAPI hlinkframe_UpdateHlink(IHlinkFrame *iface, ULONG uHLID, IMoniker *target, LPCWSTR location, LPCWSTR friendly_name)
2573 {
2574 CHECK_EXPECT(HLF_UpdateHlink);
2575 return S_OK;
2576 }
2577
2578 static IHlinkFrameVtbl hlinkframevtbl = {
2579 hlinkframe_QueryInterface,
2580 hlinkframe_AddRef,
2581 hlinkframe_Release,
2582 hlinkframe_SetBrowseContext,
2583 hlinkframe_GetBrowseContext,
2584 hlinkframe_Navigate,
2585 hlinkframe_OnNavigate,
2586 hlinkframe_UpdateHlink
2587 };
2588
2589 static IHlinkFrame testframe = { &hlinkframevtbl };
2590
test_HlinkUpdateStackItem(void)2591 static void test_HlinkUpdateStackItem(void)
2592 {
2593 static const WCHAR location[] = {'l','o','c','a','t','i','o','n',0};
2594 HRESULT hr;
2595
2596 hr = HlinkUpdateStackItem(NULL, NULL, HLID_CURRENT, &Moniker, location, NULL);
2597 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2598
2599 SET_EXPECT(HBC_UpdateHlink);
2600 hr = HlinkUpdateStackItem(NULL, &HlinkBrowseContext, HLID_CURRENT, &Moniker, location, NULL);
2601 ok(hr == S_OK, "got 0x%08x\n", hr);
2602 CHECK_CALLED(HBC_UpdateHlink);
2603
2604 SET_EXPECT(HLF_UpdateHlink);
2605 hr = HlinkUpdateStackItem(&testframe, &HlinkBrowseContext, HLID_CURRENT, &Moniker, location, NULL);
2606 ok(hr == S_OK, "got 0x%08x\n", hr);
2607 CHECK_CALLED(HLF_UpdateHlink);
2608 }
2609
START_TEST(hlink)2610 START_TEST(hlink)
2611 {
2612 CoInitialize(NULL);
2613
2614 test_HlinkIsShortcut();
2615 test_reference();
2616 test_persist();
2617 test_special_reference();
2618 test_HlinkCreateExtensionServices();
2619 test_HlinkParseDisplayName();
2620 test_HlinkResolveMonikerForData();
2621 test_HlinkGetSetMonikerReference();
2622 test_HlinkGetSetStringReference();
2623 test_HlinkMoniker();
2624 test_HashLink();
2625 test_HlinkSite();
2626 test_HlinkClone();
2627 test_StdHlink();
2628 test_Hlink_Navigate();
2629 test_HlinkUpdateStackItem();
2630
2631 CoUninitialize();
2632 }
2633