push 97f44e0adb27fff75ba63d8fb97c65db9edfbe82
[wine/hacks.git] / dlls / hlink / tests / hlink.c
blob4a59f63f322a42f1f68ea3ec9adbbe391f5e3b89
1 /*
2 * Implementation of hyperlinking (hlink.dll)
4 * Copyright 2006 Mike McCormack
5 * Copyright 2007 Jacek Caban for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include <stdio.h>
26 #include <hlink.h>
27 #include <hlguids.h>
29 #include "wine/test.h"
31 static void test_HlinkIsShortcut(void)
33 int i;
34 HRESULT hres;
36 static const WCHAR file0[] = {'f','i','l','e',0};
37 static const WCHAR file1[] = {'f','i','l','e','.','u','r','l',0};
38 static const WCHAR file2[] = {'f','i','l','e','.','l','n','k',0};
39 static const WCHAR file3[] = {'f','i','l','e','.','u','R','l',0};
40 static const WCHAR file4[] = {'f','i','l','e','u','r','l',0};
41 static const WCHAR file5[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
42 static const WCHAR file6[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
43 static const WCHAR file7[] = {'.','u','r','l',0};
45 static struct {
46 LPCWSTR file;
47 HRESULT hres;
48 } shortcut_test[] = {
49 {file0, S_FALSE},
50 {file1, S_OK},
51 {file2, S_FALSE},
52 {file3, S_OK},
53 {file4, S_FALSE},
54 {file5, S_OK},
55 {file6, S_FALSE},
56 {file7, S_OK},
57 {NULL, E_INVALIDARG}
60 for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
61 hres = HlinkIsShortcut(shortcut_test[i].file);
62 ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
63 i, hres, shortcut_test[i].hres);
67 static void test_reference(void)
69 HRESULT r;
70 IHlink *lnk = NULL;
71 IMoniker *mk = NULL;
72 const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
73 const WCHAR url2[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
74 LPWSTR str = NULL;
76 r = HlinkCreateFromString(url, NULL, NULL, NULL,
77 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
78 ok(r == S_OK, "failed to create link\n");
79 if (FAILED(r))
80 return;
82 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
83 ok(r == S_OK, "failed\n");
85 r = IHlink_GetMonikerReference(lnk, HLINKGETREF_DEFAULT, &mk, &str);
86 ok(r == S_OK, "failed\n");
87 ok(mk != NULL, "no moniker\n");
88 ok(str == NULL, "string should be null\n");
90 r = IMoniker_Release(mk);
91 ok( r == 1, "moniker refcount wrong\n");
93 r = IHlink_GetStringReference(lnk, -1, &str, NULL);
94 ok(r == S_OK, "failed\n");
96 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, &str, NULL);
97 ok(r == S_OK, "failed\n");
98 todo_wine {
99 ok(!lstrcmpW(str, url2), "url wrong\n");
101 CoTaskMemFree(str);
103 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, NULL);
104 ok(r == S_OK, "failed\n");
106 r = IHlink_GetStringReference(lnk, HLINKGETREF_DEFAULT, NULL, &str);
107 ok(r == S_OK, "failed\n");
108 ok(str == NULL, "string should be null\n");
111 /* url only */
112 static const unsigned char expected_hlink_data[] =
114 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
115 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
116 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
117 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
118 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
119 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
120 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
121 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
122 0x00,0x00,
125 /* url + friendly name */
126 static const unsigned char expected_hlink_data2[] =
128 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
129 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
130 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
131 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
132 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
133 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
134 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
135 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
136 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
137 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
138 0x67,0x00,0x2f,0x00,0x00,0x00,
141 /* url + friendly name + location */
142 static const unsigned char expected_hlink_data3[] =
144 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
145 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
146 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
147 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
148 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
149 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
150 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
151 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
152 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
153 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
154 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
155 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
156 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
159 /* relative url */
160 static const unsigned char expected_hlink_data4[] =
162 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
163 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
164 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
165 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
166 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
167 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 0x00,0x00,0x00,0x00,0x00,
173 /* url + target frame name */
174 static const unsigned char expected_hlink_data5[] =
176 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
177 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
178 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
179 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
180 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
181 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
182 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
183 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
184 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
185 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
186 0x2f,0x00,0x00,0x00,
189 /* filename */
190 static const unsigned char expected_hlink_data6[] =
192 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
193 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
194 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
195 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
196 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
197 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
198 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
199 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
200 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
201 0x5c,0x00,
204 static void test_persist_save_data(const char *testname, IHlink *lnk,
205 const unsigned char *expected_data,
206 unsigned int expected_data_size)
208 HRESULT hr;
209 IStream *stream;
210 IPersistStream *ps;
211 HGLOBAL hglobal;
212 DWORD data_size;
213 const unsigned char *data;
214 DWORD i;
215 BOOL same;
217 hr = IHlink_QueryInterface(lnk, &IID_IPersistStream, (void **)&ps);
218 ok(hr == S_OK, "IHlink_QueryInterface failed with error 0x%08x\n", hr);
220 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
221 ok(hr == S_OK, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr);
223 hr = IPersistStream_Save(ps, stream, TRUE);
224 ok(hr == S_OK, "IPersistStream_Save failed with error 0x%08x\n", hr);
226 hr = GetHGlobalFromStream(stream, &hglobal);
227 ok(hr == S_OK, "GetHGlobalFromStream failed with error 0x%08x\n", hr);
229 data_size = GlobalSize(hglobal);
231 data = GlobalLock(hglobal);
233 /* first check we have the right amount of data */
234 ok(data_size == expected_data_size,
235 "%s: Size of saved data differs (expected %d, actual %d)\n",
236 testname, expected_data_size, data_size);
238 same = TRUE;
239 /* then do a byte-by-byte comparison */
240 for (i = 0; i < min(data_size, expected_data_size); i++)
242 if ((expected_data[i] != data[i]) &&
243 (((expected_data != expected_hlink_data2) &&
244 (expected_data != expected_hlink_data3)) ||
245 ((i < 52 || i >= 56) && (i < 80 || i >= 84))))
247 same = FALSE;
248 break;
252 ok(same, "%s: Saved data differs\n", testname);
253 if (!same)
255 for (i = 0; i < data_size; i++)
257 if (i % 8 == 0) printf(" ");
258 printf("0x%02x,", data[i]);
259 if (i % 8 == 7) printf("\n");
261 printf("\n");
264 GlobalUnlock(hglobal);
266 IStream_Release(stream);
267 IPersistStream_Release(ps);
270 static void test_persist(void)
272 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
273 static const WCHAR rel_url[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
274 static const WCHAR filename[] = { 'c',':','\\',0 };
275 static const WCHAR friendly_name[] = { 'W','i','n','e',' ','H','Q',0 };
276 static const WCHAR location[] = { '_','b','l','a','n','k',0 };
277 static const WCHAR target_frame_name[] = { 't','g','t','f','r','m',0 };
278 HRESULT hr;
279 IHlink *lnk;
281 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
282 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
283 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
284 test_persist_save_data("url only", lnk, expected_hlink_data, sizeof(expected_hlink_data));
285 IHlink_Release(lnk);
287 hr = HlinkCreateFromString(url, NULL, friendly_name, NULL,
288 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
289 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
290 test_persist_save_data("url + friendly name", lnk, expected_hlink_data2, sizeof(expected_hlink_data2));
291 IHlink_Release(lnk);
293 hr = HlinkCreateFromString(url, location, friendly_name, NULL,
294 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
295 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
296 test_persist_save_data("url + friendly_name + location", lnk, expected_hlink_data3, sizeof(expected_hlink_data3));
297 IHlink_Release(lnk);
299 hr = HlinkCreateFromString(rel_url, NULL, NULL, NULL,
300 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
301 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
302 test_persist_save_data("relative url", lnk, expected_hlink_data4, sizeof(expected_hlink_data4));
303 IHlink_Release(lnk);
305 hr = HlinkCreateFromString(url, NULL, NULL, NULL,
306 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
307 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
308 hr = IHlink_SetTargetFrameName(lnk, target_frame_name);
309 ok(hr == S_OK, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr);
310 test_persist_save_data("url + target frame name", lnk, expected_hlink_data5, sizeof(expected_hlink_data5));
311 IHlink_Release(lnk);
313 hr = HlinkCreateFromString(filename, NULL, NULL, NULL,
314 0, NULL, &IID_IHlink, (LPVOID*) &lnk);
315 ok(hr == S_OK, "IHlinCreateFromString failed with error 0x%08x\n", hr);
316 test_persist_save_data("filename", lnk, expected_hlink_data6, sizeof(expected_hlink_data6));
317 IHlink_Release(lnk);
320 static void test_special_reference(void)
322 LPWSTR ref;
323 HRESULT hres;
325 hres = HlinkGetSpecialReference(HLSR_HOME, &ref);
326 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres);
327 ok(ref != NULL, "ref == NULL\n");
328 CoTaskMemFree(ref);
330 hres = HlinkGetSpecialReference(HLSR_SEARCHPAGE, &ref);
331 ok(hres == S_OK, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres);
332 ok(ref != NULL, "ref == NULL\n");
333 CoTaskMemFree(ref);
335 ref = (void*)0xdeadbeef;
336 hres = HlinkGetSpecialReference(HLSR_HISTORYFOLDER, &ref);
337 ok(hres == E_NOTIMPL, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
338 ok(ref == NULL, "ref=%p\n", ref);
340 ref = (void*)0xdeadbeef;
341 hres = HlinkGetSpecialReference(4, &ref);
342 ok(hres == E_INVALIDARG, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres);
343 ok(ref == NULL, "ref=%p\n", ref);
346 static void test_HlinkCreateExtensionServices(void)
348 IAuthenticate *authenticate;
349 LPWSTR password, username;
350 HWND hwnd;
351 HRESULT hres;
353 static const WCHAR usernameW[] = {'u','s','e','r',0};
354 static const WCHAR passwordW[] = {'p','a','s','s',0};
356 hres = HlinkCreateExtensionServices(NULL, NULL, NULL, NULL,
357 NULL, &IID_IAuthenticate, (void**)&authenticate);
358 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
359 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
361 password = username = (void*)0xdeadbeef;
362 hwnd = (void*)0xdeadbeef;
363 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
364 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
365 ok(!hwnd, "hwnd != NULL\n");
366 ok(!username, "username != NULL\n");
367 ok(!password, "password != NULL\n");
369 IAuthenticate_Release(authenticate);
372 hres = HlinkCreateExtensionServices(NULL, (HWND)0xfefefefe, usernameW, passwordW,
373 NULL, &IID_IAuthenticate, (void**)&authenticate);
374 ok(hres == S_OK, "HlinkCreateExtensionServices failed: %08x\n", hres);
375 ok(authenticate != NULL, "HlinkCreateExtensionServices returned NULL\n");
377 password = username = NULL;
378 hwnd = NULL;
379 hres = IAuthenticate_Authenticate(authenticate, &hwnd, &username, &password);
380 ok(hres == S_OK, "Authenticate failed: %08x\n", hres);
381 ok(hwnd == (HWND)0xfefefefe, "hwnd=%p\n", hwnd);
382 ok(!lstrcmpW(username, usernameW), "unexpected username\n");
383 ok(!lstrcmpW(password, passwordW), "unexpected password\n");
384 CoTaskMemFree(username);
385 CoTaskMemFree(password);
387 password = username = (void*)0xdeadbeef;
388 hwnd = (void*)0xdeadbeef;
389 hres = IAuthenticate_Authenticate(authenticate, &hwnd, NULL, &password);
390 ok(hres == E_INVALIDARG, "Authenticate failed: %08x\n", hres);
391 ok(password == (void*)0xdeadbeef, "password = %p\n", password);
392 ok(hwnd == (void*)0xdeadbeef, "hwnd = %p\n", hwnd);
394 IAuthenticate_Release(authenticate);
397 START_TEST(hlink)
399 CoInitialize(NULL);
401 test_HlinkIsShortcut();
402 test_reference();
403 test_persist();
404 test_special_reference();
405 test_HlinkCreateExtensionServices();
407 CoUninitialize();