push 502c994fb3b2157cb8d5bfd04fb7e4ce7daec2a1
[wine/hacks.git] / dlls / urlmon / tests / protocol.c
blobea19c778eaa35b25d24fe9cddd478ce5291a0ec4
1 /*
2 * Copyright 2005-2007 Jacek Caban for CodeWeavers
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
20 #define CONST_VTABLE
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "urlmon.h"
30 #include "wininet.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT2(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
42 }while(0)
44 #define CHECK_EXPECT(func) \
45 do { \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
48 }while(0)
50 #define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
54 }while(0)
56 #define CHECK_NOT_CALLED(func) \
57 do { \
58 ok(!called_ ## func, "unexpected " #func "\n"); \
59 expect_ ## func = called_ ## func = FALSE; \
60 }while(0)
62 #define CLEAR_CALLED(func) \
63 expect_ ## func = called_ ## func = FALSE
65 DEFINE_EXPECT(GetBindInfo);
66 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
67 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
68 DEFINE_EXPECT(ReportProgress_RAWMIMETYPE);
69 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE);
70 DEFINE_EXPECT(ReportProgress_CONNECTING);
71 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
72 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
73 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
74 DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID);
75 DEFINE_EXPECT(ReportProgress_COOKIE_SENT);
76 DEFINE_EXPECT(ReportProgress_REDIRECTING);
77 DEFINE_EXPECT(ReportProgress_ENCODING);
78 DEFINE_EXPECT(ReportProgress_ACCEPTRANGES);
79 DEFINE_EXPECT(ReportProgress_PROXYDETECTING);
80 DEFINE_EXPECT(ReportData);
81 DEFINE_EXPECT(ReportResult);
82 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES);
83 DEFINE_EXPECT(GetBindString_USER_AGENT);
84 DEFINE_EXPECT(GetBindString_POST_COOKIE);
85 DEFINE_EXPECT(QueryService_HttpNegotiate);
86 DEFINE_EXPECT(QueryService_InternetProtocol);
87 DEFINE_EXPECT(QueryService_HttpSecurity);
88 DEFINE_EXPECT(BeginningTransaction);
89 DEFINE_EXPECT(GetRootSecurityId);
90 DEFINE_EXPECT(OnResponse);
91 DEFINE_EXPECT(Switch);
92 DEFINE_EXPECT(Continue);
93 DEFINE_EXPECT(CreateInstance);
94 DEFINE_EXPECT(Start);
95 DEFINE_EXPECT(Terminate);
96 DEFINE_EXPECT(Read);
97 DEFINE_EXPECT(SetPriority);
98 DEFINE_EXPECT(LockRequest);
99 DEFINE_EXPECT(UnlockRequest);
101 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
102 static const WCHAR index_url[] =
103 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
105 static const WCHAR acc_mimeW[] = {'*','/','*',0};
106 static const WCHAR user_agentW[] = {'W','i','n','e',0};
107 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
108 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
109 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
110 static const WCHAR emptyW[] = {0};
112 static HRESULT expect_hrResult;
113 static LPCWSTR file_name, http_url, expect_wsz;
114 static IInternetProtocol *async_protocol = NULL;
115 static BOOL first_data_notif = FALSE, http_is_first = FALSE,
116 http_post_test = FALSE;
117 static int state = 0, prot_state;
118 static DWORD bindf = 0, ex_priority = 0;
119 static IInternetProtocol *binding_protocol;
120 static IInternetBindInfo *prot_bind_info;
121 static IInternetProtocolSink *binding_sink;
122 static void *expect_pv;
123 static HANDLE event_complete, event_complete2;
124 static BOOL binding_test;
125 static PROTOCOLDATA protocoldata, *pdata;
126 static DWORD prot_read;
127 static BOOL security_problem = FALSE;
129 static enum {
130 FILE_TEST,
131 HTTP_TEST,
132 HTTPS_TEST,
133 FTP_TEST,
134 MK_TEST,
135 BIND_TEST
136 } tested_protocol;
138 static const WCHAR protocol_names[][10] = {
139 {'f','i','l','e',0},
140 {'h','t','t','p',0},
141 {'h','t','t','p','s',0},
142 {'f','t','p',0},
143 {'m','k',0},
144 {'t','e','s','t',0}
147 static const WCHAR binding_urls[][130] = {
148 {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
149 {'h','t','t','p',':','/','/','t','e','s','t','/','t','e','s','t','.','h','t','m','l',0},
150 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
151 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
152 {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
153 '/','p','u','b','/','o','t','h','e','r',
154 '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
155 {'m','k',':','t','e','s','t',0},
156 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
159 static const char *debugstr_w(LPCWSTR str)
161 static char buf[512];
162 if(!str)
163 return "(null)";
164 WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
165 return buf;
168 static const char *debugstr_guid(REFIID riid)
170 static char buf[50];
172 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
173 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
174 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
175 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
177 return buf;
180 static int strcmp_wa(LPCWSTR strw, const char *stra)
182 WCHAR buf[512];
183 MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
184 return lstrcmpW(strw, buf);
187 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
189 if(IsEqualGUID(&IID_IUnknown, riid)
190 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
191 *ppv = iface;
192 return S_OK;
195 ok(0, "unexpected call\n");
196 return E_NOINTERFACE;
199 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
201 return 2;
204 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
206 return 1;
209 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
211 trace("HttpSecurity_GetWindow\n");
213 return S_FALSE;
216 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
218 trace("Security problem: %u\n", dwProblem);
219 ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem);
221 /* Only retry once */
222 if (security_problem)
223 return E_ABORT;
225 security_problem = TRUE;
226 SET_EXPECT(BeginningTransaction);
228 return RPC_E_RETRY;
231 static IHttpSecurityVtbl HttpSecurityVtbl = {
232 HttpSecurity_QueryInterface,
233 HttpSecurity_AddRef,
234 HttpSecurity_Release,
235 HttpSecurity_GetWindow,
236 HttpSecurity_OnSecurityProblem
239 static IHttpSecurity http_security = { &HttpSecurityVtbl };
241 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
243 if(IsEqualGUID(&IID_IUnknown, riid)
244 || IsEqualGUID(&IID_IHttpNegotiate, riid)
245 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
246 *ppv = iface;
247 return S_OK;
250 ok(0, "unexpected call\n");
251 return E_NOINTERFACE;
254 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
256 return 2;
259 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
261 return 1;
264 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
265 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
267 LPWSTR addl_headers;
269 static const WCHAR wszHeaders[] =
270 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
271 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
272 'd','e','d','\r','\n',0};
274 CHECK_EXPECT(BeginningTransaction);
276 if(binding_test)
277 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
278 else
279 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
280 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
281 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
282 if(pszAdditionalHeaders)
284 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
285 if (http_post_test)
287 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
288 if (!addl_headers)
290 http_post_test = FALSE;
291 skip("Out of memory\n");
292 return E_OUTOFMEMORY;
294 lstrcpyW(addl_headers, wszHeaders);
295 *pszAdditionalHeaders = addl_headers;
299 return S_OK;
302 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
303 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
305 CHECK_EXPECT(OnResponse);
307 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
308 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
309 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
310 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
312 return S_OK;
315 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
316 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
318 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
320 CHECK_EXPECT(GetRootSecurityId);
322 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
323 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
324 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
326 if(pcbSecurityId) {
327 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
328 *pcbSecurityId = sizeof(sec_id);
331 if(pbSecurityId)
332 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
334 return E_FAIL;
337 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
338 HttpNegotiate_QueryInterface,
339 HttpNegotiate_AddRef,
340 HttpNegotiate_Release,
341 HttpNegotiate_BeginningTransaction,
342 HttpNegotiate_OnResponse,
343 HttpNegotiate_GetRootSecurityId
346 static IHttpNegotiate2 http_negotiate = { &HttpNegotiateVtbl };
348 static HRESULT QueryInterface(REFIID,void**);
350 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
352 return QueryInterface(riid, ppv);
355 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
357 return 2;
360 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
362 return 1;
365 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
366 REFIID riid, void **ppv)
368 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
369 CHECK_EXPECT2(QueryService_HttpNegotiate);
370 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
373 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
374 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
375 CHECK_EXPECT(QueryService_InternetProtocol);
376 return E_NOINTERFACE;
379 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
380 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
381 CHECK_EXPECT(QueryService_HttpSecurity);
382 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
385 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
386 return E_FAIL;
389 static const IServiceProviderVtbl ServiceProviderVtbl = {
390 ServiceProvider_QueryInterface,
391 ServiceProvider_AddRef,
392 ServiceProvider_Release,
393 ServiceProvider_QueryService
396 static IServiceProvider service_provider = { &ServiceProviderVtbl };
398 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
400 return QueryInterface(riid, ppv);
403 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
405 return 2;
408 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
410 return 1;
413 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
415 HRESULT hres;
417 if(tested_protocol == FTP_TEST)
418 CHECK_EXPECT2(Switch);
419 else
420 CHECK_EXPECT(Switch);
421 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
423 pdata = pProtocolData;
425 if(binding_test) {
426 SetEvent(event_complete);
427 WaitForSingleObject(event_complete2, INFINITE);
428 return S_OK;
431 if (!state) {
432 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
433 if (http_is_first) {
434 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
435 CLEAR_CALLED(ReportProgress_CONNECTING);
436 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
437 } else todo_wine {
438 CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE);
439 /* IE7 does call this */
440 CLEAR_CALLED(ReportProgress_CONNECTING);
443 if(tested_protocol == FTP_TEST)
444 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
445 else if (tested_protocol != HTTPS_TEST)
446 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
447 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
448 SET_EXPECT(OnResponse);
449 if(tested_protocol == HTTPS_TEST)
450 SET_EXPECT(ReportProgress_ACCEPTRANGES);
451 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
452 if(bindf & BINDF_NEEDFILE)
453 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
457 SET_EXPECT(ReportData);
458 hres = IInternetProtocol_Continue(async_protocol, pProtocolData);
459 ok(hres == S_OK, "Continue failed: %08x\n", hres);
460 if(tested_protocol == FTP_TEST)
461 CLEAR_CALLED(ReportData);
462 else if (! security_problem)
463 CHECK_CALLED(ReportData);
465 if (!state) {
466 if (! security_problem)
468 state = 1;
469 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
470 CHECK_CALLED(OnResponse);
471 if(tested_protocol == HTTPS_TEST)
472 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
473 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
474 if(bindf & BINDF_NEEDFILE)
475 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
478 else
480 security_problem = FALSE;
481 SET_EXPECT(ReportProgress_CONNECTING);
485 SetEvent(event_complete);
487 return S_OK;
490 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
491 LPCWSTR szStatusText)
493 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
494 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
495 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
497 switch(ulStatusCode) {
498 case BINDSTATUS_MIMETYPEAVAILABLE:
499 CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
500 ok(szStatusText != NULL, "szStatusText == NULL\n");
501 if(szStatusText) {
502 if(tested_protocol == BIND_TEST)
503 ok(szStatusText == expect_wsz, "unexpected szStatusText\n");
504 else if (http_post_test)
505 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
506 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
507 "szStatusText != text/plain\n");
508 else
509 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
510 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
511 "szStatusText != text/html\n");
513 break;
514 case BINDSTATUS_DIRECTBIND:
515 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
516 ok(szStatusText == NULL, "szStatusText != NULL\n");
517 break;
518 case BINDSTATUS_RAWMIMETYPE:
519 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
520 ok(szStatusText != NULL, "szStatusText == NULL\n");
521 if(szStatusText)
522 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
523 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
524 "szStatusText != text/html\n");
525 break;
526 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
527 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
528 ok(szStatusText != NULL, "szStatusText == NULL\n");
529 if(szStatusText) {
530 if(binding_test)
531 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
532 else if(tested_protocol == FILE_TEST)
533 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = \"%s\"\n", debugstr_w(szStatusText));
534 else
535 ok(szStatusText != NULL, "szStatusText == NULL\n");
537 break;
538 case BINDSTATUS_FINDINGRESOURCE:
539 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
540 ok(szStatusText != NULL, "szStatusText == NULL\n");
541 break;
542 case BINDSTATUS_CONNECTING:
543 CHECK_EXPECT2(ReportProgress_CONNECTING);
544 ok(szStatusText != NULL, "szStatusText == NULL\n");
545 break;
546 case BINDSTATUS_SENDINGREQUEST:
547 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
548 if(tested_protocol == FILE_TEST) {
549 ok(szStatusText != NULL, "szStatusText == NULL\n");
550 if(szStatusText)
551 ok(!*szStatusText, "wrong szStatusText\n");
553 break;
554 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
555 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
556 ok(szStatusText != NULL, "szStatusText == NULL\n");
557 if(szStatusText)
558 ok(!lstrcmpW(szStatusText, text_htmlW), "szStatusText != text/html\n");
559 break;
560 case BINDSTATUS_PROTOCOLCLASSID:
561 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
562 ok(szStatusText != NULL, "szStatusText == NULL\n");
563 ok(!lstrcmpW(szStatusText, null_guid), "unexpected szStatusText\n");
564 break;
565 case BINDSTATUS_COOKIE_SENT:
566 CHECK_EXPECT(ReportProgress_COOKIE_SENT);
567 ok(szStatusText == NULL, "szStatusText != NULL\n");
568 break;
569 case BINDSTATUS_REDIRECTING:
570 CHECK_EXPECT(ReportProgress_REDIRECTING);
571 ok(szStatusText == NULL, "szStatusText = %s\n", debugstr_w(szStatusText));
572 break;
573 case BINDSTATUS_ENCODING:
574 CHECK_EXPECT(ReportProgress_ENCODING);
575 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", debugstr_w(szStatusText));
576 break;
577 case BINDSTATUS_ACCEPTRANGES:
578 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
579 ok(!szStatusText, "szStatusText = %s\n", debugstr_w(szStatusText));
580 break;
581 case BINDSTATUS_PROXYDETECTING:
582 CHECK_EXPECT(ReportProgress_PROXYDETECTING);
583 SET_EXPECT(ReportProgress_CONNECTING);
584 ok(!szStatusText, "szStatusText = %s\n", debugstr_w(szStatusText));
585 break;
586 default:
587 ok(0, "Unexpected status %d\n", ulStatusCode);
590 return S_OK;
593 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
594 ULONG ulProgress, ULONG ulProgressMax)
596 if(tested_protocol == FILE_TEST) {
597 CHECK_EXPECT2(ReportData);
599 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
600 ulProgress, ulProgressMax);
601 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
602 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION),
603 "grcfBSCF = %08x\n", grfBSCF);
604 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST)) {
605 if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
606 CHECK_EXPECT(ReportData);
607 else if (http_post_test)
608 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
610 ok(ulProgress, "ulProgress == 0\n");
612 if(first_data_notif) {
613 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
614 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
615 "grcfBSCF = %08x\n", grfBSCF);
616 first_data_notif = FALSE;
617 } else {
618 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
619 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
620 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
621 "grcfBSCF = %08x\n", grfBSCF);
624 if(!(bindf & BINDF_FROMURLMON) &&
625 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
626 if(!state) {
627 state = 1;
628 if(http_is_first) {
629 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
630 CHECK_CALLED(ReportProgress_CONNECTING);
631 } else todo_wine {
632 CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE);
633 CHECK_NOT_CALLED(ReportProgress_CONNECTING);
635 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
636 CHECK_CALLED(OnResponse);
637 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
639 SetEvent(event_complete);
641 }else {
642 BYTE buf[1000];
643 ULONG read;
644 HRESULT hres;
646 CHECK_EXPECT(ReportData);
648 if(tested_protocol == BIND_TEST)
649 return S_OK;
651 do {
652 SET_EXPECT(Read);
653 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
654 CHECK_CALLED(Read);
655 }while(hres == S_OK);
658 return S_OK;
661 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
662 DWORD dwError, LPCWSTR szResult)
664 CHECK_EXPECT(ReportResult);
666 if(tested_protocol == FTP_TEST)
667 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
668 else
669 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
670 hrResult, expect_hrResult);
671 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST)
672 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
673 else
674 ok(dwError != ERROR_SUCCESS, "dwError == ERROR_SUCCESS\n");
675 ok(!szResult, "szResult != NULL\n");
677 return S_OK;
680 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
681 ProtocolSink_QueryInterface,
682 ProtocolSink_AddRef,
683 ProtocolSink_Release,
684 ProtocolSink_Switch,
685 ProtocolSink_ReportProgress,
686 ProtocolSink_ReportData,
687 ProtocolSink_ReportResult
690 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
692 static HRESULT QueryInterface(REFIID riid, void **ppv)
694 *ppv = NULL;
696 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
697 *ppv = &protocol_sink;
698 if(IsEqualGUID(&IID_IServiceProvider, riid))
699 *ppv = &service_provider;
701 if(*ppv)
702 return S_OK;
704 return E_NOINTERFACE;
707 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
709 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
710 *ppv = iface;
711 return S_OK;
713 return E_NOINTERFACE;
716 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
718 return 2;
721 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
723 return 1;
726 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
728 DWORD cbSize;
730 static const CHAR szPostData[] = "mode=Test";
732 CHECK_EXPECT(GetBindInfo);
734 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
735 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
736 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
738 *grfBINDF = bindf;
739 if(binding_test)
740 *grfBINDF |= BINDF_FROMURLMON;
741 cbSize = pbindinfo->cbSize;
742 memset(pbindinfo, 0, cbSize);
743 pbindinfo->cbSize = cbSize;
745 if (http_post_test)
747 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly
748 * with urlmon on native (Win98 and WinXP) */
749 U(pbindinfo->stgmedData).hGlobal = GlobalAlloc(GPTR, sizeof(szPostData));
750 if (!U(pbindinfo->stgmedData).hGlobal)
752 http_post_test = FALSE;
753 skip("Out of memory\n");
754 return E_OUTOFMEMORY;
756 lstrcpy((LPSTR)U(pbindinfo->stgmedData).hGlobal, szPostData);
757 pbindinfo->cbstgmedData = sizeof(szPostData)-1;
758 pbindinfo->dwBindVerb = BINDVERB_POST;
759 pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
762 return S_OK;
765 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
766 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
768 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
769 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
771 switch(ulStringType) {
772 case BINDSTRING_ACCEPT_MIMES:
773 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
774 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
775 if(pcElFetched) {
776 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
777 *pcElFetched = 1;
779 if(ppwzStr) {
780 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
781 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
783 return S_OK;
784 case BINDSTRING_USER_AGENT:
785 CHECK_EXPECT(GetBindString_USER_AGENT);
786 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
787 if(pcElFetched) {
788 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
789 *pcElFetched = 1;
791 if(ppwzStr) {
792 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
793 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
795 return S_OK;
796 case BINDSTRING_POST_COOKIE:
797 CHECK_EXPECT(GetBindString_POST_COOKIE);
798 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
799 if(pcElFetched)
800 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
801 return S_OK;
802 default:
803 ok(0, "unexpected call\n");
806 return E_NOTIMPL;
809 static IInternetBindInfoVtbl bind_info_vtbl = {
810 BindInfo_QueryInterface,
811 BindInfo_AddRef,
812 BindInfo_Release,
813 BindInfo_GetBindInfo,
814 BindInfo_GetBindString
817 static IInternetBindInfo bind_info = { &bind_info_vtbl };
819 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
820 REFIID riid, void **ppv)
822 ok(0, "unexpected call\n");
823 return E_NOINTERFACE;
826 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
828 return 2;
831 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
833 return 1;
836 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
838 CHECK_EXPECT(SetPriority);
839 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
840 return S_OK;
843 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
845 ok(0, "unexpected call\n");
846 return E_NOTIMPL;
850 static const IInternetPriorityVtbl InternetPriorityVtbl = {
851 InternetPriority_QueryInterface,
852 InternetPriority_AddRef,
853 InternetPriority_Release,
854 InternetPriority_SetPriority,
855 InternetPriority_GetPriority
858 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
860 static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
862 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
863 *ppv = iface;
864 return S_OK;
867 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
868 trace("IID_IInternetProtocolEx not supported\n");
869 *ppv = NULL;
870 return E_NOINTERFACE;
873 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
874 *ppv = &InternetPriority;
875 return S_OK;
878 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
879 *ppv = NULL;
880 return E_NOINTERFACE;
883 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
885 return 2;
888 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
890 return 1;
893 static DWORD WINAPI thread_proc(PVOID arg)
895 HRESULT hres;
897 memset(&protocoldata, -1, sizeof(protocoldata));
899 prot_state = 0;
901 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
902 hres = IInternetProtocolSink_ReportProgress(binding_sink,
903 BINDSTATUS_FINDINGRESOURCE, hostW);
904 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
905 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
907 SET_EXPECT(ReportProgress_CONNECTING);
908 hres = IInternetProtocolSink_ReportProgress(binding_sink,
909 BINDSTATUS_CONNECTING, winehq_ipW);
910 CHECK_CALLED(ReportProgress_CONNECTING);
911 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
913 SET_EXPECT(ReportProgress_SENDINGREQUEST);
914 hres = IInternetProtocolSink_ReportProgress(binding_sink,
915 BINDSTATUS_SENDINGREQUEST, NULL);
916 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
917 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
919 prot_state = 1;
920 SET_EXPECT(Switch);
921 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
922 CHECK_CALLED(Switch);
923 ok(hres == S_OK, "Switch failed: %08x\n", hres);
925 prot_state = 2;
926 SET_EXPECT(Switch);
927 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
928 CHECK_CALLED(Switch);
929 ok(hres == S_OK, "Switch failed: %08x\n", hres);
931 prot_state = 2;
932 SET_EXPECT(Switch);
933 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
934 CHECK_CALLED(Switch);
935 ok(hres == S_OK, "Switch failed: %08x\n", hres);
937 prot_state = 3;
938 SET_EXPECT(Switch);
939 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
940 CHECK_CALLED(Switch);
941 ok(hres == S_OK, "Switch failed: %08x\n", hres);
943 SetEvent(event_complete);
945 return 0;
948 static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
949 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
950 DWORD grfPI, HANDLE_PTR dwReserved)
952 BINDINFO bindinfo, exp_bindinfo;
953 DWORD cbindf = 0;
954 HRESULT hres;
956 CHECK_EXPECT(Start);
958 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
959 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
960 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
961 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
962 ok(!grfPI, "grfPI = %x\n", grfPI);
963 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
965 memset(&bindinfo, 0, sizeof(bindinfo));
966 bindinfo.cbSize = sizeof(bindinfo);
967 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
968 SET_EXPECT(GetBindInfo);
969 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
970 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
971 CHECK_CALLED(GetBindInfo);
972 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
973 cbindf, (bindf|BINDF_FROMURLMON));
974 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
975 ReleaseBindInfo(&bindinfo);
977 SET_EXPECT(ReportProgress_SENDINGREQUEST);
978 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
979 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
980 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
982 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
983 IServiceProvider *service_provider;
984 IHttpNegotiate *http_negotiate;
985 IHttpNegotiate2 *http_negotiate2;
986 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
987 LPWSTR additional_headers = NULL;
988 BYTE sec_id[100];
989 DWORD fetched = 0, size = 100;
990 DWORD tid;
992 SET_EXPECT(GetBindString_USER_AGENT);
993 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
994 &ua, 1, &fetched);
995 CHECK_CALLED(GetBindString_USER_AGENT);
996 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
997 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
998 ok(ua != NULL, "ua = %p\n", ua);
999 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", debugstr_w(ua));
1000 CoTaskMemFree(ua);
1002 fetched = 256;
1003 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1004 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1005 accept_mimes, 256, &fetched);
1006 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1008 ok(hres == S_OK,
1009 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1010 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1011 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", debugstr_w(accept_mimes[0]));
1013 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1014 (void**)&service_provider);
1015 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1017 SET_EXPECT(QueryService_HttpNegotiate);
1018 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1019 &IID_IHttpNegotiate, (void**)&http_negotiate);
1020 CHECK_CALLED(QueryService_HttpNegotiate);
1021 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1023 SET_EXPECT(BeginningTransaction);
1024 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1025 NULL, 0, &additional_headers);
1026 CHECK_CALLED(BeginningTransaction);
1027 IHttpNegotiate_Release(http_negotiate);
1028 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1029 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1031 SET_EXPECT(QueryService_HttpNegotiate);
1032 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1033 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1034 CHECK_CALLED(QueryService_HttpNegotiate);
1035 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1037 size = 512;
1038 SET_EXPECT(GetRootSecurityId);
1039 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1040 CHECK_CALLED(GetRootSecurityId);
1041 IHttpNegotiate2_Release(http_negotiate2);
1042 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1043 ok(size == 13, "size=%d\n", size);
1045 IServiceProvider_Release(service_provider);
1047 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1049 return S_OK;
1052 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1053 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1054 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1055 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1056 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1058 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1059 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1060 expect_wsz = text_htmlW);
1061 ok(hres == S_OK,
1062 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1063 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1065 SET_EXPECT(ReportData);
1066 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1067 BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION, 13, 13);
1068 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1069 CHECK_CALLED(ReportData);
1071 if(tested_protocol == BIND_TEST) {
1072 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1073 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1076 SET_EXPECT(ReportResult);
1077 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1078 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1079 CHECK_CALLED(ReportResult);
1081 return S_OK;
1084 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
1085 PROTOCOLDATA *pProtocolData)
1087 DWORD bscf = 0;
1088 HRESULT hres;
1090 CHECK_EXPECT(Continue);
1092 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1093 if(!pProtocolData || tested_protocol == BIND_TEST)
1094 return S_OK;
1096 switch(prot_state) {
1097 case 1: {
1098 IServiceProvider *service_provider;
1099 IHttpNegotiate *http_negotiate;
1100 static WCHAR header[] = {'?',0};
1102 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1103 (void**)&service_provider);
1104 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1106 SET_EXPECT(QueryService_HttpNegotiate);
1107 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1108 &IID_IHttpNegotiate, (void**)&http_negotiate);
1109 IServiceProvider_Release(service_provider);
1110 CHECK_CALLED(QueryService_HttpNegotiate);
1111 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1113 SET_EXPECT(OnResponse);
1114 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1115 IHttpNegotiate_Release(http_negotiate);
1116 CHECK_CALLED(OnResponse);
1117 IHttpNegotiate_Release(http_negotiate);
1118 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1120 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1121 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1122 BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1123 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1124 ok(hres == S_OK,
1125 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1127 bscf |= BSCF_FIRSTDATANOTIFICATION;
1128 break;
1130 case 2:
1131 case 3:
1132 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1133 break;
1136 SET_EXPECT(ReportData);
1137 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, 100, 400);
1138 CHECK_CALLED(ReportData);
1139 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1141 if(prot_state == 3)
1142 prot_state = 4;
1144 return S_OK;
1147 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
1148 DWORD dwOptions)
1150 ok(0, "unexpected call\n");
1151 return E_NOTIMPL;
1154 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
1156 CHECK_EXPECT(Terminate);
1157 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1158 return S_OK;
1161 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
1163 ok(0, "unexpected call\n");
1164 return E_NOTIMPL;
1167 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
1169 ok(0, "unexpected call\n");
1170 return E_NOTIMPL;
1173 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
1174 ULONG cb, ULONG *pcbRead)
1176 static BOOL b = TRUE;
1178 CHECK_EXPECT(Read);
1180 ok(pv == expect_pv, "pv != expect_pv\n");
1181 ok(cb == 1000, "cb=%d\n", cb);
1182 ok(pcbRead != NULL, "pcbRead == NULL\n");
1183 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1185 if(prot_state == 3) {
1186 HRESULT hres;
1188 SET_EXPECT(ReportResult);
1189 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1190 CHECK_CALLED(ReportResult);
1192 return S_FALSE;
1195 if((b = !b))
1196 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
1198 memset(pv, 'x', 100);
1199 prot_read += *pcbRead = 100;
1200 return S_OK;
1203 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
1204 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1206 ok(0, "unexpected call\n");
1207 return E_NOTIMPL;
1210 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
1212 CHECK_EXPECT(LockRequest);
1213 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
1214 return S_OK;
1217 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
1219 CHECK_EXPECT(UnlockRequest);
1220 return S_OK;
1223 static const IInternetProtocolVtbl ProtocolVtbl = {
1224 Protocol_QueryInterface,
1225 Protocol_AddRef,
1226 Protocol_Release,
1227 Protocol_Start,
1228 Protocol_Continue,
1229 Protocol_Abort,
1230 Protocol_Terminate,
1231 Protocol_Suspend,
1232 Protocol_Resume,
1233 Protocol_Read,
1234 Protocol_Seek,
1235 Protocol_LockRequest,
1236 Protocol_UnlockRequest
1239 static IInternetProtocol Protocol = { &ProtocolVtbl };
1241 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1243 ok(0, "unexpected call\n");
1244 return E_NOINTERFACE;
1247 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1249 return 2;
1252 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1254 return 1;
1257 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1258 REFIID riid, void **ppv)
1260 CHECK_EXPECT(CreateInstance);
1262 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
1263 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
1264 ok(ppv != NULL, "ppv == NULL\n");
1266 *ppv = &Protocol;
1267 return S_OK;
1270 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1272 ok(0, "unexpected call\n");
1273 return S_OK;
1276 static const IClassFactoryVtbl ClassFactoryVtbl = {
1277 ClassFactory_QueryInterface,
1278 ClassFactory_AddRef,
1279 ClassFactory_Release,
1280 ClassFactory_CreateInstance,
1281 ClassFactory_LockServer
1284 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
1286 static void test_priority(IInternetProtocol *protocol)
1288 IInternetPriority *priority;
1289 LONG pr;
1290 HRESULT hres;
1292 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
1293 (void**)&priority);
1294 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
1295 if(FAILED(hres))
1296 return;
1298 hres = IInternetPriority_GetPriority(priority, &pr);
1299 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
1300 ok(pr == 0, "pr=%d, expected 0\n", pr);
1302 hres = IInternetPriority_SetPriority(priority, 1);
1303 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
1305 hres = IInternetPriority_GetPriority(priority, &pr);
1306 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
1307 ok(pr == 1, "pr=%d, expected 1\n", pr);
1309 IInternetPriority_Release(priority);
1312 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url, BOOL is_first)
1314 HRESULT hres;
1316 SET_EXPECT(GetBindInfo);
1317 if(!(bindf & BINDF_FROMURLMON))
1318 SET_EXPECT(ReportProgress_DIRECTBIND);
1319 if(is_first) {
1320 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1321 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1322 if(bindf & BINDF_FROMURLMON)
1323 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
1324 else
1325 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1327 SET_EXPECT(ReportData);
1328 if(is_first)
1329 SET_EXPECT(ReportResult);
1331 expect_hrResult = S_OK;
1333 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
1334 if(hres == INET_E_RESOURCE_NOT_FOUND) {
1335 win_skip("Start failed\n");
1336 return FALSE;
1338 ok(hres == S_OK, "Start failed: %08x\n", hres);
1340 CHECK_CALLED(GetBindInfo);
1341 if(!(bindf & BINDF_FROMURLMON))
1342 CHECK_CALLED(ReportProgress_DIRECTBIND);
1343 if(is_first) {
1344 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1345 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1346 if(bindf & BINDF_FROMURLMON)
1347 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
1348 else
1349 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1351 CHECK_CALLED(ReportData);
1352 if(is_first)
1353 CHECK_CALLED(ReportResult);
1355 return TRUE;
1358 static void test_file_protocol_url(LPCWSTR url)
1360 IInternetProtocolInfo *protocol_info;
1361 IUnknown *unk;
1362 IClassFactory *factory;
1363 HRESULT hres;
1365 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
1366 &IID_IUnknown, (void**)&unk);
1367 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
1368 if(FAILED(hres))
1369 return;
1371 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
1372 ok(hres == E_NOINTERFACE,
1373 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
1375 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
1376 ok(hres == S_OK, "Could not get IClassFactory interface\n");
1377 if(SUCCEEDED(hres)) {
1378 IInternetProtocol *protocol;
1379 BYTE buf[512];
1380 ULONG cb;
1381 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
1382 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
1384 if(SUCCEEDED(hres)) {
1385 if(file_protocol_start(protocol, url, TRUE)) {
1386 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
1387 ok(hres == S_OK, "Read failed: %08x\n", hres);
1388 ok(cb == 2, "cb=%u expected 2\n", cb);
1389 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
1390 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
1391 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
1392 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
1393 ok(cb == 0, "cb=%u expected 0\n", cb);
1394 hres = IInternetProtocol_UnlockRequest(protocol);
1395 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
1398 if(file_protocol_start(protocol, url, FALSE)) {
1399 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
1400 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
1401 hres = IInternetProtocol_LockRequest(protocol, 0);
1402 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
1403 hres = IInternetProtocol_UnlockRequest(protocol);
1404 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
1407 IInternetProtocol_Release(protocol);
1410 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
1411 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
1413 if(SUCCEEDED(hres)) {
1414 if(file_protocol_start(protocol, url, TRUE)) {
1415 hres = IInternetProtocol_LockRequest(protocol, 0);
1416 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
1417 hres = IInternetProtocol_Terminate(protocol, 0);
1418 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
1419 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
1420 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
1421 hres = IInternetProtocol_UnlockRequest(protocol);
1422 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
1423 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
1424 ok(hres == S_OK, "Read failed: %08x\n", hres);
1425 hres = IInternetProtocol_Terminate(protocol, 0);
1426 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
1429 IInternetProtocol_Release(protocol);
1432 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
1433 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
1435 if(SUCCEEDED(hres)) {
1436 if(file_protocol_start(protocol, url, TRUE)) {
1437 hres = IInternetProtocol_Terminate(protocol, 0);
1438 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
1439 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
1440 ok(hres == S_OK, "Read failed: %08x\n", hres);
1441 ok(cb == 2, "cb=%u expected 2\n", cb);
1444 IInternetProtocol_Release(protocol);
1447 IClassFactory_Release(factory);
1450 IUnknown_Release(unk);
1453 static void test_file_protocol_fail(void)
1455 IInternetProtocol *protocol;
1456 HRESULT hres;
1458 static const WCHAR index_url2[] =
1459 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
1461 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1462 &IID_IInternetProtocol, (void**)&protocol);
1463 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1464 if(FAILED(hres))
1465 return;
1467 SET_EXPECT(GetBindInfo);
1468 expect_hrResult = MK_E_SYNTAX;
1469 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
1470 ok(hres == MK_E_SYNTAX ||
1471 hres == E_INVALIDARG,
1472 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
1473 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
1475 SET_EXPECT(GetBindInfo);
1476 if(!(bindf & BINDF_FROMURLMON))
1477 SET_EXPECT(ReportProgress_DIRECTBIND);
1478 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1479 SET_EXPECT(ReportResult);
1480 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
1481 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
1482 ok(hres == INET_E_RESOURCE_NOT_FOUND,
1483 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
1484 CHECK_CALLED(GetBindInfo);
1485 if(!(bindf & BINDF_FROMURLMON))
1486 CHECK_CALLED(ReportProgress_DIRECTBIND);
1487 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1488 CHECK_CALLED(ReportResult);
1490 IInternetProtocol_Release(protocol);
1492 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1493 &IID_IInternetProtocol, (void**)&protocol);
1494 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1495 if(FAILED(hres))
1496 return;
1498 SET_EXPECT(GetBindInfo);
1499 if(!(bindf & BINDF_FROMURLMON))
1500 SET_EXPECT(ReportProgress_DIRECTBIND);
1501 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1502 SET_EXPECT(ReportResult);
1503 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
1505 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
1506 ok(hres == INET_E_RESOURCE_NOT_FOUND,
1507 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
1508 CHECK_CALLED(GetBindInfo);
1509 if(!(bindf & BINDF_FROMURLMON))
1510 CHECK_CALLED(ReportProgress_DIRECTBIND);
1511 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1512 CHECK_CALLED(ReportResult);
1514 SET_EXPECT(GetBindInfo);
1515 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
1516 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
1517 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
1519 SET_EXPECT(GetBindInfo);
1520 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
1521 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
1522 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
1524 IInternetProtocol_Release(protocol);
1527 static void test_file_protocol(void) {
1528 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
1529 DWORD size;
1530 ULONG len;
1531 HANDLE file;
1533 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
1534 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
1535 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
1536 static const char html_doc[] = "<HTML></HTML>";
1538 trace("Testing file protocol...\n");
1539 tested_protocol = FILE_TEST;
1541 SetLastError(0xdeadbeef);
1542 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1543 FILE_ATTRIBUTE_NORMAL, NULL);
1544 if(!file && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1546 win_skip("Detected Win9x or WinMe\n");
1547 return;
1549 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1550 if(file == INVALID_HANDLE_VALUE)
1551 return;
1552 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
1553 CloseHandle(file);
1555 file_name = wszIndexHtml;
1556 bindf = 0;
1557 test_file_protocol_url(index_url);
1558 bindf = BINDF_FROMURLMON;
1559 test_file_protocol_url(index_url);
1560 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
1561 test_file_protocol_url(index_url);
1563 memcpy(buf, wszFile, sizeof(wszFile));
1564 len = sizeof(wszFile)/sizeof(WCHAR)-1;
1565 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
1566 buf[len++] = '\\';
1567 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
1569 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
1570 bindf = 0;
1571 test_file_protocol_url(buf);
1572 bindf = BINDF_FROMURLMON;
1573 test_file_protocol_url(buf);
1575 memcpy(buf, wszFile2, sizeof(wszFile2));
1576 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
1577 file_name_buf[len++] = '\\';
1578 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
1579 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
1580 file_name = file_name_buf;
1581 bindf = 0;
1582 test_file_protocol_url(buf);
1583 bindf = BINDF_FROMURLMON;
1584 test_file_protocol_url(buf);
1586 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
1587 test_file_protocol_url(buf);
1589 memcpy(buf, wszFile3, sizeof(wszFile3));
1590 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
1591 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
1592 buf[len++] = '\\';
1593 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
1595 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
1596 bindf = 0;
1597 test_file_protocol_url(buf);
1598 bindf = BINDF_FROMURLMON;
1599 test_file_protocol_url(buf);
1601 DeleteFileW(wszIndexHtml);
1603 bindf = 0;
1604 test_file_protocol_fail();
1605 bindf = BINDF_FROMURLMON;
1606 test_file_protocol_fail();
1609 static BOOL http_protocol_start(LPCWSTR url, BOOL is_first)
1611 static BOOL got_user_agent = FALSE;
1612 HRESULT hres;
1614 first_data_notif = TRUE;
1615 state = 0;
1617 SET_EXPECT(GetBindInfo);
1618 if (!(bindf & BINDF_FROMURLMON))
1619 SET_EXPECT(ReportProgress_DIRECTBIND);
1620 SET_EXPECT(GetBindString_USER_AGENT);
1621 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1622 SET_EXPECT(QueryService_HttpNegotiate);
1623 SET_EXPECT(BeginningTransaction);
1624 SET_EXPECT(GetRootSecurityId);
1625 if (http_post_test)
1626 SET_EXPECT(GetBindString_POST_COOKIE);
1628 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
1629 ok(hres == S_OK, "Start failed: %08x\n", hres);
1630 if(FAILED(hres))
1631 return FALSE;
1633 CHECK_CALLED(GetBindInfo);
1634 if (!(bindf & BINDF_FROMURLMON))
1635 CHECK_CALLED(ReportProgress_DIRECTBIND);
1636 if (!got_user_agent)
1638 CHECK_CALLED(GetBindString_USER_AGENT);
1639 got_user_agent = TRUE;
1641 else todo_wine
1643 /* user agent only retrieved once, even with different URLs */
1644 CHECK_NOT_CALLED(GetBindString_USER_AGENT);
1646 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1647 CHECK_CALLED(QueryService_HttpNegotiate);
1648 CHECK_CALLED(BeginningTransaction);
1649 /* GetRootSecurityId called on WinXP but not on Win98 */
1650 CLEAR_CALLED(GetRootSecurityId);
1651 if (http_post_test)
1652 CHECK_CALLED(GetBindString_POST_COOKIE);
1654 return TRUE;
1657 static void test_protocol_terminate(IInternetProtocol *protocol)
1659 BYTE buf[3600];
1660 DWORD cb;
1661 HRESULT hres;
1663 hres = IInternetProtocol_LockRequest(protocol, 0);
1664 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
1666 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
1667 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
1669 hres = IInternetProtocol_Terminate(protocol, 0);
1670 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
1672 /* This wait is to give the internet handles being freed in Terminate
1673 * enough time to actually terminate in all cases. Internet handles
1674 * terminate asynchronously and native reuses the main InternetOpen
1675 * handle. The only case in which this seems to be necessary is on
1676 * wine with native wininet and urlmon, resulting in the next time
1677 * test_http_protocol_url being called the first data notification actually
1678 * being an extra last data notification from the previous connection
1679 * about once out of every ten times. */
1680 Sleep(100);
1682 hres = IInternetProtocol_UnlockRequest(protocol);
1683 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
1686 static void test_http_info(IInternetProtocol *protocol)
1688 IWinInetHttpInfo *info;
1689 HRESULT hres;
1691 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
1692 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
1694 /* TODO */
1696 IWinInetHttpInfo_Release(info);
1699 /* is_first refers to whether this is the first call to this function
1700 * _for this url_ */
1701 static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
1703 IInternetProtocolInfo *protocol_info;
1704 IClassFactory *factory;
1705 IUnknown *unk;
1706 HRESULT hres;
1708 http_url = url;
1709 http_is_first = is_first;
1711 hres = CoGetClassObject(is_https ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
1712 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
1713 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
1714 if(FAILED(hres))
1715 return;
1717 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
1718 ok(hres == E_NOINTERFACE,
1719 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
1720 hres);
1722 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
1723 ok(hres == S_OK, "Could not get IClassFactory interface\n");
1724 IUnknown_Release(unk);
1725 if(FAILED(hres))
1726 return;
1728 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
1729 (void**)&async_protocol);
1730 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
1731 if(SUCCEEDED(hres)) {
1732 BYTE buf[3600];
1733 DWORD cb;
1734 ULONG ref;
1736 test_priority(async_protocol);
1737 test_http_info(async_protocol);
1739 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1740 SET_EXPECT(ReportProgress_CONNECTING);
1741 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1742 SET_EXPECT(ReportProgress_PROXYDETECTING);
1743 if(! is_https)
1744 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1745 else
1746 SET_EXPECT(QueryService_HttpSecurity);
1747 if(!(bindf & BINDF_FROMURLMON)) {
1748 SET_EXPECT(OnResponse);
1749 SET_EXPECT(ReportProgress_RAWMIMETYPE);
1750 SET_EXPECT(ReportData);
1751 } else {
1752 SET_EXPECT(Switch);
1755 if(!http_protocol_start(url, is_first))
1756 return;
1758 SET_EXPECT(ReportResult);
1759 expect_hrResult = S_OK;
1761 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
1762 ok((hres == E_PENDING && cb==0) ||
1763 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
1765 WaitForSingleObject(event_complete, INFINITE);
1766 if(bindf & BINDF_FROMURLMON)
1767 CHECK_CALLED(Switch);
1768 else
1769 CHECK_CALLED(ReportData);
1770 if (is_https)
1771 CLEAR_CALLED(QueryService_HttpSecurity);
1773 while(1) {
1774 if(bindf & BINDF_FROMURLMON)
1775 SET_EXPECT(Switch);
1776 else
1777 SET_EXPECT(ReportData);
1778 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
1779 if(hres == E_PENDING) {
1780 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
1781 ok((hres == E_PENDING && cb==0) ||
1782 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
1783 WaitForSingleObject(event_complete, INFINITE);
1784 if(bindf & BINDF_FROMURLMON)
1785 CHECK_CALLED(Switch);
1786 else
1787 CHECK_CALLED(ReportData);
1788 }else {
1789 if(bindf & BINDF_FROMURLMON)
1790 CHECK_NOT_CALLED(Switch);
1791 else
1792 CHECK_NOT_CALLED(ReportData);
1793 if(cb == 0) break;
1796 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
1797 CHECK_CALLED(ReportResult);
1798 if (is_https)
1799 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
1801 test_protocol_terminate(async_protocol);
1802 ref = IInternetProtocol_Release(async_protocol);
1803 ok(!ref, "ref=%x\n", hres);
1806 IClassFactory_Release(factory);
1809 static void test_http_protocol(void)
1811 static const WCHAR winehq_url[] =
1812 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
1813 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
1814 static const WCHAR posttest_url[] =
1815 {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
1816 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
1817 'p','o','s','t','t','e','s','t','.','p','h','p',0};
1819 trace("Testing http protocol (not from urlmon)...\n");
1820 tested_protocol = HTTP_TEST;
1821 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
1822 test_http_protocol_url(winehq_url, FALSE, TRUE);
1824 trace("Testing http protocol (from urlmon)...\n");
1825 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
1826 test_http_protocol_url(winehq_url, FALSE, FALSE);
1828 trace("Testing http protocol (to file)...\n");
1829 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
1830 test_http_protocol_url(winehq_url, FALSE, FALSE);
1832 trace("Testing http protocol (post data)...\n");
1833 http_post_test = TRUE;
1834 /* Without this flag we get a ReportProgress_CACHEFILENAMEAVAILABLE
1835 * notification with BINDVERB_POST */
1836 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
1837 test_http_protocol_url(posttest_url, FALSE, TRUE);
1838 http_post_test = FALSE;
1841 static void test_https_protocol(void)
1843 static const WCHAR codeweavers_url[] =
1844 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
1845 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0};
1847 trace("Testing https protocol (from urlmon)...\n");
1848 tested_protocol = HTTPS_TEST;
1849 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
1850 test_http_protocol_url(codeweavers_url, TRUE, TRUE);
1854 static void test_ftp_protocol(void)
1856 IInternetProtocolInfo *protocol_info;
1857 IClassFactory *factory;
1858 IUnknown *unk;
1859 BYTE buf[4096];
1860 ULONG ref;
1861 DWORD cb;
1862 HRESULT hres;
1864 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
1865 '/','p','u','b','/','o','t','h','e','r','/',
1866 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
1868 trace("Testing ftp protocol...\n");
1870 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
1871 state = 0;
1872 tested_protocol = FTP_TEST;
1873 first_data_notif = TRUE;
1874 expect_hrResult = E_PENDING;
1876 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
1877 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
1878 if(FAILED(hres))
1879 return;
1881 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
1882 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
1884 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
1885 ok(hres == S_OK, "Could not get IClassFactory interface\n");
1886 IUnknown_Release(unk);
1887 if(FAILED(hres))
1888 return;
1890 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
1891 (void**)&async_protocol);
1892 IClassFactory_Release(factory);
1893 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
1895 test_priority(async_protocol);
1896 test_http_info(async_protocol);
1898 SET_EXPECT(GetBindInfo);
1899 SET_EXPECT(GetBindString_USER_AGENT);
1900 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1901 SET_EXPECT(ReportProgress_CONNECTING);
1902 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1903 SET_EXPECT(Switch);
1905 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
1906 ok(hres == S_OK, "Start failed: %08x\n", hres);
1907 CHECK_CALLED(GetBindInfo);
1908 todo_wine CHECK_NOT_CALLED(GetBindString_USER_AGENT);
1910 SET_EXPECT(ReportResult);
1912 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
1913 ok((hres == E_PENDING && cb==0) ||
1914 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
1916 WaitForSingleObject(event_complete, INFINITE);
1918 while(1) {
1920 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
1921 if(hres == E_PENDING)
1922 WaitForSingleObject(event_complete, INFINITE);
1923 else
1924 if(cb == 0) break;
1927 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
1928 CHECK_CALLED(ReportResult);
1929 CHECK_CALLED(Switch);
1931 test_protocol_terminate(async_protocol);
1933 ref = IInternetProtocol_Release(async_protocol);
1934 ok(!ref, "ref=%d\n", ref);
1937 static void test_gopher_protocol(void)
1939 IInternetProtocolInfo *protocol_info;
1940 IClassFactory *factory;
1941 IUnknown *unk;
1942 HRESULT hres;
1944 trace("Testing gopher protocol...\n");
1946 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
1947 ok(hres == S_OK ||
1948 hres == REGDB_E_CLASSNOTREG, /* Gopher protocol has been removed as of Vista */
1949 "CoGetClassObject failed: %08x\n", hres);
1950 if(FAILED(hres))
1951 return;
1953 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
1954 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
1956 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
1957 ok(hres == S_OK, "Could not get IClassFactory interface\n");
1958 IUnknown_Release(unk);
1959 if(FAILED(hres))
1960 return;
1962 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
1963 (void**)&async_protocol);
1964 IClassFactory_Release(factory);
1965 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
1967 test_priority(async_protocol);
1969 IInternetProtocol_Release(async_protocol);
1972 static void test_mk_protocol(void)
1974 IInternetProtocolInfo *protocol_info;
1975 IInternetProtocol *protocol;
1976 IClassFactory *factory;
1977 IUnknown *unk;
1978 HRESULT hres;
1980 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
1981 ':',':','/','t','e','s','t','.','h','t','m','l',0};
1982 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
1984 trace("Testing mk protocol...\n");
1985 tested_protocol = MK_TEST;
1987 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
1988 &IID_IUnknown, (void**)&unk);
1989 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
1991 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
1992 ok(hres == E_NOINTERFACE,
1993 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
1994 hres);
1996 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
1997 ok(hres == S_OK, "Could not get IClassFactory interface\n");
1998 IUnknown_Release(unk);
1999 if(FAILED(hres))
2000 return;
2002 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
2003 (void**)&protocol);
2004 IClassFactory_Release(factory);
2005 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2007 SET_EXPECT(GetBindInfo);
2008 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
2009 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
2010 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
2011 CLEAR_CALLED(GetBindInfo);
2013 SET_EXPECT(GetBindInfo);
2014 SET_EXPECT(ReportProgress_DIRECTBIND);
2015 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2016 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2017 SET_EXPECT(ReportResult);
2018 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2020 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
2021 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
2022 hres == INET_E_INVALID_URL, /* win2k3 */
2023 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
2025 if (hres == INET_E_RESOURCE_NOT_FOUND) {
2026 CHECK_CALLED(GetBindInfo);
2027 CLEAR_CALLED(ReportProgress_DIRECTBIND);
2028 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2029 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2030 CHECK_CALLED(ReportResult);
2031 }else {
2032 CLEAR_CALLED(GetBindInfo);
2033 CLEAR_CALLED(ReportProgress_DIRECTBIND);
2034 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
2035 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2036 CLEAR_CALLED(ReportResult);
2039 IInternetProtocol_Release(protocol);
2042 static void test_CreateBinding(void)
2044 IInternetProtocolSink *sink;
2045 IInternetProtocol *protocol;
2046 IInternetPriority *priority;
2047 IInternetSession *session;
2048 LONG p;
2049 BYTE buf[1000];
2050 DWORD read;
2051 HRESULT hres;
2053 static const WCHAR test_url[] =
2054 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
2055 static const WCHAR wsz_test[] = {'t','e','s','t',0};
2057 trace("Testing CreateBinding...\n");
2058 tested_protocol = BIND_TEST;
2059 binding_test = TRUE;
2061 hres = CoInternetGetSession(0, &session, 0);
2062 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2064 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
2065 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
2067 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
2068 binding_protocol = protocol;
2069 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
2070 ok(protocol != NULL, "protocol == NULL\n");
2072 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
2073 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
2075 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&sink);
2076 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
2078 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
2079 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2080 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
2081 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2082 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2083 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2085 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
2086 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2088 p = 0xdeadbeef;
2089 hres = IInternetPriority_GetPriority(priority, &p);
2090 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2091 ok(!p, "p=%d\n", p);
2093 ex_priority = 100;
2094 hres = IInternetPriority_SetPriority(priority, 100);
2095 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2097 p = 0xdeadbeef;
2098 hres = IInternetPriority_GetPriority(priority, &p);
2099 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2100 ok(p == 100, "p=%d\n", p);
2102 SET_EXPECT(QueryService_InternetProtocol);
2103 SET_EXPECT(CreateInstance);
2104 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
2105 SET_EXPECT(SetPriority);
2106 SET_EXPECT(Start);
2108 expect_hrResult = S_OK;
2109 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
2110 ok(hres == S_OK, "Start failed: %08x\n", hres);
2112 CHECK_CALLED(QueryService_InternetProtocol);
2113 CHECK_CALLED(CreateInstance);
2114 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
2115 CHECK_CALLED(SetPriority);
2116 CHECK_CALLED(Start);
2118 SET_EXPECT(Read);
2119 read = 0xdeadbeef;
2120 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
2121 ok(hres == S_OK, "Read failed: %08x\n", hres);
2122 ok(read == 100, "read = %d\n", read);
2123 CHECK_CALLED(Read);
2125 SET_EXPECT(Read);
2126 read = 0xdeadbeef;
2127 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
2128 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2129 ok(!read, "read = %d\n", read);
2130 CHECK_CALLED(Read);
2132 p = 0xdeadbeef;
2133 hres = IInternetPriority_GetPriority(priority, &p);
2134 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2135 ok(p == 100, "p=%d\n", p);
2137 hres = IInternetPriority_SetPriority(priority, 101);
2138 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2140 SET_EXPECT(Terminate);
2141 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
2142 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2143 CHECK_CALLED(Terminate);
2145 SET_EXPECT(Continue);
2146 hres = IInternetProtocolSink_Switch(sink, &protocoldata);
2147 ok(hres == S_OK, "Switch failed: %08x\n", hres);
2148 CHECK_CALLED(Continue);
2150 hres = IInternetProtocolSink_ReportProgress(sink,
2151 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
2152 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
2154 hres = IInternetProtocolSink_ReportResult(sink, S_OK, ERROR_SUCCESS, NULL);
2155 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
2157 hres = IInternetProtocolSink_ReportData(sink, 0, 0, 0);
2158 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
2160 IInternetProtocolSink_Release(sink);
2161 IInternetPriority_Release(priority);
2162 IInternetBindInfo_Release(prot_bind_info);
2163 IInternetProtocol_Release(protocol);
2164 IInternetSession_Release(session);
2167 static void test_binding(int prot)
2169 IInternetProtocol *protocol;
2170 IInternetSession *session;
2171 ULONG ref;
2172 HRESULT hres;
2174 trace("Testing %s binding...\n", debugstr_w(protocol_names[prot]));
2176 tested_protocol = prot;
2177 binding_test = TRUE;
2178 first_data_notif = TRUE;
2179 prot_read = 0;
2181 hres = CoInternetGetSession(0, &session, 0);
2182 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2184 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
2185 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
2187 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
2188 binding_protocol = protocol;
2189 IInternetSession_Release(session);
2190 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
2191 ok(protocol != NULL, "protocol == NULL\n");
2193 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
2194 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
2196 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
2197 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
2199 ex_priority = 0;
2200 SET_EXPECT(QueryService_InternetProtocol);
2201 SET_EXPECT(CreateInstance);
2202 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
2203 SET_EXPECT(SetPriority);
2204 SET_EXPECT(Start);
2206 expect_hrResult = S_OK;
2207 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, 0, 0);
2208 ok(hres == S_OK, "Start failed: %08x\n", hres);
2210 CHECK_CALLED(QueryService_InternetProtocol);
2211 CHECK_CALLED(CreateInstance);
2212 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
2213 CHECK_CALLED(SetPriority);
2214 CHECK_CALLED(Start);
2216 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
2217 while(prot_state < 4) {
2218 WaitForSingleObject(event_complete, INFINITE);
2219 SET_EXPECT(Continue);
2220 IInternetProtocol_Continue(protocol, pdata);
2221 CHECK_CALLED(Continue);
2222 SetEvent(event_complete2);
2225 WaitForSingleObject(event_complete, INFINITE);
2226 }else {
2227 SET_EXPECT(LockRequest);
2228 hres = IInternetProtocol_LockRequest(protocol, 0);
2229 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2230 CHECK_CALLED(LockRequest);
2232 SET_EXPECT(UnlockRequest);
2233 hres = IInternetProtocol_UnlockRequest(protocol);
2234 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2235 CHECK_CALLED(UnlockRequest);
2238 SET_EXPECT(Terminate);
2239 hres = IInternetProtocol_Terminate(protocol, 0);
2240 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2241 CHECK_CALLED(Terminate);
2243 IInternetBindInfo_Release(prot_bind_info);
2244 IInternetProtocolSink_Release(binding_sink);
2245 ref = IInternetProtocol_Release(protocol);
2246 ok(!ref, "ref=%u, expected 0\n", ref);
2249 START_TEST(protocol)
2251 OleInitialize(NULL);
2253 event_complete = CreateEvent(NULL, FALSE, FALSE, NULL);
2254 event_complete2 = CreateEvent(NULL, FALSE, FALSE, NULL);
2256 test_file_protocol();
2257 test_http_protocol();
2258 test_https_protocol();
2259 test_ftp_protocol();
2260 test_gopher_protocol();
2261 test_mk_protocol();
2262 test_CreateBinding();
2263 test_binding(FILE_TEST);
2264 test_binding(HTTP_TEST);
2266 CloseHandle(event_complete);
2267 CloseHandle(event_complete2);
2269 OleUninitialize();