Release 1.6-rc2.
[wine/testsucceed.git] / dlls / urlmon / tests / protocol.c
blobb4b8f1941d8202ce579caa5a6651357bb45d7d89
1 /*
2 * Copyright 2005-2011 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 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
33 static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
34 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
36 #define DEFINE_EXPECT(func) \
37 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
39 #define SET_EXPECT(func) \
40 expect_ ## func = TRUE
42 #define CHECK_EXPECT2(func) \
43 do { \
44 ok(expect_ ##func, "unexpected call " #func "\n"); \
45 called_ ## func = TRUE; \
46 }while(0)
48 #define CHECK_EXPECT(func) \
49 do { \
50 CHECK_EXPECT2(func); \
51 expect_ ## func = FALSE; \
52 }while(0)
54 #define CHECK_CALLED(func) \
55 do { \
56 ok(called_ ## func, "expected " #func "\n"); \
57 expect_ ## func = called_ ## func = FALSE; \
58 }while(0)
60 #define CHECK_NOT_CALLED(func) \
61 do { \
62 ok(!called_ ## func, "unexpected " #func "\n"); \
63 expect_ ## func = called_ ## func = FALSE; \
64 }while(0)
66 #define CLEAR_CALLED(func) \
67 expect_ ## func = called_ ## func = FALSE
69 DEFINE_EXPECT(GetBindInfo);
70 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
71 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
72 DEFINE_EXPECT(ReportProgress_RAWMIMETYPE);
73 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE);
74 DEFINE_EXPECT(ReportProgress_CONNECTING);
75 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
76 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
77 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
78 DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID);
79 DEFINE_EXPECT(ReportProgress_COOKIE_SENT);
80 DEFINE_EXPECT(ReportProgress_REDIRECTING);
81 DEFINE_EXPECT(ReportProgress_ENCODING);
82 DEFINE_EXPECT(ReportProgress_ACCEPTRANGES);
83 DEFINE_EXPECT(ReportProgress_PROXYDETECTING);
84 DEFINE_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
85 DEFINE_EXPECT(ReportProgress_DECODING);
86 DEFINE_EXPECT(ReportData);
87 DEFINE_EXPECT(ReportData2);
88 DEFINE_EXPECT(ReportResult);
89 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES);
90 DEFINE_EXPECT(GetBindString_USER_AGENT);
91 DEFINE_EXPECT(GetBindString_POST_COOKIE);
92 DEFINE_EXPECT(GetBindString_URL);
93 DEFINE_EXPECT(QueryService_HttpNegotiate);
94 DEFINE_EXPECT(QueryService_InternetProtocol);
95 DEFINE_EXPECT(QueryService_HttpSecurity);
96 DEFINE_EXPECT(QueryInterface_IWinInetInfo);
97 DEFINE_EXPECT(QueryInterface_IWinInetHttpInfo);
98 DEFINE_EXPECT(BeginningTransaction);
99 DEFINE_EXPECT(GetRootSecurityId);
100 DEFINE_EXPECT(OnResponse);
101 DEFINE_EXPECT(Switch);
102 DEFINE_EXPECT(Continue);
103 DEFINE_EXPECT(CreateInstance);
104 DEFINE_EXPECT(Start);
105 DEFINE_EXPECT(StartEx);
106 DEFINE_EXPECT(Terminate);
107 DEFINE_EXPECT(Read);
108 DEFINE_EXPECT(Read2);
109 DEFINE_EXPECT(SetPriority);
110 DEFINE_EXPECT(LockRequest);
111 DEFINE_EXPECT(UnlockRequest);
112 DEFINE_EXPECT(Abort);
113 DEFINE_EXPECT(MimeFilter_CreateInstance);
114 DEFINE_EXPECT(MimeFilter_Start);
115 DEFINE_EXPECT(MimeFilter_ReportData);
116 DEFINE_EXPECT(MimeFilter_ReportResult);
117 DEFINE_EXPECT(MimeFilter_Terminate);
118 DEFINE_EXPECT(MimeFilter_LockRequest);
119 DEFINE_EXPECT(MimeFilter_UnlockRequest);
120 DEFINE_EXPECT(MimeFilter_Read);
121 DEFINE_EXPECT(MimeFilter_Switch);
122 DEFINE_EXPECT(MimeFilter_Continue);
123 DEFINE_EXPECT(Stream_Seek);
124 DEFINE_EXPECT(Stream_Read);
126 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
127 static const WCHAR index_url[] =
128 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
130 static const WCHAR acc_mimeW[] = {'*','/','*',0};
131 static const WCHAR user_agentW[] = {'W','i','n','e',0};
132 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
133 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
134 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
135 static const WCHAR emptyW[] = {0};
136 static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
137 static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
139 static HRESULT expect_hrResult;
140 static LPCWSTR file_name, http_url, expect_wsz;
141 static IInternetProtocol *async_protocol = NULL;
142 static BOOL first_data_notif, http_is_first, test_redirect;
143 static int prot_state, read_report_data, post_stream_read;
144 static DWORD bindf, ex_priority , pi;
145 static IInternetProtocol *binding_protocol, *filtered_protocol;
146 static IInternetBindInfo *prot_bind_info;
147 static IInternetProtocolSink *binding_sink, *filtered_sink;
148 static void *expect_pv;
149 static HANDLE event_complete, event_complete2, event_continue, event_continue_done;
150 static BOOL binding_test;
151 static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
152 static DWORD prot_read, filter_state, http_post_test, thread_id;
153 static BOOL security_problem, test_async_req, impl_protex;
154 static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort;
155 static BOOL empty_file, no_mime, bind_from_cache;
157 enum {
158 STATE_CONNECTING,
159 STATE_SENDINGREQUEST,
160 STATE_STARTDOWNLOADING,
161 STATE_DOWNLOADING
162 } state;
164 static enum {
165 FILE_TEST,
166 HTTP_TEST,
167 HTTPS_TEST,
168 FTP_TEST,
169 MK_TEST,
170 ITS_TEST,
171 BIND_TEST
172 } tested_protocol;
174 static const WCHAR protocol_names[][10] = {
175 {'f','i','l','e',0},
176 {'h','t','t','p',0},
177 {'h','t','t','p','s',0},
178 {'f','t','p',0},
179 {'m','k',0},
180 {'i','t','s',0},
181 {'t','e','s','t',0}
184 static const WCHAR binding_urls[][130] = {
185 {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
186 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
187 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0},
188 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
189 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
190 {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
191 '/','p','u','b','/','o','t','h','e','r',
192 '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
193 {'m','k',':','t','e','s','t',0},
194 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0},
195 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
198 static const CHAR post_data[] = "mode=Test";
200 static const char *debugstr_guid(REFIID riid)
202 static char buf[50];
204 sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
205 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
206 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
207 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
209 return buf;
212 static int strcmp_wa(LPCWSTR strw, const char *stra)
214 CHAR buf[512];
215 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
216 return lstrcmpA(stra, buf);
219 static const char *w2a(LPCWSTR str)
221 static char buf[INTERNET_MAX_URL_LENGTH];
222 WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
223 return buf;
226 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
228 if(IsEqualGUID(&IID_IUnknown, riid)
229 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
230 *ppv = iface;
231 return S_OK;
234 ok(0, "unexpected call\n");
235 return E_NOINTERFACE;
238 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
240 return 2;
243 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
245 return 1;
248 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
250 trace("HttpSecurity_GetWindow\n");
252 return S_FALSE;
255 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
257 trace("Security problem: %u\n", dwProblem);
258 ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem);
260 /* Only retry once */
261 if (security_problem)
262 return E_ABORT;
264 security_problem = TRUE;
265 SET_EXPECT(BeginningTransaction);
267 return RPC_E_RETRY;
270 static IHttpSecurityVtbl HttpSecurityVtbl = {
271 HttpSecurity_QueryInterface,
272 HttpSecurity_AddRef,
273 HttpSecurity_Release,
274 HttpSecurity_GetWindow,
275 HttpSecurity_OnSecurityProblem
278 static IHttpSecurity http_security = { &HttpSecurityVtbl };
280 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
282 if(IsEqualGUID(&IID_IUnknown, riid)
283 || IsEqualGUID(&IID_IHttpNegotiate, riid)
284 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
285 *ppv = iface;
286 return S_OK;
289 ok(0, "unexpected call\n");
290 return E_NOINTERFACE;
293 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
295 return 2;
298 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
300 return 1;
303 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
304 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
306 LPWSTR addl_headers;
308 static const WCHAR wszHeaders[] =
309 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
310 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
311 'd','e','d','\r','\n',0};
313 CHECK_EXPECT(BeginningTransaction);
315 if(binding_test)
316 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
317 else
318 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
319 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
320 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
321 if(pszAdditionalHeaders)
323 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
324 if (http_post_test)
326 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
327 memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
328 *pszAdditionalHeaders = addl_headers;
332 return S_OK;
335 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
336 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
338 CHECK_EXPECT(OnResponse);
340 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
341 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
342 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
343 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
345 return S_OK;
348 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
349 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
351 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
353 CHECK_EXPECT(GetRootSecurityId);
355 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
356 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
357 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
359 if(pcbSecurityId) {
360 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
361 *pcbSecurityId = sizeof(sec_id);
364 if(pbSecurityId)
365 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
367 return E_FAIL;
370 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
371 HttpNegotiate_QueryInterface,
372 HttpNegotiate_AddRef,
373 HttpNegotiate_Release,
374 HttpNegotiate_BeginningTransaction,
375 HttpNegotiate_OnResponse,
376 HttpNegotiate_GetRootSecurityId
379 static IHttpNegotiate2 http_negotiate = { &HttpNegotiateVtbl };
381 static HRESULT QueryInterface(REFIID,void**);
383 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
385 return QueryInterface(riid, ppv);
388 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
390 return 2;
393 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
395 return 1;
398 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
399 REFIID riid, void **ppv)
401 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
402 CHECK_EXPECT2(QueryService_HttpNegotiate);
403 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
406 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
407 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
408 CHECK_EXPECT(QueryService_InternetProtocol);
409 return E_NOINTERFACE;
412 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
413 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
414 CHECK_EXPECT(QueryService_HttpSecurity);
415 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
418 ok(0, "unexpected service %s\n", debugstr_guid(guidService));
419 return E_FAIL;
422 static const IServiceProviderVtbl ServiceProviderVtbl = {
423 ServiceProvider_QueryInterface,
424 ServiceProvider_AddRef,
425 ServiceProvider_Release,
426 ServiceProvider_QueryService
429 static IServiceProvider service_provider = { &ServiceProviderVtbl };
431 static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
433 ok(0, "unexpected call\n");
434 return E_NOINTERFACE;
437 static ULONG WINAPI Stream_AddRef(IStream *iface)
439 return 2;
442 static ULONG WINAPI Stream_Release(IStream *iface)
444 return 1;
447 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
448 ULONG cb, ULONG *pcbRead)
450 CHECK_EXPECT2(Stream_Read);
452 ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
454 ok(pv != NULL, "pv == NULL\n");
455 ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
456 ok(pcbRead != NULL, "pcbRead == NULL\n");
458 if(post_stream_read) {
459 *pcbRead = 0;
460 return S_FALSE;
463 memcpy(pv, post_data, sizeof(post_data)-1);
464 post_stream_read += *pcbRead = sizeof(post_data)-1;
465 return S_OK;
468 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
469 ULONG cb, ULONG *pcbWritten)
471 ok(0, "unexpected call\n");
472 return E_NOTIMPL;
475 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
476 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
478 CHECK_EXPECT(Stream_Seek);
480 ok(!dlibMove.QuadPart, "dlibMove != 0\n");
481 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
482 ok(!plibNewPosition, "plibNewPosition == NULL\n");
484 return S_OK;
487 static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
489 ok(0, "unexpected call\n");
490 return E_NOTIMPL;
493 static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm,
494 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
496 ok(0, "unexpected call\n");
497 return E_NOTIMPL;
500 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
502 ok(0, "unexpected call\n");
503 return E_NOTIMPL;
506 static HRESULT WINAPI Stream_Revert(IStream *iface)
508 ok(0, "unexpected call\n");
509 return E_NOTIMPL;
512 static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
513 ULARGE_INTEGER cb, DWORD dwLockType)
515 ok(0, "unexpected call\n");
516 return E_NOTIMPL;
519 static HRESULT WINAPI Stream_UnlockRegion(IStream *iface,
520 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
522 ok(0, "unexpected call\n");
523 return E_NOTIMPL;
526 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
527 DWORD dwStatFlag)
529 ok(0, "unexpected call\n");
530 return E_NOTIMPL;
533 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
535 ok(0, "unexpected call\n");
536 return E_NOTIMPL;
539 static const IStreamVtbl StreamVtbl = {
540 Stream_QueryInterface,
541 Stream_AddRef,
542 Stream_Release,
543 Stream_Read,
544 Stream_Write,
545 Stream_Seek,
546 Stream_SetSize,
547 Stream_CopyTo,
548 Stream_Commit,
549 Stream_Revert,
550 Stream_LockRegion,
551 Stream_UnlockRegion,
552 Stream_Stat,
553 Stream_Clone
556 static IStream Stream = { &StreamVtbl };
558 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
560 return QueryInterface(riid, ppv);
563 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
565 return 2;
568 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
570 return 1;
573 static void call_continue(PROTOCOLDATA *protocol_data)
575 HRESULT hres;
577 if(state == STATE_CONNECTING) {
578 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
579 if (http_is_first){
580 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
581 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
583 CLEAR_CALLED(ReportProgress_CONNECTING);
585 if(tested_protocol == FTP_TEST)
586 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
587 else if (tested_protocol != HTTPS_TEST)
588 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
589 if(test_redirect)
590 CHECK_CALLED(ReportProgress_REDIRECTING);
591 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
594 switch(state) {
595 case STATE_SENDINGREQUEST:
596 SET_EXPECT(Stream_Read);
597 SET_EXPECT(ReportProgress_SENDINGREQUEST);
598 break;
599 case STATE_STARTDOWNLOADING:
600 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
601 SET_EXPECT(OnResponse);
602 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
603 SET_EXPECT(ReportProgress_ACCEPTRANGES);
604 SET_EXPECT(ReportProgress_ENCODING);
605 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
606 if(bindf & BINDF_NEEDFILE)
607 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
609 default:
610 break;
613 if(state != STATE_SENDINGREQUEST)
614 SET_EXPECT(ReportData);
615 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
616 ok(hres == S_OK, "Continue failed: %08x\n", hres);
617 if(tested_protocol == FTP_TEST || security_problem)
618 CLEAR_CALLED(ReportData);
619 else if(state != STATE_SENDINGREQUEST)
620 CHECK_CALLED(ReportData);
622 switch(state) {
623 case STATE_SENDINGREQUEST:
624 CHECK_CALLED(Stream_Read);
625 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
626 state = STATE_STARTDOWNLOADING;
627 break;
628 case STATE_STARTDOWNLOADING:
629 if (! security_problem)
631 state = STATE_DOWNLOADING;
632 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
633 CHECK_CALLED(OnResponse);
634 if(tested_protocol == HTTPS_TEST || empty_file)
635 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
636 else if(test_redirect || test_abort)
637 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
638 CLEAR_CALLED(ReportProgress_ENCODING);
639 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
640 if(bindf & BINDF_NEEDFILE)
641 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
644 else
646 security_problem = FALSE;
647 SET_EXPECT(ReportProgress_CONNECTING);
649 default:
650 break;
654 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
656 if(tested_protocol == FTP_TEST)
657 CHECK_EXPECT2(Switch);
658 else
659 CHECK_EXPECT(Switch);
661 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
662 if(binding_test) {
663 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
664 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
665 pProtocolData->grfFlags, protocoldata.grfFlags );
666 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
667 pProtocolData->dwState, protocoldata.dwState );
668 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
669 pProtocolData->pData, protocoldata.pData );
670 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
671 pProtocolData->cbData, protocoldata.cbData );
674 pdata = pProtocolData;
676 if(binding_test) {
677 SetEvent(event_complete);
678 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
679 return S_OK;
680 }if(direct_read) {
681 continue_protdata = *pProtocolData;
682 SetEvent(event_continue);
683 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
684 }else {
685 call_continue(pProtocolData);
686 SetEvent(event_complete);
689 return S_OK;
692 static const char *status_names[] =
694 "0",
695 "FINDINGRESOURCE",
696 "CONNECTING",
697 "REDIRECTING",
698 "BEGINDOWNLOADDATA",
699 "DOWNLOADINGDATA",
700 "ENDDOWNLOADDATA",
701 "BEGINDOWNLOADCOMPONENTS",
702 "INSTALLINGCOMPONENTS",
703 "ENDDOWNLOADCOMPONENTS",
704 "USINGCACHEDCOPY",
705 "SENDINGREQUEST",
706 "CLASSIDAVAILABLE",
707 "MIMETYPEAVAILABLE",
708 "CACHEFILENAMEAVAILABLE",
709 "BEGINSYNCOPERATION",
710 "ENDSYNCOPERATION",
711 "BEGINUPLOADDATA",
712 "UPLOADINGDATA",
713 "ENDUPLOADINGDATA",
714 "PROTOCOLCLASSID",
715 "ENCODING",
716 "VERIFIEDMIMETYPEAVAILABLE",
717 "CLASSINSTALLLOCATION",
718 "DECODING",
719 "LOADINGMIMEHANDLER",
720 "CONTENTDISPOSITIONATTACH",
721 "FILTERREPORTMIMETYPE",
722 "CLSIDCANINSTANTIATE",
723 "IUNKNOWNAVAILABLE",
724 "DIRECTBIND",
725 "RAWMIMETYPE",
726 "PROXYDETECTING",
727 "ACCEPTRANGES",
728 "COOKIE_SENT",
729 "COMPACT_POLICY_RECEIVED",
730 "COOKIE_SUPPRESSED",
731 "COOKIE_STATE_UNKNOWN",
732 "COOKIE_STATE_ACCEPT",
733 "COOKIE_STATE_REJECT",
734 "COOKIE_STATE_PROMPT",
735 "COOKIE_STATE_LEASH",
736 "COOKIE_STATE_DOWNGRADE",
737 "POLICY_HREF",
738 "P3P_HEADER",
739 "SESSION_COOKIE_RECEIVED",
740 "PERSISTENT_COOKIE_RECEIVED",
741 "SESSION_COOKIES_ALLOWED",
742 "CACHECONTROL",
743 "CONTENTDISPOSITIONFILENAME",
744 "MIMETEXTPLAINMISMATCH",
745 "PUBLISHERAVAILABLE",
746 "DISPLAYNAMEAVAILABLE"
749 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
750 LPCWSTR szStatusText)
752 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
753 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
754 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
756 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
757 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
758 else
759 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
761 switch(ulStatusCode) {
762 case BINDSTATUS_MIMETYPEAVAILABLE:
763 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
764 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
765 if(!short_read || !direct_read)
766 CHECK_CALLED(Read); /* set in Continue */
767 else if(short_read)
768 CHECK_CALLED(Read2); /* set in Read */
770 ok(szStatusText != NULL, "szStatusText == NULL\n");
771 if(szStatusText) {
772 if(tested_protocol == BIND_TEST)
773 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
774 else if (http_post_test)
775 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
776 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
777 "szStatusText != text/plain\n");
778 else if(empty_file)
779 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
780 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
781 && tested_protocol==HTTP_TEST && !short_read)
782 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
783 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
784 "szStatusText != image/gif\n");
785 else if(!mimefilter_test)
786 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
787 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
788 "szStatusText != text/html\n");
790 break;
791 case BINDSTATUS_DIRECTBIND:
792 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
793 ok(szStatusText == NULL, "szStatusText != NULL\n");
794 break;
795 case BINDSTATUS_RAWMIMETYPE:
796 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
797 ok(szStatusText != NULL, "szStatusText == NULL\n");
798 if(szStatusText)
799 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
800 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
801 "szStatusText != text/html\n");
802 break;
803 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
804 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
805 ok(szStatusText != NULL, "szStatusText == NULL\n");
806 if(szStatusText) {
807 if(binding_test)
808 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
809 else if(tested_protocol == FILE_TEST)
810 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
811 else
812 ok(szStatusText != NULL, "szStatusText == NULL\n");
814 break;
815 case BINDSTATUS_FINDINGRESOURCE:
816 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
817 ok(szStatusText != NULL, "szStatusText == NULL\n");
818 break;
819 case BINDSTATUS_CONNECTING:
820 CHECK_EXPECT2(ReportProgress_CONNECTING);
821 ok(szStatusText != NULL, "szStatusText == NULL\n");
822 break;
823 case BINDSTATUS_SENDINGREQUEST:
824 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
825 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
826 ok(szStatusText != NULL, "szStatusText == NULL\n");
827 if(szStatusText)
828 ok(!*szStatusText, "wrong szStatusText\n");
830 break;
831 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
832 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
833 ok(szStatusText != NULL, "szStatusText == NULL\n");
834 if(szStatusText)
835 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
836 break;
837 case BINDSTATUS_PROTOCOLCLASSID:
838 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
839 ok(szStatusText != NULL, "szStatusText == NULL\n");
840 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
841 break;
842 case BINDSTATUS_COOKIE_SENT:
843 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
844 ok(szStatusText == NULL, "szStatusText != NULL\n");
845 break;
846 case BINDSTATUS_REDIRECTING:
847 CHECK_EXPECT(ReportProgress_REDIRECTING);
848 if(test_redirect)
849 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
850 else
851 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
852 break;
853 case BINDSTATUS_ENCODING:
854 CHECK_EXPECT(ReportProgress_ENCODING);
855 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
856 break;
857 case BINDSTATUS_ACCEPTRANGES:
858 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
859 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
860 break;
861 case BINDSTATUS_PROXYDETECTING:
862 if(!called_ReportProgress_PROXYDETECTING)
863 SET_EXPECT(ReportProgress_CONNECTING);
864 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
865 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
866 break;
867 case BINDSTATUS_LOADINGMIMEHANDLER:
868 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
869 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
870 break;
871 case BINDSTATUS_DECODING:
872 CHECK_EXPECT(ReportProgress_DECODING);
873 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
874 break;
875 default:
876 ok(0, "Unexpected status %d\n", ulStatusCode);
879 return S_OK;
882 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
883 ULONG ulProgress, ULONG ulProgressMax)
885 HRESULT hres;
887 static int rec_depth;
888 rec_depth++;
890 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
891 CHECK_EXPECT2(ReportData);
893 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
894 ulProgress, ulProgressMax);
895 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
896 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
897 if(tested_protocol == FILE_TEST)
898 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
899 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
900 "grcfBSCF = %08x\n", grfBSCF);
901 else
902 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
903 }else if(bind_from_cache) {
904 CHECK_EXPECT(ReportData);
906 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
907 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
908 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
909 }else if(direct_read) {
910 BYTE buf[14096];
911 ULONG read;
913 if(!read_report_data && rec_depth == 1) {
914 BOOL reported_all_data = called_ReportData2;
916 CHECK_EXPECT2(ReportData);
918 if(short_read) {
919 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
920 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
921 "grcfBSCF = %08x\n", grfBSCF);
922 CHECK_CALLED(Read); /* Set in Continue */
923 first_data_notif = FALSE;
924 }else if(first_data_notif) {
925 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
926 first_data_notif = FALSE;
927 }else if(reported_all_data) {
928 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
929 "grcfBSCF = %08x\n", grfBSCF);
930 }else if(!direct_read) {
931 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
934 do {
935 read = 0;
936 if(emulate_prot)
937 SET_EXPECT(Read);
938 else
939 SET_EXPECT(ReportData2);
940 SET_EXPECT(ReportResult);
941 if(!emulate_prot)
942 SET_EXPECT(Switch);
943 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
944 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
945 if(hres == S_OK)
946 ok(read, "read == 0\n");
947 if(reported_all_data)
948 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
949 if(!emulate_prot && hres != E_PENDING)
950 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
951 if(emulate_prot)
952 CHECK_CALLED(Read);
953 if(!reported_all_data && called_ReportData2) {
954 if(!emulate_prot)
955 CHECK_CALLED(ReportData2);
956 CHECK_CALLED(ReportResult);
957 reported_all_data = TRUE;
958 }else {
959 if(!emulate_prot)
960 CHECK_NOT_CALLED(ReportData2);
961 CHECK_NOT_CALLED(ReportResult);
963 }while(hres == S_OK);
964 if(hres == S_FALSE)
965 wait_for_switch = FALSE;
966 }else {
967 CHECK_EXPECT(ReportData2);
969 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
971 read = 0xdeadbeef;
972 if(emulate_prot)
973 SET_EXPECT(Read2);
974 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
975 if(emulate_prot)
976 CHECK_CALLED(Read2);
977 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
978 ok(!read, "read = %d\n", read);
980 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
981 || tested_protocol == FTP_TEST)) {
982 if(empty_file)
983 CHECK_EXPECT2(ReportData);
984 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
985 CHECK_EXPECT(ReportData);
986 else if (http_post_test)
987 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
989 if(empty_file) {
990 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
991 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
992 }else {
993 ok(ulProgress, "ulProgress == 0\n");
996 if(empty_file) {
997 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
998 "grcfBSCF = %08x\n", grfBSCF);
999 first_data_notif = FALSE;
1000 }else if(first_data_notif) {
1001 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1002 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1003 "grcfBSCF = %08x\n", grfBSCF);
1004 first_data_notif = FALSE;
1005 } else {
1006 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1007 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1008 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1009 "grcfBSCF = %08x\n", grfBSCF);
1012 if(!(bindf & BINDF_FROMURLMON) &&
1013 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1014 if(state == STATE_CONNECTING) {
1015 state = STATE_DOWNLOADING;
1016 if(http_is_first) {
1017 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1018 CHECK_CALLED(ReportProgress_CONNECTING);
1020 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1021 CHECK_CALLED(OnResponse);
1022 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1024 SetEvent(event_complete);
1026 }else if(!read_report_data) {
1027 BYTE buf[1000];
1028 ULONG read;
1029 HRESULT hres;
1031 CHECK_EXPECT(ReportData);
1033 if(tested_protocol != BIND_TEST) {
1034 do {
1035 if(mimefilter_test)
1036 SET_EXPECT(MimeFilter_Read);
1037 else if(rec_depth > 1)
1038 SET_EXPECT(Read2);
1039 else
1040 SET_EXPECT(Read);
1041 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1042 if(mimefilter_test)
1043 CHECK_CALLED(MimeFilter_Read);
1044 else if(rec_depth > 1)
1045 CHECK_CALLED(Read2);
1046 else
1047 CHECK_CALLED(Read);
1048 }while(hres == S_OK);
1052 rec_depth--;
1053 return S_OK;
1056 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1057 DWORD dwError, LPCWSTR szResult)
1059 CHECK_EXPECT(ReportResult);
1061 if(tested_protocol == FTP_TEST)
1062 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1063 else
1064 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1065 hrResult, expect_hrResult);
1066 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1067 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1068 else
1069 ok(dwError != ERROR_SUCCESS ||
1070 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1071 "dwError == ERROR_SUCCESS\n");
1072 ok(!szResult, "szResult != NULL\n");
1074 if(direct_read)
1075 SET_EXPECT(ReportData); /* checked after main loop */
1077 return S_OK;
1080 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1081 ProtocolSink_QueryInterface,
1082 ProtocolSink_AddRef,
1083 ProtocolSink_Release,
1084 ProtocolSink_Switch,
1085 ProtocolSink_ReportProgress,
1086 ProtocolSink_ReportData,
1087 ProtocolSink_ReportResult
1090 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1092 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1094 ok(0, "unexpected call\n");
1095 return E_NOTIMPL;
1098 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1100 return 2;
1103 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1105 return 1;
1108 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1110 HRESULT hres;
1112 CHECK_EXPECT(MimeFilter_Switch);
1114 SET_EXPECT(Switch);
1115 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1116 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1117 CHECK_CALLED(Switch);
1119 return S_OK;
1122 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1123 LPCWSTR szStatusText)
1125 switch(ulStatusCode) {
1126 case BINDSTATUS_LOADINGMIMEHANDLER:
1128 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1129 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1130 * ProtocolSink_ReportProgress to workaround it.
1132 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1133 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1134 break;
1135 default:
1136 ok(0, "Unexpected status code %d\n", ulStatusCode);
1139 return S_OK;
1142 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1143 ULONG ulProgress, ULONG ulProgressMax)
1145 DWORD read = 0;
1146 BYTE buf[8192];
1147 HRESULT hres;
1148 BOOL report_mime = FALSE;
1150 CHECK_EXPECT(MimeFilter_ReportData);
1152 if(!filter_state && !no_mime) {
1153 SET_EXPECT(Read);
1154 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1155 if(tested_protocol == HTTP_TEST)
1156 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1157 else
1158 ok(hres == S_OK, "Read failed: %08x\n", hres);
1159 CHECK_CALLED(Read);
1161 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1162 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1163 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1164 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1166 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1167 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1168 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1169 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1171 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1174 if(no_mime && prot_read<200) {
1175 SET_EXPECT(Read);
1176 }else if(no_mime && prot_read<300) {
1177 report_mime = TRUE;
1178 SET_EXPECT(Read);
1179 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1180 SET_EXPECT(ReportData);
1181 }else if(!read_report_data) {
1182 SET_EXPECT(ReportData);
1184 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1185 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1186 if(no_mime && prot_read<=200) {
1187 CHECK_CALLED(Read);
1188 }else if(report_mime) {
1189 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1190 CHECK_CALLED(ReportData);
1191 }else if(!read_report_data) {
1192 CHECK_CALLED(ReportData);
1195 if(!filter_state)
1196 filter_state = 1;
1198 return S_OK;
1201 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1202 DWORD dwError, LPCWSTR szResult)
1204 HRESULT hres;
1206 CHECK_EXPECT(MimeFilter_ReportResult);
1208 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1209 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1210 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1212 SET_EXPECT(ReportResult);
1213 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1214 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1215 CHECK_CALLED(ReportResult);
1217 return S_OK;
1220 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1221 MimeProtocolSink_QueryInterface,
1222 MimeProtocolSink_AddRef,
1223 MimeProtocolSink_Release,
1224 MimeProtocolSink_Switch,
1225 MimeProtocolSink_ReportProgress,
1226 MimeProtocolSink_ReportData,
1227 MimeProtocolSink_ReportResult
1230 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1232 static HRESULT QueryInterface(REFIID riid, void **ppv)
1234 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1236 *ppv = NULL;
1238 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1239 *ppv = &protocol_sink;
1240 if(IsEqualGUID(&IID_IServiceProvider, riid))
1241 *ppv = &service_provider;
1242 if(IsEqualGUID(&IID_IUriContainer, riid))
1243 return E_NOINTERFACE; /* TODO */
1245 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1246 if(IsEqualGUID(&IID_undocumented, riid))
1247 return E_NOINTERFACE;
1249 if(*ppv)
1250 return S_OK;
1252 ok(0, "unexpected call %s\n", debugstr_guid(riid));
1253 return E_NOINTERFACE;
1256 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1258 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1259 *ppv = iface;
1260 return S_OK;
1262 return E_NOINTERFACE;
1265 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1267 return 2;
1270 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1272 return 1;
1275 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1277 DWORD cbSize;
1279 CHECK_EXPECT(GetBindInfo);
1281 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1282 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1283 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1285 *grfBINDF = bindf;
1286 if(binding_test)
1287 *grfBINDF |= BINDF_FROMURLMON;
1288 cbSize = pbindinfo->cbSize;
1289 memset(pbindinfo, 0, cbSize);
1290 pbindinfo->cbSize = cbSize;
1292 if(http_post_test)
1294 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1295 pbindinfo->dwBindVerb = BINDVERB_POST;
1296 pbindinfo->stgmedData.tymed = http_post_test;
1298 if(http_post_test == TYMED_HGLOBAL) {
1299 HGLOBAL data;
1301 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1302 data = GlobalAlloc(GPTR, sizeof(post_data));
1303 memcpy(data, post_data, sizeof(post_data));
1304 U(pbindinfo->stgmedData).hGlobal = data;
1305 }else {
1306 IStream *post_stream;
1307 HGLOBAL data;
1308 HRESULT hres;
1310 if(0) {
1311 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1312 data = GlobalAlloc(GPTR, sizeof(post_data));
1313 memcpy(data, post_data, sizeof(post_data));
1314 U(pbindinfo->stgmedData).hGlobal = data;
1316 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1317 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1319 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1321 U(pbindinfo->stgmedData).pstm = &Stream;
1325 return S_OK;
1328 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1329 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1331 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1332 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1334 switch(ulStringType) {
1335 case BINDSTRING_ACCEPT_MIMES:
1336 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1337 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1338 if(pcElFetched) {
1339 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1340 *pcElFetched = 1;
1342 if(ppwzStr) {
1343 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1344 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1346 return S_OK;
1347 case BINDSTRING_USER_AGENT:
1348 CHECK_EXPECT(GetBindString_USER_AGENT);
1349 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1350 if(pcElFetched) {
1351 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1352 *pcElFetched = 1;
1354 if(ppwzStr) {
1355 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1356 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1358 return S_OK;
1359 case BINDSTRING_POST_COOKIE:
1360 CHECK_EXPECT(GetBindString_POST_COOKIE);
1361 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1362 if(pcElFetched)
1363 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1364 return S_OK;
1365 case BINDSTRING_URL: {
1366 DWORD size;
1368 CHECK_EXPECT(GetBindString_URL);
1369 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1370 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1371 *pcElFetched = 1;
1373 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1374 *ppwzStr = CoTaskMemAlloc(size);
1375 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1376 return S_OK;
1378 default:
1379 ok(0, "unexpected call\n");
1382 return E_NOTIMPL;
1385 static IInternetBindInfoVtbl bind_info_vtbl = {
1386 BindInfo_QueryInterface,
1387 BindInfo_AddRef,
1388 BindInfo_Release,
1389 BindInfo_GetBindInfo,
1390 BindInfo_GetBindString
1393 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1395 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1396 REFIID riid, void **ppv)
1398 ok(0, "unexpected call\n");
1399 return E_NOINTERFACE;
1402 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1404 return 2;
1407 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1409 return 1;
1412 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1414 CHECK_EXPECT(SetPriority);
1415 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1416 return S_OK;
1419 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1421 ok(0, "unexpected call\n");
1422 return E_NOTIMPL;
1426 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1427 InternetPriority_QueryInterface,
1428 InternetPriority_AddRef,
1429 InternetPriority_Release,
1430 InternetPriority_SetPriority,
1431 InternetPriority_GetPriority
1434 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1436 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1438 return 2;
1441 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1443 return 1;
1446 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1447 DWORD dwOptions)
1449 HRESULT hres;
1451 CHECK_EXPECT(Abort);
1453 SET_EXPECT(ReportResult);
1454 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1455 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1456 CHECK_CALLED(ReportResult);
1458 return S_OK;
1461 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1463 ok(0, "unexpected call\n");
1464 return E_NOTIMPL;
1467 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1469 ok(0, "unexpected call\n");
1470 return E_NOTIMPL;
1473 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1474 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1476 ok(0, "unexpected call\n");
1477 return E_NOTIMPL;
1480 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1482 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1484 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1485 *ppv = iface;
1486 return S_OK;
1489 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1490 if(impl_protex) {
1491 *ppv = iface;
1492 return S_OK;
1494 *ppv = NULL;
1495 return E_NOINTERFACE;
1498 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1499 *ppv = &InternetPriority;
1500 return S_OK;
1503 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1504 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1505 *ppv = NULL;
1506 return E_NOINTERFACE;
1509 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1510 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1511 *ppv = NULL;
1512 return E_NOINTERFACE;
1515 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1516 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1517 *ppv = NULL;
1518 return E_NOINTERFACE;
1521 static DWORD WINAPI thread_proc(PVOID arg)
1523 HRESULT hres;
1525 memset(&protocoldata, -1, sizeof(protocoldata));
1527 prot_state = 0;
1529 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1530 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1531 BINDSTATUS_FINDINGRESOURCE, hostW);
1532 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1533 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1535 SET_EXPECT(ReportProgress_CONNECTING);
1536 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1537 BINDSTATUS_CONNECTING, winehq_ipW);
1538 CHECK_CALLED(ReportProgress_CONNECTING);
1539 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1541 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1542 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1543 BINDSTATUS_SENDINGREQUEST, NULL);
1544 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1545 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1547 prot_state = 1;
1548 SET_EXPECT(Switch);
1549 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1550 CHECK_CALLED(Switch);
1551 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1553 if(!short_read) {
1554 prot_state = 2;
1555 if(mimefilter_test)
1556 SET_EXPECT(MimeFilter_Switch);
1557 else
1558 SET_EXPECT(Switch);
1559 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1560 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1561 if(mimefilter_test)
1562 CHECK_CALLED(MimeFilter_Switch);
1563 else
1564 CHECK_CALLED(Switch);
1566 if(test_abort) {
1567 SetEvent(event_complete);
1568 return 0;
1571 prot_state = 2;
1572 if(mimefilter_test)
1573 SET_EXPECT(MimeFilter_Switch);
1574 else
1575 SET_EXPECT(Switch);
1576 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1577 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1578 if(mimefilter_test)
1579 CHECK_CALLED(MimeFilter_Switch);
1580 else
1581 CHECK_CALLED(Switch);
1583 prot_state = 3;
1584 if(mimefilter_test)
1585 SET_EXPECT(MimeFilter_Switch);
1586 else
1587 SET_EXPECT(Switch);
1588 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1589 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1590 if(mimefilter_test)
1591 CHECK_CALLED(MimeFilter_Switch);
1592 else
1593 CHECK_CALLED(Switch);
1596 SetEvent(event_complete);
1598 return 0;
1601 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1603 BINDINFO bindinfo, exp_bindinfo;
1604 DWORD cbindf = 0;
1605 HRESULT hres;
1607 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1608 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1609 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1610 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1611 ok(!pi, "pi = %x\n", pi);
1613 if(binding_test)
1614 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1616 memset(&bindinfo, 0, sizeof(bindinfo));
1617 bindinfo.cbSize = sizeof(bindinfo);
1618 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1619 SET_EXPECT(GetBindInfo);
1620 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1621 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1622 CHECK_CALLED(GetBindInfo);
1623 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1624 cbindf, (bindf|BINDF_FROMURLMON));
1625 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1626 pReleaseBindInfo(&bindinfo);
1628 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1629 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1630 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1631 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1633 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1634 IServiceProvider *service_provider;
1635 IHttpNegotiate *http_negotiate;
1636 IHttpNegotiate2 *http_negotiate2;
1637 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1638 LPWSTR additional_headers = NULL;
1639 BYTE sec_id[100];
1640 DWORD fetched = 0, size = 100;
1641 DWORD tid;
1643 SET_EXPECT(GetBindString_USER_AGENT);
1644 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1645 &ua, 1, &fetched);
1646 CHECK_CALLED(GetBindString_USER_AGENT);
1647 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1648 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1649 ok(ua != NULL, "ua = %p\n", ua);
1650 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1651 CoTaskMemFree(ua);
1653 fetched = 256;
1654 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1655 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1656 accept_mimes, 256, &fetched);
1657 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1659 ok(hres == S_OK,
1660 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1661 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1662 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1663 CoTaskMemFree(accept_mimes[0]);
1665 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1666 (void**)&service_provider);
1667 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1669 SET_EXPECT(QueryService_HttpNegotiate);
1670 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1671 &IID_IHttpNegotiate, (void**)&http_negotiate);
1672 CHECK_CALLED(QueryService_HttpNegotiate);
1673 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1675 SET_EXPECT(BeginningTransaction);
1676 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1677 NULL, 0, &additional_headers);
1678 CHECK_CALLED(BeginningTransaction);
1679 IHttpNegotiate_Release(http_negotiate);
1680 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1681 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1683 SET_EXPECT(QueryService_HttpNegotiate);
1684 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1685 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1686 CHECK_CALLED(QueryService_HttpNegotiate);
1687 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1689 size = 512;
1690 SET_EXPECT(GetRootSecurityId);
1691 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1692 CHECK_CALLED(GetRootSecurityId);
1693 IHttpNegotiate2_Release(http_negotiate2);
1694 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1695 ok(size == 13, "size=%d\n", size);
1697 IServiceProvider_Release(service_provider);
1699 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1700 return;
1703 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1704 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1705 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1706 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1707 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1709 if(mimefilter_test) {
1710 SET_EXPECT(MimeFilter_CreateInstance);
1711 SET_EXPECT(MimeFilter_Start);
1712 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1714 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1715 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1716 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1717 ok(hres == S_OK,
1718 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1719 if(mimefilter_test) {
1720 CHECK_CALLED(MimeFilter_CreateInstance);
1721 CHECK_CALLED(MimeFilter_Start);
1722 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1723 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1724 }else {
1725 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1728 if(mimefilter_test)
1729 SET_EXPECT(MimeFilter_ReportData);
1730 else
1731 SET_EXPECT(ReportData);
1732 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1733 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1734 13, 13);
1735 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1736 if(mimefilter_test)
1737 CHECK_CALLED(MimeFilter_ReportData);
1738 else
1739 CHECK_CALLED(ReportData);
1741 if(tested_protocol == ITS_TEST) {
1742 SET_EXPECT(ReportData);
1743 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1744 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1745 CHECK_CALLED(ReportData);
1748 if(tested_protocol == BIND_TEST) {
1749 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1750 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1753 if(mimefilter_test)
1754 SET_EXPECT(MimeFilter_ReportResult);
1755 else
1756 SET_EXPECT(ReportResult);
1757 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1758 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1759 if(mimefilter_test)
1760 CHECK_CALLED(MimeFilter_ReportResult);
1761 else
1762 CHECK_CALLED(ReportResult);
1765 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1766 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1767 DWORD grfPI, HANDLE_PTR dwReserved)
1769 CHECK_EXPECT(Start);
1771 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1772 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1773 return S_OK;
1776 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1777 PROTOCOLDATA *pProtocolData)
1779 DWORD bscf = 0, pr;
1780 HRESULT hres;
1782 CHECK_EXPECT(Continue);
1784 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1785 if(!pProtocolData || tested_protocol == BIND_TEST)
1786 return S_OK;
1787 if(binding_test) {
1788 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1789 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1790 pProtocolData->grfFlags, protocoldata.grfFlags );
1791 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1792 pProtocolData->dwState, protocoldata.dwState );
1793 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1794 pProtocolData->pData, protocoldata.pData );
1795 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1796 pProtocolData->cbData, protocoldata.cbData );
1799 switch(prot_state) {
1800 case 1: {
1801 IServiceProvider *service_provider;
1802 IHttpNegotiate *http_negotiate;
1803 static WCHAR header[] = {'?',0};
1805 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1806 (void**)&service_provider);
1807 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1809 SET_EXPECT(QueryService_HttpNegotiate);
1810 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1811 &IID_IHttpNegotiate, (void**)&http_negotiate);
1812 IServiceProvider_Release(service_provider);
1813 CHECK_CALLED(QueryService_HttpNegotiate);
1814 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1816 SET_EXPECT(OnResponse);
1817 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1818 IHttpNegotiate_Release(http_negotiate);
1819 CHECK_CALLED(OnResponse);
1820 IHttpNegotiate_Release(http_negotiate);
1821 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1823 if(mimefilter_test) {
1824 SET_EXPECT(MimeFilter_CreateInstance);
1825 SET_EXPECT(MimeFilter_Start);
1826 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1827 }else if(!(pi & PI_MIMEVERIFICATION)) {
1828 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1830 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1831 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1832 if(mimefilter_test) {
1833 CHECK_CALLED(MimeFilter_CreateInstance);
1834 CHECK_CALLED(MimeFilter_Start);
1835 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1836 }else if(!(pi & PI_MIMEVERIFICATION)) {
1837 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1839 ok(hres == S_OK,
1840 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1842 bscf |= BSCF_FIRSTDATANOTIFICATION;
1843 break;
1845 case 2:
1846 case 3:
1847 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1848 break;
1851 pr = prot_read;
1852 if(mimefilter_test)
1853 SET_EXPECT(MimeFilter_ReportData);
1854 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1855 if(pr < 200)
1856 SET_EXPECT(Read); /* checked in ReportData for short_read */
1857 if(pr == 200) {
1858 if(!mimefilter_test)
1859 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1860 SET_EXPECT(GetBindInfo);
1861 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1863 if(pr >= 200)
1864 SET_EXPECT(ReportData);
1865 }else {
1866 SET_EXPECT(ReportData);
1869 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1870 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1872 if(mimefilter_test) {
1873 SET_EXPECT(MimeFilter_ReportData);
1874 }else if(pi & PI_MIMEVERIFICATION) {
1875 if(!short_read && pr < 200)
1876 CHECK_CALLED(Read);
1877 if(pr == 200) {
1878 CLEAR_CALLED(GetBindInfo); /* IE9 */
1879 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1881 }else {
1882 CHECK_CALLED(ReportData);
1885 if(prot_state == 3)
1886 prot_state = 4;
1888 return S_OK;
1891 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1893 CHECK_EXPECT(Terminate);
1894 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1895 return S_OK;
1898 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1899 ULONG cb, ULONG *pcbRead)
1901 if(read_report_data)
1902 CHECK_EXPECT2(Read2);
1904 if(mimefilter_test || short_read) {
1905 if(!read_report_data)
1906 CHECK_EXPECT2(Read);
1907 }else if((pi & PI_MIMEVERIFICATION)) {
1908 if(!read_report_data)
1909 CHECK_EXPECT2(Read);
1911 if(prot_read < 300) {
1912 ok(pv != expect_pv, "pv == expect_pv\n");
1913 if(prot_read < 300)
1914 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1915 else
1916 ok(cb == 700, "cb=%d\n", cb);
1917 }else {
1918 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1920 }else {
1921 if(!read_report_data)
1922 CHECK_EXPECT(Read);
1924 ok(pv == expect_pv, "pv != expect_pv\n");
1925 ok(cb == 1000, "cb=%d\n", cb);
1926 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1928 ok(pcbRead != NULL, "pcbRead == NULL\n");
1930 if(prot_state == 3 || (short_read && prot_state != 4)) {
1931 HRESULT hres;
1933 prot_state = 4;
1934 if(short_read) {
1935 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1936 SET_EXPECT(GetBindInfo);
1937 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1939 if(mimefilter_test)
1940 SET_EXPECT(MimeFilter_ReportData);
1941 else if(direct_read)
1942 SET_EXPECT(ReportData2);
1943 read_report_data++;
1944 hres = IInternetProtocolSink_ReportData(binding_sink,
1945 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1946 read_report_data--;
1947 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1948 if(short_read) {
1949 CLEAR_CALLED(GetBindInfo); /* IE9 */
1950 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1952 if(mimefilter_test)
1953 CHECK_CALLED(MimeFilter_ReportData);
1954 else if(direct_read)
1955 CHECK_CALLED(ReportData2);
1957 if(mimefilter_test)
1958 SET_EXPECT(MimeFilter_ReportResult);
1959 else
1960 SET_EXPECT(ReportResult);
1961 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1962 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1963 if(mimefilter_test)
1964 CHECK_CALLED(MimeFilter_ReportResult);
1965 else
1966 CHECK_CALLED(ReportResult);
1968 if(cb > 100)
1969 cb = 100;
1970 memset(pv, 'x', cb);
1971 if(cb>6)
1972 memcpy(pv, "gif87a", 6);
1973 prot_read += *pcbRead = cb;
1974 return S_OK;
1975 }if(prot_state == 4) {
1976 *pcbRead = 0;
1977 return S_FALSE;
1980 if((async_read_pending = !async_read_pending)) {
1981 *pcbRead = 0;
1982 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
1985 if(cb > 100)
1986 cb = 100;
1987 memset(pv, 'x', cb);
1988 if(cb>6)
1989 memcpy(pv, "gif87a", 6);
1990 prot_read += *pcbRead = cb;
1991 return S_OK;
1994 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
1996 CHECK_EXPECT(LockRequest);
1997 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
1998 return S_OK;
2001 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2003 CHECK_EXPECT(UnlockRequest);
2004 return S_OK;
2007 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2008 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2009 DWORD grfPI, HANDLE *dwReserved)
2011 CHECK_EXPECT(StartEx);
2012 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2013 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2014 return S_OK;
2017 static const IInternetProtocolExVtbl ProtocolVtbl = {
2018 ProtocolEmul_QueryInterface,
2019 Protocol_AddRef,
2020 Protocol_Release,
2021 ProtocolEmul_Start,
2022 ProtocolEmul_Continue,
2023 Protocol_Abort,
2024 ProtocolEmul_Terminate,
2025 Protocol_Suspend,
2026 Protocol_Resume,
2027 ProtocolEmul_Read,
2028 Protocol_Seek,
2029 ProtocolEmul_LockRequest,
2030 ProtocolEmul_UnlockRequest,
2031 ProtocolEmul_StartEx
2034 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2036 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2038 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2039 *ppv = iface;
2040 return S_OK;
2043 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2044 *ppv = &mime_protocol_sink;
2045 return S_OK;
2048 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2049 *ppv = NULL;
2050 return E_NOINTERFACE;
2053 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2054 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2055 DWORD grfPI, HANDLE_PTR dwReserved)
2057 PROTOCOLFILTERDATA *data;
2058 LPOLESTR url_str = NULL;
2059 DWORD fetched = 0;
2060 BINDINFO bindinfo;
2061 DWORD cbindf = 0;
2062 HRESULT hres;
2064 CHECK_EXPECT(MimeFilter_Start);
2066 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2067 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2068 ok(dwReserved, "dwReserved == 0\n");
2069 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2070 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2072 if(binding_test) {
2073 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2074 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2075 }else {
2076 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2077 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2080 data = (void*)dwReserved;
2081 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2082 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2083 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2084 ok(!data->pUnk, "data->pUnk != NULL\n");
2085 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2086 if(binding_test) {
2087 IInternetProtocolSink *prot_sink;
2089 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2090 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2091 IInternetProtocolSink_Release(prot_sink);
2093 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2095 filtered_protocol = data->pProtocol;
2096 IInternetProtocol_AddRef(filtered_protocol);
2097 }else {
2098 IInternetProtocol *prot;
2100 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2101 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2102 IInternetProtocol_Release(prot);
2104 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2107 filtered_sink = pOIProtSink;
2109 SET_EXPECT(ReportProgress_DECODING);
2110 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2111 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2112 CHECK_CALLED(ReportProgress_DECODING);
2114 SET_EXPECT(GetBindInfo);
2115 memset(&bindinfo, 0, sizeof(bindinfo));
2116 bindinfo.cbSize = sizeof(bindinfo);
2117 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2118 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2119 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2120 CHECK_CALLED(GetBindInfo);
2122 SET_EXPECT(GetBindString_URL);
2123 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2124 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2125 ok(fetched == 1, "fetched = %d\n", fetched);
2126 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2127 CoTaskMemFree(url_str);
2128 CHECK_CALLED(GetBindString_URL);
2130 return S_OK;
2133 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2134 PROTOCOLDATA *pProtocolData)
2136 CHECK_EXPECT(MimeFilter_Continue);
2137 return E_NOTIMPL;
2140 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2142 HRESULT hres;
2144 CHECK_EXPECT(MimeFilter_Terminate);
2146 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2148 SET_EXPECT(Terminate);
2149 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2150 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2151 CHECK_CALLED(Terminate);
2153 return S_OK;
2156 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2157 ULONG cb, ULONG *pcbRead)
2159 BYTE buf[2096];
2160 DWORD read = 0;
2161 HRESULT hres;
2163 CHECK_EXPECT(MimeFilter_Read);
2165 ok(pv != NULL, "pv == NULL\n");
2166 ok(cb != 0, "cb == 0\n");
2167 ok(pcbRead != NULL, "pcbRead == NULL\n");
2169 if(read_report_data)
2170 SET_EXPECT(Read2);
2171 else
2172 SET_EXPECT(Read);
2173 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2174 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2175 if(read_report_data)
2176 CHECK_CALLED(Read2);
2177 else
2178 CHECK_CALLED(Read);
2180 if(pcbRead) {
2181 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2182 *pcbRead = read;
2185 memset(pv, 'x', read);
2186 return hres;
2189 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2191 HRESULT hres;
2193 CHECK_EXPECT(MimeFilter_LockRequest);
2195 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2197 SET_EXPECT(LockRequest);
2198 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2199 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2200 CHECK_CALLED(LockRequest);
2202 return S_OK;
2205 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2207 HRESULT hres;
2209 CHECK_EXPECT(MimeFilter_UnlockRequest);
2211 SET_EXPECT(UnlockRequest);
2212 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2213 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2214 CHECK_CALLED(UnlockRequest);
2216 return S_OK;
2219 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2220 MimeProtocol_QueryInterface,
2221 Protocol_AddRef,
2222 Protocol_Release,
2223 MimeProtocol_Start,
2224 Protocol_Continue,
2225 Protocol_Abort,
2226 MimeProtocol_Terminate,
2227 Protocol_Suspend,
2228 Protocol_Resume,
2229 MimeProtocol_Read,
2230 Protocol_Seek,
2231 MimeProtocol_LockRequest,
2232 MimeProtocol_UnlockRequest
2235 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2237 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2239 ok(0, "unexpected call\n");
2240 return E_NOINTERFACE;
2243 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2245 return 2;
2248 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2250 return 1;
2253 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2254 REFIID riid, void **ppv)
2256 CHECK_EXPECT(CreateInstance);
2258 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2259 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
2260 ok(ppv != NULL, "ppv == NULL\n");
2262 *ppv = &Protocol;
2263 return S_OK;
2266 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2268 ok(0, "unexpected call\n");
2269 return S_OK;
2272 static const IClassFactoryVtbl ClassFactoryVtbl = {
2273 ClassFactory_QueryInterface,
2274 ClassFactory_AddRef,
2275 ClassFactory_Release,
2276 ClassFactory_CreateInstance,
2277 ClassFactory_LockServer
2280 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2282 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2284 CHECK_EXPECT(MimeFilter_CreateInstance);
2286 ok(!outer, "outer = %p\n", outer);
2287 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", debugstr_guid(riid));
2289 *ppv = &MimeProtocol;
2290 return S_OK;
2293 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2294 ClassFactory_QueryInterface,
2295 ClassFactory_AddRef,
2296 ClassFactory_Release,
2297 MimeFilter_CreateInstance,
2298 ClassFactory_LockServer
2301 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2303 #define TEST_BINDING 0x0001
2304 #define TEST_FILTER 0x0002
2305 #define TEST_FIRST_HTTP 0x0004
2306 #define TEST_DIRECT_READ 0x0008
2307 #define TEST_POST 0x0010
2308 #define TEST_EMULATEPROT 0x0020
2309 #define TEST_SHORT_READ 0x0040
2310 #define TEST_REDIRECT 0x0080
2311 #define TEST_ABORT 0x0100
2312 #define TEST_ASYNCREQ 0x0200
2313 #define TEST_USEIURI 0x0400
2314 #define TEST_IMPLPROTEX 0x0800
2315 #define TEST_EMPTY 0x1000
2316 #define TEST_NOMIME 0x2000
2317 #define TEST_FROMCACHE 0x4000
2319 static void register_filter(BOOL do_register)
2321 IInternetSession *session;
2322 HRESULT hres;
2324 hres = pCoInternetGetSession(0, &session, 0);
2325 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2327 if(do_register) {
2328 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2329 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2330 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2331 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2332 }else {
2333 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2334 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2335 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2336 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2339 IInternetSession_Release(session);
2342 static void init_test(int prot, DWORD flags)
2344 tested_protocol = prot;
2345 binding_test = (flags & TEST_BINDING) != 0;
2346 first_data_notif = TRUE;
2347 prot_read = 0;
2348 prot_state = 0;
2349 async_read_pending = TRUE;
2350 mimefilter_test = (flags & TEST_FILTER) != 0;
2351 no_mime = (flags & TEST_NOMIME) != 0;
2352 filter_state = 0;
2353 post_stream_read = 0;
2354 ResetEvent(event_complete);
2355 ResetEvent(event_complete2);
2356 ResetEvent(event_continue);
2357 ResetEvent(event_continue_done);
2358 async_protocol = binding_protocol = filtered_protocol = NULL;
2359 filtered_sink = NULL;
2360 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2361 first_data_notif = TRUE;
2362 state = STATE_CONNECTING;
2363 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2364 direct_read = (flags & TEST_DIRECT_READ) != 0;
2365 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2366 wait_for_switch = TRUE;
2367 short_read = (flags & TEST_SHORT_READ) != 0;
2368 http_post_test = TYMED_NULL;
2369 test_redirect = (flags & TEST_REDIRECT) != 0;
2370 test_abort = (flags & TEST_ABORT) != 0;
2371 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2372 empty_file = (flags & TEST_EMPTY) != 0;
2373 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2375 register_filter(mimefilter_test);
2378 static void test_priority(IInternetProtocol *protocol)
2380 IInternetPriority *priority;
2381 LONG pr;
2382 HRESULT hres;
2384 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2385 (void**)&priority);
2386 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2387 if(FAILED(hres))
2388 return;
2390 hres = IInternetPriority_GetPriority(priority, &pr);
2391 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2392 ok(pr == 0, "pr=%d, expected 0\n", pr);
2394 hres = IInternetPriority_SetPriority(priority, 1);
2395 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2397 hres = IInternetPriority_GetPriority(priority, &pr);
2398 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2399 ok(pr == 1, "pr=%d, expected 1\n", pr);
2401 IInternetPriority_Release(priority);
2404 static void test_early_abort(const CLSID *clsid)
2406 IInternetProtocol *protocol;
2407 HRESULT hres;
2409 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2410 &IID_IInternetProtocol, (void**)&protocol);
2411 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2413 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2414 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2416 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2417 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2419 IInternetProtocol_Release(protocol);
2422 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2423 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2425 HRESULT hres;
2427 SET_EXPECT(GetBindInfo);
2428 if(!(bindf & BINDF_FROMURLMON))
2429 SET_EXPECT(ReportProgress_DIRECTBIND);
2430 if(is_first) {
2431 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2432 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2433 if(bindf & BINDF_FROMURLMON)
2434 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2435 else
2436 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2438 SET_EXPECT(ReportData);
2439 if(is_first)
2440 SET_EXPECT(ReportResult);
2442 expect_hrResult = S_OK;
2444 if(protocolex) {
2445 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2446 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2447 }else {
2448 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2449 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2450 win_skip("Start failed\n");
2451 return FALSE;
2453 ok(hres == S_OK, "Start failed: %08x\n", hres);
2456 CHECK_CALLED(GetBindInfo);
2457 if(!(bindf & BINDF_FROMURLMON))
2458 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2459 if(is_first) {
2460 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2461 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2462 if(bindf & BINDF_FROMURLMON)
2463 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2464 else
2465 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2467 CHECK_CALLED(ReportData);
2468 if(is_first)
2469 CHECK_CALLED(ReportResult);
2471 return TRUE;
2474 static void test_file_protocol_url(LPCWSTR url)
2476 IInternetProtocolInfo *protocol_info;
2477 IUnknown *unk;
2478 IClassFactory *factory;
2479 IInternetProtocol *protocol;
2480 BYTE buf[512];
2481 ULONG cb;
2482 HRESULT hres;
2484 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2485 &IID_IUnknown, (void**)&unk);
2486 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2487 if(FAILED(hres))
2488 return;
2490 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2491 ok(hres == E_NOINTERFACE,
2492 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2494 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2495 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2496 IUnknown_Release(unk);
2497 if(FAILED(hres))
2498 return;
2500 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2501 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2503 if(SUCCEEDED(hres)) {
2504 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2505 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2506 ok(hres == S_OK, "Read failed: %08x\n", hres);
2507 ok(cb == 2, "cb=%u expected 2\n", cb);
2508 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2509 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2510 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2511 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2512 ok(cb == 0, "cb=%u expected 0\n", cb);
2513 hres = IInternetProtocol_UnlockRequest(protocol);
2514 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2517 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2518 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2519 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2520 hres = IInternetProtocol_LockRequest(protocol, 0);
2521 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2522 hres = IInternetProtocol_UnlockRequest(protocol);
2523 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2526 IInternetProtocol_Release(protocol);
2529 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2530 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2531 if(SUCCEEDED(hres)) {
2532 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2533 hres = IInternetProtocol_LockRequest(protocol, 0);
2534 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2535 hres = IInternetProtocol_Terminate(protocol, 0);
2536 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2537 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2538 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2539 hres = IInternetProtocol_UnlockRequest(protocol);
2540 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2541 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2542 ok(hres == S_OK, "Read failed: %08x\n", hres);
2543 hres = IInternetProtocol_Terminate(protocol, 0);
2544 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2547 IInternetProtocol_Release(protocol);
2550 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2551 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2552 if(SUCCEEDED(hres)) {
2553 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2554 hres = IInternetProtocol_Terminate(protocol, 0);
2555 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2556 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2557 ok(hres == S_OK, "Read failed: %08x\n", hres);
2558 ok(cb == 2, "cb=%u expected 2\n", cb);
2561 IInternetProtocol_Release(protocol);
2564 if(pCreateUri) {
2565 IInternetProtocolEx *protocolex;
2566 IUri *uri;
2568 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2569 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2571 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2572 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2574 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2575 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2576 ok(hres == S_OK, "Read failed: %08x\n", hres);
2577 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2578 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2579 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2580 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2583 IUri_Release(uri);
2584 IInternetProtocolEx_Release(protocolex);
2586 hres = pCreateUri(url, 0, 0, &uri);
2587 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2589 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2590 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2592 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2593 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2594 ok(hres == S_OK, "Read failed: %08x\n", hres);
2595 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2596 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2597 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2598 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2601 IUri_Release(uri);
2602 IInternetProtocolEx_Release(protocolex);
2603 }else {
2604 win_skip("Skipping file protocol StartEx tests\n");
2607 IClassFactory_Release(factory);
2610 static void test_file_protocol_fail(void)
2612 IInternetProtocol *protocol;
2613 HRESULT hres;
2615 static const WCHAR index_url2[] =
2616 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2618 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2619 &IID_IInternetProtocol, (void**)&protocol);
2620 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2621 if(FAILED(hres))
2622 return;
2624 SET_EXPECT(GetBindInfo);
2625 expect_hrResult = MK_E_SYNTAX;
2626 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2627 ok(hres == MK_E_SYNTAX ||
2628 hres == E_INVALIDARG,
2629 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2630 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2632 SET_EXPECT(GetBindInfo);
2633 if(!(bindf & BINDF_FROMURLMON))
2634 SET_EXPECT(ReportProgress_DIRECTBIND);
2635 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2636 SET_EXPECT(ReportResult);
2637 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2638 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2639 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2640 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2641 CHECK_CALLED(GetBindInfo);
2642 if(!(bindf & BINDF_FROMURLMON))
2643 CHECK_CALLED(ReportProgress_DIRECTBIND);
2644 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2645 CHECK_CALLED(ReportResult);
2647 IInternetProtocol_Release(protocol);
2649 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2650 &IID_IInternetProtocol, (void**)&protocol);
2651 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2652 if(FAILED(hres))
2653 return;
2655 SET_EXPECT(GetBindInfo);
2656 if(!(bindf & BINDF_FROMURLMON))
2657 SET_EXPECT(ReportProgress_DIRECTBIND);
2658 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2659 SET_EXPECT(ReportResult);
2660 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2662 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2663 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2664 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2665 CHECK_CALLED(GetBindInfo);
2666 if(!(bindf & BINDF_FROMURLMON))
2667 CHECK_CALLED(ReportProgress_DIRECTBIND);
2668 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2669 CHECK_CALLED(ReportResult);
2671 SET_EXPECT(GetBindInfo);
2672 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2673 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2674 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2676 SET_EXPECT(GetBindInfo);
2677 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2678 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2679 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2681 IInternetProtocol_Release(protocol);
2684 static void test_file_protocol(void) {
2685 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2686 DWORD size;
2687 ULONG len;
2688 HANDLE file;
2690 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2691 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2692 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2693 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2694 static const char html_doc[] = "<HTML></HTML>";
2696 trace("Testing file protocol...\n");
2697 init_test(FILE_TEST, 0);
2699 SetLastError(0xdeadbeef);
2700 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2701 FILE_ATTRIBUTE_NORMAL, NULL);
2702 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2703 if(file == INVALID_HANDLE_VALUE)
2704 return;
2705 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2706 CloseHandle(file);
2708 file_name = wszIndexHtml;
2709 bindf = 0;
2710 test_file_protocol_url(index_url);
2711 bindf = BINDF_FROMURLMON;
2712 test_file_protocol_url(index_url);
2713 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2714 test_file_protocol_url(index_url);
2716 memcpy(buf, wszFile, sizeof(wszFile));
2717 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2718 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2719 buf[len++] = '\\';
2720 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2722 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2723 bindf = 0;
2724 test_file_protocol_url(buf);
2725 bindf = BINDF_FROMURLMON;
2726 test_file_protocol_url(buf);
2728 memcpy(buf, wszFile2, sizeof(wszFile2));
2729 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2730 file_name_buf[len++] = '\\';
2731 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2732 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2733 file_name = file_name_buf;
2734 bindf = 0;
2735 test_file_protocol_url(buf);
2736 bindf = BINDF_FROMURLMON;
2737 test_file_protocol_url(buf);
2739 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2740 test_file_protocol_url(buf);
2742 memcpy(buf, wszFile3, sizeof(wszFile3));
2743 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2744 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2745 buf[len++] = '\\';
2746 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2748 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2749 bindf = 0;
2750 test_file_protocol_url(buf);
2751 bindf = BINDF_FROMURLMON;
2752 test_file_protocol_url(buf);
2754 memcpy(buf, wszFile4, sizeof(wszFile4));
2755 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2756 file_name_buf[len++] = '\\';
2757 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2758 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2759 file_name = file_name_buf;
2760 bindf = 0;
2761 test_file_protocol_url(buf);
2762 bindf = BINDF_FROMURLMON;
2763 test_file_protocol_url(buf);
2765 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2766 test_file_protocol_url(buf);
2768 DeleteFileW(wszIndexHtml);
2770 bindf = 0;
2771 test_file_protocol_fail();
2772 bindf = BINDF_FROMURLMON;
2773 test_file_protocol_fail();
2776 static void create_cache_entry(const WCHAR *urlw)
2778 FILETIME now, tomorrow, yesterday;
2779 char file_path[MAX_PATH];
2780 BYTE content[1000];
2781 ULARGE_INTEGER li;
2782 const char *url;
2783 HANDLE file;
2784 DWORD size;
2785 unsigned i;
2786 BOOL res;
2788 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2790 trace("Testing cache read...\n");
2792 url = w2a(urlw);
2794 for(i = 0; i < sizeof(content); i++)
2795 content[i] = '0' + (i%10);
2797 GetSystemTimeAsFileTime(&now);
2798 li.u.HighPart = now.dwHighDateTime;
2799 li.u.LowPart = now.dwLowDateTime;
2800 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2801 tomorrow.dwHighDateTime = li.u.HighPart;
2802 tomorrow.dwLowDateTime = li.u.LowPart;
2803 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2804 yesterday.dwHighDateTime = li.u.HighPart;
2805 yesterday.dwLowDateTime = li.u.LowPart;
2807 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2808 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2810 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2811 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2813 WriteFile(file, content, sizeof(content), &size, NULL);
2814 CloseHandle(file);
2816 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2817 cache_headers, sizeof(cache_headers)-1, "", 0);
2818 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2821 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2823 static BOOL got_user_agent = FALSE;
2824 IUri *uri = NULL;
2825 HRESULT hres;
2827 if(use_iuri && pCreateUri) {
2828 hres = pCreateUri(url, 0, 0, &uri);
2829 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2832 SET_EXPECT(GetBindInfo);
2833 if (!(bindf & BINDF_FROMURLMON))
2834 SET_EXPECT(ReportProgress_DIRECTBIND);
2835 if(!got_user_agent)
2836 SET_EXPECT(GetBindString_USER_AGENT);
2837 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2838 SET_EXPECT(QueryService_HttpNegotiate);
2839 SET_EXPECT(BeginningTransaction);
2840 SET_EXPECT(GetRootSecurityId);
2841 if(http_post_test) {
2842 SET_EXPECT(GetBindString_POST_COOKIE);
2843 if(http_post_test == TYMED_ISTREAM)
2844 SET_EXPECT(Stream_Seek);
2846 if(bind_from_cache) {
2847 SET_EXPECT(OnResponse);
2848 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2849 SET_EXPECT(ReportData);
2852 if(uri) {
2853 IInternetProtocolEx *protocolex;
2855 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2856 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2858 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2859 ok(hres == S_OK, "Start failed: %08x\n", hres);
2861 IInternetProtocolEx_Release(protocolex);
2862 IUri_Release(uri);
2863 }else {
2864 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2865 ok(hres == S_OK, "Start failed: %08x\n", hres);
2867 if(FAILED(hres))
2868 return FALSE;
2870 CHECK_CALLED(GetBindInfo);
2871 if (!(bindf & BINDF_FROMURLMON))
2872 CHECK_CALLED(ReportProgress_DIRECTBIND);
2873 if (!got_user_agent)
2875 CHECK_CALLED(GetBindString_USER_AGENT);
2876 got_user_agent = TRUE;
2878 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2879 CHECK_CALLED(QueryService_HttpNegotiate);
2880 CHECK_CALLED(BeginningTransaction);
2881 /* GetRootSecurityId called on WinXP but not on Win98 */
2882 CLEAR_CALLED(GetRootSecurityId);
2883 if(http_post_test) {
2884 CHECK_CALLED(GetBindString_POST_COOKIE);
2885 if(http_post_test == TYMED_ISTREAM)
2886 CHECK_CALLED(Stream_Seek);
2888 if(bind_from_cache) {
2889 CHECK_CALLED(OnResponse);
2890 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2891 CHECK_CALLED(ReportData);
2894 return TRUE;
2897 static void test_protocol_terminate(IInternetProtocol *protocol)
2899 BYTE buf[3600];
2900 DWORD cb;
2901 HRESULT hres;
2903 hres = IInternetProtocol_LockRequest(protocol, 0);
2904 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2906 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2907 ok(hres == test_abort ? S_OK : S_FALSE, "Read failed: %08x\n", hres);
2909 hres = IInternetProtocol_Terminate(protocol, 0);
2910 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2912 /* This wait is to give the internet handles being freed in Terminate
2913 * enough time to actually terminate in all cases. Internet handles
2914 * terminate asynchronously and native reuses the main InternetOpen
2915 * handle. The only case in which this seems to be necessary is on
2916 * wine with native wininet and urlmon, resulting in the next time
2917 * test_http_protocol_url being called the first data notification actually
2918 * being an extra last data notification from the previous connection
2919 * about once out of every ten times. */
2920 Sleep(100);
2922 hres = IInternetProtocol_UnlockRequest(protocol);
2923 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2926 static void test_http_info(IInternetProtocol *protocol)
2928 IWinInetHttpInfo *info;
2929 HRESULT hres;
2931 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2932 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2934 /* TODO */
2936 IWinInetHttpInfo_Release(info);
2939 /* is_first refers to whether this is the first call to this function
2940 * _for this url_ */
2941 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
2943 IInternetProtocolInfo *protocol_info;
2944 IClassFactory *factory;
2945 IUnknown *unk;
2946 HRESULT hres;
2948 init_test(prot, flags);
2949 http_url = url;
2950 http_post_test = tymed;
2952 if(flags & TEST_FROMCACHE)
2953 create_cache_entry(url);
2955 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
2956 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
2957 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2958 if(FAILED(hres))
2959 return;
2961 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2962 ok(hres == E_NOINTERFACE,
2963 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
2964 hres);
2966 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2967 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2968 IUnknown_Release(unk);
2969 if(FAILED(hres))
2970 return;
2972 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
2973 (void**)&async_protocol);
2974 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2975 if(SUCCEEDED(hres)) {
2976 BYTE buf[3600];
2977 DWORD cb;
2978 ULONG ref;
2980 test_priority(async_protocol);
2981 test_http_info(async_protocol);
2983 SET_EXPECT(ReportProgress_COOKIE_SENT);
2984 if(http_is_first) {
2985 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
2986 SET_EXPECT(ReportProgress_CONNECTING);
2988 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2989 if(test_redirect)
2990 SET_EXPECT(ReportProgress_REDIRECTING);
2991 SET_EXPECT(ReportProgress_PROXYDETECTING);
2992 if(prot == HTTP_TEST)
2993 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2994 else
2995 SET_EXPECT(QueryService_HttpSecurity);
2996 if(!(bindf & BINDF_FROMURLMON)) {
2997 SET_EXPECT(OnResponse);
2998 SET_EXPECT(ReportProgress_RAWMIMETYPE);
2999 SET_EXPECT(ReportData);
3000 } else {
3001 SET_EXPECT(Switch);
3004 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3005 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3006 IInternetProtocol_Release(async_protocol);
3007 return;
3010 if(!direct_read && !test_abort && !bind_from_cache)
3011 SET_EXPECT(ReportResult);
3012 expect_hrResult = test_abort ? E_ABORT : S_OK;
3014 if(direct_read) {
3015 SET_EXPECT(Switch);
3016 while(wait_for_switch) {
3017 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3018 CHECK_CALLED(Switch); /* Set in ReportData */
3019 call_continue(&continue_protdata);
3020 SetEvent(event_continue_done);
3022 }else if(bind_from_cache) {
3023 BYTE buf[1500];
3025 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3026 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3028 SET_EXPECT(ReportResult);
3029 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3030 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3031 CHECK_CALLED(ReportResult);
3033 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3034 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3035 }else {
3036 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3037 ok((hres == E_PENDING && cb==0) ||
3038 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3040 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3041 if(bindf & BINDF_FROMURLMON)
3042 CHECK_CALLED(Switch);
3043 else
3044 CHECK_CALLED(ReportData);
3045 if(prot == HTTPS_TEST)
3046 CLEAR_CALLED(QueryService_HttpSecurity);
3048 while(1) {
3049 if(bindf & BINDF_FROMURLMON)
3050 SET_EXPECT(Switch);
3051 else
3052 SET_EXPECT(ReportData);
3053 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3054 if(hres == E_PENDING) {
3055 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3056 ok((hres == E_PENDING && cb==0) ||
3057 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3058 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3059 if(bindf & BINDF_FROMURLMON)
3060 CHECK_CALLED(Switch);
3061 else
3062 CHECK_CALLED(ReportData);
3064 if(test_abort) {
3065 HRESULT hres;
3067 SET_EXPECT(ReportResult);
3068 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3069 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3070 CHECK_CALLED(ReportResult);
3072 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3073 ok(hres == INET_E_RESULT_DISPATCHED, "Abort failed: %08x\n", hres);
3074 break;
3076 }else {
3077 if(bindf & BINDF_FROMURLMON)
3078 CHECK_NOT_CALLED(Switch);
3079 else
3080 CHECK_NOT_CALLED(ReportData);
3081 if(cb == 0) break;
3084 if(!test_abort) {
3085 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3086 CHECK_CALLED(ReportResult);
3089 if(prot == HTTPS_TEST)
3090 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3092 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3093 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3095 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3096 ok(hres == INET_E_RESULT_DISPATCHED, "Abort failed: %08x\n", hres);
3098 test_protocol_terminate(async_protocol);
3100 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3101 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3103 ref = IInternetProtocol_Release(async_protocol);
3104 ok(!ref, "ref=%x\n", ref);
3107 IClassFactory_Release(factory);
3109 if(flags & TEST_FROMCACHE) {
3110 BOOL res;
3112 res = DeleteUrlCacheEntryW(url);
3113 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3117 static void test_http_protocol(void)
3119 static const WCHAR posttest_url[] =
3120 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3121 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3122 static const WCHAR redirect_url[] =
3123 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3124 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3125 static const WCHAR winetest_url[] =
3126 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3127 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3128 static const WCHAR empty_url[] =
3129 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3130 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3131 static const WCHAR cache_only_url[] =
3132 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3133 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3136 trace("Testing http protocol (not from urlmon)...\n");
3137 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3138 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3140 trace("Testing http protocol (from urlmon)...\n");
3141 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3142 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3144 trace("Testing http protocol (to file)...\n");
3145 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3146 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3148 trace("Testing http protocol (post data)...\n");
3149 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3150 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3152 trace("Testing http protocol (post data stream)...\n");
3153 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3155 trace("Testing http protocol (direct read)...\n");
3156 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3157 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3159 trace("Testing http protocol (redirected)...\n");
3160 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3161 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3163 trace("Testing http protocol empty file...\n");
3164 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3165 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3167 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3168 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3169 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3170 * tests work on Windows and have them around for the future.
3172 if(broken(1)) {
3173 trace("Testing http protocol (from cache)...\n");
3174 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3175 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3178 trace("Testing http protocol abort...\n");
3179 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3180 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3182 test_early_abort(&CLSID_HttpProtocol);
3183 test_early_abort(&CLSID_HttpSProtocol);
3186 static void test_https_protocol(void)
3188 static const WCHAR codeweavers_url[] =
3189 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
3190 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0};
3192 trace("Testing https protocol (from urlmon)...\n");
3193 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3194 test_http_protocol_url(codeweavers_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3198 static void test_ftp_protocol(void)
3200 IInternetProtocolInfo *protocol_info;
3201 IClassFactory *factory;
3202 IUnknown *unk;
3203 BYTE buf[4096];
3204 ULONG ref;
3205 DWORD cb;
3206 HRESULT hres;
3208 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3209 '/','p','u','b','/','o','t','h','e','r','/',
3210 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3212 trace("Testing ftp protocol...\n");
3214 init_test(FTP_TEST, 0);
3216 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3217 state = STATE_STARTDOWNLOADING;
3218 expect_hrResult = E_PENDING;
3220 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3221 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3222 if(FAILED(hres))
3223 return;
3225 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3226 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3228 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3229 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3230 IUnknown_Release(unk);
3231 if(FAILED(hres))
3232 return;
3234 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3235 (void**)&async_protocol);
3236 IClassFactory_Release(factory);
3237 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3239 test_priority(async_protocol);
3240 test_http_info(async_protocol);
3242 SET_EXPECT(GetBindInfo);
3243 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3244 SET_EXPECT(ReportProgress_CONNECTING);
3245 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3246 SET_EXPECT(Switch);
3248 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3249 ok(hres == S_OK, "Start failed: %08x\n", hres);
3250 CHECK_CALLED(GetBindInfo);
3252 SET_EXPECT(ReportResult);
3254 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3255 ok((hres == E_PENDING && cb==0) ||
3256 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3258 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3260 while(1) {
3261 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3262 if(hres == E_PENDING)
3264 DWORD ret = WaitForSingleObject(event_complete, 90000);
3265 ok( ret == WAIT_OBJECT_0, "wait timed out\n" );
3266 if (ret != WAIT_OBJECT_0) break;
3268 else
3269 if(cb == 0) break;
3272 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3273 CHECK_CALLED(ReportResult);
3274 CHECK_CALLED(Switch);
3276 test_protocol_terminate(async_protocol);
3278 if(pCreateUri) {
3279 IInternetProtocolEx *protocolex;
3281 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3282 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3283 IInternetProtocolEx_Release(protocolex);
3286 ref = IInternetProtocol_Release(async_protocol);
3287 ok(!ref, "ref=%d\n", ref);
3289 test_early_abort(&CLSID_FtpProtocol);
3292 static void test_gopher_protocol(void)
3294 IInternetProtocolInfo *protocol_info;
3295 IClassFactory *factory;
3296 IUnknown *unk;
3297 HRESULT hres;
3299 trace("Testing gopher protocol...\n");
3301 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3302 ok(hres == S_OK ||
3303 hres == REGDB_E_CLASSNOTREG, /* Gopher protocol has been removed as of Vista */
3304 "CoGetClassObject failed: %08x\n", hres);
3305 if(FAILED(hres))
3306 return;
3308 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3309 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3311 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3312 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3313 IUnknown_Release(unk);
3314 if(FAILED(hres))
3315 return;
3317 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3318 (void**)&async_protocol);
3319 IClassFactory_Release(factory);
3320 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3322 test_priority(async_protocol);
3324 IInternetProtocol_Release(async_protocol);
3326 test_early_abort(&CLSID_GopherProtocol);
3329 static void test_mk_protocol(void)
3331 IInternetProtocolInfo *protocol_info;
3332 IInternetProtocol *protocol;
3333 IClassFactory *factory;
3334 IUnknown *unk;
3335 HRESULT hres;
3337 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3338 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3339 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3341 trace("Testing mk protocol...\n");
3342 init_test(MK_TEST, 0);
3344 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3345 &IID_IUnknown, (void**)&unk);
3346 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3348 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3349 ok(hres == E_NOINTERFACE,
3350 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3351 hres);
3353 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3354 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3355 IUnknown_Release(unk);
3356 if(FAILED(hres))
3357 return;
3359 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3360 (void**)&protocol);
3361 IClassFactory_Release(factory);
3362 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3364 SET_EXPECT(GetBindInfo);
3365 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3366 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3367 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3368 CLEAR_CALLED(GetBindInfo);
3370 SET_EXPECT(GetBindInfo);
3371 SET_EXPECT(ReportProgress_DIRECTBIND);
3372 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3373 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3374 SET_EXPECT(ReportResult);
3375 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3377 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3378 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3379 hres == INET_E_INVALID_URL, /* win2k3 */
3380 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3382 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3383 CHECK_CALLED(GetBindInfo);
3384 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3385 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3386 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3387 CHECK_CALLED(ReportResult);
3388 }else {
3389 CLEAR_CALLED(GetBindInfo);
3390 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3391 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3392 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3393 CLEAR_CALLED(ReportResult);
3396 IInternetProtocol_Release(protocol);
3399 static void test_CreateBinding(void)
3401 IInternetProtocol *protocol;
3402 IInternetPriority *priority;
3403 IInternetSession *session;
3404 IWinInetHttpInfo *http_info;
3405 IWinInetInfo *inet_info;
3406 LONG p;
3407 BYTE buf[1000];
3408 DWORD read;
3409 HRESULT hres;
3411 static const WCHAR test_url[] =
3412 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3413 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3415 trace("Testing CreateBinding...\n");
3416 init_test(BIND_TEST, TEST_BINDING);
3418 hres = pCoInternetGetSession(0, &session, 0);
3419 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3421 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3422 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3424 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3425 binding_protocol = protocol;
3426 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3427 ok(protocol != NULL, "protocol == NULL\n");
3429 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3430 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3432 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3433 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3435 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3436 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3437 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3438 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3439 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3440 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3442 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3443 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3445 p = 0xdeadbeef;
3446 hres = IInternetPriority_GetPriority(priority, &p);
3447 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3448 ok(!p, "p=%d\n", p);
3450 ex_priority = 100;
3451 hres = IInternetPriority_SetPriority(priority, 100);
3452 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3454 p = 0xdeadbeef;
3455 hres = IInternetPriority_GetPriority(priority, &p);
3456 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3457 ok(p == 100, "p=%d\n", p);
3459 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3460 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3462 SET_EXPECT(QueryService_InternetProtocol);
3463 SET_EXPECT(CreateInstance);
3464 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3465 SET_EXPECT(SetPriority);
3466 SET_EXPECT(Start);
3468 expect_hrResult = S_OK;
3469 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3470 ok(hres == S_OK, "Start failed: %08x\n", hres);
3472 CHECK_CALLED(QueryService_InternetProtocol);
3473 CHECK_CALLED(CreateInstance);
3474 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3475 CHECK_CALLED(SetPriority);
3476 CHECK_CALLED(Start);
3478 SET_EXPECT(QueryInterface_IWinInetInfo);
3479 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3480 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3481 CHECK_CALLED(QueryInterface_IWinInetInfo);
3483 SET_EXPECT(QueryInterface_IWinInetInfo);
3484 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3485 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3486 CHECK_CALLED(QueryInterface_IWinInetInfo);
3488 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3489 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3490 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3491 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3493 SET_EXPECT(Read);
3494 read = 0xdeadbeef;
3495 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3496 ok(hres == S_OK, "Read failed: %08x\n", hres);
3497 ok(read == 100, "read = %d\n", read);
3498 CHECK_CALLED(Read);
3500 SET_EXPECT(Read);
3501 read = 0xdeadbeef;
3502 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3503 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3504 ok(!read, "read = %d\n", read);
3505 CHECK_CALLED(Read);
3507 p = 0xdeadbeef;
3508 hres = IInternetPriority_GetPriority(priority, &p);
3509 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3510 ok(p == 100, "p=%d\n", p);
3512 hres = IInternetPriority_SetPriority(priority, 101);
3513 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3515 SET_EXPECT(Terminate);
3516 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3517 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3518 CHECK_CALLED(Terminate);
3520 SET_EXPECT(Continue);
3521 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3522 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3523 CHECK_CALLED(Continue);
3525 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3526 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3527 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3529 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3530 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3532 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3533 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3535 IInternetProtocolSink_Release(binding_sink);
3536 IInternetPriority_Release(priority);
3537 IInternetBindInfo_Release(prot_bind_info);
3538 IInternetProtocol_Release(protocol);
3540 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3541 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3542 ok(protocol != NULL, "protocol == NULL\n");
3544 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3545 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3547 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3548 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3550 IInternetProtocol_Release(protocol);
3552 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3553 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3555 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3556 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3557 ok(protocol != NULL, "protocol == NULL\n");
3559 SET_EXPECT(QueryService_InternetProtocol);
3560 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3561 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3562 CHECK_CALLED(QueryService_InternetProtocol);
3564 IInternetProtocol_Release(protocol);
3566 IInternetSession_Release(session);
3569 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3571 IInternetProtocolEx *protocolex = NULL;
3572 IInternetProtocol *protocol;
3573 IInternetSession *session;
3574 IUri *uri = NULL;
3575 ULONG ref;
3576 HRESULT hres;
3578 pi = grf_pi;
3580 init_test(prot, test_flags|TEST_BINDING);
3582 hres = pCoInternetGetSession(0, &session, 0);
3583 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3585 if(test_flags & TEST_EMULATEPROT) {
3586 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3587 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3590 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3591 binding_protocol = protocol;
3592 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3593 ok(protocol != NULL, "protocol == NULL\n");
3595 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3596 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3598 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3599 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3601 if(test_flags & TEST_USEIURI) {
3602 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3603 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3605 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3606 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3609 ex_priority = 0;
3610 SET_EXPECT(QueryService_InternetProtocol);
3611 SET_EXPECT(CreateInstance);
3612 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3613 SET_EXPECT(SetPriority);
3614 if(impl_protex)
3615 SET_EXPECT(StartEx);
3616 else
3617 SET_EXPECT(Start);
3619 expect_hrResult = S_OK;
3621 if(protocolex) {
3622 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3623 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3624 }else {
3625 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3626 ok(hres == S_OK, "Start failed: %08x\n", hres);
3629 CHECK_CALLED(QueryService_InternetProtocol);
3630 CHECK_CALLED(CreateInstance);
3631 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3632 CHECK_CALLED(SetPriority);
3633 if(impl_protex)
3634 CHECK_CALLED(StartEx);
3635 else
3636 CHECK_CALLED(Start);
3638 if(protocolex)
3639 IInternetProtocolEx_Release(protocolex);
3640 if(uri)
3641 IUri_Release(uri);
3643 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3644 while(prot_state < 4) {
3645 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3646 if(mimefilter_test && filtered_protocol) {
3647 SET_EXPECT(Continue);
3648 IInternetProtocol_Continue(filtered_protocol, pdata);
3649 CHECK_CALLED(Continue);
3650 }else {
3651 SET_EXPECT(Continue);
3652 IInternetProtocol_Continue(protocol, pdata);
3653 CHECK_CALLED(Continue);
3655 if(test_abort && prot_state == 2) {
3656 SET_EXPECT(Abort);
3657 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3658 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3659 CHECK_CALLED(Abort);
3661 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3662 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3663 SetEvent(event_complete2);
3664 break;
3666 SetEvent(event_complete2);
3668 if(direct_read)
3669 CHECK_CALLED(ReportData); /* Set in ReportResult */
3670 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3671 }else {
3672 if(mimefilter_test)
3673 SET_EXPECT(MimeFilter_LockRequest);
3674 else
3675 SET_EXPECT(LockRequest);
3676 hres = IInternetProtocol_LockRequest(protocol, 0);
3677 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3678 if(mimefilter_test)
3679 CHECK_CALLED(MimeFilter_LockRequest);
3680 else
3681 CHECK_CALLED(LockRequest);
3683 if(mimefilter_test)
3684 SET_EXPECT(MimeFilter_UnlockRequest);
3685 else
3686 SET_EXPECT(UnlockRequest);
3687 hres = IInternetProtocol_UnlockRequest(protocol);
3688 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3689 if(mimefilter_test)
3690 CHECK_CALLED(MimeFilter_UnlockRequest);
3691 else
3692 CHECK_CALLED(UnlockRequest);
3695 if(mimefilter_test)
3696 SET_EXPECT(MimeFilter_Terminate);
3697 else
3698 SET_EXPECT(Terminate);
3699 hres = IInternetProtocol_Terminate(protocol, 0);
3700 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3701 if(mimefilter_test)
3702 CLEAR_CALLED(MimeFilter_Terminate);
3703 else
3704 CHECK_CALLED(Terminate);
3706 if(filtered_protocol)
3707 IInternetProtocol_Release(filtered_protocol);
3708 IInternetBindInfo_Release(prot_bind_info);
3709 IInternetProtocolSink_Release(binding_sink);
3710 ref = IInternetProtocol_Release(protocol);
3711 ok(!ref, "ref=%u, expected 0\n", ref);
3713 if(test_flags & TEST_EMULATEPROT) {
3714 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3715 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3718 IInternetSession_Release(session);
3721 START_TEST(protocol)
3723 HMODULE hurlmon;
3725 hurlmon = GetModuleHandle("urlmon.dll");
3726 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3727 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3728 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3730 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3731 win_skip("Various needed functions not present, too old IE\n");
3732 return;
3735 if(!pCreateUri)
3736 win_skip("CreateUri not supported\n");
3738 OleInitialize(NULL);
3740 event_complete = CreateEvent(NULL, FALSE, FALSE, NULL);
3741 event_complete2 = CreateEvent(NULL, FALSE, FALSE, NULL);
3742 event_continue = CreateEvent(NULL, FALSE, FALSE, NULL);
3743 event_continue_done = CreateEvent(NULL, FALSE, FALSE, NULL);
3744 thread_id = GetCurrentThreadId();
3746 test_file_protocol();
3747 test_http_protocol();
3748 if(pCreateUri)
3749 test_https_protocol();
3750 else
3751 win_skip("Skipping https tests on too old platform\n");
3752 test_ftp_protocol();
3753 test_gopher_protocol();
3754 test_mk_protocol();
3755 test_CreateBinding();
3757 bindf &= ~BINDF_FROMURLMON;
3758 trace("Testing file binding (mime verification, emulate prot)...\n");
3759 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3760 trace("Testing http binding (mime verification, emulate prot)...\n");
3761 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3762 trace("Testing its binding (mime verification, emulate prot)...\n");
3763 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3764 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3765 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3766 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3767 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3768 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3769 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3770 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3771 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3772 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3773 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3774 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3775 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3776 if(pCreateUri) {
3777 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3778 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3779 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3780 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3781 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3782 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3785 CloseHandle(event_complete);
3786 CloseHandle(event_complete2);
3787 CloseHandle(event_continue);
3788 CloseHandle(event_continue_done);
3790 OleUninitialize();