ReactOS  0.4.12-dev-432-g3463b2d
hlink.c
Go to the documentation of this file.
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);
60 
61 DEFINE_EXPECT(ComposeWith);
62 DEFINE_EXPECT(OnNavigationComplete);
64 DEFINE_EXPECT(Reduce);
65 
66 DEFINE_EXPECT(GetClassID);
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_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
85 DEFINE_GUID(IID_IHlinkHistory,0x79eac9c8,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b);
86 
87 static const WCHAR winehq_urlW[] =
88  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
89  '/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
90 static const WCHAR winehq_404W[] =
91  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
92  '/','t','e','s','t','s','/','f','a','k','e','u','r','l',0};
93 
94 static void test_HlinkIsShortcut(void)
95 {
96  UINT i;
97  HRESULT hres;
98 
99  static const WCHAR file0[] = {'f','i','l','e',0};
100  static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
101  static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
102  static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
103  static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
104  static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
105  static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
106  static const WCHAR file7[] = {'.','u','r','l',0};
107 
108  static struct {
109  LPCWSTR file;
110  HRESULT hres;
111  } shortcut_test[] = {
112  {file0, S_FALSE},
113  {file1, S_OK},
114  {file2, S_FALSE},
115  {file3, S_OK},
116  {file4, S_FALSE},
117  {file5, S_OK},
118  {file6, S_FALSE},
119  {file7, S_OK},
120  {NULL, E_INVALIDARG}
121  };
122 
123  for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
124  hres = HlinkIsShortcut(shortcut_test[i].file);
125  ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
126  i, hres, shortcut_test[i].hres);
127  }
128 }
129 
130 static void test_reference(void)
131 {
132  HRESULT r;
133  IHlink *lnk = NULL;
134  IMoniker *mk = NULL;
135  const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
136  const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
137  LPWSTR str = NULL;
138 
140  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
141  ok(r == S_OK, "failed to create link\n");
142  if (FAILED(r))
143  return;
144 
145  r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
146  ok(r == S_OK, "failed\n");
147 
148  r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
149  ok(r == S_OK, "failed\n");
150  ok(mk != NULL, "no moniker\n");
151  ok(str == NULL, "string should be null\n");
152 
153  r = IMoniker_Release(mk);
154  ok( r == 1, "moniker refcount wrong\n");
155 
156  r = IHlink_GetStringReference(lnk, -1, &str, NULL);
157  ok(r == S_OK, "failed\n");
159 
160  r = IHlink_GetStringReference(lnk, -1, NULL, NULL);
161  ok(r == S_OK, "failed, r=%08x\n", r);
162 
163  r = IHlink_GetStringReference(lnk, -1, NULL, &str);
164  ok(r == S_OK, "failed, r=%08x\n", r);
165  ok(str == NULL, "string should be null\n");
166 
167  r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
168  ok(r == S_OK, "failed\n");
169  ok(!lstrcmpW(str, url2), "url wrong\n");
171 
172  r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
173  ok(r == S_OK, "failed\n");
174 
175  r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
176  ok(r == S_OK, "failed\n");
177  ok(str == NULL, "string should be null\n");
178 
179  /* Unimplented functions checks */
180  r = IHlink_GetAdditionalParams(lnk, NULL);
181  ok(r == E_NOTIMPL, "failed\n");
182 
183  r = IHlink_SetAdditionalParams(lnk, NULL);
184  ok(r == E_NOTIMPL, "failed\n");
185 
186  IHlink_Release(lnk);
187 }
188 
189 /* url only */
190 static const unsigned char expected_hlink_data[] =
191 {
192  0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
193  0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
194  0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
195  0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
196  0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
197  0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
198  0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
199  0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
200  0x00,0x00,
201 };
202 
203 /* url only (IE7) */
204 static const unsigned char expected_hlink_data_ie7[] =
205 {
206  0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
207  0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
208  0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
209  0x3e,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
210  0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
211  0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
212  0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
213  0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
214  0x00,0x00,0x79,0x58,0x81,0xf4,0x3b,0x1d,
215  0x7f,0x48,0xaf,0x2c,0x82,0x5d,0xc4,0x85,
216  0x27,0x63,0x00,0x00,0x00,0x00,0xa5,0xab,
217  0x00,0x00,
218 };
219 
220 /* url + friendly name */
221 static const unsigned char expected_hlink_data2[] =
222 {
223  0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
224  0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
225  0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
226  0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
227  0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
228  0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
229  0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
230  0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
231  0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
232  0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
233  0x67,0x00,0x2f,0x00,0x00,0x00,
234 };
235 
236 /* url + friendly name (IE7) */
237 static const unsigned char expected_hlink_data2_ie7[] =
238 {
239  0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
240  0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
241  0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
242  0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
243  0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
244  0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
245  0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
246  0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
247  0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
248  0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
249  0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
250  0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
251  0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
252  0x00,0x00,0xa5,0xab,0x00,0x00,
253 };
254 
255 /* url + friendly name + location */
256 static const unsigned char expected_hlink_data3[] =
257 {
258  0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
259  0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
260  0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
261  0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
262  0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
263  0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
264  0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
265  0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
266  0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
267  0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
268  0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
269  0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
270  0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
271 };
272 
273 /* url + friendly name + location (IE7) */
274 static const unsigned char expected_hlink_data3_ie7[] =
275 {
276  0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
277  0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
278  0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
279  0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
280  0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
281  0x00,0x4b,0xa9,0x0b,0x3e,0x00,0x00,0x00,
282  0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
283  0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
284  0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
285  0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
286  0x67,0x00,0x2f,0x00,0x00,0x00,0x79,0x58,
287  0x81,0xf4,0x3b,0x1d,0x7f,0x48,0xaf,0x2c,
288  0x82,0x5d,0xc4,0x85,0x27,0x63,0x00,0x00,
289  0x00,0x00,0xa5,0xab,0x00,0x00,0x07,0x00,
290  0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
291  0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
292 };
293 
294 /* relative url */
295 static const unsigned char expected_hlink_data4[] =
296 {
297  0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
298  0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
299  0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
300  0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
301  0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
302  0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
303  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
304  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
305  0x00,0x00,0x00,0x00,0x00,
306 };
307 
308 /* url + target frame name */
309 static const unsigned char expected_hlink_data5[] =
310 {
311  0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
312  0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
313  0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
314  0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
315  0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
316  0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
317  0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
318  0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
319  0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
320  0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
321  0x2f,0x00,0x00,0x00,
322 };
323 
324 /* url + target frame name (IE7) */
325 static const unsigned char expected_hlink_data5_ie7[] =
326 {
327  0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
328  0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
329  0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
330  0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
331  0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
332  0xa9,0x0b,0x3e,0x00,0x00,0x00,0x68,0x00,
333  0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
334  0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
335  0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
336  0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
337  0x2f,0x00,0x00,0x00,0x79,0x58,0x81,0xf4,
338  0x3b,0x1d,0x7f,0x48,0xaf,0x2c,0x82,0x5d,
339  0xc4,0x85,0x27,0x63,0x00,0x00,0x00,0x00,
340  0xa5,0xab,0x00,0x00,
341 };
342 
343 /* filename */
344 static const unsigned char expected_hlink_data6[] =
345 {
346  0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
347  0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
348  0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
349  0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
350  0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
351  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
352  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
353  0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
354  0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
355  0x5c,0x00,
356 };
357 
358 static void test_persist_save_data(const char *testname, IHlink *lnk,
359  const unsigned char *expected_data,
360  unsigned int expected_data_size,
361  const unsigned char *expected_data_alt,
362  unsigned int expected_data_alt_size)
363 {
364  HRESULT hr;
365  IStream *stream;
366  IPersistStream *ps;
367  HGLOBAL hglobal;
368  DWORD data_size;
369  const unsigned char *data;
370  DWORD i;
371  BOOL same;
372 
373  hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
374  ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
375 
377  ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
378 
379  hr = IPersistStream_Save(ps, stream, TRUE);
380  ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
381 
382  hr = GetHGlobalFromStream(stream, &hglobal);
383  ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
384 
385  data_size = GlobalSize(hglobal);
386 
387  data = GlobalLock(hglobal);
388 
389  /* first check we have the right amount of data */
390  ok((data_size == expected_data_size) ||
391  (data_size == expected_data_alt_size),
392  "%s: Size of saved data differs (expected %d or %d, actual %d)\n",
393  testname, expected_data_size, expected_data_alt_size, data_size);
394 
395  same = TRUE;
396  /* then do a byte-by-byte comparison */
397  for (i = 0; i < min(data_size, expected_data_size); i++)
398  {
399  if ((expected_data[i] != data[i]) &&
400  (((expected_data != expected_hlink_data2) &&
401  (expected_data != expected_hlink_data3)) ||
402  ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
403  {
404  same = FALSE;
405  break;
406  }
407  }
408 
409  if (!same && (expected_data_alt != expected_data))
410  {
411  /* then try the alternate data */
412  same = TRUE;
413  for (i = 0; i < min(data_size, expected_data_alt_size); i++)
414  {
415  if ((expected_data_alt == expected_hlink_data_ie7 && i == 89) /* Win10 */ ||
416  (expected_data_alt == expected_hlink_data2_ie7 && i == 109) /* Win10 */ ||
417  (expected_data_alt == expected_hlink_data3_ie7 && i == 109) /* Win10 */ ||
418  (expected_data_alt == expected_hlink_data5_ie7 && i == 107) /* Win10 */)
419  {
420  ok(data[i] == 0 || broken(data[i] == 1) || broken(data[i] == 3),
421  "Expected 0 or 1, got %d\n", data[i]);
422  continue;
423  }
424  if ((expected_data_alt[i] != data[i]) &&
425  (((expected_data_alt != expected_hlink_data2) &&
426  (expected_data_alt != expected_hlink_data3)) ||
427  ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
428  {
429  same = FALSE;
430  break;
431  }
432  }
433  }
434 
435  ok(same, "%s: Saved data differs\n", testname);
436  if (!same)
437  {
438  for (i = 0; i < data_size; i++)
439  {
440  if (i % 8 == 0) printf(" ");
441  printf("0x%02x,", data[i]);
442  if (i % 8 == 7) printf("\n");
443  }
444  printf("\n");
445  }
446 
447  GlobalUnlock(hglobal);
448 
449  IStream_Release(stream);
450  IPersistStream_Release(ps);
451 }
452 
453 static void test_persist(void)
454 {
455  static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
456  static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
457  static const WCHAR filename[] = { 'c',':','\\',0 };
458  static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
459  static const WCHAR location[] = { '_','b','l','a','n','k',0 };
460  static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
461  HRESULT hr;
462  IHlink *lnk;
463 
465  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
466  ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
467  if (!lnk) {
468  skip("Can't create lnk, skipping test_persist.\n");
469  return;
470  }
471  test_persist_save_data("url only", lnk,
474  IHlink_Release(lnk);
475 
477  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
478  ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
479  test_persist_save_data("url + friendly name", lnk,
482  IHlink_Release(lnk);
483 
485  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
486  ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
487  test_persist_save_data("url + friendly_name + location", lnk,
490  IHlink_Release(lnk);
491 
493  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
494  ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
495  test_persist_save_data("relative url", lnk,
498  IHlink_Release(lnk);
499 
501  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
502  ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
503  hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
504  ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
505  test_persist_save_data("url + target frame name", lnk,
508  IHlink_Release(lnk);
509 
511  0, NULL, &IID_IHlink, (LPVOID*) &lnk);
512  ok(hr == S_OK, "HlinkCreateFromString failed with error 0x%08x\n", hr);
513  test_persist_save_data("filename", lnk,
516  IHlink_Release(lnk);
517 }
518 
519 static void test_special_reference(void)
520 {
521  LPWSTR ref;
522  HRESULT hres;
523 
525  ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
526  ok(ref != NULL, "ref == NULL\n");
528 
530  ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
531  ok(ref != NULL, "ref == NULL\n");
533 
534  ref = (void*)0xdeadbeef;
536  ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
537  ok(ref == NULL, "ref=%p\n", ref);
538 
539  ref = (void*)0xdeadbeef;
541  ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
542  ok(ref == NULL, "ref=%p\n", ref);
543 }
544 
546 {
547  IAuthenticate *authenticate;
550  HWND hwnd;
551  HRESULT hres;
552 
553  static const WCHAR usernameW[] = {'u','s','e','r',0};
554  static const WCHAR passwordW[] = {'p','a','s','s',0};
555  static const WCHAR headersW[] = {'h','e','a','d','e','r','s',0};
556  static const WCHAR headersexW[] = {'h','e','a','d','e','r','s','\r','\n',0};
557 
559  NULL, &IID_IAuthenticate, (void**)&authenticate);
560  ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
561  ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
562 
563  password = username = (void*)0xdeadbeef;
564  hwnd = (void*)0xdeadbeef;
565  hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
566  ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
567  ok(!hwnd, "hwnd != NULL\n");
568  ok(!username, "username != NULL\n");
569  ok(!password, "password != NULL\n");
570 
571  hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
572  ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
573 
574  headers = (void*)0xdeadbeef;
575  hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
576  0, &headers);
577  ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
578  ok(headers == NULL, "headers != NULL\n");
579 
580  hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
581  0, NULL);
582  ok(hres == E_INVALIDARG, "BeginningTransaction failed: %08x, expected E_INVALIDARG\n", hres);
583 
584  headers = (void*)0xdeadbeef;
585  hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
586  ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
587  ok(headers == NULL, "headers != NULL\n");
588 
589  IHttpNegotiate_Release(http_negotiate);
590  IAuthenticate_Release(authenticate);
591 
592 
593  hres = HlinkCreateExtensionServices(headersW, (HWND)0xfefefefe, usernameW, passwordW,
594  NULL, &IID_IAuthenticate, (void**)&authenticate);
595  ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
596  ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
597 
598  password = username = NULL;
599  hwnd = NULL;
600  hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
601  ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
602  ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
603  ok(!lstrcmpW(username, usernameW), "unexpected username\n");
604  ok(!lstrcmpW(password, passwordW), "unexpected password\n");
607 
608  password = username = (void*)0xdeadbeef;
609  hwnd = (void*)0xdeadbeef;
610  hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
611  ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
612  ok(password == (void*)0xdeadbeef, "password = %p\n", password);
613  ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
614 
615  hres = IAuthenticate_QueryInterface(authenticate, &IID_IHttpNegotiate, (void**)&http_negotiate);
616  ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
617 
618  headers = (void*)0xdeadbeef;
619  hres = IHttpNegotiate_BeginningTransaction(http_negotiate, (void*)0xdeadbeef, (void*)0xdeadbeef,
620  0, &headers);
621  ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
622  ok(!lstrcmpW(headers, headersexW), "unexpected headers %s\n", wine_dbgstr_w(headers));
624 
625  headers = (void*)0xdeadbeef;
626  hres = IHttpNegotiate_OnResponse(http_negotiate, 200, (void*)0xdeadbeef, (void*)0xdeadbeef, &headers);
627  ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
628  ok(headers == NULL, "unexpected headers %s\n", wine_dbgstr_w(headers));
629 
630  IHttpNegotiate_Release(http_negotiate);
631  IAuthenticate_Release(authenticate);
632 }
633 
634 static void test_HlinkParseDisplayName(void)
635 {
636  IMoniker *mon = NULL;
637  LPWSTR name;
638  DWORD issys;
639  ULONG eaten = 0;
640  IBindCtx *bctx;
641  HRESULT hres;
642 
643  static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
644  static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
645  '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
646  '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
647  static const WCHAR file_urlW[] =
648  {'f','i','l','e',':','/','/','/','c',':','\\','f','i','l','e','.','t','x','t',0};
649 
650  CreateBindCtx(0, &bctx);
651 
652  hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
653  ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
654  ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
655  ok(mon != NULL, "mon == NULL\n");
656 
657  hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
658  ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
659  ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
661 
662  hres = IMoniker_IsSystemMoniker(mon, &issys);
663  ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
664  ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
665 
666  IMoniker_Release(mon);
667 
668  hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
669  ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
670  ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
671  ok(mon != NULL, "mon == NULL\n");
672 
673  hres = IMoniker_IsSystemMoniker(mon, &issys);
674  ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
675  ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
676 
677  IMoniker_Release(mon);
678 
679  hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
680  ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
681  ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
682  ok(mon != NULL, "mon == NULL\n");
683 
684  hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
685  ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
686  ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", wine_dbgstr_w(name));
688 
689  hres = IMoniker_IsSystemMoniker(mon, &issys);
690  ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
691  ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
692 
693  IMoniker_Release(mon);
694 
695  hres = HlinkParseDisplayName(bctx, file_urlW, FALSE, &eaten, &mon);
696  ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
697  ok(eaten == sizeof(file_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
698  ok(mon != NULL, "mon == NULL\n");
699 
700  hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
701  ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
702  ok(!lstrcmpW(name, file_urlW+8), "wrong display name %s\n", wine_dbgstr_w(name));
704 
705  hres = IMoniker_IsSystemMoniker(mon, &issys);
706  ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
707  ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys);
708 
709  IMoniker_Release(mon);
710  IBindCtx_Release(bctx);
711 }
712 
713 static IBindCtx *_bctx;
714 
716 {
717  ok(0, "unexpected call\n");
718  return E_NOINTERFACE;
719 }
720 
722 {
723  return 2;
724 }
725 
727 {
728  return 1;
729 }
730 
732  REFGUID guidService, REFIID riid, void **ppv)
733 {
734  ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
735  return E_NOINTERFACE;
736 }
737 
738 static IServiceProviderVtbl ServiceProviderVtbl = {
743 };
744 
746 
748 {
749  *ppv = NULL;
750 
751  if(IsEqualGUID(riid, &IID_IServiceProvider)) {
752  *ppv = &ServiceProvider;
753  return S_OK;
754  }
755 
756  ok(0, "unexpected interface %s\n", wine_dbgstr_guid(riid));
757  return E_NOINTERFACE;
758 }
759 
761 {
762  return 2;
763 }
764 
766 {
767  return 1;
768 }
769 
771  IBinding *pib)
772 {
773  ok(0, "unexpected call\n");
774  return E_NOTIMPL;
775 }
776 
778 {
779  ok(0, "unexpected call\n");
780  return E_NOTIMPL;
781 }
782 
784 {
785  ok(0, "unexpected call\n");
786  return E_NOTIMPL;
787 }
788 
790  ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
791 {
792  ok(0, "unexpected call\n");
793  return E_NOTIMPL;
794 }
795 
797 {
798  ok(0, "unexpected call\n");
799  return E_NOTIMPL;
800 }
801 
802 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
803 {
804  ok(0, "unexpected call\n");
805  return E_NOTIMPL;
806 }
807 
809  DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
810 {
811  ok(0, "unexpected call\n");
812  return E_NOTIMPL;
813 }
814 
816 {
817  ok(0, "unexpected call\n");
818  return E_NOTIMPL;
819 }
820 
821 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
833 };
834 
836 
838  IHlinkBrowseContext *iface, REFIID riid, void **ppv)
839 {
840  *ppv = NULL;
841 
842  if (IsEqualGUID(&IID_IHlinkHistory, riid))
843  CHECK_EXPECT(HBC_QueryInterface_IHlinkHistory);
844  else if (IsEqualGUID(&IID_IMarshal, riid))
845  CHECK_EXPECT2(HBC_QueryInterface_IMarshal);
847  CHECK_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
848  else if (IsEqualGUID(&IID_IUnknown, riid))
849  CHECK_EXPECT(HBC_QueryInterface_IUnknown);
850  else
851  ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
852 
853  return E_NOINTERFACE;
854 }
855 
857 {
858  return 2;
859 }
860 
862 {
863  return 1;
864 }
865 
867  DWORD reserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister)
868 {
869  ok(0, "unexpected call\n");
870  return E_NOTIMPL;
871 }
872 
874 
877  IMoniker *pimk, BOOL fBindIfRootRegistered, IUnknown **ppiunk)
878 {
879  IBindCtx *bctx;
880  WCHAR *name;
881  HRESULT hr;
882 
883  CHECK_EXPECT(HBC_GetObject);
884 
885  CreateBindCtx(0, &bctx);
886  hr = IMoniker_GetDisplayName(pimk, bctx, NULL, &name);
887  ok(hr == S_OK, "Failed to get display name, hr %#x.\n", hr);
888  ok(!lstrcmpW(winehq_urlW, name) || !lstrcmpW(winehq_404W, name), "got unexpected url\n");
890  IBindCtx_Release(bctx);
891 
892  ok(fBindIfRootRegistered == 1, "fBindIfRootRegistered = %x\n", fBindIfRootRegistered);
893 
894  *ppiunk = HBC_object;
895  return HBC_object ? S_OK : 0xdeadbeef;
896 }
897 
899 {
900  ok(0, "unexpected call\n");
901  return E_NOTIMPL;
902 }
903 
905  IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
906 {
907  ok(0, "unexpected call\n");
908  return E_NOTIMPL;
909 }
910 
912  IHlinkBrowseContext *iface, HLBWINFO *phlbwi)
913 {
914  ok(0, "unexpected call\n");
915  return E_NOTIMPL;
916 }
917 
919  IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
920 {
921  ok(0, "unexpected call\n");
922  return E_NOTIMPL;
923 }
924 
926  IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, ULONG *puHLID)
927 {
928  ok(0, "unexpected call\n");
929  return E_NOTIMPL;
930 }
931 
934 {
935  CHECK_EXPECT(HBC_UpdateHlink);
936  return S_OK;
937 }
938 
940  DWORD dwReserved, DWORD grfHLFNAMEF, IEnumHLITEM **ppienumhlitem)
941 {
942  ok(0, "unexpected call\n");
943  return E_NOTIMPL;
944 }
945 
947  DWORD grfHLQF, ULONG uHLID)
948 {
949  ok(0, "unexpected call\n");
950  return E_NOTIMPL;
951 }
952 
954  ULONG uHLID, IHlink **ppihl)
955 {
956  ok(0, "unexpected call\n");
957  return E_NOTIMPL;
958 }
959 
961  IHlinkBrowseContext *iface, ULONG uHLID)
962 {
963  ok(0, "unexpected call\n");
964  return E_NOTIMPL;
965 }
966 
968  IUnknown *piunkOuter, REFIID riid, IUnknown **ppiunkObj)
969 {
970  ok(0, "unexpected call\n");
971  return E_NOTIMPL;
972 }
973 
975 {
976  ok(0, "unexpected call\n");
977  return E_NOTIMPL;
978 }
979 
980 static IHlinkBrowseContextVtbl HlinkBrowseContextVtbl = {
998 };
999 
1001 
1003 {
1004  if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
1005  CHECK_EXPECT(HT_QueryInterface_IHlinkTarget);
1006  *ppv = iface;
1007  return S_OK;
1008  }
1009 
1010  ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid));
1011  return E_NOINTERFACE;
1012 }
1013 
1015 {
1016  return 2;
1017 }
1018 
1020 {
1021  return 1;
1022 }
1023 
1025  IHlinkBrowseContext *pihlbc)
1026 {
1027  CHECK_EXPECT(HT_SetBrowseContext);
1028 
1029  ok(pihlbc == &HlinkBrowseContext, "pihlbc != &HlinkBrowseContext (%p)\n", pihlbc);
1030  return S_OK;
1031 }
1032 
1034  IHlinkBrowseContext **ppihlbc)
1035 {
1036  CHECK_EXPECT(HT_GetBrowseContext);
1037 
1038  *ppihlbc = NULL;
1039  return S_OK;
1040 }
1041 
1043  DWORD grfHLNF, LPCWSTR pwzJumpLocation)
1044 {
1045  CHECK_EXPECT(HT_Navigate);
1046 
1047  ok(grfHLNF == 0, "grfHLNF = %x\n", grfHLNF);
1048  ok(pwzJumpLocation == NULL, "pwzJumpLocation = %s\n", wine_dbgstr_w(pwzJumpLocation));
1049  return S_OK;
1050 }
1051 
1053  LPCWSTR pwzLocation, DWORD dwAssign, IMoniker **ppimkLocation)
1054 {
1055  ok(0, "unexpected call\n");
1056  return E_NOTIMPL;
1057 }
1058 
1060  LPCWSTR pwzLocation, LPWSTR *ppwzFriendlyName)
1061 {
1062  CHECK_EXPECT(HT_GetFriendlyName);
1063  return E_NOTIMPL;
1064 }
1065 
1066 static IHlinkTargetVtbl HlinkTargetVtbl = {
1075 };
1076 
1078 
1080 {
1081  *ppv = NULL;
1082 
1083  ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid));
1084  return E_NOINTERFACE;
1085 }
1086 
1088 {
1089  return 2;
1090 }
1091 
1093 {
1094  return 1;
1095 }
1096 
1098 {
1099  CHECK_EXPECT(GetClassID);
1100  *pClassID = IID_IUnknown; /* not a valid CLSID */
1101  return S_OK;
1102 }
1103 
1105 {
1106  ok(0, "unexpected call\n");
1107  return E_NOTIMPL;
1108 }
1109 
1111 {
1112  ok(0, "unexpected call\n");
1113  return E_NOTIMPL;
1114 }
1115 
1116 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
1117 {
1118  CHECK_EXPECT(Save);
1119  return S_OK;
1120 }
1121 
1123 {
1124  ok(0, "unexpected call\n");
1125  return E_NOTIMPL;
1126 }
1127 
1129  REFIID riid, void **ppv)
1130 {
1131  CHECK_EXPECT(BindToObject);
1132 
1133  ok(pbc != _bctx, "pbc != _bctx\n");
1134  ok(pmkToLeft == NULL, "pmkToLeft = %p\n", pmkToLeft);
1135  ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1136  ok(ppv != NULL, "ppv == NULL\n");
1137  ok(*ppv == NULL, "*ppv = %p\n", *ppv);
1138 
1139  *ppv = &HlinkTarget;
1140  return S_OK;
1141 }
1142 
1144  REFIID riid, void **ppv)
1145 {
1146  IUnknown *unk;
1147  HRESULT hres;
1148 
1149  static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
1150 
1151  CHECK_EXPECT(BindToStorage);
1152 
1153  ok(pbc == _bctx, "pbc != _bctx\n");
1154  ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1155  ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
1156  ok(ppv != NULL, "ppv == NULL\n");
1157  ok(*ppv == NULL, "*ppv=%p\n", *ppv);
1158 
1159  hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
1160  ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
1161  ok(unk != NULL, "unk == NULL\n");
1162 
1163  IUnknown_Release(unk);
1164 
1165  return S_OK;
1166 }
1167 
1168 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
1169  IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
1170 {
1171  CHECK_EXPECT(Reduce);
1172  return E_NOTIMPL;
1173 }
1174 
1176  BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
1177 {
1178  ok(0, "unexpected call\n");
1179  return E_NOTIMPL;
1180 }
1181 
1182 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
1183 {
1184  CHECK_EXPECT(Enum);
1185  return E_NOTIMPL;
1186 }
1187 
1188 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
1189 {
1190  ok(0, "unexpected call\n");
1191  return E_NOTIMPL;
1192 }
1193 
1194 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
1195 {
1196  ok(0, "unexpected call\n");
1197  return E_NOTIMPL;
1198 }
1199 
1200 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1201  IMoniker *pmkNewlyRunning)
1202 {
1203  ok(0, "unexpected call\n");
1204  return E_NOTIMPL;
1205 }
1206 
1208  IMoniker *pmkToLeft, FILETIME *pFileTime)
1209 {
1210  ok(0, "unexpected call\n");
1211  return E_NOTIMPL;
1212 }
1213 
1215 {
1216  ok(0, "unexpected call\n");
1217  return E_NOTIMPL;
1218 }
1219 
1221  IMoniker **ppmkPrefix)
1222 {
1223  ok(0, "unexpected call\n");
1224  return E_NOTIMPL;
1225 }
1226 
1228  IMoniker **pmkRelPath)
1229 {
1230  ok(0, "unexpected call\n");
1231  return E_NOTIMPL;
1232 }
1233 
1235  IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
1236 {
1238 
1239  ok(pbc != NULL, "pbc == NULL\n");
1240  ok(pbc != _bctx, "pbc == _bctx\n");
1241  ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1242 
1243  *ppszDisplayName = CoTaskMemAlloc(sizeof(winehq_urlW));
1244  memcpy(*ppszDisplayName, winehq_urlW, sizeof(winehq_urlW));
1245  return S_OK;
1246 }
1247 
1249  IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
1250 {
1251  ok(0, "unexpected call\n");
1252  return E_NOTIMPL;
1253 }
1254 
1256 {
1257  CHECK_EXPECT2(IsSystemMoniker);
1258 
1259  *pdwMksys = MKSYS_URLMONIKER;
1260  return S_OK;
1261 }
1262 
1263 static IMonikerVtbl MonikerVtbl = {
1269  Moniker_Load,
1270  Moniker_Save,
1276  Moniker_Enum,
1278  Moniker_Hash,
1287 };
1288 
1289 static IMoniker Moniker = { &MonikerVtbl };
1290 
1292 {
1293  IBindCtx *bctx;
1294  HRESULT hres;
1295 
1296  CreateBindCtx(0, &bctx);
1297  _bctx = bctx;
1298 
1299  SET_EXPECT(IsSystemMoniker);
1301  SET_EXPECT(BindToStorage);
1302 
1304  ok(hres == S_OK, "HlinkResolveMonikerForData failed: %08x\n", hres);
1305 
1306  CHECK_CALLED(IsSystemMoniker);
1308  CHECK_CALLED(BindToStorage);
1309 
1310  IBindCtx_Release(bctx);
1311  _bctx = NULL;
1312 }
1313 
1315 {
1316  IMoniker *found_trgt, *dummy, *dummy2;
1317  IHlink *hlink;
1318  HRESULT hres;
1319  const WCHAR one[] = {'1',0};
1320  const WCHAR two[] = {'2',0};
1321  const WCHAR name[] = {'a',0};
1322  WCHAR *found_loc;
1323 
1324  /* create two dummy monikers to use as targets */
1326  ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1327 
1328  hres = CreateItemMoniker(two, two, &dummy2);
1329  ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
1330 
1331  /* create a new hlink: target => dummy, location => one */
1332  hres = HlinkCreateFromMoniker(dummy, one, name, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1333  ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1334 
1335  /* validate the target and location */
1336  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1337  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1338  ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1339  ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1340  IMoniker_Release(found_trgt);
1341  CoTaskMemFree(found_loc);
1342 
1343  /* set location => two */
1344  hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two);
1345  ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1346 
1347  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1348  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1349  ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1350  ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1351  IMoniker_Release(found_trgt);
1352  CoTaskMemFree(found_loc);
1353 
1354  /* set target => dummy2 */
1355  hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one);
1356  ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1357 
1358  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1359  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1360  ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1361  ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc));
1362  IMoniker_Release(found_trgt);
1363  CoTaskMemFree(found_loc);
1364 
1365  /* set target => dummy, location => one */
1366  hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, dummy, one);
1367  ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1368 
1369  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1370  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1371  ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1372  ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1373  IMoniker_Release(found_trgt);
1374  CoTaskMemFree(found_loc);
1375 
1376  /* no HLINKSETF flags */
1377  hres = IHlink_SetMonikerReference(hlink, 0, dummy2, two);
1378  ok(hres == E_INVALIDARG, "IHlink_SetMonikerReference should've failed with E_INVALIDARG (0x%08x), failed with 0x%08x\n", E_INVALIDARG, hres);
1379 
1380  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1381  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1382  ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1383  ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1384  IMoniker_Release(found_trgt);
1385  CoTaskMemFree(found_loc);
1386 
1387  /* invalid HLINKSETF flags */
1388  /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1389  if (0)
1390  IHlink_SetMonikerReference(hlink, 12, dummy2, two);
1391 
1392  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1393  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1394  ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
1395  ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1396  IMoniker_Release(found_trgt);
1397  CoTaskMemFree(found_loc);
1398 
1399  /* valid & invalid HLINKSETF flags */
1400  hres = IHlink_SetMonikerReference(hlink, 12 | HLINKSETF_TARGET, dummy2, two);
1401  ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1402 
1403  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1404  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1405  ok(found_trgt == dummy2, "Found target should've been %p, was: %p\n", dummy2, found_trgt);
1406  ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc));
1407  IMoniker_Release(found_trgt);
1408  CoTaskMemFree(found_loc);
1409 
1410  /* NULL args */
1411  hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, NULL, NULL);
1412  ok(hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1413 
1414  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
1415  ok(hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1416  ok(found_trgt == NULL, "Found target should've been %p, was: %p\n", NULL, found_trgt);
1417  ok(found_loc == NULL, "Found location should've been %s, was: %s\n", wine_dbgstr_w(NULL), wine_dbgstr_w(found_loc));
1418  if(found_trgt)
1419  IMoniker_Release(found_trgt);
1420 
1421  IHlink_Release(hlink);
1422  IMoniker_Release(dummy2);
1423  IMoniker_Release(dummy);
1424 
1425  SET_EXPECT(Reduce);
1426  SET_EXPECT(Enum);
1427  SET_EXPECT(IsSystemMoniker);
1430  &IID_IHlink, (void **)&hlink);
1431  ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1432 
1433  hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_ABSOLUTE,
1434  &found_trgt, &found_loc);
1435  ok(hres == S_OK, "CreateFromMoniker failed: %08x\n", hres);
1436  ok(found_trgt == &Moniker, "Got unexpected moniker: %p\n", found_trgt);
1437  ok(found_loc == NULL, "Got unexpected location: %p\n", found_loc);
1438  todo_wine CHECK_CALLED(Reduce);
1440  CHECK_CALLED(IsSystemMoniker);
1442 
1443  IHlink_Release(hlink);
1444 }
1445 
1447 {
1448  IHlink *link;
1449  static const WCHAR one[] = {'1',0};
1450  static const WCHAR two[] = {'2',0};
1451  static const WCHAR three[] = {'3',0};
1452  static const WCHAR empty[] = {0};
1453  WCHAR *fnd_tgt, *fnd_loc;
1454  HRESULT hres;
1455 
1456  /* create a new hlink: target => NULL, location => one */
1457  hres = HlinkCreateFromMoniker(NULL, one, empty, NULL, 0, NULL, &IID_IHlink, (void**)&link);
1458  ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
1459 
1460  /* test setting/getting location */
1461  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1462  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1463  ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1464  ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1465  CoTaskMemFree(fnd_tgt);
1466  CoTaskMemFree(fnd_loc);
1467 
1468  hres = IHlink_SetStringReference(link, HLINKSETF_LOCATION, one, two);
1469  ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1470 
1471  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1472  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1473  ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1474  ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1475  CoTaskMemFree(fnd_tgt);
1476  CoTaskMemFree(fnd_loc);
1477 
1478  hres = IHlink_SetStringReference(link, -HLINKSETF_LOCATION, two, one);
1479  ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1480 
1481  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1482  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1483  ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1484  ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1485  CoTaskMemFree(fnd_tgt);
1486  CoTaskMemFree(fnd_loc);
1487 
1488  /* test setting/getting target */
1489  hres = IHlink_SetStringReference(link, HLINKSETF_TARGET, two, three);
1490  ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1491 
1492  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1493  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1494  ok(!lstrcmpW(fnd_tgt, two), "Found target should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_tgt));
1495  ok(!lstrcmpW(fnd_loc, one), "Found location should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_loc));
1496  CoTaskMemFree(fnd_tgt);
1497  CoTaskMemFree(fnd_loc);
1498 
1499  hres = IHlink_SetStringReference(link, -HLINKSETF_TARGET, three, two);
1500  ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1501 
1502  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1503  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1504  ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1505  ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1506  CoTaskMemFree(fnd_tgt);
1507  CoTaskMemFree(fnd_loc);
1508 
1509  /* test setting/getting both */
1510  hres = IHlink_SetStringReference(link, HLINKSETF_TARGET | HLINKSETF_LOCATION, one, two);
1511  ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1512 
1513  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1514  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1515  ok(!lstrcmpW(fnd_tgt, one), "Found target should have been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(fnd_tgt));
1516  ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1517  CoTaskMemFree(fnd_tgt);
1518  CoTaskMemFree(fnd_loc);
1519 
1520  hres = IHlink_SetStringReference(link, -(HLINKSETF_TARGET | HLINKSETF_LOCATION), three, one);
1521  ok(hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1522 
1523  hres = IHlink_GetStringReference(link, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1524  ok(hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1525  ok(!lstrcmpW(fnd_tgt, three), "Found target should have been %s, was: %s\n", wine_dbgstr_w(three), wine_dbgstr_w(fnd_tgt));
1526  ok(!lstrcmpW(fnd_loc, two), "Found location should have been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(fnd_loc));
1527  CoTaskMemFree(fnd_tgt);
1528  CoTaskMemFree(fnd_loc);
1529 
1530  /* test invalid flags/params */
1531  hres = IHlink_GetStringReference(link, 4, &fnd_tgt, &fnd_loc);
1532  ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1533  "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1534  ok(fnd_tgt == NULL, "Found target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1535  ok(fnd_loc == NULL, "Found location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1536  CoTaskMemFree(fnd_tgt);
1537  CoTaskMemFree(fnd_loc);
1538 
1539  hres = IHlink_GetStringReference(link, -1, &fnd_tgt, NULL);
1540  todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1541  "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1542  CoTaskMemFree(fnd_tgt);
1543 
1544  hres = IHlink_GetStringReference(link, -1, NULL, NULL);
1545  ok(hres == S_OK, "failed, hres=%08x\n", hres);
1546 
1547  hres = IHlink_GetStringReference(link, -1, NULL, &fnd_loc);
1548  ok(hres == S_OK, "failed, hres=%08x\n", hres);
1549  CoTaskMemFree(fnd_loc);
1550 
1551  hres = IHlink_GetStringReference(link, -1, &fnd_tgt, &fnd_loc);
1552  todo_wine ok(hres == E_FAIL, "IHlink_GetStringReference should have failed "
1553  "with E_FAIL (0x%08x), instead: 0x%08x\n", E_FAIL, hres);
1554  CoTaskMemFree(fnd_tgt);
1555  CoTaskMemFree(fnd_loc);
1556 
1557  hres = IHlink_GetStringReference(link, -2, &fnd_tgt, &fnd_loc);
1558  ok(hres == E_INVALIDARG, "IHlink_GetStringReference should have failed "
1559  "with E_INVALIDARG (0x%08x), instead: 0x%08x\n", E_INVALIDARG, hres);
1560  CoTaskMemFree(fnd_tgt);
1561  CoTaskMemFree(fnd_loc);
1562 
1563  if (0)
1564  {
1565  /* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
1566  IHlink_SetStringReference(link, 4, NULL, NULL);
1567  IHlink_SetStringReference(link, -4, NULL, NULL);
1568  }
1569 
1570  IHlink_Release(link);
1571 }
1572 
1573 #define setStringRef(h,f,t,l) r_setStringRef(__LINE__,h,f,t,l)
1574 static void r_setStringRef(unsigned line, IHlink *hlink, DWORD flags, const WCHAR *tgt, const WCHAR *loc)
1575 {
1576  HRESULT hres;
1577  hres = IHlink_SetStringReference(hlink, flags, tgt, loc);
1578  ok_(__FILE__,line) (hres == S_OK, "IHlink_SetStringReference failed: 0x%08x\n", hres);
1579 }
1580 
1581 #define getStringRef(h,t,l) r_getStringRef(__LINE__,h,t,l)
1582 static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, const WCHAR *exp_loc)
1583 {
1584  HRESULT hres;
1585  WCHAR *fnd_tgt, *fnd_loc;
1586 
1587  hres = IHlink_GetStringReference(hlink, HLINKGETREF_DEFAULT, &fnd_tgt, &fnd_loc);
1588  ok_(__FILE__,line) (hres == S_OK, "IHlink_GetStringReference failed: 0x%08x\n", hres);
1589 
1590  if(exp_tgt)
1591  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));
1592  else
1593  ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
1594 
1595  if(exp_loc)
1596  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));
1597  else
1598  ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1599 
1600  CoTaskMemFree(fnd_tgt);
1601  CoTaskMemFree(fnd_loc);
1602 }
1603 
1604 #define setMonikerRef(h,f,t,l) r_setMonikerRef(__LINE__,h,f,t,l)
1605 static void r_setMonikerRef(unsigned line, IHlink *hlink, DWORD flags, IMoniker *tgt, const WCHAR *loc)
1606 {
1607  HRESULT hres;
1608  hres = IHlink_SetMonikerReference(hlink, flags, tgt, loc);
1609  ok_(__FILE__,line) (hres == S_OK, "IHlink_SetMonikerReference failed: 0x%08x\n", hres);
1610 }
1611 
1612 /* passing 0xFFFFFFFF as exp_tgt will return the retrieved target & not test it */
1613 #define getMonikerRef(h,t,l,r) r_getMonikerRef(__LINE__,h,t,l,r)
1614 static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt, const WCHAR *exp_loc, DWORD ref)
1615 {
1616  HRESULT hres;
1617  IMoniker *fnd_tgt;
1618  WCHAR *fnd_loc;
1619 
1620  hres = IHlink_GetMonikerReference(hlink, ref, &fnd_tgt, &fnd_loc);
1621  ok_(__FILE__,line) (hres == S_OK, "IHlink_GetMonikerReference failed: 0x%08x\n", hres);
1622 
1623  if(exp_loc)
1624  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));
1625  else
1626  ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
1627 
1628  CoTaskMemFree(fnd_loc);
1629 
1630  if(exp_tgt == (IMoniker*)0xFFFFFFFF)
1631  return fnd_tgt;
1632 
1633  ok_(__FILE__,line) (fnd_tgt == exp_tgt, "Found moniker target should have been %p, was: %p\n", exp_tgt, fnd_tgt);
1634 
1635  if(fnd_tgt)
1636  IMoniker_Release(fnd_tgt);
1637 
1638  return NULL;
1639 }
1640 
1641 static void test_HlinkMoniker(void)
1642 {
1643  IHlink *hlink;
1644  IMoniker *aMon, *file_mon;
1645  static const WCHAR emptyW[] = {0};
1646  static const WCHAR wordsW[] = {'w','o','r','d','s',0};
1647  static const WCHAR aW[] = {'a',0};
1648  static const WCHAR bW[] = {'b',0};
1649  HRESULT hres;
1650 
1651  hres = HlinkCreateFromString(NULL, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hlink);
1652  ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1653  getStringRef(hlink, NULL, NULL);
1654  getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1655 
1656  /* setting a string target creates a moniker reference */
1657  setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, aW, wordsW);
1658  getStringRef(hlink, aW, wordsW);
1659  aMon = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, wordsW, HLINKGETREF_RELATIVE);
1660  ok(aMon != NULL, "Moniker from %s target should not be NULL\n", wine_dbgstr_w(aW));
1661  if(aMon)
1662  IMoniker_Release(aMon);
1663 
1664  /* setting target & location to the empty string deletes the moniker
1665  * reference */
1666  setStringRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, emptyW, emptyW);
1667  getStringRef(hlink, NULL, NULL);
1668  getMonikerRef(hlink, NULL, NULL, HLINKGETREF_RELATIVE);
1669 
1670  /* setting a moniker target also sets the target string to that moniker's
1671  * display name */
1672  hres = CreateFileMoniker(bW, &file_mon);
1673  ok(hres == S_OK, "CreateFileMoniker failed: 0x%08x\n", hres);
1674 
1675  setMonikerRef(hlink, HLINKSETF_TARGET | HLINKSETF_LOCATION, file_mon, wordsW);
1676  getStringRef(hlink, bW, wordsW);
1677  getMonikerRef(hlink, file_mon, wordsW, HLINKGETREF_RELATIVE);
1678 
1679  IMoniker_Release(file_mon);
1680 
1681  IHlink_Release(hlink);
1682 }
1683 
1684 static void test_HashLink(void)
1685 {
1686  IHlink *hlink;
1687  IMoniker *pmk;
1688  const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
1689  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};
1690  const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
1691  const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
1692  const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
1693  const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
1694  const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
1695  HRESULT hres;
1696 
1697  /* simple single hash test */
1698  hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1699  ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1700  ok(hlink != NULL, "Didn't get an hlink\n");
1701 
1702  if(hlink){
1703  getStringRef(hlink, tgt_partW, loc_partW);
1704  pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1705  ok(pmk != NULL, "Found moniker should not be NULL\n");
1706  if(pmk)
1707  IMoniker_Release(pmk);
1708 
1709  setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
1710  getStringRef(hlink, hash_targetW, loc_partW);
1711 
1712  IHlink_Release(hlink);
1713  }
1714 
1715  /* two hashes in the target */
1716  hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1717  ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1718  ok(hlink != NULL, "Didn't get an hlink\n");
1719 
1720  if(hlink){
1721  getStringRef(hlink, tgt_partW, two_hash_loc_partW);
1722  pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW, HLINKGETREF_RELATIVE);
1723  ok(pmk != NULL, "Found moniker should not be NULL\n");
1724  if(pmk)
1725  IMoniker_Release(pmk);
1726 
1727  IHlink_Release(hlink);
1728  }
1729 
1730  /* target with hash plus a location string */
1731  hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1732  ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1733  ok(hlink != NULL, "Didn't get an hlink\n");
1734 
1735  if(hlink){
1736  getStringRef(hlink, tgt_partW, test_locW);
1737  pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW, HLINKGETREF_RELATIVE);
1738  ok(pmk != NULL, "Found moniker should not be NULL\n");
1739  if(pmk)
1740  IMoniker_Release(pmk);
1741 
1742  IHlink_Release(hlink);
1743  }
1744 
1745  /* target with hash containing no "target part" */
1746  hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
1747  ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
1748  ok(hlink != NULL, "Didn't get an hlink\n");
1749 
1750  if(hlink){
1751  getStringRef(hlink, NULL, loc_partW);
1752  pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW, HLINKGETREF_RELATIVE);
1753  ok(pmk == NULL, "Found moniker should be NULL\n");
1754  if(pmk)
1755  IMoniker_Release(pmk);
1756 
1757  IHlink_Release(hlink);
1758  }
1759 }
1760 
1761 static const WCHAR site_monikerW[] = {'S','I','T','E','_','M','O','N','I','K','E','R',0};
1762 static const WCHAR ref_monikerW[] = {'R','E','F','_','M','O','N','I','K','E','R',0};
1763 
1765  IBindCtx *pbc, IMoniker *toLeft, REFIID riid, void **obj)
1766 {
1767  ok(0, "BTS: %p %p %p %s %p\n", iface, pbc, toLeft, wine_dbgstr_guid(riid), obj);
1768  return E_NOTIMPL;
1769 }
1770 
1772  IMoniker *right, BOOL onlyIfNotGeneric, IMoniker **composite)
1773 {
1774  LPOLESTR rightName;
1775  HRESULT hres;
1776 
1777  ok(onlyIfNotGeneric == 0, "Expected onlyIfNotGeneric to be FALSE\n");
1778 
1779  CHECK_EXPECT(ComposeWith);
1780 
1781  hres = IMoniker_GetDisplayName(right, NULL, NULL, &rightName);
1782  ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1783  ok(!lstrcmpW(rightName, ref_monikerW),
1784  "Expected to get moniker set via SetMonikerReference, instead got: %s\n",
1785  wine_dbgstr_w(rightName));
1786  CoTaskMemFree(rightName);
1787 
1788  *composite = NULL;
1789 
1790  /* unlikely error code to verify this return result is used */
1791  return E_OUTOFMEMORY;
1792 }
1793 
1795  IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1796 {
1799  return S_OK;
1800 }
1801 
1803  IBindCtx *pbc, IMoniker *toLeft, LPOLESTR *displayName)
1804 {
1807  return S_OK;
1808 }
1809 
1811  DWORD *mksys)
1812 {
1813  return S_FALSE;
1814 }
1815 
1816 static IMonikerVtbl hls_site_MonikerVtbl = {
1822  Moniker_Load,
1823  Moniker_Save,
1829  Moniker_Enum,
1831  Moniker_Hash,
1840 };
1841 
1842 static IMonikerVtbl hls_ref_MonikerVtbl = {
1848  Moniker_Load,
1849  Moniker_Save,
1855  Moniker_Enum,
1857  Moniker_Hash,
1866 };
1867 
1870 
1872  void **obj)
1873 {
1874  ok(0, "QI: %p %s %p\n", iface, wine_dbgstr_guid(iid), obj);
1875  return E_NOTIMPL;
1876 }
1877 
1879 {
1880  return 2;
1881 }
1882 
1884 {
1885  return 1;
1886 }
1887 
1889  REFGUID service, REFIID riid, IUnknown **punk)
1890 {
1891  ok(0, "QS: %p %x %s %s %p\n", iface, siteData, wine_dbgstr_guid(service),
1892  wine_dbgstr_guid(riid), punk);
1893  return E_NOTIMPL;
1894 }
1895 
1896 #define SITEDATA_SUCCESS 1
1897 #define SITEDATA_NOTIMPL 2
1898 
1900  DWORD assign, DWORD which, IMoniker **pmk)
1901 {
1902  ok(siteData == SITEDATA_NOTIMPL ||
1903  siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1904 
1905  if(siteData == SITEDATA_SUCCESS){
1906  *pmk = &hls_site_Moniker;
1907  return S_OK;
1908  }
1909 
1910  return E_NOTIMPL;
1911 }
1912 
1914  DWORD reserved)
1915 {
1916  ok(0, "RTN: %p %x %x\n", iface, siteData, reserved);
1917  return E_NOTIMPL;
1918 }
1919 
1921  DWORD siteData, DWORD reserved, HRESULT error, LPCWSTR errorStr)
1922 {
1923  CHECK_EXPECT(OnNavigationComplete);
1924  ok(siteData == SITEDATA_SUCCESS, "Unexpected site data: %u\n", siteData);
1925  ok(error == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", error);
1926  return E_NOTIMPL;
1927 }
1928 
1929 static IHlinkSiteVtbl HlinkSiteVtbl = {
1931  hls_AddRef,
1932  hls_Release,
1937 };
1938 
1940 
1941 static void test_HlinkSite(void)
1942 {
1943  IHlink *hl;
1944  IMoniker *mon_ref;
1945  IBindCtx *pbc;
1946  HRESULT hres;
1947 
1949  &IID_IHlink, (LPVOID*)&hl);
1950  ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
1951  getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1952 
1953  hres = IHlink_SetHlinkSite(hl, &HlinkSite, SITEDATA_SUCCESS);
1954  ok(hres == S_OK, "SetHlinkSite failed: %08x\n", hres);
1955  getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
1956  getStringRef(hl, NULL, NULL);
1957 
1958  hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1959  ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1960  ok(mon_ref == NULL, "Didn't get expected moniker, instead: %p\n", mon_ref);
1961 
1962  hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1963  ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1964  ok(mon_ref == &hls_site_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1965 
1966  SET_EXPECT(Reduce);
1967  SET_EXPECT(Enum);
1968  hres = IHlink_SetMonikerReference(hl, HLINKSETF_TARGET, &hls_ref_Moniker, NULL);
1969  ok(hres == S_OK, "SetMonikerReference failed: %08x\n", hres);
1970  todo_wine CHECK_CALLED(Reduce);
1972 
1973  getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
1974 
1975  SET_EXPECT(Enum);
1978 
1979  hres = IHlink_GetMonikerReference(hl, HLINKGETREF_RELATIVE, &mon_ref, NULL);
1980  ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
1981  ok(mon_ref == &hls_ref_Moniker, "Didn't get expected moniker, instead: %p\n", mon_ref);
1982  IMoniker_Release(mon_ref);
1983 
1984  SET_EXPECT(ComposeWith);
1985  hres = IHlink_GetMonikerReference(hl, HLINKGETREF_ABSOLUTE, &mon_ref, NULL);
1986  ok(hres == E_OUTOFMEMORY, "Expected E_OUTOFMEMORY, got: %08x\n", hres);
1987  ok(mon_ref == NULL, "Shouldn't have got a Moniker, got: %p\n", mon_ref);
1988  CHECK_CALLED(ComposeWith);
1989 
1990  hres = CreateBindCtx(0, &pbc);
1991  ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1992 
1993  SET_EXPECT(ComposeWith);
1994  SET_EXPECT(OnNavigationComplete);
1995  hres = IHlink_Navigate(hl, 0, pbc, NULL, NULL);
1996  ok(hres == E_OUTOFMEMORY, "Navigate should've failed: %08x\n", hres);
1997  CHECK_CALLED(ComposeWith);
1998  CHECK_CALLED(OnNavigationComplete);
1999 
2000  IBindCtx_Release(pbc);
2001  IHlink_Release(hl);
2002 
2003  SET_EXPECT(Reduce);
2004  SET_EXPECT(Enum);
2006  NULL, &IID_IHlink, (LPVOID*)&hl);
2007  ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2008  todo_wine CHECK_CALLED(Reduce);
2010  getMonikerRef(hl, &hls_ref_Moniker, NULL, HLINKGETREF_RELATIVE);
2011  IHlink_Release(hl);
2012 
2014  NULL, &IID_IHlink, (LPVOID*)&hl);
2015  ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2016  getMonikerRef(hl, NULL, NULL, HLINKGETREF_RELATIVE);
2017  IHlink_Release(hl);
2018 
2019  SET_EXPECT(Reduce);
2020  SET_EXPECT(Enum);
2021  SET_EXPECT(IsSystemMoniker);
2024  NULL, &IID_IHlink, (LPVOID*)&hl);
2025  ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2026  getMonikerRef(hl, &Moniker, NULL, HLINKGETREF_ABSOLUTE);
2027  IHlink_Release(hl);
2028  todo_wine CHECK_CALLED(Reduce);
2030  CHECK_CALLED(IsSystemMoniker);
2032 }
2033 
2034 static void test_HlinkClone(void)
2035 {
2036  HRESULT hres;
2037  IHlink *hl, *cloned = NULL;
2038  IMoniker *dummy, *fnd_mk;
2039  IHlinkSite *fnd_site;
2040  WCHAR *fnd_name;
2041  DWORD fnd_data;
2042  const WCHAR one[] = {'1',0};
2043  const WCHAR two[] = {'2',0};
2044  const WCHAR name[] = {'a',0};
2045 
2046  hres = HlinkClone(NULL, NULL, NULL, 0, NULL);
2047  ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
2048 
2050  &IID_IHlink, (void**)&hl);
2051  ok(hres == S_OK, "HlinkCreateFromString failed: %08x\n", hres);
2052 
2053  hres = HlinkClone(hl, &IID_IHlink, NULL, 0, NULL);
2054  ok(hres == E_INVALIDARG, "Got wrong failure code: %08x\n", hres);
2055 
2056  if (0)
2057  {
2058  /* crash on Windows XP */
2059  HlinkClone(hl, NULL, NULL, 0, NULL);
2060 
2061  HlinkClone(hl, NULL, NULL, 0, (void**)&cloned);
2062  }
2063 
2064  hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2065  ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2066  ok(cloned != NULL, "Didn't get a clone\n");
2067  getMonikerRef(cloned, NULL, NULL, HLINKGETREF_RELATIVE);
2068  IHlink_Release(cloned);
2069 
2070  IHlink_Release(hl);
2071 
2072  SET_EXPECT(Reduce);
2073  SET_EXPECT(Enum);
2074  hres = HlinkCreateFromMoniker(&hls_ref_Moniker, two, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2075  todo_wine CHECK_CALLED(Reduce);
2077  ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2078  getMonikerRef(hl, &hls_ref_Moniker, two, HLINKGETREF_RELATIVE);
2079 
2080  SET_EXPECT(Save);
2081  SET_EXPECT(GetClassID);
2082  cloned = (IHlink*)0xdeadbeef;
2083  hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2084  /* fails because of invalid CLSID given by Moniker_GetClassID */
2085  ok(hres == REGDB_E_CLASSNOTREG, "Wrong error code: %08x\n", hres);
2086  ok(cloned == NULL, "Shouldn't have gotten a clone\n");
2087  CHECK_CALLED(Save);
2088  CHECK_CALLED(GetClassID);
2089 
2090  IHlink_Release(hl);
2091 
2093  ok(hres == S_OK, "CreateItemMoniker failed: 0x%08x\n", hres);
2094 
2095  hres = HlinkCreateFromMoniker(dummy, two, name, &HlinkSite, SITEDATA_SUCCESS, NULL, &IID_IHlink, (void**)&hl);
2096  ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2097  getMonikerRef(hl, dummy, two, HLINKGETREF_RELATIVE);
2098 
2099  cloned = NULL;
2100  hres = HlinkClone(hl, &IID_IHlink, NULL, 0, (void**)&cloned);
2101  ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2102  ok(cloned != NULL, "Should have gotten a clone\n");
2103 
2104  fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, two, HLINKGETREF_RELATIVE);
2105  ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2106  ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2107 
2108  fnd_name = NULL;
2109  hres = IHlink_GetFriendlyName(cloned, HLFNAMEF_DEFAULT, &fnd_name);
2110  ok(hres == S_OK, "GetFriendlyName failed: %08x\n", hres);
2111  ok(fnd_name != NULL, "Expected friendly name to be non-NULL\n");
2112  ok(lstrcmpW(fnd_name, name) == 0, "Expected friendly name to be %s, was %s\n",
2113  wine_dbgstr_w(name), wine_dbgstr_w(fnd_name));
2114  CoTaskMemFree(fnd_name);
2115 
2116  fnd_site = (IHlinkSite*)0xdeadbeef;
2117  fnd_data = 4;
2118  hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2119  ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
2120  ok(fnd_site == NULL, "Expected NULL site\n");
2121  ok(fnd_data == 4, "Expected site data to be 4, was: %d\n", fnd_data);
2122 
2123  IHlink_Release(cloned);
2124  IHlink_Release(hl);
2125 
2126  hres = HlinkCreateFromMoniker(dummy, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void**)&hl);
2127  ok(hres == S_OK, "HlinkCreateFromMoniker failed: 0x%08x\n", hres);
2128  getMonikerRef(hl, dummy, NULL, HLINKGETREF_RELATIVE);
2129 
2130  cloned = NULL;
2131  hres = HlinkClone(hl, &IID_IHlink, &HlinkSite, SITEDATA_SUCCESS, (void**)&cloned);
2132  ok(hres == S_OK, "HlinkClone failed: %08x\n", hres);
2133  ok(cloned != NULL, "Should have gotten a clone\n");
2134 
2135  fnd_mk = getMonikerRef(cloned, (IMoniker*)0xFFFFFFFF, NULL, HLINKGETREF_RELATIVE);
2136  ok(fnd_mk != NULL, "Expected non-null Moniker\n");
2137  ok(fnd_mk != dummy, "Expected a new Moniker to be created\n");
2138 
2139  fnd_site = (IHlinkSite*)0xdeadbeef;
2140  fnd_data = 4;
2141  hres = IHlink_GetHlinkSite(cloned, &fnd_site, &fnd_data);
2142  ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
2143  ok(fnd_site == &HlinkSite, "Expected found site to be HlinkSite, was: %p\n", fnd_site);
2144  ok(fnd_data == SITEDATA_SUCCESS, "Unexpected site data: %u\n", fnd_data);
2145 
2146  IHlink_Release(cloned);
2147  IHlink_Release(hl);
2148 
2149  IMoniker_Release(dummy);
2150 }
2151 
2152 static void test_StdHlink(void)
2153 {
2154  IHlink *hlink;
2155  WCHAR *str;
2156  HRESULT hres;
2157 
2158  static const WCHAR testW[] = {'t','e','s','t',0};
2159 
2160  hres = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2161  &IID_IHlink, (void**)&hlink);
2162  ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2163 
2164  str = (void*)0xdeadbeef;
2165  hres = IHlink_GetTargetFrameName(hlink, &str);
2166  ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
2167  ok(!str, "str = %s\n", wine_dbgstr_w(str));
2168 
2169  hres = IHlink_SetTargetFrameName(hlink, testW);
2170  ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
2171 
2172  str = (void*)0xdeadbeef;
2173  hres = IHlink_GetTargetFrameName(hlink, &str);
2174  ok(hres == S_OK, "GetTargetFrameName failed: %08x\n", hres);
2175  ok(!lstrcmpW(str, testW), "str = %s\n", wine_dbgstr_w(str));
2176  CoTaskMemFree(str);
2177 
2178  hres = IHlink_SetTargetFrameName(hlink, NULL);
2179  ok(hres == S_OK, "SetTargetFrameName failed: %08x\n", hres);
2180 
2181  str = (void*)0xdeadbeef;
2182  hres = IHlink_GetTargetFrameName(hlink, &str);
2183  ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
2184  ok(!str, "str = %s\n", wine_dbgstr_w(str));
2185 
2186  IHlink_Release(hlink);
2187 }
2188 
2189 static void test_Hlink_Navigate(void)
2190 {
2191  IHlink *hlink;
2192  IBindCtx *pbc;
2193  HRESULT hres;
2194 
2195  hres = CreateBindCtx(0, &pbc);
2196  ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2197  _bctx = pbc;
2198 
2199  HBC_object = NULL;
2200 
2201  SET_EXPECT(Reduce);
2202  SET_EXPECT(Enum);
2203  SET_EXPECT(IsSystemMoniker);
2206  0, NULL, &IID_IHlink, (void**)&hlink);
2207  ok(hres == S_OK, "HlinkCreateFromMoniker failed: %08x\n", hres);
2208  todo_wine CHECK_CALLED(Reduce);
2210  todo_wine CHECK_CALLED(IsSystemMoniker);
2212 
2213  SET_EXPECT(IsSystemMoniker);
2215  SET_EXPECT(HBC_GetObject);
2216  SET_EXPECT(Reduce);
2217  SET_EXPECT(BindToObject);
2218  SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2219  SET_EXPECT(HT_GetBrowseContext);
2220  SET_EXPECT(HT_SetBrowseContext);
2221  SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2222  SET_EXPECT(HT_Navigate);
2223  SET_EXPECT(HT_GetFriendlyName);
2224  hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2225  ok(hres == S_OK, "Navigate failed: %08x\n", hres);
2226  CHECK_CALLED(IsSystemMoniker);
2228  CHECK_CALLED(HBC_GetObject);
2229  todo_wine CHECK_CALLED(Reduce);
2230  CHECK_CALLED(BindToObject);
2231  CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2232  todo_wine CHECK_CALLED(HT_GetBrowseContext);
2233  CHECK_CALLED(HT_SetBrowseContext);
2234  todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2235  CHECK_CALLED(HT_Navigate);
2236  todo_wine CHECK_CALLED(HT_GetFriendlyName);
2237 
2238  /* Test with valid return from HlinkBrowseContext::GetObject */
2240 
2241  SET_EXPECT(IsSystemMoniker);
2243  SET_EXPECT(HBC_GetObject);
2244  SET_EXPECT(HT_QueryInterface_IHlinkTarget);
2245  SET_EXPECT(HT_Navigate);
2246  SET_EXPECT(HT_GetFriendlyName);
2247  hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
2248  ok(hres == S_OK, "Navigate failed: %08x\n", hres);
2249  CHECK_CALLED(IsSystemMoniker);
2251  CHECK_CALLED(HBC_GetObject);
2252  CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
2253  CHECK_CALLED(HT_Navigate);
2254  todo_wine CHECK_CALLED(HT_GetFriendlyName);
2255 
2256  HBC_object = NULL;
2257 
2258 if (0) { /* these currently open a browser window on wine */
2259  /* Test from string */
2260  SET_EXPECT(HBC_GetObject);
2262  todo_wine ok(hres == INET_E_OBJECT_NOT_FOUND, "Expected INET_E_OBJECT_NOT_FOUND, got %08x\n", hres);
2263  CHECK_CALLED(HBC_GetObject);
2264 
2265  /* MSDN claims browse context and bind context can't be null, but they can */
2266  SET_EXPECT(HBC_GetObject);
2268  todo_wine ok(hres == INET_E_OBJECT_NOT_FOUND, "Expected INET_E_OBJECT_NOT_FOUND, got %08x\n", hres);
2269  CHECK_CALLED(HBC_GetObject);
2270 }
2271 
2272  /* these open a browser window, so mark them interactive only */
2274  {
2275  /* both parameters null */
2276  SET_EXPECT(IsSystemMoniker);
2278  hres = IHlink_Navigate(hlink, 0, NULL, NULL, NULL);
2279  ok(hres == DRAGDROP_S_DROP, "Expected DRAGDROP_S_DROP, got %08x\n", hres);
2280  CHECK_CALLED(IsSystemMoniker);
2282 
2283  /* same, from string */
2285  ok(hres == DRAGDROP_S_DROP, "Expected DRAGDROP_S_DROP, got %08x\n", hres);
2286 
2287  /* try basic test with valid URL */
2288  SET_EXPECT(HBC_GetObject);
2289  SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
2290  SET_EXPECT(HBC_QueryInterface_IMarshal);
2291  SET_EXPECT(HBC_QueryInterface_IdentityUnmarshal);
2292  SET_EXPECT(HBC_QueryInterface_IUnknown);
2294  ok(hres == S_OK, "Expected S_OK, got %08x\n", hres);
2295  CHECK_CALLED(HBC_GetObject);
2296  todo_wine CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
2297  todo_wine CHECK_CALLED(HBC_QueryInterface_IMarshal);
2298  todo_wine CHECK_CALLED(HBC_QueryInterface_IdentityUnmarshal);
2299  todo_wine CHECK_CALLED(HBC_QueryInterface_IUnknown);
2300  }
2301  else
2302  skip("interactive IHlink_Navigate tests\n");
2303 
2304  IHlink_Release(hlink);
2305  IBindCtx_Release(pbc);
2306  _bctx = NULL;
2307 }
2308 
2310 {
2311  if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IHlinkFrame))
2312  {
2313  *obj = iface;
2314  return S_OK;
2315  }
2316 
2317  *obj = NULL;
2318  return E_NOINTERFACE;
2319 }
2320 
2322 {
2323  return 2;
2324 }
2325 
2327 {
2328  return 1;
2329 }
2330 
2332 {
2333  ok(0, "unexpected %p\n", bc);
2334  return E_NOTIMPL;
2335 }
2336 
2338 {
2339  *bc = NULL;
2340  ok(0, "unexpected %p\n", bc);
2341  return E_NOTIMPL;
2342 }
2343 
2345 {
2346  ok(0, "unexpected\n");
2347  return E_NOTIMPL;
2348 }
2349 
2351  DWORD reserved)
2352 {
2353  ok(0, "unexpected\n");
2354  return E_NOTIMPL;
2355 }
2356 
2358 {
2359  CHECK_EXPECT(HLF_UpdateHlink);
2360  return S_OK;
2361 }
2362 
2363 static IHlinkFrameVtbl hlinkframevtbl = {
2372 };
2373 
2375 
2376 static void test_HlinkUpdateStackItem(void)
2377 {
2378  static const WCHAR location[] = {'l','o','c','a','t','i','o','n',0};
2379  HRESULT hr;
2380 
2381  hr = HlinkUpdateStackItem(NULL, NULL, HLID_CURRENT, &Moniker, location, NULL);
2382  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2383 
2384  SET_EXPECT(HBC_UpdateHlink);
2386  ok(hr == S_OK, "got 0x%08x\n", hr);
2387  CHECK_CALLED(HBC_UpdateHlink);
2388 
2389  SET_EXPECT(HLF_UpdateHlink);
2391  ok(hr == S_OK, "got 0x%08x\n", hr);
2392  CHECK_CALLED(HLF_UpdateHlink);
2393 }
2394 
2396 {
2397  CoInitialize(NULL);
2398 
2400  test_reference();
2401  test_persist();
2409  test_HashLink();
2410  test_HlinkSite();
2411  test_HlinkClone();
2412  test_StdHlink();
2415 
2416  CoUninitialize();
2417 }
const CLSID CLSID_IdentityUnmarshal
WCHAR OLECHAR
Definition: compat.h:1926
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
#define E_NOINTERFACE
Definition: winerror.h:2364
const char * rel_url
Definition: protocol.c:463
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
#define error(str)
Definition: mkdosfs.c:1605
Definition: scsiwmi.h:51
BOOL GetDisplayName(LPCTSTR ServiceName)
Definition: name.c:12
interface IBindCtx * LPBC
Definition: objfwd.h:18
LPBATCH_CONTEXT bc
Definition: batch.c:66
__wchar_t WCHAR
Definition: xmlstorage.h:180
REFIID riid
Definition: precomp.h:44
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static GLenum which
Definition: wgl_font.c:159
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
REFIID LPVOID * ppv
Definition: atlbase.h:39
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const char * wine_dbgstr_guid(const GUID *guid)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
vector< Header * > headers
Definition: sdkparse.cpp:39
int winetest_interactive
char displayName[]
Definition: tftpd.cpp:35
const char * filename
Definition: ioapi.h:135
static LPOLESTR
Definition: stg_prop.c:33
#define E_FAIL
Definition: ddrawi.h:102
Definition: send.c:47
static const WCHAR url2[]
Definition: misc.c:300
static const WCHAR empty[]
Definition: task.c:29
static double one
Definition: j0_y0.c:80
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
long LONG
Definition: pedump.c:60
static double two
Definition: jn_yn.c:52
GLenum GLint ref
Definition: glext.h:6028
r reserved
Definition: btrfs.c:2655
HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, IMoniker **ppmk)
Definition: itemmoniker.c:936
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
#define S_FALSE
Definition: winerror.h:2357
static IBindStatusCallbackEx bsc
Definition: url.c:2149
static int Save(const char **args)
Definition: vfdcmd.c:1851
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
static const WCHAR aW[]
Definition: htmlelem.c:21
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
#define ok(value,...)
Definition: CComObject.cpp:34
static WCHAR username[]
Definition: url.c:32
unsigned int BOOL
Definition: ntddk_ex.h:94
HRESULT hres
Definition: protocol.c:465
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR url[]
Definition: encode.c:1432
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, IMoniker **ppmk)
Definition: filemoniker.c:1415
const GUID IID_IUnknown
const char file[]
Definition: icontest.c:11
unsigned int UINT
Definition: ndis.h:50
HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders, HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword, IUnknown *punkOuter, REFIID riid, void **ppv)
Definition: extserv.c:301
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble right
Definition: glext.h:10859
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
const GUID IID_IPersistStream
Definition: proxy.cpp:13
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define todo_wine
Definition: test.h:154
Definition: parse.h:22
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
GLuint GLuint stream
Definition: glext.h:7522
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
MIXER_STATUS Enum(IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR *DeviceName, OUT PHANDLE OutHandle, OUT PHANDLE OutKey)
Definition: mmixer.c:225
#define WINAPI
Definition: msvc.h:20
#define broken(x)
Definition: _sntprintf.h:21
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3237
#define S_OK
Definition: intsafe.h:59
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
static const WCHAR emptyW[]
Definition: navigate.c:36
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1994
unsigned char dummy
Definition: maze.c:118
static const WCHAR friendly_name[]
Definition: devenum.c:38
#define DRAGDROP_S_DROP
Definition: winerror.h:2646
#define skip(...)
Definition: CString.cpp:57
#define E_NOTIMPL
Definition: ddrawi.h:99
#define min(a, b)
Definition: monoChain.cc:55
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4024
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1900
Definition: name.c:36
static WCHAR BSCBHolder[]
Definition: url.c:158
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
static IHttpNegotiate2 http_negotiate
Definition: protocol.c:387
const WCHAR * link
Definition: db.cpp:926
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
static const WCHAR testW[]
Definition: jsregexp.c:44
#define ok_(x1, x2)
Definition: CString.cpp:56
#define printf
Definition: config.h:203
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031