2 * Unit tests to document InternetShortcut's behaviour
4 * Copyright 2008 Damjan Jovanovic
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
40 #include "wine/test.h"
42 static HRESULT WINAPI
Unknown_QueryInterface(IUnknown
*pUnknown
, REFIID riid
, void **ppvObject
)
44 if (IsEqualGUID(&IID_IUnknown
, riid
))
46 *ppvObject
= pUnknown
;
52 static ULONG WINAPI
Unknown_AddRef(IUnknown
*pUnknown
)
57 static ULONG WINAPI
Unknown_Release(IUnknown
*pUnknown
)
62 static IUnknownVtbl unknownVtbl
= {
63 Unknown_QueryInterface
,
68 static IUnknown unknown
= {
72 static void test_Aggregability(void)
75 IUnknown
*pUnknown
= NULL
;
77 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUnknown
, (void**)&pUnknown
);
78 ok(hr
== S_OK
, "could not create instance of CLSID_InternetShortcut with IID_IUnknown, hr = 0x%lx\n", hr
);
80 IUnknown_Release(pUnknown
);
82 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUniformResourceLocatorA
, (void**)&pUnknown
);
83 ok(hr
== S_OK
, "could not create instance of CLSID_InternetShortcut with IID_IUniformResourceLocatorA, hr = 0x%lx\n", hr
);
85 IUnknown_Release(pUnknown
);
87 hr
= CoCreateInstance(&CLSID_InternetShortcut
, &unknown
, CLSCTX_ALL
, &IID_IUnknown
, (void**)&pUnknown
);
88 ok(hr
== CLASS_E_NOAGGREGATION
, "aggregation didn't fail like it should, hr = 0x%lx\n", hr
);
90 IUnknown_Release(pUnknown
);
93 static void can_query_interface(IUnknown
*pUnknown
, REFIID riid
)
96 IUnknown
*newInterface
;
97 hr
= IUnknown_QueryInterface(pUnknown
, riid
, (void**)&newInterface
);
98 ok(hr
== S_OK
, "interface %s could not be queried\n", wine_dbgstr_guid(riid
));
100 IUnknown_Release(newInterface
);
103 static void test_QueryInterface(void)
108 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUnknown
, (void**)&pUnknown
);
109 ok(hr
== S_OK
, "Could not create InternetShortcut object: %08lx\n", hr
);
111 can_query_interface(pUnknown
, &IID_IUniformResourceLocatorA
);
112 can_query_interface(pUnknown
, &IID_IUniformResourceLocatorW
);
113 can_query_interface(pUnknown
, &IID_IPersistFile
);
114 IUnknown_Release(pUnknown
);
117 #define test_shortcut_url(a,b) _test_shortcut_url(__LINE__,a,b)
118 static void _test_shortcut_url(unsigned line
, IUnknown
*unk
, const char *exurl
)
120 IUniformResourceLocatorA
*locator_a
;
124 hres
= IUnknown_QueryInterface(unk
, &IID_IUniformResourceLocatorA
, (void**)&locator_a
);
125 ok_(__FILE__
,line
)(hres
== S_OK
, "Could not get IUniformResourceLocatorA iface: %08lx\n", hres
);
127 hres
= locator_a
->lpVtbl
->GetURL(locator_a
, &url_a
);
128 ok_(__FILE__
,line
)(hres
== S_OK
, "GetURL failed: %08lx\n", hres
);
129 ok_(__FILE__
,line
)(!strcmp(url_a
, exurl
), "unexpected URL, got %s, expected %s\n", url_a
, exurl
);
130 CoTaskMemFree(url_a
);
132 IUnknown_Release((IUnknown
*)locator_a
);
135 #define check_string_transform(a,b,c,d,e) _check_string_transform(__LINE__,a,b,c,d,e)
136 static void _check_string_transform(unsigned line
, IUniformResourceLocatorA
*urlA
, LPCSTR input
, DWORD flags
,
137 LPCSTR expectedOutput
, BOOL is_todo
)
142 hr
= urlA
->lpVtbl
->SetURL(urlA
, input
, flags
);
143 ok_(__FILE__
,line
)(hr
== S_OK
, "SetUrl failed, hr=0x%lx\n", hr
);
147 output
= (void*)0xdeadbeef;
148 hr
= urlA
->lpVtbl
->GetURL(urlA
, &output
);
150 todo_wine_if(is_todo
) {
151 ok_(__FILE__
,line
)(hr
== S_OK
, "GetUrl failed, hr=0x%lx\n", hr
);
154 ok_(__FILE__
,line
)(!lstrcmpA(output
, expectedOutput
), "unexpected URL change %s -> %s (expected %s)\n",
155 input
, output
, expectedOutput
);
158 ok_(__FILE__
,line
)(hr
== S_FALSE
, "GetUrl failed, hr=0x%lx\n", hr
);
160 ok_(__FILE__
,line
)(!output
, "GetUrl returned %s\n", output
);
163 CoTaskMemFree(output
);
166 static void test_ReadAndWriteProperties(void)
171 IUniformResourceLocatorA
*urlA
;
172 IUniformResourceLocatorA
*urlAFromFile
;
173 WCHAR fileNameW
[MAX_PATH
];
174 static WCHAR iconPath
[] = L
"file:///C:/arbitrary/icon/path";
175 char testurl
[] = "http://some/bogus/url.html";
176 PROPVARIANT pv
[2], pvread
[2];
178 ps
[0].ulKind
= PRSPEC_PROPID
;
179 U(ps
[0]).propid
= PID_IS_ICONFILE
;
180 ps
[1].ulKind
= PRSPEC_PROPID
;
181 U(ps
[1]).propid
= PID_IS_ICONINDEX
;
183 pv
[0].vt
= VT_LPWSTR
;
184 U(pv
[0]).pwszVal
= iconPath
;
186 U(pv
[1]).lVal
= iconIndex
;
188 /* Make sure we have a valid temporary directory */
189 GetTempPathW(MAX_PATH
, fileNameW
);
190 lstrcatW(fileNameW
, L
"testshortcut.url");
192 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUniformResourceLocatorA
, (void**)&urlA
);
193 ok(hr
== S_OK
, "Could not create CLSID_InternetShortcut instance: %08lx\n", hr
);
197 IPropertyStorage
*pPropStgWrite
;
198 IPropertySetStorage
*pPropSetStg
;
200 /* We need to set a URL -- IPersistFile refuses to save without one. */
201 hr
= urlA
->lpVtbl
->SetURL(urlA
, testurl
, 0);
202 ok(hr
== S_OK
, "Failed to set a URL. hr=0x%lx\n", hr
);
204 /* Write this shortcut out to a file so that we can test reading it in again. */
205 hr
= urlA
->lpVtbl
->QueryInterface(urlA
, &IID_IPersistFile
, (void **) &pf
);
206 ok(hr
== S_OK
, "Failed to get the IPersistFile for writing. hr=0x%lx\n", hr
);
208 hr
= IPersistFile_Save(pf
, fileNameW
, TRUE
);
209 ok(hr
== S_OK
, "Failed to save via IPersistFile. hr=0x%lx\n", hr
);
211 IPersistFile_Release(pf
);
213 hr
= urlA
->lpVtbl
->QueryInterface(urlA
, &IID_IPropertySetStorage
, (void **) &pPropSetStg
);
214 ok(hr
== S_OK
, "Unable to get an IPropertySetStorage, hr=0x%lx\n", hr
);
216 hr
= IPropertySetStorage_Open(pPropSetStg
, &FMTID_Intshcut
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, &pPropStgWrite
);
217 ok(hr
== S_OK
, "Unable to get an IPropertyStorage for writing, hr=0x%lx\n", hr
);
219 hr
= IPropertyStorage_WriteMultiple(pPropStgWrite
, 2, ps
, pv
, 0);
220 ok(hr
== S_OK
, "Unable to set properties, hr=0x%lx\n", hr
);
222 memset(pvread
, 0, sizeof(pvread
));
223 hr
= IPropertyStorage_ReadMultiple(pPropStgWrite
, 2, ps
, pvread
);
224 ok(hr
== S_OK
, "Unable to read properties, hr=0x%lx\n", hr
);
225 ok(pvread
[1].vt
== VT_I4
, "got %d\n", pvread
[1].vt
);
226 ok(U(pvread
[1]).lVal
== iconIndex
, "Read wrong icon index: %d\n", U(pvread
[1]).iVal
);
227 ok(pvread
[0].vt
== VT_LPWSTR
, "got %d\n", pvread
[0].vt
);
228 ok(lstrcmpW(U(pvread
[0]).pwszVal
, iconPath
) == 0, "Wrong icon path read: %s\n", wine_dbgstr_w(U(pvread
[0]).pwszVal
));
229 PropVariantClear(&pvread
[0]);
230 PropVariantClear(&pvread
[1]);
232 hr
= IPropertyStorage_Commit(pPropStgWrite
, STGC_DEFAULT
);
233 ok(hr
== S_OK
, "Failed to commit properties, hr=0x%lx\n", hr
);
235 pPropStgWrite
->lpVtbl
->Release(pPropStgWrite
);
236 urlA
->lpVtbl
->Release(urlA
);
237 IPropertySetStorage_Release(pPropSetStg
);
240 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUniformResourceLocatorA
, (void**)&urlAFromFile
);
241 ok(hr
== S_OK
, "Could not create CLSID_InternetShortcut instance: %08lx\n", hr
);
244 IPropertySetStorage
*pPropSetStg
;
245 IPropertyStorage
*pPropStgRead
;
246 PROPVARIANT pvread
[2];
250 /* Now read that .url file back in. */
251 hr
= urlAFromFile
->lpVtbl
->QueryInterface(urlAFromFile
, &IID_IPersistFile
, (void **) &pf
);
252 ok(hr
== S_OK
, "Failed to get the IPersistFile for reading. hr=0x%lx\n", hr
);
254 hr
= IPersistFile_Load(pf
, fileNameW
, 0);
255 ok(hr
== S_OK
, "Failed to load via IPersistFile. hr=0x%lx\n", hr
);
256 IPersistFile_Release(pf
);
259 hr
= urlAFromFile
->lpVtbl
->GetURL(urlAFromFile
, &url
);
260 ok(hr
== S_OK
, "Unable to get url from file, hr=0x%lx\n", hr
);
261 ok(lstrcmpA(url
, testurl
) == 0, "Wrong url read from file: %s\n",url
);
264 hr
= urlAFromFile
->lpVtbl
->QueryInterface(urlAFromFile
, &IID_IPropertySetStorage
, (void **) &pPropSetStg
);
265 ok(hr
== S_OK
, "Unable to get an IPropertySetStorage, hr=0x%lx\n", hr
);
267 hr
= IPropertySetStorage_Open(pPropSetStg
, &FMTID_Intshcut
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, &pPropStgRead
);
268 ok(hr
== S_OK
, "Unable to get an IPropertyStorage for reading, hr=0x%lx\n", hr
);
270 memset(pvread
, 0, sizeof(pvread
));
271 hr
= IPropertyStorage_ReadMultiple(pPropStgRead
, 2, ps
, pvread
);
272 todo_wine
/* Wine doesn't yet support setting properties after save */
274 ok(hr
== S_OK
, "Unable to read properties, hr=0x%lx\n", hr
);
275 ok(pvread
[1].vt
== VT_I4
, "got %d\n", pvread
[1].vt
);
276 ok(U(pvread
[1]).lVal
== iconIndex
, "Read wrong icon index: %d\n", U(pvread
[1]).iVal
);
277 ok(pvread
[0].vt
== VT_LPWSTR
, "got %d\n", pvread
[0].vt
);
278 ok(lstrcmpW(U(pvread
[0]).pwszVal
, iconPath
) == 0, "Wrong icon path read: %s\n", wine_dbgstr_w(U(pvread
[0]).pwszVal
));
280 PropVariantClear(&pvread
[0]);
281 PropVariantClear(&pvread
[1]);
283 hr
= IPropertyStorage_WriteMultiple(pPropStgRead
, 2, ps
, pv
, 0);
284 ok(hr
== STG_E_ACCESSDENIED
, "setting properties should return STG_E_ACCESSDENIED instead of 0x%lx\n", hr
);
286 IPropertyStorage_Release(pPropStgRead
);
287 IPropertySetStorage_Release(pPropSetStg
);
288 urlAFromFile
->lpVtbl
->Release(urlAFromFile
);
289 DeleteFileW(fileNameW
);
293 static void test_NullURLs(void)
297 IUniformResourceLocatorA
*urlA
;
299 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUniformResourceLocatorA
, (void**)&urlA
);
300 ok(hr
== S_OK
, "Could not create InternetShortcut object: %08lx\n", hr
);
302 hr
= urlA
->lpVtbl
->GetURL(urlA
, &url
);
303 ok(hr
== S_FALSE
, "getting uninitialized URL unexpectedly failed, hr=0x%lx\n", hr
);
304 ok(url
== NULL
, "uninitialized URL is not NULL but %s\n", url
);
306 hr
= urlA
->lpVtbl
->SetURL(urlA
, NULL
, 0);
307 ok(hr
== S_OK
, "setting NULL URL unexpectedly failed, hr=0x%lx\n", hr
);
309 hr
= urlA
->lpVtbl
->GetURL(urlA
, &url
);
310 ok(hr
== S_FALSE
, "getting NULL URL unexpectedly failed, hr=0x%lx\n", hr
);
311 ok(url
== NULL
, "URL unexpectedly not NULL but %s\n", url
);
313 urlA
->lpVtbl
->Release(urlA
);
321 static const load_test_t load_tests
[] = {
322 {"[InternetShortcut]\n"
323 "URL=http://www.winehq.org/\n"
326 "[{000214A0-0000-0000-C000-000000000046}]\n"
329 "http://www.winehq.org/"
333 static void test_Load(void)
335 IPersistFile
*persist_file
;
336 const load_test_t
*test
;
337 WCHAR file_path
[MAX_PATH
];
342 GetTempPathW(MAX_PATH
, file_path
);
343 lstrcatW(file_path
, L
"test.url");
345 for(test
= load_tests
; test
< load_tests
+ ARRAY_SIZE(load_tests
); test
++) {
346 IPropertySetStorage
*propsetstorage
;
347 IPropertyStorage
*propstorage
;
351 file
= CreateFileW(file_path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
352 ok(file
!= INVALID_HANDLE_VALUE
, "could not create test file\n");
353 if(file
== INVALID_HANDLE_VALUE
)
356 WriteFile(file
, test
->data
, strlen(test
->data
), &size
, NULL
);
359 hres
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IPersistFile
, (void**)&persist_file
);
360 ok(hres
== S_OK
, "Could not create InternetShortcut instance: %08lx\n", hres
);
362 hres
= IPersistFile_Load(persist_file
, file_path
, 0);
363 ok(hres
== S_OK
, "Load failed: %08lx\n", hres
);
365 test_shortcut_url((IUnknown
*)persist_file
, test
->url
);
367 hres
= IPersistFile_QueryInterface(persist_file
, &IID_IPropertySetStorage
, (void **)&propsetstorage
);
368 ok(hres
== S_OK
, "Unable to get an IPropertySetStorage, hr=0x%lx\n", hres
);
370 hres
= IPropertySetStorage_Open(propsetstorage
, &FMTID_Intshcut
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, &propstorage
);
371 ok(hres
== S_OK
, "Unable to get an IPropertyStorage for reading, hr=0x%lx\n", hres
);
373 ps
.ulKind
= PRSPEC_PROPID
;
374 U(ps
).propid
= PID_IS_ICONFILE
;
376 hres
= IPropertyStorage_ReadMultiple(propstorage
, 1, &ps
, &v
);
377 ok(hres
== S_FALSE
, "got 0x%08lx\n", hres
);
378 ok(v
.vt
== VT_EMPTY
, "got %d\n", v
.vt
);
380 ps
.ulKind
= PRSPEC_PROPID
;
381 U(ps
).propid
= PID_IS_ICONINDEX
;
383 hres
= IPropertyStorage_ReadMultiple(propstorage
, 1, &ps
, &v
);
384 ok(hres
== S_FALSE
, "got 0x%08lx\n", hres
);
385 ok(v
.vt
== VT_EMPTY
, "got %d\n", v
.vt
);
387 IPropertyStorage_Release(propstorage
);
388 IPropertySetStorage_Release(propsetstorage
);
390 IPersistFile_Release(persist_file
);
391 DeleteFileW(file_path
);
395 static void test_SetURLFlags(void)
398 IUniformResourceLocatorA
*urlA
;
400 hr
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUniformResourceLocatorA
, (void**)&urlA
);
401 ok(hr
== S_OK
, "Could not create InternetShortcut object: %08lx\n", hr
);
403 check_string_transform(urlA
, "somerandomstring", 0, NULL
, TRUE
);
404 check_string_transform(urlA
, "www.winehq.org", 0, NULL
, TRUE
);
406 check_string_transform(urlA
, "www.winehq.org", IURL_SETURL_FL_GUESS_PROTOCOL
, "http://www.winehq.org/", FALSE
);
407 check_string_transform(urlA
, "ftp.winehq.org", IURL_SETURL_FL_GUESS_PROTOCOL
, "ftp://ftp.winehq.org/", FALSE
);
409 urlA
->lpVtbl
->Release(urlA
);
412 static void test_InternetShortcut(void)
414 IUniformResourceLocatorA
*url
;
417 hres
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_ALL
, &IID_IUniformResourceLocatorA
, (void**)&url
);
418 ok(hres
== S_OK
, "Could not create CLSID_InternetShortcut instance: %08lx\n", hres
);
421 url
->lpVtbl
->Release(url
);
423 test_Aggregability();
424 test_QueryInterface();
427 test_ReadAndWriteProperties();
435 test_InternetShortcut();