mfplat/sample: Optimize copying to 2d buffer.
[wine.git] / dlls / mshtml / tests / protocol.c
blobfe437765bfb484196bb1df30bcc8258a8cc04cc0
1 /*
2 * Copyright 2005 Jacek Caban
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include <wine/test.h>
22 #include <stdarg.h>
23 #include <stdio.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "urlmon.h"
29 #include "shlwapi.h"
30 #include "wininet.h"
32 #include "initguid.h"
34 #define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37 #define SET_EXPECT(func) \
38 expect_ ## func = TRUE
40 #define CHECK_EXPECT(func) \
41 do { \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 expect_ ## func = FALSE; \
44 called_ ## func = TRUE; \
45 }while(0)
47 #define CHECK_EXPECT2(func) \
48 do { \
49 ok(expect_ ##func, "unexpected call " #func "\n"); \
50 called_ ## func = TRUE; \
51 }while(0)
53 #define CHECK_CALLED(func) \
54 do { \
55 ok(called_ ## func, "expected " #func "\n"); \
56 expect_ ## func = called_ ## func = FALSE; \
57 }while(0)
59 DEFINE_GUID(CLSID_ResProtocol, 0x3050F3BC, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
60 DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
61 DEFINE_GUID(CLSID_JSProtocol, 0x3050F3B2, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
63 DEFINE_EXPECT(GetBindInfo);
64 DEFINE_EXPECT(ReportProgress);
65 DEFINE_EXPECT(ReportData);
66 DEFINE_EXPECT(ReportResult);
67 DEFINE_EXPECT(outer_QI_test);
69 static HRESULT expect_hrResult;
70 static BOOL expect_hr_win32err = FALSE;
71 static DWORD bindf;
73 static const WCHAR about_blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
74 static const WCHAR about_test_url[] = {'a','b','o','u','t',':','t','e','s','t',0};
75 static const WCHAR about_res_url[] = {'r','e','s',':','b','l','a','n','k',0};
76 static const WCHAR javascript_test_url[] = {'j','a','v','a','s','c','r','i','p','t',':','t','e','s','t','(',')',0};
78 static WCHAR res_url_base[INTERNET_MAX_URL_LENGTH] = {'r','e','s',':','/','/'};
79 static unsigned res_url_base_len;
81 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
83 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
84 *ppv = iface;
85 return S_OK;
88 *ppv = NULL;
89 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
90 return E_NOINTERFACE;
93 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
95 return 2;
98 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
100 return 1;
103 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
105 ok(0, "unexpected call\n");
106 return E_NOTIMPL;
109 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
110 LPCWSTR szStatusText)
112 static const WCHAR text_html[] = {'t','e','x','t','/','h','t','m','l',0};
114 CHECK_EXPECT(ReportProgress);
116 ok(ulStatusCode == BINDSTATUS_MIMETYPEAVAILABLE
117 || ulStatusCode == BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
118 "ulStatusCode=%ld\n", ulStatusCode);
119 ok(!lstrcmpW(szStatusText, text_html), "szStatusText != text/html\n");
121 return S_OK;
124 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress,
125 ULONG ulProgressMax)
127 CHECK_EXPECT(ReportData);
129 ok(ulProgress == ulProgressMax, "ulProgress != ulProgressMax\n");
130 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE),
131 "grcf = %08lx\n", grfBSCF);
133 return S_OK;
136 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError,
137 LPCWSTR szResult)
139 CHECK_EXPECT(ReportResult);
141 if(expect_hr_win32err) {
142 ok((hrResult&0xffff0000) == ((FACILITY_WIN32 << 16)|0x80000000) || hrResult == expect_hrResult,
143 "expected win32 err or %08lx got: %08lx\n", expect_hrResult, hrResult);
144 }else {
145 ok(hrResult == expect_hrResult || (expect_hrResult == E_INVALIDARG && hrResult == MK_E_SYNTAX)
146 || (expect_hrResult == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND) &&
147 (hrResult == MK_E_SYNTAX || hrResult == HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND))),
148 "expected: %08lx got: %08lx\n", expect_hrResult, hrResult);
149 expect_hrResult = hrResult;
151 ok(dwError == 0, "dwError = %ld\n", dwError);
152 ok(!szResult, "szResult != NULL\n");
154 return S_OK;
157 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
158 ProtocolSink_QueryInterface,
159 ProtocolSink_AddRef,
160 ProtocolSink_Release,
161 ProtocolSink_Switch,
162 ProtocolSink_ReportProgress,
163 ProtocolSink_ReportData,
164 ProtocolSink_ReportResult
167 static IInternetProtocolSink protocol_sink = {
168 &protocol_sink_vtbl
171 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
173 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
174 *ppv = iface;
175 return S_OK;
178 *ppv = NULL;
179 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
180 return E_NOINTERFACE;
183 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
185 return 2;
188 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
190 return 1;
193 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
195 CHECK_EXPECT(GetBindInfo);
197 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
198 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
199 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %ld\n", pbindinfo->cbSize);
201 *grfBINDF = bindf;
202 return S_OK;
205 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr,
206 ULONG cEl, ULONG *pcElFetched)
208 ok(0, "unexpected call\n");
209 return E_NOTIMPL;
212 static IInternetBindInfoVtbl bind_info_vtbl = {
213 BindInfo_QueryInterface,
214 BindInfo_AddRef,
215 BindInfo_Release,
216 BindInfo_GetBindInfo,
217 BindInfo_GetBindString
220 static IInternetBindInfo bind_info = {
221 &bind_info_vtbl
224 static void test_protocol_fail(IInternetProtocol *protocol, LPCWSTR url, HRESULT expected_hres,
225 BOOL expect_win32err)
227 HRESULT hres;
229 SET_EXPECT(GetBindInfo);
230 SET_EXPECT(ReportResult);
232 expect_hrResult = expected_hres;
233 expect_hr_win32err = expect_win32err;
234 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
235 if(expect_win32err)
236 ok((hres&0xffff0000) == ((FACILITY_WIN32 << 16)|0x80000000) || hres == expect_hrResult,
237 "expected win32 err or %08lx got: %08lx\n", expected_hres, hres);
238 else
239 ok(hres == expect_hrResult, "expected: %08lx got: %08lx\n", expect_hrResult, hres);
241 CHECK_CALLED(GetBindInfo);
242 CHECK_CALLED(ReportResult);
245 static void protocol_start(IInternetProtocol *protocol, const WCHAR *url)
247 HRESULT hres;
249 SET_EXPECT(GetBindInfo);
250 SET_EXPECT(ReportResult);
251 SET_EXPECT(ReportProgress);
252 SET_EXPECT(ReportData);
253 expect_hrResult = S_OK;
254 expect_hr_win32err = FALSE;
256 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
257 ok(hres == S_OK, "Start failed: %08lx\n", hres);
259 CHECK_CALLED(GetBindInfo);
260 CHECK_CALLED(ReportProgress);
261 CHECK_CALLED(ReportData);
262 CHECK_CALLED(ReportResult);
265 static void test_res_url_fail(const WCHAR *url_suffix)
267 WCHAR url[INTERNET_MAX_URL_LENGTH];
268 IInternetProtocol *protocol;
269 HRESULT hres;
271 wcscpy(url, res_url_base);
272 wcscat(url, url_suffix);
274 hres = CoCreateInstance(&CLSID_ResProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&protocol);
275 ok(hres == S_OK, "Could not create ResProtocol instance: %08lx\n", hres);
277 SET_EXPECT(GetBindInfo);
278 SET_EXPECT(ReportResult);
279 expect_hr_win32err = TRUE;
280 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
281 ok(HRESULT_FACILITY(hres) == FACILITY_WIN32,
282 "%s: expected win32 error, got: %08lx\n", debugstr_w(url_suffix), hres);
283 CHECK_CALLED(GetBindInfo);
284 CHECK_CALLED(ReportResult);
286 IInternetProtocol_Release(protocol);
289 static void test_res_url(const char *url_suffix)
291 WCHAR url[INTERNET_MAX_URL_LENGTH];
292 IInternetProtocol *protocol;
293 ULONG size, ref;
294 BYTE buf[100];
295 HRESULT hres;
297 memcpy(url, res_url_base, res_url_base_len*sizeof(WCHAR));
298 MultiByteToWideChar(CP_ACP, 0, url_suffix, -1, url+res_url_base_len, ARRAY_SIZE(url)-res_url_base_len);
300 hres = CoCreateInstance(&CLSID_ResProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&protocol);
301 ok(hres == S_OK, "Could not create ResProtocol instance: %08lx\n", hres);
303 protocol_start(protocol, url);
305 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &size);
306 ok(hres == S_OK, "Read failed: %08lx\n", hres);
308 hres = IInternetProtocol_Terminate(protocol, 0);
309 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
312 ref = IInternetProtocol_Release(protocol);
313 ok(!ref, "ref=%lu\n", ref);
316 static void res_sec_url_cmp(LPCWSTR url, DWORD size, LPCWSTR file)
318 WCHAR buf[MAX_PATH];
319 DWORD len;
321 static const WCHAR fileW[] = {'f','i','l','e',':','/','/'};
323 if(size < ARRAY_SIZE(fileW) || memcmp(url, fileW, sizeof(fileW))) {
324 ok(0, "wrong URL protocol\n");
325 return;
328 SetLastError(0xdeadbeef);
329 len = SearchPathW(NULL, file, NULL, ARRAY_SIZE(buf), buf, NULL);
330 if(!len) {
331 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
332 win_skip("SearchPathW is not implemented\n");
333 else
334 ok(0, "SearchPath failed: %lu\n", GetLastError());
335 return;
338 len += ARRAY_SIZE(fileW)+1;
339 ok(len == size, "wrong size %lu, expected %lu\n", size, len);
340 ok(!lstrcmpW(url + ARRAY_SIZE(fileW), buf), "wrong file part %s\n", wine_dbgstr_w(url));
343 static void test_res_protocol(void)
345 IInternetProtocolInfo *protocol_info;
346 IUnknown *unk;
347 IClassFactory *factory;
348 HRESULT hres;
350 static const WCHAR blank_url[] =
351 {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l','/','b','l','a','n','k','.','h','t','m',0};
352 static const WCHAR test_part_url[] = {'r','e','s',':','/','/','C','S','S','/','t','e','s','t',0};
353 static const WCHAR wrong_url1[] =
354 {'m','s','h','t','m','l','.','d','l','l','/','b','l','a','n','k','.','m','t','h',0};
355 static const WCHAR wrong_url2[] =
356 {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',0};
357 static const WCHAR wrong_url3[] =
358 {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l','/','x','x','.','h','t','m',0};
359 static const WCHAR wrong_url4[] =
360 {'r','e','s',':','/','/','x','x','.','d','l','l','/','b','l','a','n','k','.','h','t','m',0};
361 static const WCHAR wrong_url5[] =
362 {'r','e','s',':','/','/','s','h','t','m','l','.','d','l','l','/','b','l','a','n','k','.','h','t','m',0};
363 static const WCHAR wrong_url6[] =
364 {'r','e','s',':','/','/','c',':','\\','d','i','r','\\','f','i','l','e','.','d','l','l','/','b','l','a','n','k','.','h','t','m',0};
365 static const WCHAR mshtml_dllW[] = {'m','s','h','t','m','l','.','d','l','l',0};
367 hres = CoGetClassObject(&CLSID_ResProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
368 ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
369 if(FAILED(hres))
370 return;
372 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
373 ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08lx\n", hres);
374 if(SUCCEEDED(hres)) {
375 WCHAR buf[128];
376 DWORD size, expected_size;
377 int i;
379 for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) {
380 if(i != PARSE_SECURITY_URL && i != PARSE_DOMAIN) {
381 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, i, 0, buf,
382 ARRAY_SIZE(buf), &size, 0);
383 ok(hres == INET_E_DEFAULT_ACTION,
384 "[%d] failed: %08lx, expected INET_E_DEFAULT_ACTION\n", i, hres);
388 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_SECURITY_URL, 0, buf,
389 ARRAY_SIZE(buf), &size, 0);
390 ok(hres == S_OK, "ParseUrl failed: %08lx\n", hres);
391 res_sec_url_cmp(buf, size, mshtml_dllW);
392 ok(size == lstrlenW(buf)+1, "size = %ld\n", size);
393 expected_size = size;
395 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_SECURITY_URL, 0, buf,
396 expected_size, &size, 0);
397 ok(hres == S_OK, "ParseUrl failed: %08lx\n", hres);
398 res_sec_url_cmp(buf, size, mshtml_dllW);
399 ok(size == expected_size, "size = %ld\n", size);
401 size = 0;
402 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_SECURITY_URL, 0, buf,
403 3, &size, 0);
404 ok(hres == S_FALSE, "ParseUrl failed: %08lx, expected S_FALSE\n", hres);
405 ok(size == expected_size, "size = %ld\n", size);
407 hres = IInternetProtocolInfo_ParseUrl(protocol_info, wrong_url1, PARSE_SECURITY_URL, 0, buf,
408 ARRAY_SIZE(buf), &size, 0);
409 ok(hres == MK_E_SYNTAX || hres == E_INVALIDARG,
410 "ParseUrl failed: %08lx, expected MK_E_SYNTAX\n", hres);
412 hres = IInternetProtocolInfo_ParseUrl(protocol_info, wrong_url5, PARSE_SECURITY_URL, 0, buf,
413 ARRAY_SIZE(buf), &size, 0);
414 ok(hres == MK_E_SYNTAX, "ParseUrl failed: %08lx, expected MK_E_SYNTAX\n", hres);
416 hres = IInternetProtocolInfo_ParseUrl(protocol_info, wrong_url6, PARSE_SECURITY_URL, 0, buf,
417 ARRAY_SIZE(buf), &size, 0);
418 ok(hres == MK_E_SYNTAX, "ParseUrl failed: %08lx, expected MK_E_SYNTAX\n", hres);
420 size = 0xdeadbeef;
421 buf[0] = '?';
422 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_DOMAIN, 0, buf,
423 ARRAY_SIZE(buf), &size, 0);
424 ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08lx\n", hres);
425 ok(buf[0] == '?', "buf changed\n");
426 ok(size == ARRAY_SIZE(blank_url) || size == ARRAY_SIZE(buf), /* IE8 */ "size=%ld\n", size);
428 size = 0xdeadbeef;
429 hres = IInternetProtocolInfo_ParseUrl(protocol_info, wrong_url1, PARSE_DOMAIN, 0, buf,
430 ARRAY_SIZE(buf), &size, 0);
431 ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08lx\n", hres);
432 ok(buf[0] == '?', "buf changed\n");
433 ok(size == ARRAY_SIZE(wrong_url1) || size == ARRAY_SIZE(buf), /* IE8 */ "size=%ld\n", size);
435 if (0)
437 /* Crashes on windows */
438 size = 0xdeadbeef;
439 buf[0] = '?';
440 hres = IInternetProtocolInfo_ParseUrl(protocol_info, NULL, PARSE_DOMAIN, 0, buf,
441 ARRAY_SIZE(buf), &size, 0);
442 ok(hres == E_FAIL, "ParseUrl failed: %08lx\n", hres);
443 ok(buf[0] == '?', "buf changed\n");
444 ok(size == 1, "size=%lu, expected 1\n", size);
446 buf[0] = '?';
447 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_DOMAIN, 0, buf,
448 ARRAY_SIZE(buf), NULL, 0);
449 ok(hres == E_POINTER, "ParseUrl failed: %08lx\n", hres);
450 ok(buf[0] == '?', "buf changed\n");
452 buf[0] = '?';
453 hres = IInternetProtocolInfo_ParseUrl(protocol_info, NULL, PARSE_DOMAIN, 0, buf,
454 ARRAY_SIZE(buf), NULL, 0);
455 ok(hres == E_POINTER, "ParseUrl failed: %08lx\n", hres);
456 ok(buf[0] == '?', "buf changed\n");
459 buf[0] = '?';
460 hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_UNESCAPE+1, 0, buf,
461 ARRAY_SIZE(buf), &size, 0);
462 ok(hres == INET_E_DEFAULT_ACTION,
463 "ParseUrl failed: %08lx, expected INET_E_DEFAULT_ACTION\n", hres);
464 ok(buf[0] == '?', "buf changed\n");
466 size = 0xdeadbeef;
467 hres = IInternetProtocolInfo_CombineUrl(protocol_info, blank_url, test_part_url,
468 0, buf, ARRAY_SIZE(buf), &size, 0);
469 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
470 ok(size == 0xdeadbeef, "size=%ld\n", size);
472 size = 0xdeadbeef;
473 hres = IInternetProtocolInfo_CombineUrl(protocol_info, blank_url, test_part_url,
474 URL_FILE_USE_PATHURL, buf, ARRAY_SIZE(buf), &size, 0);
475 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
476 ok(size == 0xdeadbeef, "size=%ld\n", size);
478 size = 0xdeadbeef;
479 hres = IInternetProtocolInfo_CombineUrl(protocol_info, NULL, NULL,
480 URL_FILE_USE_PATHURL, NULL, 0xdeadbeef, NULL, 0);
481 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
482 ok(size == 0xdeadbeef, "size=%ld\n", size);
484 hres = IInternetProtocolInfo_CompareUrl(protocol_info, blank_url, blank_url, 0);
485 ok(hres == E_NOTIMPL, "CompareUrl failed: %08lx\n", hres);
487 hres = IInternetProtocolInfo_CompareUrl(protocol_info, NULL, NULL, 0xdeadbeef);
488 ok(hres == E_NOTIMPL, "CompareUrl failed: %08lx\n", hres);
490 for(i=0; i<30; i++) {
491 if(i == QUERY_USES_NETWORK || i == QUERY_IS_SECURE || i == QUERY_IS_SAFE)
492 continue;
494 hres = IInternetProtocolInfo_QueryInfo(protocol_info, blank_url, i, 0,
495 buf, sizeof(buf), &size, 0);
496 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER,
497 "QueryInfo(%d) returned: %08lx, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", i, hres);
500 size = 0xdeadbeef;
501 memset(buf, '?', sizeof(buf));
502 hres = IInternetProtocolInfo_QueryInfo(protocol_info, blank_url, QUERY_USES_NETWORK, 0,
503 buf, sizeof(buf), &size, 0);
504 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
505 ok(size == sizeof(DWORD), "size=%ld\n", size);
506 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
508 memset(buf, '?', sizeof(buf));
509 hres = IInternetProtocolInfo_QueryInfo(protocol_info, blank_url, QUERY_USES_NETWORK, 0,
510 buf, sizeof(buf), NULL, 0);
511 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
512 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
514 hres = IInternetProtocolInfo_QueryInfo(protocol_info, blank_url, QUERY_USES_NETWORK, 0,
515 buf, 3, &size, 0);
516 ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx, expected E_FAIL\n", hres);
518 size = 0xdeadbeef;
519 memset(buf, '?', sizeof(buf));
520 hres = IInternetProtocolInfo_QueryInfo(protocol_info, NULL, QUERY_USES_NETWORK, 0,
521 buf, sizeof(buf), &size, 0);
522 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
523 ok(size == sizeof(DWORD), "size=%ld\n", size);
524 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
526 hres = IInternetProtocolInfo_QueryInfo(protocol_info, blank_url, QUERY_USES_NETWORK, 0,
527 NULL, sizeof(buf), &size, 0);
528 ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx, expected E_FAIL\n", hres);
530 hres = IInternetProtocolInfo_QueryInfo(protocol_info, blank_url, 60, 0,
531 NULL, sizeof(buf), &size, 0);
532 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER,
533 "QueryInfo failed: %08lx, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres);
535 IInternetProtocolInfo_Release(protocol_info);
538 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
539 ok(hres == S_OK, "Could not get IClassFactory interface\n");
540 if(SUCCEEDED(hres)) {
541 IInternetProtocol *protocol;
542 BYTE buf[512];
543 ULONG cb;
544 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
545 ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
547 if(SUCCEEDED(hres)) {
548 IInternetPriority *priority;
550 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
551 ok(hres == E_NOINTERFACE,
552 "QueryInterface(IInternetPriority) returned %08lx, expected E_NOINTEFACE\n", hres);
554 test_protocol_fail(protocol, wrong_url1, E_INVALIDARG, FALSE);
555 test_protocol_fail(protocol, wrong_url2,
556 HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), FALSE);
557 test_protocol_fail(protocol, wrong_url3, E_FAIL, TRUE);
558 test_protocol_fail(protocol, wrong_url4, E_FAIL, TRUE);
560 cb = 0xdeadbeef;
561 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
562 ok(hres == E_FAIL, "Read returned %08lx expected E_FAIL\n", hres);
563 ok(cb == 0xdeadbeef, "cb=%lu expected 0xdeadbeef\n", cb);
565 protocol_start(protocol, blank_url);
566 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
567 ok(hres == S_OK, "Read failed: %08lx\n", hres);
568 ok(cb == 2, "cb=%lu expected 2\n", cb);
569 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
570 ok(hres == S_OK, "Read failed: %08lx\n", hres);
571 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
572 ok(hres == S_FALSE, "Read failed: %08lx expected S_FALSE\n", hres);
573 ok(cb == 0, "cb=%lu expected 0\n", cb);
574 hres = IInternetProtocol_UnlockRequest(protocol);
575 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
577 protocol_start(protocol, blank_url);
578 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
579 ok(hres == S_OK, "Read failed: %08lx\n", hres);
580 hres = IInternetProtocol_LockRequest(protocol, 0);
581 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
582 hres = IInternetProtocol_UnlockRequest(protocol);
583 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
584 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
585 ok(hres == S_OK, "Read failed: %08lx\n", hres);
587 protocol_start(protocol, blank_url);
588 hres = IInternetProtocol_LockRequest(protocol, 0);
589 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
590 hres = IInternetProtocol_Terminate(protocol, 0);
591 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
592 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
593 ok(hres == S_OK, "Read failed: %08lx\n\n", hres);
594 hres = IInternetProtocol_UnlockRequest(protocol);
595 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
596 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
597 ok(hres == S_OK, "Read failed: %08lx\n", hres);
598 hres = IInternetProtocol_Terminate(protocol, 0);
599 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
600 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
601 ok(hres == S_OK, "Read failed: %08lx\n", hres);
602 ok(cb == 2, "cb=%lu expected 2\n", cb);
604 protocol_start(protocol, blank_url);
605 hres = IInternetProtocol_LockRequest(protocol, 0);
606 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
607 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
608 ok(hres == S_OK, "Read failed: %08lx\n", hres);
609 protocol_start(protocol, blank_url);
610 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
611 ok(hres == S_OK, "Read failed: %08lx\n", hres);
612 hres = IInternetProtocol_Terminate(protocol, 0);
613 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
615 IInternetProtocol_Release(protocol);
618 IClassFactory_Release(factory);
621 IUnknown_Release(unk);
623 test_res_url("/blank.html");
624 test_res_url("/123");
625 test_res_url("/#23/blank.html");
626 test_res_url("/#23/123");
627 test_res_url("/23/blank.html");
628 test_res_url("/23/123");
630 test_res_url("/jstest.html");
631 test_res_url("/jstest-rtfile.html");
632 test_res_url("/#2110/jstest-rtfile.html");
633 test_res_url("/2110/jstest-rtfile.html");
635 test_res_url_fail(L"/doesntexist/jstest-rtfile.html");
636 test_res_url_fail(L"/2/jstest-rtfile.html");
637 test_res_url_fail(L"/23/jstest-rtfile.html"); /* no fallback from explicit RT_HTML */
639 test_res_url("/Test/res.html");
640 test_res_url("/test/dir/dir2/res.html");
642 if(GetProcAddress(GetModuleHandleA("urlmon.dll"), "CreateUri")) {
643 test_res_url("/test/dir/dir2/res.html?query_part");
644 test_res_url("/test/dir/dir2/res.html#hash_part");
645 test_res_url("/#123");
646 test_res_url("/#23/#123");
647 test_res_url("/#123#456");
648 }else {
649 win_skip("IUri not supported\n");
653 static void do_test_about_protocol(IClassFactory *factory, DWORD bf)
655 IInternetProtocol *protocol;
656 IInternetPriority *priority;
657 BYTE buf[512];
658 ULONG cb;
659 HRESULT hres;
661 static const WCHAR blank_html[] = {0xfeff,'<','H','T','M','L','>','<','/','H','T','M','L','>',0};
662 static const WCHAR test_html[] =
663 {0xfeff,'<','H','T','M','L','>','t','e','s','t','<','/','H','T','M','L','>',0};
665 bindf = bf;
667 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
668 ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
669 if(FAILED(hres))
670 return;
672 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
673 ok(hres == E_NOINTERFACE,
674 "QueryInterface(IInternetPriority) returned %08lx, expected E_NOINTEFACE\n", hres);
676 protocol_start(protocol, about_blank_url);
677 hres = IInternetProtocol_LockRequest(protocol, 0);
678 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
679 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
680 ok(hres == S_OK, "Read failed: %08lx\n", hres);
681 ok(cb == sizeof(blank_html), "cb=%ld\n", cb);
682 ok(!memcmp(buf, blank_html, cb), "Read wrong data\n");
683 hres = IInternetProtocol_UnlockRequest(protocol);
684 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
686 protocol_start(protocol, about_test_url);
687 hres = IInternetProtocol_LockRequest(protocol, 0);
688 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
689 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
690 ok(hres == S_OK, "Read failed: %08lx\n", hres);
691 ok(cb == sizeof(test_html), "cb=%ld\n", cb);
692 ok(!memcmp(buf, test_html, cb), "Read wrong data\n");
693 hres = IInternetProtocol_UnlockRequest(protocol);
694 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
696 protocol_start(protocol, about_res_url);
697 hres = IInternetProtocol_LockRequest(protocol, 0);
698 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
699 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
700 ok(hres == S_OK, "Read failed: %08lx\n", hres);
701 ok(cb == sizeof(blank_html), "cb=%ld\n", cb);
702 ok(!memcmp(buf, blank_html, cb), "Read wrong data\n");
703 hres = IInternetProtocol_UnlockRequest(protocol);
704 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
706 IInternetProtocol_Release(protocol);
709 static void test_about_protocol(void)
711 IInternetProtocolInfo *protocol_info;
712 IUnknown *unk;
713 IClassFactory *factory;
714 HRESULT hres;
716 hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
717 ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
718 if(FAILED(hres))
719 return;
721 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
722 ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08lx\n", hres);
723 if(SUCCEEDED(hres)) {
724 WCHAR buf[128];
725 DWORD size;
726 int i;
728 for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) {
729 if(i != PARSE_SECURITY_URL && i != PARSE_DOMAIN) {
730 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, i, 0, buf,
731 ARRAY_SIZE(buf), &size, 0);
732 ok(hres == INET_E_DEFAULT_ACTION,
733 "[%d] failed: %08lx, expected INET_E_DEFAULT_ACTION\n", i, hres);
737 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_SECURITY_URL, 0, buf,
738 ARRAY_SIZE(buf), &size, 0);
739 ok(hres == S_OK, "ParseUrl failed: %08lx\n", hres);
740 ok(!lstrcmpW(about_blank_url, buf), "buf != blank_url\n");
742 size = 0xdeadbeef;
743 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_SECURITY_URL, 0, buf,
744 3, &size, 0);
745 ok(hres == S_FALSE, "ParseUrl failed: %08lx, expected S_FALSE\n", hres);
746 ok(size == 12, "size = %ld\n", size);
748 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_test_url, PARSE_SECURITY_URL, 0, buf,
749 ARRAY_SIZE(buf), &size, 0);
750 ok(hres == S_OK, "ParseUrl failed: %08lx\n", hres);
751 ok(!lstrcmpW(about_test_url, buf), "buf != test_url\n");
752 ok(size == 11, "size = %ld\n", size);
754 size = 0xdeadbeef;
755 buf[0] = '?';
756 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_DOMAIN, 0, buf,
757 ARRAY_SIZE(buf), &size, 0);
758 ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08lx\n", hres);
759 ok(buf[0] == '?' || buf[0] == '\0' /* Win10 */,
760 "Expected buf to be unchanged or empty, got %s\n",
761 wine_dbgstr_w(buf));
762 ok(size == ARRAY_SIZE(about_blank_url) || size == ARRAY_SIZE(buf), /* IE8 */
763 "size=%ld\n", size);
765 if (0)
767 /* Crashes on windows */
768 size = 0xdeadbeef;
769 buf[0] = '?';
770 hres = IInternetProtocolInfo_ParseUrl(protocol_info, NULL, PARSE_DOMAIN, 0, buf,
771 ARRAY_SIZE(buf), &size, 0);
772 ok(hres == E_FAIL, "ParseUrl failed: %08lx\n", hres);
773 ok(buf[0] == '?', "buf changed\n");
774 ok(size == 1, "size=%lu, expected 1\n", size);
776 buf[0] = '?';
777 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_DOMAIN, 0, buf,
778 ARRAY_SIZE(buf), NULL, 0);
779 ok(hres == E_POINTER, "ParseUrl failed: %08lx\n", hres);
780 ok(buf[0] == '?', "buf changed\n");
782 buf[0] = '?';
783 hres = IInternetProtocolInfo_ParseUrl(protocol_info, NULL, PARSE_DOMAIN, 0, buf,
784 ARRAY_SIZE(buf), NULL, 0);
785 ok(hres == E_POINTER, "ParseUrl failed: %08lx\n", hres);
786 ok(buf[0] == '?', "buf changed\n");
789 hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_UNESCAPE+1, 0, buf,
790 ARRAY_SIZE(buf), &size, 0);
791 ok(hres == INET_E_DEFAULT_ACTION,
792 "ParseUrl failed: %08lx, expected INET_E_DEFAULT_ACTION\n", hres);
794 size = 0xdeadbeef;
795 hres = IInternetProtocolInfo_CombineUrl(protocol_info, about_blank_url, about_test_url,
796 0, buf, ARRAY_SIZE(buf), &size, 0);
797 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
798 ok(size == 0xdeadbeef, "size=%ld\n", size);
800 size = 0xdeadbeef;
801 hres = IInternetProtocolInfo_CombineUrl(protocol_info, about_blank_url, about_test_url,
802 URL_FILE_USE_PATHURL, buf, ARRAY_SIZE(buf), &size, 0);
803 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
804 ok(size == 0xdeadbeef, "size=%ld\n", size);
806 size = 0xdeadbeef;
807 hres = IInternetProtocolInfo_CombineUrl(protocol_info, NULL, NULL,
808 URL_FILE_USE_PATHURL, buf, ARRAY_SIZE(buf), &size, 0);
809 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
810 ok(size == 0xdeadbeef, "size=%ld\n", size);
812 hres = IInternetProtocolInfo_CompareUrl(protocol_info, about_blank_url, about_blank_url, 0);
813 ok(hres == E_NOTIMPL, "CompareUrl failed: %08lx\n", hres);
815 hres = IInternetProtocolInfo_CompareUrl(protocol_info, NULL, NULL, 0xdeadbeef);
816 ok(hres == E_NOTIMPL, "CompareUrl failed: %08lx\n", hres);
818 for(i=0; i<30; i++) {
819 switch(i) {
820 case QUERY_CAN_NAVIGATE:
821 case QUERY_USES_NETWORK:
822 case QUERY_IS_CACHED:
823 case QUERY_IS_INSTALLEDENTRY:
824 case QUERY_IS_CACHED_OR_MAPPED:
825 case QUERY_IS_SECURE:
826 case QUERY_IS_SAFE:
827 case QUERY_USES_HISTORYFOLDER:
828 case QUERY_IS_CACHED_AND_USABLE_OFFLINE:
829 break;
830 default:
831 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, i, 0,
832 buf, sizeof(buf), &size, 0);
833 ok(hres == E_FAIL, "QueryInfo(%d) returned: %08lx, expected E_FAIL\n", i, hres);
837 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_CAN_NAVIGATE, 0,
838 buf, sizeof(buf), &size, 0);
839 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER ||
840 hres == E_FAIL, /* win2k */
841 "QueryInfo returned: %08lx, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER or E_FAIL\n", hres);
843 size = 0xdeadbeef;
844 memset(buf, '?', sizeof(buf));
845 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0,
846 buf, sizeof(buf), &size, 0);
847 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
848 ok(size == sizeof(DWORD), "size=%ld\n", size);
849 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
851 memset(buf, '?', sizeof(buf));
852 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0,
853 buf, sizeof(buf), NULL, 0);
854 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
855 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
857 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0,
858 buf, 3, &size, 0);
859 ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx, expected E_FAIL\n", hres);
861 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0,
862 NULL, sizeof(buf), &size, 0);
863 ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx, expected E_FAIL\n", hres);
865 hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, 60, 0,
866 NULL, sizeof(buf), &size, 0);
867 ok(hres == E_FAIL, "QueryInfo failed: %08lx, expected E_FAIL\n", hres);
869 IInternetProtocolInfo_Release(protocol_info);
872 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
873 ok(hres == S_OK, "Could not get IClassFactory interface\n");
874 if(SUCCEEDED(hres)) {
875 do_test_about_protocol(factory, 0);
876 do_test_about_protocol(factory,
877 BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE);
879 IClassFactory_Release(factory);
882 IUnknown_Release(unk);
885 static void test_javascript_protocol(void)
887 IInternetProtocolInfo *protocol_info;
888 IUnknown *unk;
889 IClassFactory *factory;
890 HRESULT hres;
892 hres = CoGetClassObject(&CLSID_JSProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
893 ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
894 if(FAILED(hres))
895 return;
897 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
898 ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08lx\n", hres);
899 if(SUCCEEDED(hres)) {
900 WCHAR buf[128];
901 DWORD size;
902 int i;
904 for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) {
905 if(i != PARSE_SECURITY_URL && i != PARSE_DOMAIN) {
906 hres = IInternetProtocolInfo_ParseUrl(protocol_info, javascript_test_url, i, 0, buf,
907 ARRAY_SIZE(buf), &size, 0);
908 ok(hres == INET_E_DEFAULT_ACTION,
909 "[%d] failed: %08lx, expected INET_E_DEFAULT_ACTION\n", i, hres);
913 hres = IInternetProtocolInfo_ParseUrl(protocol_info, javascript_test_url, PARSE_UNESCAPE+1, 0, buf,
914 ARRAY_SIZE(buf), &size, 0);
915 ok(hres == INET_E_DEFAULT_ACTION,
916 "ParseUrl failed: %08lx, expected INET_E_DEFAULT_ACTION\n", hres);
918 size = 0xdeadbeef;
919 hres = IInternetProtocolInfo_CombineUrl(protocol_info, javascript_test_url, javascript_test_url,
920 0, buf, ARRAY_SIZE(buf), &size, 0);
921 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08lx\n", hres);
922 ok(size == 0xdeadbeef, "size=%ld\n", size);
924 hres = IInternetProtocolInfo_CompareUrl(protocol_info, javascript_test_url, javascript_test_url, 0);
925 ok(hres == E_NOTIMPL, "CompareUrl failed: %08lx\n", hres);
927 for(i=0; i<30; i++) {
928 switch(i) {
929 case QUERY_USES_NETWORK:
930 case QUERY_IS_SECURE:
931 break;
932 default:
933 hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, i, 0,
934 buf, sizeof(buf), &size, 0);
935 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER,
936 "QueryInfo(%d) returned: %08lx, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", i, hres);
941 memset(buf, '?', sizeof(buf));
942 hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0,
943 buf, sizeof(buf), &size, 0);
944 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
945 ok(size == sizeof(DWORD), "size=%ld\n", size);
946 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
948 memset(buf, '?', sizeof(buf));
949 hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0,
950 buf, sizeof(buf), NULL, 0);
951 ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx\n", hres);
952 ok(!*(DWORD*)buf, "buf=%ld\n", *(DWORD*)buf);
954 hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0,
955 buf, 3, &size, 0);
956 ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx, expected E_FAIL\n", hres);
958 hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0,
959 NULL, sizeof(buf), &size, 0);
960 ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08lx, expected E_FAIL\n", hres);
962 hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, 60, 0,
963 NULL, sizeof(buf), &size, 0);
964 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER,
965 "QueryInfo failed: %08lx, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres);
967 /* FIXME: test QUERY_IS_SECURE */
969 IInternetProtocolInfo_Release(protocol_info);
972 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
973 ok(hres == S_OK, "Could not get IClassFactory interface\n");
974 if(SUCCEEDED(hres))
975 IClassFactory_Release(factory);
977 IUnknown_Release(unk);
980 static const IID outer_test_iid = {0xabcabc00,0,0,{0,0,0,0,0,0,0,0x66}};
982 static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
984 if(IsEqualGUID(riid, &outer_test_iid)) {
985 CHECK_EXPECT(outer_QI_test);
986 *ppv = (IUnknown*)0xdeadbeef;
987 return S_OK;
989 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
990 return E_NOINTERFACE;
993 static ULONG WINAPI outer_AddRef(IUnknown *iface)
995 return 2;
998 static ULONG WINAPI outer_Release(IUnknown *iface)
1000 return 1;
1003 static const IUnknownVtbl outer_vtbl = {
1004 outer_QueryInterface,
1005 outer_AddRef,
1006 outer_Release
1009 static void test_com_aggregation(const CLSID *clsid)
1011 IUnknown outer = { &outer_vtbl };
1012 IClassFactory *class_factory;
1013 IUnknown *unk, *unk2, *unk3;
1014 HRESULT hres;
1016 hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&class_factory);
1017 ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
1019 hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IUnknown, (void**)&unk);
1020 ok(hres == S_OK, "CreateInstance returned: %08lx\n", hres);
1022 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&unk2);
1023 ok(hres == S_OK, "Could not get IDispatch iface: %08lx\n", hres);
1025 SET_EXPECT(outer_QI_test);
1026 hres = IUnknown_QueryInterface(unk2, &outer_test_iid, (void**)&unk3);
1027 CHECK_CALLED(outer_QI_test);
1028 ok(hres == S_OK, "Could not get IInternetProtocol iface: %08lx\n", hres);
1029 ok(unk3 == (IUnknown*)0xdeadbeef, "unexpected unk2\n");
1031 IUnknown_Release(unk2);
1032 IUnknown_Release(unk);
1034 unk = (void*)0xdeadbeef;
1035 hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IInternetProtocol, (void**)&unk);
1036 ok(hres == E_INVALIDARG, "CreateInstance returned: %08lx\n", hres);
1037 ok(!unk, "unk = %p\n", unk);
1039 IClassFactory_Release(class_factory);
1042 START_TEST(protocol)
1044 res_url_base_len = 6 + GetModuleFileNameW(NULL, res_url_base + 6 /* strlen("res://") */,
1045 ARRAY_SIZE(res_url_base)-6);
1047 OleInitialize(NULL);
1049 test_res_protocol();
1050 test_about_protocol();
1051 test_javascript_protocol();
1053 test_com_aggregation(&CLSID_AboutProtocol);
1054 test_com_aggregation(&CLSID_ResProtocol);
1056 OleUninitialize();