85d93687d3ebad7d67e9d3804386459aed1bc30d
[reactos.git] / rostests / winetests / urlmon / protocol.c
1 /*
2 * Copyright 2005-2011 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #define WIN32_NO_STATUS
20 #define _INC_WINDOWS
21 #define COM_NO_WINDOWS_H
22
23 #define COBJMACROS
24 #define CONST_VTABLE
25
26 #include <wine/test.h>
27 //#include <stdarg.h>
28 #include <stdio.h>
29
30 //#include "windef.h"
31 //#include "winbase.h"
32 #include <winnls.h>
33 #include <ole2.h>
34 //#include "urlmon.h"
35 #include <wininet.h>
36
37 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
38 static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
39 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
40
41 #define DEFINE_EXPECT(func) \
42 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
43
44 #define SET_EXPECT(func) \
45 expect_ ## func = TRUE
46
47 #define CHECK_EXPECT2(func) \
48 do { \
49 ok(expect_ ##func, "unexpected call " #func "\n"); \
50 called_ ## func = TRUE; \
51 }while(0)
52
53 #define CHECK_EXPECT(func) \
54 do { \
55 CHECK_EXPECT2(func); \
56 expect_ ## func = FALSE; \
57 }while(0)
58
59 #define CHECK_CALLED(func) \
60 do { \
61 ok(called_ ## func, "expected " #func "\n"); \
62 expect_ ## func = called_ ## func = FALSE; \
63 }while(0)
64
65 #define CHECK_NOT_CALLED(func) \
66 do { \
67 ok(!called_ ## func, "unexpected " #func "\n"); \
68 expect_ ## func = called_ ## func = FALSE; \
69 }while(0)
70
71 #define CLEAR_CALLED(func) \
72 expect_ ## func = called_ ## func = FALSE
73
74 DEFINE_EXPECT(GetBindInfo);
75 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
76 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
77 DEFINE_EXPECT(ReportProgress_RAWMIMETYPE);
78 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE);
79 DEFINE_EXPECT(ReportProgress_CONNECTING);
80 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
81 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
82 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
83 DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID);
84 DEFINE_EXPECT(ReportProgress_COOKIE_SENT);
85 DEFINE_EXPECT(ReportProgress_REDIRECTING);
86 DEFINE_EXPECT(ReportProgress_ENCODING);
87 DEFINE_EXPECT(ReportProgress_ACCEPTRANGES);
88 DEFINE_EXPECT(ReportProgress_PROXYDETECTING);
89 DEFINE_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
90 DEFINE_EXPECT(ReportProgress_DECODING);
91 DEFINE_EXPECT(ReportData);
92 DEFINE_EXPECT(ReportData2);
93 DEFINE_EXPECT(ReportResult);
94 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES);
95 DEFINE_EXPECT(GetBindString_USER_AGENT);
96 DEFINE_EXPECT(GetBindString_POST_COOKIE);
97 DEFINE_EXPECT(GetBindString_URL);
98 DEFINE_EXPECT(GetBindString_ROOTDOC_URL);
99 DEFINE_EXPECT(QueryService_HttpNegotiate);
100 DEFINE_EXPECT(QueryService_InternetProtocol);
101 DEFINE_EXPECT(QueryService_HttpSecurity);
102 DEFINE_EXPECT(QueryInterface_IWinInetInfo);
103 DEFINE_EXPECT(QueryInterface_IWinInetHttpInfo);
104 DEFINE_EXPECT(BeginningTransaction);
105 DEFINE_EXPECT(GetRootSecurityId);
106 DEFINE_EXPECT(OnResponse);
107 DEFINE_EXPECT(Switch);
108 DEFINE_EXPECT(Continue);
109 DEFINE_EXPECT(CreateInstance);
110 DEFINE_EXPECT(Start);
111 DEFINE_EXPECT(StartEx);
112 DEFINE_EXPECT(Terminate);
113 DEFINE_EXPECT(Read);
114 DEFINE_EXPECT(Read2);
115 DEFINE_EXPECT(SetPriority);
116 DEFINE_EXPECT(LockRequest);
117 DEFINE_EXPECT(UnlockRequest);
118 DEFINE_EXPECT(Abort);
119 DEFINE_EXPECT(MimeFilter_CreateInstance);
120 DEFINE_EXPECT(MimeFilter_Start);
121 DEFINE_EXPECT(MimeFilter_ReportData);
122 DEFINE_EXPECT(MimeFilter_ReportResult);
123 DEFINE_EXPECT(MimeFilter_Terminate);
124 DEFINE_EXPECT(MimeFilter_LockRequest);
125 DEFINE_EXPECT(MimeFilter_UnlockRequest);
126 DEFINE_EXPECT(MimeFilter_Read);
127 DEFINE_EXPECT(MimeFilter_Switch);
128 DEFINE_EXPECT(MimeFilter_Continue);
129 DEFINE_EXPECT(Stream_Seek);
130 DEFINE_EXPECT(Stream_Read);
131
132 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
133 static const WCHAR index_url[] =
134 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
135
136 static const WCHAR acc_mimeW[] = {'*','/','*',0};
137 static const WCHAR user_agentW[] = {'W','i','n','e',0};
138 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
139 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
140 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
141 static const WCHAR emptyW[] = {0};
142 static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
143 static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
144
145 static HRESULT expect_hrResult;
146 static LPCWSTR file_name, http_url, expect_wsz;
147 static IInternetProtocol *async_protocol = NULL;
148 static BOOL first_data_notif, http_is_first, test_redirect;
149 static int prot_state, read_report_data, post_stream_read;
150 static DWORD bindf, ex_priority , pi;
151 static IInternetProtocol *binding_protocol, *filtered_protocol;
152 static IInternetBindInfo *prot_bind_info;
153 static IInternetProtocolSink *binding_sink, *filtered_sink;
154 static void *expect_pv;
155 static HANDLE event_complete, event_complete2, event_continue, event_continue_done;
156 static BOOL binding_test;
157 static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
158 static DWORD prot_read, filter_state, http_post_test, thread_id;
159 static BOOL security_problem, test_async_req, impl_protex;
160 static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort;
161 static BOOL empty_file, no_mime, bind_from_cache, file_with_hash;
162
163 enum {
164 STATE_CONNECTING,
165 STATE_SENDINGREQUEST,
166 STATE_STARTDOWNLOADING,
167 STATE_DOWNLOADING
168 } state;
169
170 static enum {
171 FILE_TEST,
172 HTTP_TEST,
173 HTTPS_TEST,
174 FTP_TEST,
175 MK_TEST,
176 ITS_TEST,
177 BIND_TEST
178 } tested_protocol;
179
180 static const WCHAR protocol_names[][10] = {
181 {'f','i','l','e',0},
182 {'h','t','t','p',0},
183 {'h','t','t','p','s',0},
184 {'f','t','p',0},
185 {'m','k',0},
186 {'i','t','s',0},
187 {'t','e','s','t',0}
188 };
189
190 static const WCHAR binding_urls[][130] = {
191 {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
192 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
193 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0},
194 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
195 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
196 {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
197 '/','p','u','b','/','o','t','h','e','r',
198 '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
199 {'m','k',':','t','e','s','t',0},
200 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0},
201 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
202 };
203
204 static const CHAR post_data[] = "mode=Test";
205
206 static int strcmp_wa(LPCWSTR strw, const char *stra)
207 {
208 CHAR buf[512];
209 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
210 return lstrcmpA(stra, buf);
211 }
212
213 static const char *w2a(LPCWSTR str)
214 {
215 static char buf[INTERNET_MAX_URL_LENGTH];
216 WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
217 return buf;
218 }
219
220 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
221 {
222 if(IsEqualGUID(&IID_IUnknown, riid)
223 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
224 *ppv = iface;
225 return S_OK;
226 }
227
228 ok(0, "unexpected call\n");
229 return E_NOINTERFACE;
230 }
231
232 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
233 {
234 return 2;
235 }
236
237 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
238 {
239 return 1;
240 }
241
242 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
243 {
244 trace("HttpSecurity_GetWindow\n");
245
246 return S_FALSE;
247 }
248
249 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
250 {
251 trace("Security problem: %u\n", dwProblem);
252 ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem);
253
254 /* Only retry once */
255 if (security_problem)
256 return E_ABORT;
257
258 security_problem = TRUE;
259 SET_EXPECT(BeginningTransaction);
260
261 return RPC_E_RETRY;
262 }
263
264 static IHttpSecurityVtbl HttpSecurityVtbl = {
265 HttpSecurity_QueryInterface,
266 HttpSecurity_AddRef,
267 HttpSecurity_Release,
268 HttpSecurity_GetWindow,
269 HttpSecurity_OnSecurityProblem
270 };
271
272 static IHttpSecurity http_security = { &HttpSecurityVtbl };
273
274 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
275 {
276 if(IsEqualGUID(&IID_IUnknown, riid)
277 || IsEqualGUID(&IID_IHttpNegotiate, riid)
278 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
279 *ppv = iface;
280 return S_OK;
281 }
282
283 ok(0, "unexpected call\n");
284 return E_NOINTERFACE;
285 }
286
287 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
288 {
289 return 2;
290 }
291
292 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
293 {
294 return 1;
295 }
296
297 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
298 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
299 {
300 LPWSTR addl_headers;
301
302 static const WCHAR wszHeaders[] =
303 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
304 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
305 'd','e','d','\r','\n',0};
306
307 CHECK_EXPECT(BeginningTransaction);
308
309 if(binding_test)
310 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
311 else
312 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
313 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
314 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
315 if(pszAdditionalHeaders)
316 {
317 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
318 if (http_post_test)
319 {
320 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
321 memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
322 *pszAdditionalHeaders = addl_headers;
323 }
324 }
325
326 return S_OK;
327 }
328
329 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
330 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
331 {
332 CHECK_EXPECT(OnResponse);
333
334 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
335 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
336 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
337 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
338
339 return S_OK;
340 }
341
342 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
343 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
344 {
345 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
346
347 CHECK_EXPECT(GetRootSecurityId);
348
349 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
350 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
351 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
352
353 if(pcbSecurityId) {
354 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
355 *pcbSecurityId = sizeof(sec_id);
356 }
357
358 if(pbSecurityId)
359 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
360
361 return E_FAIL;
362 }
363
364 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
365 HttpNegotiate_QueryInterface,
366 HttpNegotiate_AddRef,
367 HttpNegotiate_Release,
368 HttpNegotiate_BeginningTransaction,
369 HttpNegotiate_OnResponse,
370 HttpNegotiate_GetRootSecurityId
371 };
372
373 static IHttpNegotiate2 http_negotiate = { &HttpNegotiateVtbl };
374
375 static HRESULT QueryInterface(REFIID,void**);
376
377 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
378 {
379 return QueryInterface(riid, ppv);
380 }
381
382 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
383 {
384 return 2;
385 }
386
387 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
388 {
389 return 1;
390 }
391
392 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
393 REFIID riid, void **ppv)
394 {
395 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
396 CHECK_EXPECT2(QueryService_HttpNegotiate);
397 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
398 }
399
400 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
401 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
402 CHECK_EXPECT(QueryService_InternetProtocol);
403 return E_NOINTERFACE;
404 }
405
406 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
407 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
408 CHECK_EXPECT(QueryService_HttpSecurity);
409 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
410 }
411
412 if(IsEqualGUID(&IID_IGetBindHandle, guidService)) {
413 trace("QueryService(IID_IGetBindHandle)\n");
414 *ppv = NULL;
415 return E_NOINTERFACE;
416 }
417
418 if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
419 trace("QueryService(IID_IWindowForBindingUI)\n");
420 *ppv = NULL;
421 return E_NOINTERFACE;
422 }
423
424 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
425 return E_FAIL;
426 }
427
428 static const IServiceProviderVtbl ServiceProviderVtbl = {
429 ServiceProvider_QueryInterface,
430 ServiceProvider_AddRef,
431 ServiceProvider_Release,
432 ServiceProvider_QueryService
433 };
434
435 static IServiceProvider service_provider = { &ServiceProviderVtbl };
436
437 static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
438 {
439 static const IID IID_strm_unknown = {0x2f68429a,0x199a,0x4043,{0x93,0x11,0xf2,0xfe,0x7c,0x13,0xcc,0xb9}};
440
441 if(!IsEqualGUID(&IID_strm_unknown, riid)) /* IE11 */
442 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
443
444 *ppv = NULL;
445 return E_NOINTERFACE;
446 }
447
448 static ULONG WINAPI Stream_AddRef(IStream *iface)
449 {
450 return 2;
451 }
452
453 static ULONG WINAPI Stream_Release(IStream *iface)
454 {
455 return 1;
456 }
457
458 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
459 ULONG cb, ULONG *pcbRead)
460 {
461 CHECK_EXPECT2(Stream_Read);
462
463 ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
464
465 ok(pv != NULL, "pv == NULL\n");
466 ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
467 ok(pcbRead != NULL, "pcbRead == NULL\n");
468
469 if(post_stream_read) {
470 *pcbRead = 0;
471 return S_FALSE;
472 }
473
474 memcpy(pv, post_data, sizeof(post_data)-1);
475 post_stream_read += *pcbRead = sizeof(post_data)-1;
476 return S_OK;
477 }
478
479 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
480 ULONG cb, ULONG *pcbWritten)
481 {
482 ok(0, "unexpected call\n");
483 return E_NOTIMPL;
484 }
485
486 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
487 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
488 {
489 CHECK_EXPECT(Stream_Seek);
490
491 ok(!dlibMove.QuadPart, "dlibMove != 0\n");
492 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
493 ok(!plibNewPosition, "plibNewPosition == NULL\n");
494
495 return S_OK;
496 }
497
498 static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
499 {
500 ok(0, "unexpected call\n");
501 return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm,
505 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
506 {
507 ok(0, "unexpected call\n");
508 return E_NOTIMPL;
509 }
510
511 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
512 {
513 ok(0, "unexpected call\n");
514 return E_NOTIMPL;
515 }
516
517 static HRESULT WINAPI Stream_Revert(IStream *iface)
518 {
519 ok(0, "unexpected call\n");
520 return E_NOTIMPL;
521 }
522
523 static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
524 ULARGE_INTEGER cb, DWORD dwLockType)
525 {
526 ok(0, "unexpected call\n");
527 return E_NOTIMPL;
528 }
529
530 static HRESULT WINAPI Stream_UnlockRegion(IStream *iface,
531 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
532 {
533 ok(0, "unexpected call\n");
534 return E_NOTIMPL;
535 }
536
537 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
538 DWORD dwStatFlag)
539 {
540 ok(0, "unexpected call\n");
541 return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
545 {
546 ok(0, "unexpected call\n");
547 return E_NOTIMPL;
548 }
549
550 static const IStreamVtbl StreamVtbl = {
551 Stream_QueryInterface,
552 Stream_AddRef,
553 Stream_Release,
554 Stream_Read,
555 Stream_Write,
556 Stream_Seek,
557 Stream_SetSize,
558 Stream_CopyTo,
559 Stream_Commit,
560 Stream_Revert,
561 Stream_LockRegion,
562 Stream_UnlockRegion,
563 Stream_Stat,
564 Stream_Clone
565 };
566
567 static IStream Stream = { &StreamVtbl };
568
569 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
570 {
571 return QueryInterface(riid, ppv);
572 }
573
574 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
575 {
576 return 2;
577 }
578
579 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
580 {
581 return 1;
582 }
583
584 static void call_continue(PROTOCOLDATA *protocol_data)
585 {
586 HRESULT hres;
587
588 if (winetest_debug > 1)
589 trace("continue in state %d\n", state);
590
591 if(state == STATE_CONNECTING) {
592 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
593 if (http_is_first){
594 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
595 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
596 }
597 CLEAR_CALLED(ReportProgress_CONNECTING);
598 }
599 if(tested_protocol == FTP_TEST)
600 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
601 else if (tested_protocol != HTTPS_TEST)
602 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
603 if(test_redirect)
604 CHECK_CALLED(ReportProgress_REDIRECTING);
605 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
606 }
607
608 switch(state) {
609 case STATE_SENDINGREQUEST:
610 SET_EXPECT(Stream_Read);
611 SET_EXPECT(ReportProgress_SENDINGREQUEST);
612 break;
613 case STATE_STARTDOWNLOADING:
614 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
615 SET_EXPECT(OnResponse);
616 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
617 SET_EXPECT(ReportProgress_ACCEPTRANGES);
618 SET_EXPECT(ReportProgress_ENCODING);
619 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
620 if(bindf & BINDF_NEEDFILE)
621 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
622 }
623 default:
624 break;
625 }
626
627 if(state != STATE_SENDINGREQUEST)
628 SET_EXPECT(ReportData);
629 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
630 ok(hres == S_OK, "Continue failed: %08x\n", hres);
631 if(tested_protocol == FTP_TEST || security_problem)
632 CLEAR_CALLED(ReportData);
633 else if(state != STATE_SENDINGREQUEST)
634 CHECK_CALLED(ReportData);
635
636 switch(state) {
637 case STATE_SENDINGREQUEST:
638 CHECK_CALLED(Stream_Read);
639 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
640 state = STATE_STARTDOWNLOADING;
641 break;
642 case STATE_STARTDOWNLOADING:
643 if (! security_problem)
644 {
645 state = STATE_DOWNLOADING;
646 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
647 CHECK_CALLED(OnResponse);
648 if(tested_protocol == HTTPS_TEST || empty_file)
649 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
650 else if(test_redirect || test_abort)
651 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
652 CLEAR_CALLED(ReportProgress_ENCODING);
653 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
654 if(bindf & BINDF_NEEDFILE)
655 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
656 }
657 }
658 else
659 {
660 security_problem = FALSE;
661 SET_EXPECT(ReportProgress_CONNECTING);
662 }
663 default:
664 break;
665 }
666 }
667
668 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
669 {
670 if(tested_protocol == FTP_TEST)
671 CHECK_EXPECT2(Switch);
672 else
673 CHECK_EXPECT(Switch);
674
675 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
676 if(binding_test) {
677 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
678 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
679 pProtocolData->grfFlags, protocoldata.grfFlags );
680 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
681 pProtocolData->dwState, protocoldata.dwState );
682 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
683 pProtocolData->pData, protocoldata.pData );
684 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
685 pProtocolData->cbData, protocoldata.cbData );
686 }
687
688 pdata = pProtocolData;
689
690 if(binding_test) {
691 SetEvent(event_complete);
692 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
693 return S_OK;
694 }if(direct_read) {
695 continue_protdata = *pProtocolData;
696 SetEvent(event_continue);
697 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
698 }else {
699 call_continue(pProtocolData);
700 SetEvent(event_complete);
701 }
702
703 return S_OK;
704 }
705
706 static const char *status_names[] =
707 {
708 "0",
709 "FINDINGRESOURCE",
710 "CONNECTING",
711 "REDIRECTING",
712 "BEGINDOWNLOADDATA",
713 "DOWNLOADINGDATA",
714 "ENDDOWNLOADDATA",
715 "BEGINDOWNLOADCOMPONENTS",
716 "INSTALLINGCOMPONENTS",
717 "ENDDOWNLOADCOMPONENTS",
718 "USINGCACHEDCOPY",
719 "SENDINGREQUEST",
720 "CLASSIDAVAILABLE",
721 "MIMETYPEAVAILABLE",
722 "CACHEFILENAMEAVAILABLE",
723 "BEGINSYNCOPERATION",
724 "ENDSYNCOPERATION",
725 "BEGINUPLOADDATA",
726 "UPLOADINGDATA",
727 "ENDUPLOADINGDATA",
728 "PROTOCOLCLASSID",
729 "ENCODING",
730 "VERIFIEDMIMETYPEAVAILABLE",
731 "CLASSINSTALLLOCATION",
732 "DECODING",
733 "LOADINGMIMEHANDLER",
734 "CONTENTDISPOSITIONATTACH",
735 "FILTERREPORTMIMETYPE",
736 "CLSIDCANINSTANTIATE",
737 "IUNKNOWNAVAILABLE",
738 "DIRECTBIND",
739 "RAWMIMETYPE",
740 "PROXYDETECTING",
741 "ACCEPTRANGES",
742 "COOKIE_SENT",
743 "COMPACT_POLICY_RECEIVED",
744 "COOKIE_SUPPRESSED",
745 "COOKIE_STATE_UNKNOWN",
746 "COOKIE_STATE_ACCEPT",
747 "COOKIE_STATE_REJECT",
748 "COOKIE_STATE_PROMPT",
749 "COOKIE_STATE_LEASH",
750 "COOKIE_STATE_DOWNGRADE",
751 "POLICY_HREF",
752 "P3P_HEADER",
753 "SESSION_COOKIE_RECEIVED",
754 "PERSISTENT_COOKIE_RECEIVED",
755 "SESSION_COOKIES_ALLOWED",
756 "CACHECONTROL",
757 "CONTENTDISPOSITIONFILENAME",
758 "MIMETEXTPLAINMISMATCH",
759 "PUBLISHERAVAILABLE",
760 "DISPLAYNAMEAVAILABLE"
761 };
762
763 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
764 LPCWSTR szStatusText)
765 {
766 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
767 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
768 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
769
770 if (winetest_debug > 1)
771 {
772 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
773 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
774 else
775 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
776 }
777
778 switch(ulStatusCode) {
779 case BINDSTATUS_MIMETYPEAVAILABLE:
780 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
781 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
782 if(!short_read || !direct_read)
783 CHECK_CALLED(Read); /* set in Continue */
784 else if(short_read)
785 CHECK_CALLED(Read2); /* set in Read */
786 }
787 ok(szStatusText != NULL, "szStatusText == NULL\n");
788 if(szStatusText) {
789 if(tested_protocol == BIND_TEST)
790 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
791 else if (http_post_test)
792 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
793 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
794 "szStatusText != text/plain\n");
795 else if(empty_file)
796 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
797 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
798 && tested_protocol==HTTP_TEST && !short_read)
799 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
800 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
801 "szStatusText != image/gif\n");
802 else if(!mimefilter_test)
803 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
804 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
805 "szStatusText != text/html\n");
806 }
807 break;
808 case BINDSTATUS_DIRECTBIND:
809 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
810 ok(szStatusText == NULL, "szStatusText != NULL\n");
811 break;
812 case BINDSTATUS_RAWMIMETYPE:
813 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
814 ok(szStatusText != NULL, "szStatusText == NULL\n");
815 if(szStatusText)
816 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
817 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
818 "szStatusText != text/html\n");
819 break;
820 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
821 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
822 ok(szStatusText != NULL, "szStatusText == NULL\n");
823 if(szStatusText) {
824 if(binding_test)
825 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
826 else if(tested_protocol == FILE_TEST)
827 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
828 else
829 ok(szStatusText != NULL, "szStatusText == NULL\n");
830 }
831 break;
832 case BINDSTATUS_FINDINGRESOURCE:
833 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
834 ok(szStatusText != NULL, "szStatusText == NULL\n");
835 break;
836 case BINDSTATUS_CONNECTING:
837 CHECK_EXPECT2(ReportProgress_CONNECTING);
838 ok(szStatusText != NULL, "szStatusText == NULL\n");
839 break;
840 case BINDSTATUS_SENDINGREQUEST:
841 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
842 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
843 ok(szStatusText != NULL, "szStatusText == NULL\n");
844 if(szStatusText)
845 ok(!*szStatusText, "wrong szStatusText\n");
846 }
847 break;
848 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
849 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
850 ok(szStatusText != NULL, "szStatusText == NULL\n");
851 if(szStatusText)
852 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
853 break;
854 case BINDSTATUS_PROTOCOLCLASSID:
855 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
856 ok(szStatusText != NULL, "szStatusText == NULL\n");
857 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
858 break;
859 case BINDSTATUS_COOKIE_SENT:
860 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
861 ok(szStatusText == NULL, "szStatusText != NULL\n");
862 break;
863 case BINDSTATUS_REDIRECTING:
864 CHECK_EXPECT(ReportProgress_REDIRECTING);
865 if(test_redirect)
866 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
867 else
868 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
869 break;
870 case BINDSTATUS_ENCODING:
871 CHECK_EXPECT(ReportProgress_ENCODING);
872 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
873 break;
874 case BINDSTATUS_ACCEPTRANGES:
875 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
876 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
877 break;
878 case BINDSTATUS_PROXYDETECTING:
879 if(!called_ReportProgress_PROXYDETECTING)
880 SET_EXPECT(ReportProgress_CONNECTING);
881 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
882 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
883 break;
884 case BINDSTATUS_LOADINGMIMEHANDLER:
885 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
886 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
887 break;
888 case BINDSTATUS_DECODING:
889 CHECK_EXPECT(ReportProgress_DECODING);
890 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
891 break;
892 case BINDSTATUS_RESERVED_7:
893 trace("BINDSTATUS_RESERVED_7\n");
894 break;
895 default:
896 ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
897 };
898
899 return S_OK;
900 }
901
902 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
903 ULONG ulProgress, ULONG ulProgressMax)
904 {
905 HRESULT hres;
906
907 static int rec_depth;
908 rec_depth++;
909
910 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
911 CHECK_EXPECT2(ReportData);
912
913 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
914 ulProgress, ulProgressMax);
915 if(!file_with_hash)
916 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
917 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
918 if(tested_protocol == FILE_TEST)
919 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
920 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
921 "grcfBSCF = %08x\n", grfBSCF);
922 else
923 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
924 }else if(bind_from_cache) {
925 CHECK_EXPECT(ReportData);
926
927 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
928 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
929 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
930 }else if(direct_read) {
931 BYTE buf[14096];
932 ULONG read;
933
934 if(!read_report_data && rec_depth == 1) {
935 BOOL reported_all_data = called_ReportData2;
936
937 CHECK_EXPECT2(ReportData);
938
939 if(short_read) {
940 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
941 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
942 "grcfBSCF = %08x\n", grfBSCF);
943 CHECK_CALLED(Read); /* Set in Continue */
944 first_data_notif = FALSE;
945 }else if(first_data_notif) {
946 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
947 first_data_notif = FALSE;
948 }else if(reported_all_data) {
949 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
950 "grcfBSCF = %08x\n", grfBSCF);
951 }else if(!direct_read) {
952 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
953 }
954
955 do {
956 read = 0;
957 if(emulate_prot)
958 SET_EXPECT(Read);
959 else
960 SET_EXPECT(ReportData2);
961 SET_EXPECT(ReportResult);
962 if(!emulate_prot)
963 SET_EXPECT(Switch);
964 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
965 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
966 if(hres == S_OK)
967 ok(read, "read == 0\n");
968 if(reported_all_data)
969 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
970 if(!emulate_prot && hres != E_PENDING)
971 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
972 if(emulate_prot)
973 CHECK_CALLED(Read);
974 if(!reported_all_data && called_ReportData2) {
975 if(!emulate_prot)
976 CHECK_CALLED(ReportData2);
977 CHECK_CALLED(ReportResult);
978 reported_all_data = TRUE;
979 }else {
980 if(!emulate_prot)
981 CHECK_NOT_CALLED(ReportData2);
982 CHECK_NOT_CALLED(ReportResult);
983 }
984 }while(hres == S_OK);
985 if(hres == S_FALSE)
986 wait_for_switch = FALSE;
987 }else {
988 CHECK_EXPECT(ReportData2);
989
990 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
991
992 read = 0xdeadbeef;
993 if(emulate_prot)
994 SET_EXPECT(Read2);
995 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
996 if(emulate_prot)
997 CHECK_CALLED(Read2);
998 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
999 ok(!read, "read = %d\n", read);
1000 }
1001 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
1002 || tested_protocol == FTP_TEST)) {
1003 if(empty_file)
1004 CHECK_EXPECT2(ReportData);
1005 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
1006 CHECK_EXPECT(ReportData);
1007 else if (http_post_test)
1008 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
1009
1010 if(empty_file) {
1011 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
1012 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
1013 }else {
1014 ok(ulProgress, "ulProgress == 0\n");
1015 }
1016
1017 if(empty_file) {
1018 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1019 "grcfBSCF = %08x\n", grfBSCF);
1020 first_data_notif = FALSE;
1021 }else if(first_data_notif) {
1022 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1023 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1024 "grcfBSCF = %08x\n", grfBSCF);
1025 first_data_notif = FALSE;
1026 } else {
1027 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1028 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1029 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1030 "grcfBSCF = %08x\n", grfBSCF);
1031 }
1032
1033 if(!(bindf & BINDF_FROMURLMON) &&
1034 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1035 if(state == STATE_CONNECTING) {
1036 state = STATE_DOWNLOADING;
1037 if(http_is_first) {
1038 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1039 CHECK_CALLED(ReportProgress_CONNECTING);
1040 }
1041 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1042 CHECK_CALLED(OnResponse);
1043 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1044 }
1045 SetEvent(event_complete);
1046 }
1047 }else if(!read_report_data) {
1048 BYTE buf[1000];
1049 ULONG read;
1050 HRESULT hres;
1051
1052 CHECK_EXPECT(ReportData);
1053
1054 if(tested_protocol != BIND_TEST) {
1055 do {
1056 if(mimefilter_test)
1057 SET_EXPECT(MimeFilter_Read);
1058 else if(rec_depth > 1)
1059 SET_EXPECT(Read2);
1060 else
1061 SET_EXPECT(Read);
1062 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1063 if(mimefilter_test)
1064 CHECK_CALLED(MimeFilter_Read);
1065 else if(rec_depth > 1)
1066 CHECK_CALLED(Read2);
1067 else
1068 CHECK_CALLED(Read);
1069 }while(hres == S_OK);
1070 }
1071 }
1072
1073 rec_depth--;
1074 return S_OK;
1075 }
1076
1077 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1078 DWORD dwError, LPCWSTR szResult)
1079 {
1080 CHECK_EXPECT(ReportResult);
1081
1082 if(tested_protocol == FTP_TEST)
1083 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1084 else
1085 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1086 hrResult, expect_hrResult);
1087 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1088 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1089 else
1090 ok(dwError != ERROR_SUCCESS ||
1091 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1092 "dwError == ERROR_SUCCESS\n");
1093 ok(!szResult, "szResult != NULL\n");
1094
1095 if(direct_read)
1096 SET_EXPECT(ReportData); /* checked after main loop */
1097
1098 return S_OK;
1099 }
1100
1101 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1102 ProtocolSink_QueryInterface,
1103 ProtocolSink_AddRef,
1104 ProtocolSink_Release,
1105 ProtocolSink_Switch,
1106 ProtocolSink_ReportProgress,
1107 ProtocolSink_ReportData,
1108 ProtocolSink_ReportResult
1109 };
1110
1111 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1112
1113 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1114 {
1115 ok(0, "unexpected call\n");
1116 return E_NOTIMPL;
1117 }
1118
1119 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1120 {
1121 return 2;
1122 }
1123
1124 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1125 {
1126 return 1;
1127 }
1128
1129 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1130 {
1131 HRESULT hres;
1132
1133 CHECK_EXPECT(MimeFilter_Switch);
1134
1135 SET_EXPECT(Switch);
1136 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1137 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1138 CHECK_CALLED(Switch);
1139
1140 return S_OK;
1141 }
1142
1143 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1144 LPCWSTR szStatusText)
1145 {
1146 switch(ulStatusCode) {
1147 case BINDSTATUS_LOADINGMIMEHANDLER:
1148 /*
1149 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1150 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1151 * ProtocolSink_ReportProgress to workaround it.
1152 */
1153 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1154 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1155 break;
1156 default:
1157 ok(0, "Unexpected status code %d\n", ulStatusCode);
1158 }
1159
1160 return S_OK;
1161 }
1162
1163 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1164 ULONG ulProgress, ULONG ulProgressMax)
1165 {
1166 DWORD read = 0;
1167 BYTE buf[8192];
1168 HRESULT hres;
1169 BOOL report_mime = FALSE;
1170
1171 CHECK_EXPECT(MimeFilter_ReportData);
1172
1173 if(!filter_state && !no_mime) {
1174 SET_EXPECT(Read);
1175 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1176 if(tested_protocol == HTTP_TEST)
1177 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1178 else
1179 ok(hres == S_OK, "Read failed: %08x\n", hres);
1180 CHECK_CALLED(Read);
1181
1182 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1183 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1184 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1185 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1186
1187 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1188 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1189 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1190 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1191
1192 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1193 }
1194
1195 if(no_mime && prot_read<200) {
1196 SET_EXPECT(Read);
1197 }else if(no_mime && prot_read<300) {
1198 report_mime = TRUE;
1199 SET_EXPECT(Read);
1200 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1201 SET_EXPECT(ReportData);
1202 }else if(!read_report_data) {
1203 SET_EXPECT(ReportData);
1204 }
1205 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1206 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1207 if(no_mime && prot_read<=200) {
1208 CHECK_CALLED(Read);
1209 }else if(report_mime) {
1210 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1211 CHECK_CALLED(ReportData);
1212 }else if(!read_report_data) {
1213 CHECK_CALLED(ReportData);
1214 }
1215
1216 if(!filter_state)
1217 filter_state = 1;
1218
1219 return S_OK;
1220 }
1221
1222 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1223 DWORD dwError, LPCWSTR szResult)
1224 {
1225 HRESULT hres;
1226
1227 CHECK_EXPECT(MimeFilter_ReportResult);
1228
1229 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1230 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1231 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1232
1233 SET_EXPECT(ReportResult);
1234 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1235 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1236 CHECK_CALLED(ReportResult);
1237
1238 return S_OK;
1239 }
1240
1241 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1242 MimeProtocolSink_QueryInterface,
1243 MimeProtocolSink_AddRef,
1244 MimeProtocolSink_Release,
1245 MimeProtocolSink_Switch,
1246 MimeProtocolSink_ReportProgress,
1247 MimeProtocolSink_ReportData,
1248 MimeProtocolSink_ReportResult
1249 };
1250
1251 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1252
1253 static HRESULT QueryInterface(REFIID riid, void **ppv)
1254 {
1255 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1256 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1257
1258 *ppv = NULL;
1259
1260 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1261 *ppv = &protocol_sink;
1262 if(IsEqualGUID(&IID_IServiceProvider, riid))
1263 *ppv = &service_provider;
1264 if(IsEqualGUID(&IID_IUriContainer, riid))
1265 return E_NOINTERFACE; /* TODO */
1266
1267 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1268 if(IsEqualGUID(&IID_undocumented, riid))
1269 return E_NOINTERFACE;
1270 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1271 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1272 return E_NOINTERFACE;
1273
1274 if(*ppv)
1275 return S_OK;
1276
1277 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1278 return E_NOINTERFACE;
1279 }
1280
1281 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1282 {
1283 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1284 *ppv = iface;
1285 return S_OK;
1286 }
1287 return E_NOINTERFACE;
1288 }
1289
1290 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1291 {
1292 return 2;
1293 }
1294
1295 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1296 {
1297 return 1;
1298 }
1299
1300 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1301 {
1302 DWORD cbSize;
1303
1304 CHECK_EXPECT(GetBindInfo);
1305
1306 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1307 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1308 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1309
1310 *grfBINDF = bindf;
1311 if(binding_test)
1312 *grfBINDF |= BINDF_FROMURLMON;
1313 cbSize = pbindinfo->cbSize;
1314 memset(pbindinfo, 0, cbSize);
1315 pbindinfo->cbSize = cbSize;
1316
1317 if(http_post_test)
1318 {
1319 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1320 pbindinfo->dwBindVerb = BINDVERB_POST;
1321 pbindinfo->stgmedData.tymed = http_post_test;
1322
1323 if(http_post_test == TYMED_HGLOBAL) {
1324 HGLOBAL data;
1325
1326 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1327 data = GlobalAlloc(GPTR, sizeof(post_data));
1328 memcpy(data, post_data, sizeof(post_data));
1329 U(pbindinfo->stgmedData).hGlobal = data;
1330 }else {
1331 IStream *post_stream;
1332 HGLOBAL data;
1333 HRESULT hres;
1334
1335 if(0) {
1336 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1337 data = GlobalAlloc(GPTR, sizeof(post_data));
1338 memcpy(data, post_data, sizeof(post_data));
1339 U(pbindinfo->stgmedData).hGlobal = data;
1340
1341 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1342 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1343
1344 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1345 }
1346 U(pbindinfo->stgmedData).pstm = &Stream;
1347 }
1348 }
1349
1350 return S_OK;
1351 }
1352
1353 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1354 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1355 {
1356 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1357 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1358
1359 switch(ulStringType) {
1360 case BINDSTRING_ACCEPT_MIMES:
1361 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1362 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1363 if(pcElFetched) {
1364 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1365 *pcElFetched = 1;
1366 }
1367 if(ppwzStr) {
1368 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1369 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1370 }
1371 return S_OK;
1372 case BINDSTRING_USER_AGENT:
1373 CHECK_EXPECT(GetBindString_USER_AGENT);
1374 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1375 if(pcElFetched) {
1376 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1377 *pcElFetched = 1;
1378 }
1379 if(ppwzStr) {
1380 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1381 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1382 }
1383 return S_OK;
1384 case BINDSTRING_POST_COOKIE:
1385 CHECK_EXPECT(GetBindString_POST_COOKIE);
1386 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1387 if(pcElFetched)
1388 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1389 return S_OK;
1390 case BINDSTRING_URL: {
1391 DWORD size;
1392
1393 CHECK_EXPECT(GetBindString_URL);
1394 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1395 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1396 *pcElFetched = 1;
1397
1398 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1399 *ppwzStr = CoTaskMemAlloc(size);
1400 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1401 return S_OK;
1402 }
1403 case BINDSTRING_ROOTDOC_URL:
1404 CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1405 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1406 return E_NOTIMPL;
1407 default:
1408 ok(0, "unexpected ulStringType %d\n", ulStringType);
1409 }
1410
1411 return E_NOTIMPL;
1412 }
1413
1414 static IInternetBindInfoVtbl bind_info_vtbl = {
1415 BindInfo_QueryInterface,
1416 BindInfo_AddRef,
1417 BindInfo_Release,
1418 BindInfo_GetBindInfo,
1419 BindInfo_GetBindString
1420 };
1421
1422 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1423
1424 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1425 REFIID riid, void **ppv)
1426 {
1427 ok(0, "unexpected call\n");
1428 return E_NOINTERFACE;
1429 }
1430
1431 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1432 {
1433 return 2;
1434 }
1435
1436 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1437 {
1438 return 1;
1439 }
1440
1441 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1442 {
1443 CHECK_EXPECT(SetPriority);
1444 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1445 return S_OK;
1446 }
1447
1448 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1449 {
1450 ok(0, "unexpected call\n");
1451 return E_NOTIMPL;
1452 }
1453
1454
1455 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1456 InternetPriority_QueryInterface,
1457 InternetPriority_AddRef,
1458 InternetPriority_Release,
1459 InternetPriority_SetPriority,
1460 InternetPriority_GetPriority
1461 };
1462
1463 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1464
1465 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1466 {
1467 return 2;
1468 }
1469
1470 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1471 {
1472 return 1;
1473 }
1474
1475 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1476 DWORD dwOptions)
1477 {
1478 HRESULT hres;
1479
1480 CHECK_EXPECT(Abort);
1481
1482 SET_EXPECT(ReportResult);
1483 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1484 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1485 CHECK_CALLED(ReportResult);
1486
1487 return S_OK;
1488 }
1489
1490 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1491 {
1492 ok(0, "unexpected call\n");
1493 return E_NOTIMPL;
1494 }
1495
1496 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1497 {
1498 ok(0, "unexpected call\n");
1499 return E_NOTIMPL;
1500 }
1501
1502 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1503 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1504 {
1505 ok(0, "unexpected call\n");
1506 return E_NOTIMPL;
1507 }
1508
1509 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1510 {
1511 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1512
1513 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1514 *ppv = iface;
1515 return S_OK;
1516 }
1517
1518 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1519 if(impl_protex) {
1520 *ppv = iface;
1521 return S_OK;
1522 }
1523 *ppv = NULL;
1524 return E_NOINTERFACE;
1525 }
1526
1527 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1528 *ppv = &InternetPriority;
1529 return S_OK;
1530 }
1531
1532 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1533 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1534 *ppv = NULL;
1535 return E_NOINTERFACE;
1536 }
1537
1538 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1539 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1540 *ppv = NULL;
1541 return E_NOINTERFACE;
1542 }
1543
1544 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1545 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1546 *ppv = NULL;
1547 return E_NOINTERFACE;
1548 }
1549
1550 static DWORD WINAPI thread_proc(PVOID arg)
1551 {
1552 HRESULT hres;
1553
1554 memset(&protocoldata, -1, sizeof(protocoldata));
1555
1556 prot_state = 0;
1557
1558 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1559 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1560 BINDSTATUS_FINDINGRESOURCE, hostW);
1561 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1562 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1563
1564 SET_EXPECT(ReportProgress_CONNECTING);
1565 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1566 BINDSTATUS_CONNECTING, winehq_ipW);
1567 CHECK_CALLED(ReportProgress_CONNECTING);
1568 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1569
1570 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1571 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1572 BINDSTATUS_SENDINGREQUEST, NULL);
1573 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1574 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1575
1576 prot_state = 1;
1577 SET_EXPECT(Switch);
1578 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1579 CHECK_CALLED(Switch);
1580 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1581
1582 if(!short_read) {
1583 prot_state = 2;
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);
1594
1595 if(test_abort) {
1596 SetEvent(event_complete);
1597 return 0;
1598 }
1599
1600 prot_state = 2;
1601 if(mimefilter_test)
1602 SET_EXPECT(MimeFilter_Switch);
1603 else
1604 SET_EXPECT(Switch);
1605 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1606 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1607 if(mimefilter_test)
1608 CHECK_CALLED(MimeFilter_Switch);
1609 else
1610 CHECK_CALLED(Switch);
1611
1612 prot_state = 3;
1613 if(mimefilter_test)
1614 SET_EXPECT(MimeFilter_Switch);
1615 else
1616 SET_EXPECT(Switch);
1617 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1618 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1619 if(mimefilter_test)
1620 CHECK_CALLED(MimeFilter_Switch);
1621 else
1622 CHECK_CALLED(Switch);
1623 }
1624
1625 SetEvent(event_complete);
1626
1627 return 0;
1628 }
1629
1630 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1631 {
1632 BINDINFO bindinfo, exp_bindinfo;
1633 DWORD cbindf = 0;
1634 HRESULT hres;
1635
1636 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1637 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1638 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1639 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1640 ok(!pi, "pi = %x\n", pi);
1641
1642 if(binding_test)
1643 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1644
1645 memset(&bindinfo, 0, sizeof(bindinfo));
1646 bindinfo.cbSize = sizeof(bindinfo);
1647 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1648 SET_EXPECT(GetBindInfo);
1649 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1650 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1651 CHECK_CALLED(GetBindInfo);
1652 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1653 cbindf, (bindf|BINDF_FROMURLMON));
1654 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1655 pReleaseBindInfo(&bindinfo);
1656
1657 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1658 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1659 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1660 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1661
1662 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1663 IServiceProvider *service_provider;
1664 IHttpNegotiate *http_negotiate;
1665 IHttpNegotiate2 *http_negotiate2;
1666 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1667 LPWSTR additional_headers = NULL;
1668 BYTE sec_id[100];
1669 DWORD fetched = 0, size = 100;
1670 DWORD tid;
1671
1672 SET_EXPECT(GetBindString_USER_AGENT);
1673 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1674 &ua, 1, &fetched);
1675 CHECK_CALLED(GetBindString_USER_AGENT);
1676 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1677 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1678 ok(ua != NULL, "ua = %p\n", ua);
1679 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1680 CoTaskMemFree(ua);
1681
1682 fetched = 256;
1683 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1684 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1685 accept_mimes, 256, &fetched);
1686 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1687
1688 ok(hres == S_OK,
1689 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1690 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1691 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1692 CoTaskMemFree(accept_mimes[0]);
1693
1694 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1695 (void**)&service_provider);
1696 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1697
1698 SET_EXPECT(QueryService_HttpNegotiate);
1699 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1700 &IID_IHttpNegotiate, (void**)&http_negotiate);
1701 CHECK_CALLED(QueryService_HttpNegotiate);
1702 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1703
1704 SET_EXPECT(BeginningTransaction);
1705 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1706 NULL, 0, &additional_headers);
1707 CHECK_CALLED(BeginningTransaction);
1708 IHttpNegotiate_Release(http_negotiate);
1709 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1710 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1711
1712 SET_EXPECT(QueryService_HttpNegotiate);
1713 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1714 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1715 CHECK_CALLED(QueryService_HttpNegotiate);
1716 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1717
1718 size = 512;
1719 SET_EXPECT(GetRootSecurityId);
1720 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1721 CHECK_CALLED(GetRootSecurityId);
1722 IHttpNegotiate2_Release(http_negotiate2);
1723 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1724 ok(size == 13, "size=%d\n", size);
1725
1726 IServiceProvider_Release(service_provider);
1727
1728 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1729 return;
1730 }
1731
1732 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1733 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1734 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1735 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1736 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1737
1738 if(mimefilter_test) {
1739 SET_EXPECT(MimeFilter_CreateInstance);
1740 SET_EXPECT(MimeFilter_Start);
1741 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1742 }
1743 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1744 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1745 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1746 ok(hres == S_OK,
1747 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1748 if(mimefilter_test) {
1749 CHECK_CALLED(MimeFilter_CreateInstance);
1750 CHECK_CALLED(MimeFilter_Start);
1751 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1752 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1753 }else {
1754 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1755 }
1756
1757 if(mimefilter_test)
1758 SET_EXPECT(MimeFilter_ReportData);
1759 else
1760 SET_EXPECT(ReportData);
1761 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1762 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1763 13, 13);
1764 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1765 if(mimefilter_test)
1766 CHECK_CALLED(MimeFilter_ReportData);
1767 else
1768 CHECK_CALLED(ReportData);
1769
1770 if(tested_protocol == ITS_TEST) {
1771 SET_EXPECT(ReportData);
1772 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1773 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1774 CHECK_CALLED(ReportData);
1775 }
1776
1777 if(tested_protocol == BIND_TEST) {
1778 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1779 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1780 }
1781
1782 if(mimefilter_test)
1783 SET_EXPECT(MimeFilter_ReportResult);
1784 else
1785 SET_EXPECT(ReportResult);
1786 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1787 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1788 if(mimefilter_test)
1789 CHECK_CALLED(MimeFilter_ReportResult);
1790 else
1791 CHECK_CALLED(ReportResult);
1792 }
1793
1794 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1795 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1796 DWORD grfPI, HANDLE_PTR dwReserved)
1797 {
1798 CHECK_EXPECT(Start);
1799
1800 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1801 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1802 return S_OK;
1803 }
1804
1805 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1806 PROTOCOLDATA *pProtocolData)
1807 {
1808 DWORD bscf = 0, pr;
1809 HRESULT hres;
1810
1811 CHECK_EXPECT(Continue);
1812
1813 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1814 if(!pProtocolData || tested_protocol == BIND_TEST)
1815 return S_OK;
1816 if(binding_test) {
1817 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1818 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1819 pProtocolData->grfFlags, protocoldata.grfFlags );
1820 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1821 pProtocolData->dwState, protocoldata.dwState );
1822 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1823 pProtocolData->pData, protocoldata.pData );
1824 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1825 pProtocolData->cbData, protocoldata.cbData );
1826 }
1827
1828 switch(prot_state) {
1829 case 1: {
1830 IServiceProvider *service_provider;
1831 IHttpNegotiate *http_negotiate;
1832 static const WCHAR header[] = {'?',0};
1833
1834 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1835 (void**)&service_provider);
1836 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1837
1838 SET_EXPECT(QueryService_HttpNegotiate);
1839 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1840 &IID_IHttpNegotiate, (void**)&http_negotiate);
1841 IServiceProvider_Release(service_provider);
1842 CHECK_CALLED(QueryService_HttpNegotiate);
1843 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1844
1845 SET_EXPECT(OnResponse);
1846 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1847 IHttpNegotiate_Release(http_negotiate);
1848 CHECK_CALLED(OnResponse);
1849 IHttpNegotiate_Release(http_negotiate);
1850 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1851
1852 if(mimefilter_test) {
1853 SET_EXPECT(MimeFilter_CreateInstance);
1854 SET_EXPECT(MimeFilter_Start);
1855 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1856 }else if(!(pi & PI_MIMEVERIFICATION)) {
1857 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1858 }
1859 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1860 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1861 if(mimefilter_test) {
1862 CHECK_CALLED(MimeFilter_CreateInstance);
1863 CHECK_CALLED(MimeFilter_Start);
1864 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1865 }else if(!(pi & PI_MIMEVERIFICATION)) {
1866 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1867 }
1868 ok(hres == S_OK,
1869 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1870
1871 bscf |= BSCF_FIRSTDATANOTIFICATION;
1872 break;
1873 }
1874 case 2:
1875 case 3:
1876 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1877 break;
1878 }
1879
1880 pr = prot_read;
1881 if(mimefilter_test)
1882 SET_EXPECT(MimeFilter_ReportData);
1883 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1884 if(pr < 200)
1885 SET_EXPECT(Read); /* checked in ReportData for short_read */
1886 if(pr == 200) {
1887 if(!mimefilter_test)
1888 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1889 SET_EXPECT(GetBindInfo);
1890 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1891 }
1892 if(pr >= 200)
1893 SET_EXPECT(ReportData);
1894 }else {
1895 SET_EXPECT(ReportData);
1896 }
1897
1898 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1899 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1900
1901 if(mimefilter_test) {
1902 SET_EXPECT(MimeFilter_ReportData);
1903 }else if(pi & PI_MIMEVERIFICATION) {
1904 if(!short_read && pr < 200)
1905 CHECK_CALLED(Read);
1906 if(pr == 200) {
1907 CLEAR_CALLED(GetBindInfo); /* IE9 */
1908 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1909 }
1910 }else {
1911 CHECK_CALLED(ReportData);
1912 }
1913
1914 if(prot_state == 3)
1915 prot_state = 4;
1916
1917 return S_OK;
1918 }
1919
1920 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1921 {
1922 CHECK_EXPECT(Terminate);
1923 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1924 return S_OK;
1925 }
1926
1927 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1928 ULONG cb, ULONG *pcbRead)
1929 {
1930 if(read_report_data)
1931 CHECK_EXPECT2(Read2);
1932
1933 if(mimefilter_test || short_read) {
1934 if(!read_report_data)
1935 CHECK_EXPECT2(Read);
1936 }else if((pi & PI_MIMEVERIFICATION)) {
1937 if(!read_report_data)
1938 CHECK_EXPECT2(Read);
1939
1940 if(prot_read < 300) {
1941 ok(pv != expect_pv, "pv == expect_pv\n");
1942 if(prot_read < 300)
1943 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1944 else
1945 ok(cb == 700, "cb=%d\n", cb);
1946 }else {
1947 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1948 }
1949 }else {
1950 if(!read_report_data)
1951 CHECK_EXPECT(Read);
1952
1953 ok(pv == expect_pv, "pv != expect_pv\n");
1954 ok(cb == 1000, "cb=%d\n", cb);
1955 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1956 }
1957 ok(pcbRead != NULL, "pcbRead == NULL\n");
1958
1959 if(prot_state == 3 || (short_read && prot_state != 4)) {
1960 HRESULT hres;
1961
1962 prot_state = 4;
1963 if(short_read) {
1964 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1965 SET_EXPECT(GetBindInfo);
1966 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1967 }
1968 if(mimefilter_test)
1969 SET_EXPECT(MimeFilter_ReportData);
1970 else if(direct_read)
1971 SET_EXPECT(ReportData2);
1972 read_report_data++;
1973 hres = IInternetProtocolSink_ReportData(binding_sink,
1974 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1975 read_report_data--;
1976 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1977 if(short_read) {
1978 CLEAR_CALLED(GetBindInfo); /* IE9 */
1979 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1980 }
1981 if(mimefilter_test)
1982 CHECK_CALLED(MimeFilter_ReportData);
1983 else if(direct_read)
1984 CHECK_CALLED(ReportData2);
1985
1986 if(mimefilter_test)
1987 SET_EXPECT(MimeFilter_ReportResult);
1988 else
1989 SET_EXPECT(ReportResult);
1990 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1991 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1992 if(mimefilter_test)
1993 CHECK_CALLED(MimeFilter_ReportResult);
1994 else
1995 CHECK_CALLED(ReportResult);
1996
1997 if(cb > 100)
1998 cb = 100;
1999 memset(pv, 'x', cb);
2000 if(cb>6)
2001 memcpy(pv, "gif87a", 6);
2002 prot_read += *pcbRead = cb;
2003 return S_OK;
2004 }
2005
2006 if(prot_state == 4) {
2007 *pcbRead = 0;
2008 return S_FALSE;
2009 }
2010
2011 if((async_read_pending = !async_read_pending)) {
2012 *pcbRead = 0;
2013 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
2014 }
2015
2016 if(cb > 100)
2017 cb = 100;
2018 memset(pv, 'x', cb);
2019 if(cb>6)
2020 memcpy(pv, "gif87a", 6);
2021 prot_read += *pcbRead = cb;
2022 return S_OK;
2023 }
2024
2025 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2026 {
2027 CHECK_EXPECT(LockRequest);
2028 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2029 return S_OK;
2030 }
2031
2032 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2033 {
2034 CHECK_EXPECT(UnlockRequest);
2035 return S_OK;
2036 }
2037
2038 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2039 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2040 DWORD grfPI, HANDLE *dwReserved)
2041 {
2042 CHECK_EXPECT(StartEx);
2043 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2044 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2045 return S_OK;
2046 }
2047
2048 static const IInternetProtocolExVtbl ProtocolVtbl = {
2049 ProtocolEmul_QueryInterface,
2050 Protocol_AddRef,
2051 Protocol_Release,
2052 ProtocolEmul_Start,
2053 ProtocolEmul_Continue,
2054 Protocol_Abort,
2055 ProtocolEmul_Terminate,
2056 Protocol_Suspend,
2057 Protocol_Resume,
2058 ProtocolEmul_Read,
2059 Protocol_Seek,
2060 ProtocolEmul_LockRequest,
2061 ProtocolEmul_UnlockRequest,
2062 ProtocolEmul_StartEx
2063 };
2064
2065 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2066
2067 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2068 {
2069 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2070 *ppv = iface;
2071 return S_OK;
2072 }
2073
2074 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2075 *ppv = &mime_protocol_sink;
2076 return S_OK;
2077 }
2078
2079 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2080 *ppv = NULL;
2081 return E_NOINTERFACE;
2082 }
2083
2084 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2085 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2086 DWORD grfPI, HANDLE_PTR dwReserved)
2087 {
2088 PROTOCOLFILTERDATA *data;
2089 LPOLESTR url_str = NULL;
2090 DWORD fetched = 0;
2091 BINDINFO bindinfo;
2092 DWORD cbindf = 0;
2093 HRESULT hres;
2094
2095 CHECK_EXPECT(MimeFilter_Start);
2096
2097 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2098 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2099 ok(dwReserved, "dwReserved == 0\n");
2100 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2101 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2102
2103 if(binding_test) {
2104 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2105 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2106 }else {
2107 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2108 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2109 }
2110
2111 data = (void*)dwReserved;
2112 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2113 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2114 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2115 ok(!data->pUnk, "data->pUnk != NULL\n");
2116 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2117 if(binding_test) {
2118 IInternetProtocolSink *prot_sink;
2119
2120 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2121 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2122 IInternetProtocolSink_Release(prot_sink);
2123
2124 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2125
2126 filtered_protocol = data->pProtocol;
2127 IInternetProtocol_AddRef(filtered_protocol);
2128 }else {
2129 IInternetProtocol *prot;
2130
2131 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2132 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2133 IInternetProtocol_Release(prot);
2134
2135 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2136 }
2137
2138 filtered_sink = pOIProtSink;
2139
2140 SET_EXPECT(ReportProgress_DECODING);
2141 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2142 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2143 CHECK_CALLED(ReportProgress_DECODING);
2144
2145 SET_EXPECT(GetBindInfo);
2146 memset(&bindinfo, 0, sizeof(bindinfo));
2147 bindinfo.cbSize = sizeof(bindinfo);
2148 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2149 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2150 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2151 CHECK_CALLED(GetBindInfo);
2152
2153 SET_EXPECT(GetBindString_URL);
2154 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2155 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2156 ok(fetched == 1, "fetched = %d\n", fetched);
2157 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2158 CoTaskMemFree(url_str);
2159 CHECK_CALLED(GetBindString_URL);
2160
2161 return S_OK;
2162 }
2163
2164 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2165 PROTOCOLDATA *pProtocolData)
2166 {
2167 CHECK_EXPECT(MimeFilter_Continue);
2168 return E_NOTIMPL;
2169 }
2170
2171 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2172 {
2173 HRESULT hres;
2174
2175 CHECK_EXPECT(MimeFilter_Terminate);
2176
2177 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2178
2179 SET_EXPECT(Terminate);
2180 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2181 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2182 CHECK_CALLED(Terminate);
2183
2184 return S_OK;
2185 }
2186
2187 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2188 ULONG cb, ULONG *pcbRead)
2189 {
2190 BYTE buf[2096];
2191 DWORD read = 0;
2192 HRESULT hres;
2193
2194 CHECK_EXPECT(MimeFilter_Read);
2195
2196 ok(pv != NULL, "pv == NULL\n");
2197 ok(cb != 0, "cb == 0\n");
2198 ok(pcbRead != NULL, "pcbRead == NULL\n");
2199
2200 if(read_report_data)
2201 SET_EXPECT(Read2);
2202 else
2203 SET_EXPECT(Read);
2204 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2205 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2206 if(read_report_data)
2207 CHECK_CALLED(Read2);
2208 else
2209 CHECK_CALLED(Read);
2210
2211 if(pcbRead) {
2212 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2213 *pcbRead = read;
2214 }
2215
2216 memset(pv, 'x', read);
2217 return hres;
2218 }
2219
2220 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2221 {
2222 HRESULT hres;
2223
2224 CHECK_EXPECT(MimeFilter_LockRequest);
2225
2226 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2227
2228 SET_EXPECT(LockRequest);
2229 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2230 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2231 CHECK_CALLED(LockRequest);
2232
2233 return S_OK;
2234 }
2235
2236 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2237 {
2238 HRESULT hres;
2239
2240 CHECK_EXPECT(MimeFilter_UnlockRequest);
2241
2242 SET_EXPECT(UnlockRequest);
2243 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2244 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2245 CHECK_CALLED(UnlockRequest);
2246
2247 return S_OK;
2248 }
2249
2250 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2251 MimeProtocol_QueryInterface,
2252 Protocol_AddRef,
2253 Protocol_Release,
2254 MimeProtocol_Start,
2255 Protocol_Continue,
2256 Protocol_Abort,
2257 MimeProtocol_Terminate,
2258 Protocol_Suspend,
2259 Protocol_Resume,
2260 MimeProtocol_Read,
2261 Protocol_Seek,
2262 MimeProtocol_LockRequest,
2263 MimeProtocol_UnlockRequest
2264 };
2265
2266 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2267
2268 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2269 {
2270 ok(0, "unexpected call\n");
2271 return E_NOINTERFACE;
2272 }
2273
2274 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2275 {
2276 return 2;
2277 }
2278
2279 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2280 {
2281 return 1;
2282 }
2283
2284 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2285 REFIID riid, void **ppv)
2286 {
2287 CHECK_EXPECT(CreateInstance);
2288
2289 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2290 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2291 ok(ppv != NULL, "ppv == NULL\n");
2292
2293 *ppv = &Protocol;
2294 return S_OK;
2295 }
2296
2297 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2298 {
2299 ok(0, "unexpected call\n");
2300 return S_OK;
2301 }
2302
2303 static const IClassFactoryVtbl ClassFactoryVtbl = {
2304 ClassFactory_QueryInterface,
2305 ClassFactory_AddRef,
2306 ClassFactory_Release,
2307 ClassFactory_CreateInstance,
2308 ClassFactory_LockServer
2309 };
2310
2311 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2312
2313 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2314 {
2315 CHECK_EXPECT(MimeFilter_CreateInstance);
2316
2317 ok(!outer, "outer = %p\n", outer);
2318 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2319
2320 *ppv = &MimeProtocol;
2321 return S_OK;
2322 }
2323
2324 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2325 ClassFactory_QueryInterface,
2326 ClassFactory_AddRef,
2327 ClassFactory_Release,
2328 MimeFilter_CreateInstance,
2329 ClassFactory_LockServer
2330 };
2331
2332 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2333
2334 #define TEST_BINDING 0x0001
2335 #define TEST_FILTER 0x0002
2336 #define TEST_FIRST_HTTP 0x0004
2337 #define TEST_DIRECT_READ 0x0008
2338 #define TEST_POST 0x0010
2339 #define TEST_EMULATEPROT 0x0020
2340 #define TEST_SHORT_READ 0x0040
2341 #define TEST_REDIRECT 0x0080
2342 #define TEST_ABORT 0x0100
2343 #define TEST_ASYNCREQ 0x0200
2344 #define TEST_USEIURI 0x0400
2345 #define TEST_IMPLPROTEX 0x0800
2346 #define TEST_EMPTY 0x1000
2347 #define TEST_NOMIME 0x2000
2348 #define TEST_FROMCACHE 0x4000
2349
2350 static void register_filter(BOOL do_register)
2351 {
2352 IInternetSession *session;
2353 HRESULT hres;
2354
2355 hres = pCoInternetGetSession(0, &session, 0);
2356 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2357
2358 if(do_register) {
2359 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2360 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2361 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2362 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2363 }else {
2364 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2365 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2366 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2367 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2368 }
2369
2370 IInternetSession_Release(session);
2371 }
2372
2373 static void init_test(int prot, DWORD flags)
2374 {
2375 tested_protocol = prot;
2376 binding_test = (flags & TEST_BINDING) != 0;
2377 first_data_notif = TRUE;
2378 prot_read = 0;
2379 prot_state = 0;
2380 async_read_pending = TRUE;
2381 mimefilter_test = (flags & TEST_FILTER) != 0;
2382 no_mime = (flags & TEST_NOMIME) != 0;
2383 filter_state = 0;
2384 post_stream_read = 0;
2385 ResetEvent(event_complete);
2386 ResetEvent(event_complete2);
2387 ResetEvent(event_continue);
2388 ResetEvent(event_continue_done);
2389 async_protocol = binding_protocol = filtered_protocol = NULL;
2390 filtered_sink = NULL;
2391 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2392 first_data_notif = TRUE;
2393 state = STATE_CONNECTING;
2394 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2395 direct_read = (flags & TEST_DIRECT_READ) != 0;
2396 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2397 wait_for_switch = TRUE;
2398 short_read = (flags & TEST_SHORT_READ) != 0;
2399 http_post_test = TYMED_NULL;
2400 test_redirect = (flags & TEST_REDIRECT) != 0;
2401 test_abort = (flags & TEST_ABORT) != 0;
2402 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2403 empty_file = (flags & TEST_EMPTY) != 0;
2404 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2405 file_with_hash = FALSE;
2406
2407 register_filter(mimefilter_test);
2408 }
2409
2410 static void test_priority(IInternetProtocol *protocol)
2411 {
2412 IInternetPriority *priority;
2413 LONG pr;
2414 HRESULT hres;
2415
2416 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2417 (void**)&priority);
2418 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2419 if(FAILED(hres))
2420 return;
2421
2422 hres = IInternetPriority_GetPriority(priority, &pr);
2423 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2424 ok(pr == 0, "pr=%d, expected 0\n", pr);
2425
2426 hres = IInternetPriority_SetPriority(priority, 1);
2427 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2428
2429 hres = IInternetPriority_GetPriority(priority, &pr);
2430 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2431 ok(pr == 1, "pr=%d, expected 1\n", pr);
2432
2433 IInternetPriority_Release(priority);
2434 }
2435
2436 static void test_early_abort(const CLSID *clsid)
2437 {
2438 IInternetProtocol *protocol;
2439 HRESULT hres;
2440
2441 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2442 &IID_IInternetProtocol, (void**)&protocol);
2443 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2444
2445 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2446 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2447
2448 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2449 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2450
2451 IInternetProtocol_Release(protocol);
2452 }
2453
2454 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2455 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2456 {
2457 HRESULT hres;
2458
2459 SET_EXPECT(GetBindInfo);
2460 if(!(bindf & BINDF_FROMURLMON))
2461 SET_EXPECT(ReportProgress_DIRECTBIND);
2462 if(is_first) {
2463 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2464 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2465 if(bindf & BINDF_FROMURLMON)
2466 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2467 else
2468 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2469 }
2470 SET_EXPECT(ReportData);
2471 if(is_first)
2472 SET_EXPECT(ReportResult);
2473
2474 expect_hrResult = S_OK;
2475
2476 if(protocolex) {
2477 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2478 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2479 }else {
2480 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2481 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2482 win_skip("Start failed\n");
2483 return FALSE;
2484 }
2485 ok(hres == S_OK, "Start failed: %08x\n", hres);
2486 }
2487
2488 CHECK_CALLED(GetBindInfo);
2489 if(!(bindf & BINDF_FROMURLMON))
2490 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2491 if(is_first) {
2492 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2493 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2494 if(bindf & BINDF_FROMURLMON)
2495 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2496 else
2497 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2498 }
2499 CHECK_CALLED(ReportData);
2500 if(is_first)
2501 CHECK_CALLED(ReportResult);
2502
2503 return TRUE;
2504 }
2505
2506 static void test_file_protocol_url(LPCWSTR url)
2507 {
2508 IInternetProtocolInfo *protocol_info;
2509 IUnknown *unk;
2510 IClassFactory *factory;
2511 IInternetProtocol *protocol;
2512 BYTE buf[512];
2513 ULONG cb;
2514 HRESULT hres;
2515
2516 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2517 &IID_IUnknown, (void**)&unk);
2518 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2519 if(FAILED(hres))
2520 return;
2521
2522 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2523 ok(hres == E_NOINTERFACE,
2524 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2525
2526 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2527 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2528 IUnknown_Release(unk);
2529 if(FAILED(hres))
2530 return;
2531
2532 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2533 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2534
2535 if(SUCCEEDED(hres)) {
2536 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2537 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2538 ok(hres == S_OK, "Read failed: %08x\n", hres);
2539 ok(cb == 2, "cb=%u expected 2\n", cb);
2540 buf[2] = 0;
2541 ok(!memcmp(buf, file_with_hash ? "XX" : "<H", 2), "Unexpected data %s\n", buf);
2542 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2543 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2544 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2545 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2546 ok(cb == 0, "cb=%u expected 0\n", cb);
2547 hres = IInternetProtocol_UnlockRequest(protocol);
2548 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2549 }
2550
2551 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2552 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2553 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2554 hres = IInternetProtocol_LockRequest(protocol, 0);
2555 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2556 hres = IInternetProtocol_UnlockRequest(protocol);
2557 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2558 }
2559
2560 IInternetProtocol_Release(protocol);
2561 }
2562
2563 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2564 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2565 if(SUCCEEDED(hres)) {
2566 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2567 hres = IInternetProtocol_LockRequest(protocol, 0);
2568 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2569 hres = IInternetProtocol_Terminate(protocol, 0);
2570 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2571 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2572 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2573 hres = IInternetProtocol_UnlockRequest(protocol);
2574 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2575 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2576 if(file_with_hash) /* FIXME: An effect of UnlockRequest call? */
2577 todo_wine ok(hres == S_OK, "Read failed: %08x\n", hres);
2578 else
2579 ok(hres == S_OK, "Read failed: %08x\n", hres);
2580 hres = IInternetProtocol_Terminate(protocol, 0);
2581 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2582 }
2583
2584 IInternetProtocol_Release(protocol);
2585 }
2586
2587 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2588 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2589 if(SUCCEEDED(hres)) {
2590 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2591 hres = IInternetProtocol_Terminate(protocol, 0);
2592 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2593 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2594 ok(hres == S_OK, "Read failed: %08x\n", hres);
2595 ok(cb == 2, "cb=%u expected 2\n", cb);
2596 }
2597
2598 IInternetProtocol_Release(protocol);
2599 }
2600
2601 if(pCreateUri) {
2602 IInternetProtocolEx *protocolex;
2603 IUri *uri;
2604
2605 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2606 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2607
2608 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2609 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2610
2611 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2612 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2613 ok(hres == S_OK, "Read failed: %08x\n", hres);
2614 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2615 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2616 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2617 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2618 }
2619
2620 IUri_Release(uri);
2621 IInternetProtocolEx_Release(protocolex);
2622
2623 hres = pCreateUri(url, 0, 0, &uri);
2624 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2625
2626 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2627 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2628
2629 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2630 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2631 ok(hres == S_OK, "Read failed: %08x\n", hres);
2632 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2633 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2634 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2635 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2636 }
2637
2638 IUri_Release(uri);
2639 IInternetProtocolEx_Release(protocolex);
2640 }else {
2641 win_skip("Skipping file protocol StartEx tests\n");
2642 }
2643
2644 IClassFactory_Release(factory);
2645 }
2646
2647 static void test_file_protocol_fail(void)
2648 {
2649 IInternetProtocol *protocol;
2650 HRESULT hres;
2651
2652 static const WCHAR index_url2[] =
2653 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2654
2655 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2656 &IID_IInternetProtocol, (void**)&protocol);
2657 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2658 if(FAILED(hres))
2659 return;
2660
2661 SET_EXPECT(GetBindInfo);
2662 expect_hrResult = MK_E_SYNTAX;
2663 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2664 ok(hres == MK_E_SYNTAX ||
2665 hres == E_INVALIDARG,
2666 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2667 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2668
2669 SET_EXPECT(GetBindInfo);
2670 if(!(bindf & BINDF_FROMURLMON))
2671 SET_EXPECT(ReportProgress_DIRECTBIND);
2672 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2673 SET_EXPECT(ReportResult);
2674 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2675 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2676 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2677 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2678 CHECK_CALLED(GetBindInfo);
2679 if(!(bindf & BINDF_FROMURLMON))
2680 CHECK_CALLED(ReportProgress_DIRECTBIND);
2681 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2682 CHECK_CALLED(ReportResult);
2683
2684 IInternetProtocol_Release(protocol);
2685
2686 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2687 &IID_IInternetProtocol, (void**)&protocol);
2688 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2689 if(FAILED(hres))
2690 return;
2691
2692 SET_EXPECT(GetBindInfo);
2693 if(!(bindf & BINDF_FROMURLMON))
2694 SET_EXPECT(ReportProgress_DIRECTBIND);
2695 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2696 SET_EXPECT(ReportResult);
2697 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2698
2699 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2700 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2701 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2702 CHECK_CALLED(GetBindInfo);
2703 if(!(bindf & BINDF_FROMURLMON))
2704 CHECK_CALLED(ReportProgress_DIRECTBIND);
2705 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2706 CHECK_CALLED(ReportResult);
2707
2708 SET_EXPECT(GetBindInfo);
2709 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2710 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2711 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2712
2713 SET_EXPECT(GetBindInfo);
2714 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2715 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2716 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2717
2718 IInternetProtocol_Release(protocol);
2719 }
2720
2721 static void test_file_protocol(void) {
2722 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2723 DWORD size;
2724 ULONG len;
2725 HANDLE file;
2726
2727 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2728 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2729 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2730 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2731 static const char html_doc[] = "<HTML></HTML>";
2732 static const WCHAR fragmentW[] = {'#','f','r','a','g',0};
2733
2734 trace("Testing file protocol...\n");
2735 init_test(FILE_TEST, 0);
2736
2737 SetLastError(0xdeadbeef);
2738 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2739 FILE_ATTRIBUTE_NORMAL, NULL);
2740 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2741 if(file == INVALID_HANDLE_VALUE)
2742 return;
2743 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2744 CloseHandle(file);
2745
2746 file_name = wszIndexHtml;
2747 bindf = 0;
2748 test_file_protocol_url(index_url);
2749 bindf = BINDF_FROMURLMON;
2750 test_file_protocol_url(index_url);
2751 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2752 test_file_protocol_url(index_url);
2753
2754 memcpy(buf, wszFile, sizeof(wszFile));
2755 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2756 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2757 buf[len++] = '\\';
2758 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2759
2760 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2761 bindf = 0;
2762 test_file_protocol_url(buf);
2763 bindf = BINDF_FROMURLMON;
2764 test_file_protocol_url(buf);
2765
2766 memcpy(buf, wszFile2, sizeof(wszFile2));
2767 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2768 file_name_buf[len++] = '\\';
2769 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2770 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2771 file_name = file_name_buf;
2772 bindf = 0;
2773 test_file_protocol_url(buf);
2774 bindf = BINDF_FROMURLMON;
2775 test_file_protocol_url(buf);
2776
2777 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2778 test_file_protocol_url(buf);
2779
2780 memcpy(buf, wszFile3, sizeof(wszFile3));
2781 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2782 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2783 buf[len++] = '\\';
2784 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2785
2786 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2787 bindf = 0;
2788 test_file_protocol_url(buf);
2789 bindf = BINDF_FROMURLMON;
2790 test_file_protocol_url(buf);
2791
2792 memcpy(buf, wszFile4, sizeof(wszFile4));
2793 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2794 file_name_buf[len++] = '\\';
2795 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2796 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2797 file_name = file_name_buf;
2798 bindf = 0;
2799 test_file_protocol_url(buf);
2800 bindf = BINDF_FROMURLMON;
2801 test_file_protocol_url(buf);
2802
2803 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2804 test_file_protocol_url(buf);
2805
2806 /* Fragment part of URL is skipped if the file doesn't exist. */
2807 lstrcatW(buf, fragmentW);
2808 test_file_protocol_url(buf);
2809
2810 /* Fragment part is considered a part of the file name, if the file exsists. */
2811 len = lstrlenW(file_name_buf);
2812 lstrcpyW(file_name_buf+len, fragmentW);
2813 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2814 FILE_ATTRIBUTE_NORMAL, NULL);
2815 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2816 WriteFile(file, "XXX", 3, &size, NULL);
2817 CloseHandle(file);
2818 file_name_buf[len] = 0;
2819
2820 file_with_hash = TRUE;
2821 test_file_protocol_url(buf);
2822
2823 DeleteFileW(wszIndexHtml);
2824 DeleteFileW(file_name_buf);
2825
2826 bindf = 0;
2827 test_file_protocol_fail();
2828 bindf = BINDF_FROMURLMON;
2829 test_file_protocol_fail();
2830 }
2831
2832 static void create_cache_entry(const WCHAR *urlw)
2833 {
2834 FILETIME now, tomorrow, yesterday;
2835 char file_path[MAX_PATH];
2836 BYTE content[1000];
2837 ULARGE_INTEGER li;
2838 const char *url;
2839 HANDLE file;
2840 DWORD size;
2841 unsigned i;
2842 BOOL res;
2843
2844 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2845
2846 trace("Testing cache read...\n");
2847
2848 url = w2a(urlw);
2849
2850 for(i = 0; i < sizeof(content); i++)
2851 content[i] = '0' + (i%10);
2852
2853 GetSystemTimeAsFileTime(&now);
2854 li.u.HighPart = now.dwHighDateTime;
2855 li.u.LowPart = now.dwLowDateTime;
2856 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2857 tomorrow.dwHighDateTime = li.u.HighPart;
2858 tomorrow.dwLowDateTime = li.u.LowPart;
2859 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2860 yesterday.dwHighDateTime = li.u.HighPart;
2861 yesterday.dwLowDateTime = li.u.LowPart;
2862
2863 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2864 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2865
2866 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2867 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2868
2869 WriteFile(file, content, sizeof(content), &size, NULL);
2870 CloseHandle(file);
2871
2872 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2873 cache_headers, sizeof(cache_headers)-1, "", 0);
2874 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2875 }
2876
2877 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2878 {
2879 static BOOL got_user_agent = FALSE;
2880 IUri *uri = NULL;
2881 HRESULT hres;
2882
2883 if(use_iuri && pCreateUri) {
2884 hres = pCreateUri(url, 0, 0, &uri);
2885 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2886 }
2887
2888 SET_EXPECT(GetBindInfo);
2889 if (!(bindf & BINDF_FROMURLMON))
2890 SET_EXPECT(ReportProgress_DIRECTBIND);
2891 if(!got_user_agent)
2892 SET_EXPECT(GetBindString_USER_AGENT);
2893 SET_EXPECT(GetBindString_ROOTDOC_URL);
2894 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2895 SET_EXPECT(QueryService_HttpNegotiate);
2896 SET_EXPECT(BeginningTransaction);
2897 SET_EXPECT(GetRootSecurityId);
2898 if(http_post_test) {
2899 SET_EXPECT(GetBindString_POST_COOKIE);
2900 if(http_post_test == TYMED_ISTREAM)
2901 SET_EXPECT(Stream_Seek);
2902 }
2903 if(bind_from_cache) {
2904 SET_EXPECT(OnResponse);
2905 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2906 SET_EXPECT(ReportData);
2907 }
2908
2909 if(uri) {
2910 IInternetProtocolEx *protocolex;
2911
2912 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2913 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2914
2915 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2916 ok(hres == S_OK, "Start failed: %08x\n", hres);
2917
2918 IInternetProtocolEx_Release(protocolex);
2919 IUri_Release(uri);
2920 }else {
2921 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2922 ok(hres == S_OK, "Start failed: %08x\n", hres);
2923 }
2924 if(FAILED(hres))
2925 return FALSE;
2926
2927 CHECK_CALLED(GetBindInfo);
2928 if (!(bindf & BINDF_FROMURLMON))
2929 CHECK_CALLED(ReportProgress_DIRECTBIND);
2930 if (!got_user_agent)
2931 {
2932 CHECK_CALLED(GetBindString_USER_AGENT);
2933 got_user_agent = TRUE;
2934 }
2935 CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
2936 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2937 CHECK_CALLED(QueryService_HttpNegotiate);
2938 CHECK_CALLED(BeginningTransaction);
2939 /* GetRootSecurityId called on WinXP but not on Win98 */
2940 CLEAR_CALLED(GetRootSecurityId);
2941 if(http_post_test) {
2942 CHECK_CALLED(GetBindString_POST_COOKIE);
2943 if(http_post_test == TYMED_ISTREAM)
2944 CHECK_CALLED(Stream_Seek);
2945 }
2946 if(bind_from_cache) {
2947 CHECK_CALLED(OnResponse);
2948 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2949 CHECK_CALLED(ReportData);
2950 }
2951
2952 return TRUE;
2953 }
2954
2955 static void test_protocol_terminate(IInternetProtocol *protocol)
2956 {
2957 BYTE buf[3600];
2958 DWORD cb;
2959 HRESULT hres;
2960
2961 hres = IInternetProtocol_LockRequest(protocol, 0);
2962 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2963
2964 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2965 ok(hres == (test_abort ? S_OK : S_FALSE), "Read failed: %08x\n", hres);
2966
2967 hres = IInternetProtocol_Terminate(protocol, 0);
2968 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2969
2970 /* This wait is to give the internet handles being freed in Terminate
2971 * enough time to actually terminate in all cases. Internet handles
2972 * terminate asynchronously and native reuses the main InternetOpen
2973 * handle. The only case in which this seems to be necessary is on
2974 * wine with native wininet and urlmon, resulting in the next time
2975 * test_http_protocol_url being called the first data notification actually
2976 * being an extra last data notification from the previous connection
2977 * about once out of every ten times. */
2978 Sleep(100);
2979
2980 hres = IInternetProtocol_UnlockRequest(protocol);
2981 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2982 }
2983
2984 static void test_http_info(IInternetProtocol *protocol)
2985 {
2986 IWinInetHttpInfo *info;
2987 HRESULT hres;
2988
2989 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2990 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2991
2992 /* TODO */
2993
2994 IWinInetHttpInfo_Release(info);
2995 }
2996
2997 /* is_first refers to whether this is the first call to this function
2998 * _for this url_ */
2999 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
3000 {
3001 IInternetProtocolInfo *protocol_info;
3002 IClassFactory *factory;
3003 IUnknown *unk;
3004 HRESULT hres;
3005
3006 init_test(prot, flags);
3007 http_url = url;
3008 http_post_test = tymed;
3009
3010 if(flags & TEST_FROMCACHE)
3011 create_cache_entry(url);
3012
3013 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
3014 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3015 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3016 if(FAILED(hres))
3017 return;
3018
3019 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3020 ok(hres == E_NOINTERFACE,
3021 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3022 hres);
3023
3024 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3025 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3026 IUnknown_Release(unk);
3027 if(FAILED(hres))
3028 return;
3029
3030 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3031 (void**)&async_protocol);
3032 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3033 if(SUCCEEDED(hres)) {
3034 BYTE buf[3600];
3035 DWORD cb;
3036 ULONG ref;
3037
3038 test_priority(async_protocol);
3039 test_http_info(async_protocol);
3040
3041 SET_EXPECT(ReportProgress_COOKIE_SENT);
3042 if(http_is_first) {
3043 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3044 SET_EXPECT(ReportProgress_CONNECTING);
3045 }
3046 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3047 if(test_redirect)
3048 SET_EXPECT(ReportProgress_REDIRECTING);
3049 SET_EXPECT(ReportProgress_PROXYDETECTING);
3050 if(prot == HTTP_TEST)
3051 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3052 else
3053 SET_EXPECT(QueryService_HttpSecurity);
3054 if(!(bindf & BINDF_FROMURLMON)) {
3055 SET_EXPECT(OnResponse);
3056 SET_EXPECT(ReportProgress_RAWMIMETYPE);
3057 SET_EXPECT(ReportData);
3058 } else {
3059 SET_EXPECT(Switch);
3060 }
3061
3062 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3063 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3064 IInternetProtocol_Release(async_protocol);
3065 return;
3066 }
3067
3068 if(!direct_read && !test_abort && !bind_from_cache)
3069 SET_EXPECT(ReportResult);
3070 expect_hrResult = test_abort ? E_ABORT : S_OK;
3071
3072 if(direct_read) {
3073 SET_EXPECT(Switch);
3074 while(wait_for_switch) {
3075 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3076 CHECK_CALLED(Switch); /* Set in ReportData */
3077 call_continue(&continue_protdata);
3078 SetEvent(event_continue_done);
3079 }
3080 }else if(bind_from_cache) {
3081 BYTE buf[1500];
3082
3083 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3084 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3085
3086 SET_EXPECT(ReportResult);
3087 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3088 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3089 CHECK_CALLED(ReportResult);
3090
3091 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3092 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3093 }else {
3094 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3095 ok((hres == E_PENDING && cb==0) ||
3096 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3097
3098 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3099 if(bindf & BINDF_FROMURLMON)
3100 CHECK_CALLED(Switch);
3101 else
3102 CHECK_CALLED(ReportData);
3103 if(prot == HTTPS_TEST)
3104 CLEAR_CALLED(QueryService_HttpSecurity);
3105
3106 while(1) {
3107 if(bindf & BINDF_FROMURLMON)
3108 SET_EXPECT(Switch);
3109 else
3110 SET_EXPECT(ReportData);
3111 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3112 if(hres == E_PENDING) {
3113 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3114 ok((hres == E_PENDING && cb==0) ||
3115 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3116 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3117 if(bindf & BINDF_FROMURLMON)
3118 CHECK_CALLED(Switch);
3119 else
3120 CHECK_CALLED(ReportData);
3121
3122 if(test_abort) {
3123 HRESULT hres;
3124
3125 SET_EXPECT(ReportResult);
3126 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3127 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3128 CHECK_CALLED(ReportResult);
3129
3130 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3131 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3132 break;
3133 }
3134 }else {
3135 if(bindf & BINDF_FROMURLMON)
3136 CHECK_NOT_CALLED(Switch);
3137 else
3138 CHECK_NOT_CALLED(ReportData);
3139 if(cb == 0) break;
3140 }
3141 }
3142 if(!test_abort) {
3143 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3144 CHECK_CALLED(ReportResult);
3145 }
3146 }
3147 if(prot == HTTPS_TEST)
3148 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3149
3150 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3151 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3152
3153 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3154 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3155
3156 test_protocol_terminate(async_protocol);
3157
3158 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3159 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3160
3161 ref = IInternetProtocol_Release(async_protocol);
3162 ok(!ref, "ref=%x\n", ref);
3163 }
3164
3165 IClassFactory_Release(factory);
3166
3167 if(flags & TEST_FROMCACHE) {
3168 BOOL res;
3169
3170 res = DeleteUrlCacheEntryW(url);
3171 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3172 }
3173 }
3174
3175 static void test_http_protocol(void)
3176 {
3177 static const WCHAR posttest_url[] =
3178 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3179 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3180 static const WCHAR redirect_url[] =
3181 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3182 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3183 static const WCHAR winetest_url[] =
3184 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3185 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3186 static const WCHAR empty_url[] =
3187 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3188 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3189 static const WCHAR cache_only_url[] =
3190 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3191 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3192
3193
3194 trace("Testing http protocol (not from urlmon)...\n");
3195 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3196 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3197
3198 trace("Testing http protocol (from urlmon)...\n");
3199 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3200 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3201
3202 trace("Testing http protocol (to file)...\n");
3203 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3204 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3205
3206 trace("Testing http protocol (post data)...\n");
3207 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3208 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3209
3210 trace("Testing http protocol (post data stream)...\n");
3211 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3212
3213 trace("Testing http protocol (direct read)...\n");
3214 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3215 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3216
3217 trace("Testing http protocol (redirected)...\n");
3218 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3219 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3220
3221 trace("Testing http protocol empty file...\n");
3222 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3223 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3224
3225 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3226 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3227 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3228 * tests work on Windows and have them around for the future.
3229 */
3230 if(broken(1)) {
3231 trace("Testing http protocol (from cache)...\n");
3232 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3233 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3234 }
3235
3236 trace("Testing http protocol abort...\n");
3237 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3238 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3239
3240 test_early_abort(&CLSID_HttpProtocol);
3241 test_early_abort(&CLSID_HttpSProtocol);
3242 }
3243
3244 static void test_https_protocol(void)
3245 {
3246 static const WCHAR https_winehq_url[] =
3247 {'h','t','t','p','s',':','/'