2 * Implementation of hyperlinking (hlink.dll)
4 * Copyright 2006 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/test.h"
30 static void test_HlinkIsShortcut(void)
35 static const WCHAR file0
[] = {'f','i','l','e',0};
36 static const WCHAR file1
[] = {'f','i','l','e','.','u','r','l',0};
37 static const WCHAR file2
[] = {'f','i','l','e','.','l','n','k',0};
38 static const WCHAR file3
[] = {'f','i','l','e','.','u','R','l',0};
39 static const WCHAR file4
[] = {'f','i','l','e','u','r','l',0};
40 static const WCHAR file5
[] = {'c',':','\\','f','i','l','e','.','u','r','l',0};
41 static const WCHAR file6
[] = {'c',':','\\','f','i','l','e','.','l','n','k',0};
42 static const WCHAR file7
[] = {'.','u','r','l',0};
59 for(i
=0; i
<sizeof(shortcut_test
)/sizeof(shortcut_test
[0]); i
++) {
60 hres
= HlinkIsShortcut(shortcut_test
[i
].file
);
61 ok(hres
== shortcut_test
[i
].hres
, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
62 i
, hres
, shortcut_test
[i
].hres
);
66 static void test_reference(void)
71 const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
72 const WCHAR url2
[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',0 };
75 r
= HlinkCreateFromString(url
, NULL
, NULL
, NULL
,
76 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
77 ok(r
== S_OK
, "failed to create link\n");
81 r
= IHlink_GetMonikerReference(lnk
, HLINKGETREF_DEFAULT
, NULL
, NULL
);
82 ok(r
== S_OK
, "failed\n");
84 r
= IHlink_GetMonikerReference(lnk
, HLINKGETREF_DEFAULT
, &mk
, &str
);
85 ok(r
== S_OK
, "failed\n");
86 ok(mk
!= NULL
, "no moniker\n");
87 ok(str
== NULL
, "string should be null\n");
89 r
= IMoniker_Release(mk
);
90 ok( r
== 1, "moniker refcount wrong\n");
92 r
= IHlink_GetStringReference(lnk
, -1, &str
, NULL
);
93 ok(r
== S_OK
, "failed\n");
95 r
= IHlink_GetStringReference(lnk
, HLINKGETREF_DEFAULT
, &str
, NULL
);
96 ok(r
== S_OK
, "failed\n");
98 ok(!lstrcmpW(str
, url2
), "url wrong\n");
102 r
= IHlink_GetStringReference(lnk
, HLINKGETREF_DEFAULT
, NULL
, NULL
);
103 ok(r
== S_OK
, "failed\n");
105 r
= IHlink_GetStringReference(lnk
, HLINKGETREF_DEFAULT
, NULL
, &str
);
106 ok(r
== S_OK
, "failed\n");
107 ok(str
== NULL
, "string should be null\n");
111 static const unsigned char expected_hlink_data
[] =
113 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
114 0xe0,0xc9,0xea,0x79,0xf9,0xba,0xce,0x11,
115 0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b,
116 0x26,0x00,0x00,0x00,0x68,0x00,0x74,0x00,
117 0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,
118 0x2f,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,
119 0x65,0x00,0x68,0x00,0x71,0x00,0x2e,0x00,
120 0x6f,0x00,0x72,0x00,0x67,0x00,0x2f,0x00,
124 /* url + friendly name */
125 static const unsigned char expected_hlink_data2
[] =
127 0x02,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
128 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
129 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
130 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
131 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
132 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
133 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
134 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
135 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
136 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
137 0x67,0x00,0x2f,0x00,0x00,0x00,
140 /* url + friendly name + location */
141 static const unsigned char expected_hlink_data3
[] =
143 0x02,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,
144 0x08,0x00,0x00,0x00,0x57,0x00,0x69,0x00,
145 0x6e,0x00,0x65,0x00,0x20,0x00,0x48,0x00,
146 0x51,0x00,0x00,0x00,0xe0,0xc9,0xea,0x79,
147 0xf9,0xba,0xce,0x11,0x8c,0x82,0x00,0xaa,
148 0x00,0x4b,0xa9,0x0b,0x26,0x00,0x00,0x00,
149 0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,
150 0x3a,0x00,0x2f,0x00,0x2f,0x00,0x77,0x00,
151 0x69,0x00,0x6e,0x00,0x65,0x00,0x68,0x00,
152 0x71,0x00,0x2e,0x00,0x6f,0x00,0x72,0x00,
153 0x67,0x00,0x2f,0x00,0x00,0x00,0x07,0x00,
154 0x00,0x00,0x5f,0x00,0x62,0x00,0x6c,0x00,
155 0x61,0x00,0x6e,0x00,0x6b,0x00,0x00,0x00,
159 static const unsigned char expected_hlink_data4
[] =
161 0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
162 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
163 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
164 0x00,0x00,0x0b,0x00,0x00,0x00,0x69,0x6e,
165 0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,
166 0x00,0xff,0xff,0xad,0xde,0x00,0x00,0x00,
167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 0x00,0x00,0x00,0x00,0x00,
172 /* url + target frame name */
173 static const unsigned char expected_hlink_data5
[] =
175 0x02,0x00,0x00,0x00,0x83,0x00,0x00,0x00,
176 0x07,0x00,0x00,0x00,0x74,0x00,0x67,0x00,
177 0x74,0x00,0x66,0x00,0x72,0x00,0x6d,0x00,
178 0x00,0x00,0xe0,0xc9,0xea,0x79,0xf9,0xba,
179 0xce,0x11,0x8c,0x82,0x00,0xaa,0x00,0x4b,
180 0xa9,0x0b,0x26,0x00,0x00,0x00,0x68,0x00,
181 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
182 0x2f,0x00,0x2f,0x00,0x77,0x00,0x69,0x00,
183 0x6e,0x00,0x65,0x00,0x68,0x00,0x71,0x00,
184 0x2e,0x00,0x6f,0x00,0x72,0x00,0x67,0x00,
189 static const unsigned char expected_hlink_data6
[] =
191 0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
192 0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
193 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
194 0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x3a,
195 0x5c,0x00,0xff,0xff,0xad,0xde,0x00,0x00,
196 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
197 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
198 0x00,0x00,0x0c,0x00,0x00,0x00,0x06,0x00,
199 0x00,0x00,0x03,0x00,0x63,0x00,0x3a,0x00,
203 static void test_persist_save_data(const char *testname
, IHlink
*lnk
,
204 const unsigned char *expected_data
,
205 unsigned int expected_data_size
)
212 const unsigned char *data
;
216 hr
= IHlink_QueryInterface(lnk
, &IID_IPersistStream
, (void **)&ps
);
217 ok(hr
== S_OK
, "IHlink_QueryInterface failed with error 0x%08x\n", hr
);
219 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
220 ok(hr
== S_OK
, "CreateStreamOnHGlobal failed with error 0x%08x\n", hr
);
222 hr
= IPersistStream_Save(ps
, stream
, TRUE
);
223 ok(hr
== S_OK
, "IPersistStream_Save failed with error 0x%08x\n", hr
);
225 hr
= GetHGlobalFromStream(stream
, &hglobal
);
226 ok(hr
== S_OK
, "GetHGlobalFromStream failed with error 0x%08x\n", hr
);
228 data_size
= GlobalSize(hglobal
);
230 data
= GlobalLock(hglobal
);
232 /* first check we have the right amount of data */
233 ok(data_size
== expected_data_size
,
234 "%s: Size of saved data differs (expected %d, actual %d)\n",
235 testname
, expected_data_size
, data_size
);
238 /* then do a byte-by-byte comparison */
239 for (i
= 0; i
< min(data_size
, expected_data_size
); i
++)
241 if ((expected_data
[i
] != data
[i
]) &&
242 (((expected_data
!= expected_hlink_data2
) &&
243 (expected_data
!= expected_hlink_data3
)) ||
244 ((i
< 52 || i
>= 56) && (i
< 80 || i
>= 84))))
251 ok(same
, "%s: Saved data differs\n", testname
);
254 for (i
= 0; i
< data_size
; i
++)
256 if (i
% 8 == 0) printf(" ");
257 printf("0x%02x,", data
[i
]);
258 if (i
% 8 == 7) printf("\n");
263 GlobalUnlock(hglobal
);
265 IStream_Release(stream
);
266 IPersistStream_Release(ps
);
269 static void test_persist(void)
271 static const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0 };
272 static const WCHAR rel_url
[] = { 'i','n','d','e','x','.','h','t','m','l',0 };
273 static const WCHAR filename
[] = { 'c',':','\\',0 };
274 static const WCHAR friendly_name
[] = { 'W','i','n','e',' ','H','Q',0 };
275 static const WCHAR location
[] = { '_','b','l','a','n','k',0 };
276 static const WCHAR target_frame_name
[] = { 't','g','t','f','r','m',0 };
280 hr
= HlinkCreateFromString(url
, NULL
, NULL
, NULL
,
281 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
282 ok(hr
== S_OK
, "IHlinCreateFromString failed with error 0x%08x\n", hr
);
283 test_persist_save_data("url only", lnk
, expected_hlink_data
, sizeof(expected_hlink_data
));
286 hr
= HlinkCreateFromString(url
, NULL
, friendly_name
, NULL
,
287 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
288 ok(hr
== S_OK
, "IHlinCreateFromString failed with error 0x%08x\n", hr
);
289 test_persist_save_data("url + friendly name", lnk
, expected_hlink_data2
, sizeof(expected_hlink_data2
));
292 hr
= HlinkCreateFromString(url
, location
, friendly_name
, NULL
,
293 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
294 ok(hr
== S_OK
, "IHlinCreateFromString failed with error 0x%08x\n", hr
);
295 test_persist_save_data("url + friendly_name + location", lnk
, expected_hlink_data3
, sizeof(expected_hlink_data3
));
298 hr
= HlinkCreateFromString(rel_url
, NULL
, NULL
, NULL
,
299 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
300 ok(hr
== S_OK
, "IHlinCreateFromString failed with error 0x%08x\n", hr
);
301 test_persist_save_data("relative url", lnk
, expected_hlink_data4
, sizeof(expected_hlink_data4
));
304 hr
= HlinkCreateFromString(url
, NULL
, NULL
, NULL
,
305 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
306 ok(hr
== S_OK
, "IHlinCreateFromString failed with error 0x%08x\n", hr
);
307 hr
= IHlink_SetTargetFrameName(lnk
, target_frame_name
);
308 ok(hr
== S_OK
, "IHlink_SetTargetFrameName failed with error 0x%08x\n", hr
);
309 test_persist_save_data("url + target frame name", lnk
, expected_hlink_data5
, sizeof(expected_hlink_data5
));
312 hr
= HlinkCreateFromString(filename
, NULL
, NULL
, NULL
,
313 0, NULL
, &IID_IHlink
, (LPVOID
*) &lnk
);
314 ok(hr
== S_OK
, "IHlinCreateFromString failed with error 0x%08x\n", hr
);
315 test_persist_save_data("filename", lnk
, expected_hlink_data6
, sizeof(expected_hlink_data6
));
319 static void test_special_reference(void)
324 hres
= HlinkGetSpecialReference(HLSR_HOME
, &ref
);
326 ok(hres
== S_OK
, "HlinkGetSpecialReference(HLSR_HOME) failed: %08x\n", hres
);
328 ok(ref
!= NULL
, "ref == NULL\n");
331 hres
= HlinkGetSpecialReference(HLSR_SEARCHPAGE
, &ref
);
333 ok(hres
== S_OK
, "HlinkGetSpecialReference(HLSR_SEARCHPAGE) failed: %08x\n", hres
);
335 ok(ref
!= NULL
, "ref == NULL\n");
338 ref
= (void*)0xdeadbeef;
339 hres
= HlinkGetSpecialReference(HLSR_HISTORYFOLDER
, &ref
);
340 ok(hres
== E_NOTIMPL
, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres
);
341 ok(ref
== NULL
, "ref=%p\n", ref
);
343 ref
= (void*)0xdeadbeef;
344 hres
= HlinkGetSpecialReference(4, &ref
);
345 ok(hres
== E_INVALIDARG
, "HlinkGetSpecialReference(HLSR_HISTORYFOLDER) failed: %08x\n", hres
);
346 ok(ref
== NULL
, "ref=%p\n", ref
);
353 test_HlinkIsShortcut();
356 test_special_reference();