[URLMON_WINETEST]
[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;
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 trace("continue in state %d\n", state);
589
590 if(state == STATE_CONNECTING) {
591 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
592 if (http_is_first){
593 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
594 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
595 }
596 CLEAR_CALLED(ReportProgress_CONNECTING);
597 }
598 if(tested_protocol == FTP_TEST)
599 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
600 else if (tested_protocol != HTTPS_TEST)
601 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
602 if(test_redirect)
603 CHECK_CALLED(ReportProgress_REDIRECTING);
604 state = test_async_req ? STATE_SENDINGREQUEST : STATE_STARTDOWNLOADING;
605 }
606
607 switch(state) {
608 case STATE_SENDINGREQUEST:
609 SET_EXPECT(Stream_Read);
610 SET_EXPECT(ReportProgress_SENDINGREQUEST);
611 break;
612 case STATE_STARTDOWNLOADING:
613 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
614 SET_EXPECT(OnResponse);
615 if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file)
616 SET_EXPECT(ReportProgress_ACCEPTRANGES);
617 SET_EXPECT(ReportProgress_ENCODING);
618 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
619 if(bindf & BINDF_NEEDFILE)
620 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
621 }
622 default:
623 break;
624 }
625
626 if(state != STATE_SENDINGREQUEST)
627 SET_EXPECT(ReportData);
628 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
629 ok(hres == S_OK, "Continue failed: %08x\n", hres);
630 if(tested_protocol == FTP_TEST || security_problem)
631 CLEAR_CALLED(ReportData);
632 else if(state != STATE_SENDINGREQUEST)
633 CHECK_CALLED(ReportData);
634
635 switch(state) {
636 case STATE_SENDINGREQUEST:
637 CHECK_CALLED(Stream_Read);
638 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
639 state = STATE_STARTDOWNLOADING;
640 break;
641 case STATE_STARTDOWNLOADING:
642 if (! security_problem)
643 {
644 state = STATE_DOWNLOADING;
645 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
646 CHECK_CALLED(OnResponse);
647 if(tested_protocol == HTTPS_TEST || empty_file)
648 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
649 else if(test_redirect || test_abort)
650 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
651 CLEAR_CALLED(ReportProgress_ENCODING);
652 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
653 if(bindf & BINDF_NEEDFILE)
654 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
655 }
656 }
657 else
658 {
659 security_problem = FALSE;
660 SET_EXPECT(ReportProgress_CONNECTING);
661 }
662 default:
663 break;
664 }
665 }
666
667 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
668 {
669 if(tested_protocol == FTP_TEST)
670 CHECK_EXPECT2(Switch);
671 else
672 CHECK_EXPECT(Switch);
673
674 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
675 if(binding_test) {
676 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
677 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
678 pProtocolData->grfFlags, protocoldata.grfFlags );
679 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
680 pProtocolData->dwState, protocoldata.dwState );
681 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
682 pProtocolData->pData, protocoldata.pData );
683 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
684 pProtocolData->cbData, protocoldata.cbData );
685 }
686
687 pdata = pProtocolData;
688
689 if(binding_test) {
690 SetEvent(event_complete);
691 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
692 return S_OK;
693 }if(direct_read) {
694 continue_protdata = *pProtocolData;
695 SetEvent(event_continue);
696 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
697 }else {
698 call_continue(pProtocolData);
699 SetEvent(event_complete);
700 }
701
702 return S_OK;
703 }
704
705 static const char *status_names[] =
706 {
707 "0",
708 "FINDINGRESOURCE",
709 "CONNECTING",
710 "REDIRECTING",
711 "BEGINDOWNLOADDATA",
712 "DOWNLOADINGDATA",
713 "ENDDOWNLOADDATA",
714 "BEGINDOWNLOADCOMPONENTS",
715 "INSTALLINGCOMPONENTS",
716 "ENDDOWNLOADCOMPONENTS",
717 "USINGCACHEDCOPY",
718 "SENDINGREQUEST",
719 "CLASSIDAVAILABLE",
720 "MIMETYPEAVAILABLE",
721 "CACHEFILENAMEAVAILABLE",
722 "BEGINSYNCOPERATION",
723 "ENDSYNCOPERATION",
724 "BEGINUPLOADDATA",
725 "UPLOADINGDATA",
726 "ENDUPLOADINGDATA",
727 "PROTOCOLCLASSID",
728 "ENCODING",
729 "VERIFIEDMIMETYPEAVAILABLE",
730 "CLASSINSTALLLOCATION",
731 "DECODING",
732 "LOADINGMIMEHANDLER",
733 "CONTENTDISPOSITIONATTACH",
734 "FILTERREPORTMIMETYPE",
735 "CLSIDCANINSTANTIATE",
736 "IUNKNOWNAVAILABLE",
737 "DIRECTBIND",
738 "RAWMIMETYPE",
739 "PROXYDETECTING",
740 "ACCEPTRANGES",
741 "COOKIE_SENT",
742 "COMPACT_POLICY_RECEIVED",
743 "COOKIE_SUPPRESSED",
744 "COOKIE_STATE_UNKNOWN",
745 "COOKIE_STATE_ACCEPT",
746 "COOKIE_STATE_REJECT",
747 "COOKIE_STATE_PROMPT",
748 "COOKIE_STATE_LEASH",
749 "COOKIE_STATE_DOWNGRADE",
750 "POLICY_HREF",
751 "P3P_HEADER",
752 "SESSION_COOKIE_RECEIVED",
753 "PERSISTENT_COOKIE_RECEIVED",
754 "SESSION_COOKIES_ALLOWED",
755 "CACHECONTROL",
756 "CONTENTDISPOSITIONFILENAME",
757 "MIMETEXTPLAINMISMATCH",
758 "PUBLISHERAVAILABLE",
759 "DISPLAYNAMEAVAILABLE"
760 };
761
762 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
763 LPCWSTR szStatusText)
764 {
765 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
766 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
767 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
768
769 if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0]))
770 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
771 else
772 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
773
774 switch(ulStatusCode) {
775 case BINDSTATUS_MIMETYPEAVAILABLE:
776 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
777 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
778 if(!short_read || !direct_read)
779 CHECK_CALLED(Read); /* set in Continue */
780 else if(short_read)
781 CHECK_CALLED(Read2); /* set in Read */
782 }
783 ok(szStatusText != NULL, "szStatusText == NULL\n");
784 if(szStatusText) {
785 if(tested_protocol == BIND_TEST)
786 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
787 else if (http_post_test)
788 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
789 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
790 "szStatusText != text/plain\n");
791 else if(empty_file)
792 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
793 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
794 && tested_protocol==HTTP_TEST && !short_read)
795 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
796 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
797 "szStatusText != image/gif\n");
798 else if(!mimefilter_test)
799 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
800 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
801 "szStatusText != text/html\n");
802 }
803 break;
804 case BINDSTATUS_DIRECTBIND:
805 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
806 ok(szStatusText == NULL, "szStatusText != NULL\n");
807 break;
808 case BINDSTATUS_RAWMIMETYPE:
809 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
810 ok(szStatusText != NULL, "szStatusText == NULL\n");
811 if(szStatusText)
812 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
813 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
814 "szStatusText != text/html\n");
815 break;
816 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
817 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
818 ok(szStatusText != NULL, "szStatusText == NULL\n");
819 if(szStatusText) {
820 if(binding_test)
821 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
822 else if(tested_protocol == FILE_TEST)
823 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
824 else
825 ok(szStatusText != NULL, "szStatusText == NULL\n");
826 }
827 break;
828 case BINDSTATUS_FINDINGRESOURCE:
829 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
830 ok(szStatusText != NULL, "szStatusText == NULL\n");
831 break;
832 case BINDSTATUS_CONNECTING:
833 CHECK_EXPECT2(ReportProgress_CONNECTING);
834 ok(szStatusText != NULL, "szStatusText == NULL\n");
835 break;
836 case BINDSTATUS_SENDINGREQUEST:
837 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
838 if(tested_protocol == FILE_TEST || tested_protocol == ITS_TEST) {
839 ok(szStatusText != NULL, "szStatusText == NULL\n");
840 if(szStatusText)
841 ok(!*szStatusText, "wrong szStatusText\n");
842 }
843 break;
844 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
845 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
846 ok(szStatusText != NULL, "szStatusText == NULL\n");
847 if(szStatusText)
848 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
849 break;
850 case BINDSTATUS_PROTOCOLCLASSID:
851 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
852 ok(szStatusText != NULL, "szStatusText == NULL\n");
853 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
854 break;
855 case BINDSTATUS_COOKIE_SENT:
856 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
857 ok(szStatusText == NULL, "szStatusText != NULL\n");
858 break;
859 case BINDSTATUS_REDIRECTING:
860 CHECK_EXPECT(ReportProgress_REDIRECTING);
861 if(test_redirect)
862 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
863 else
864 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
865 break;
866 case BINDSTATUS_ENCODING:
867 CHECK_EXPECT(ReportProgress_ENCODING);
868 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
869 break;
870 case BINDSTATUS_ACCEPTRANGES:
871 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
872 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
873 break;
874 case BINDSTATUS_PROXYDETECTING:
875 if(!called_ReportProgress_PROXYDETECTING)
876 SET_EXPECT(ReportProgress_CONNECTING);
877 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
878 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
879 break;
880 case BINDSTATUS_LOADINGMIMEHANDLER:
881 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
882 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
883 break;
884 case BINDSTATUS_DECODING:
885 CHECK_EXPECT(ReportProgress_DECODING);
886 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
887 break;
888 case BINDSTATUS_RESERVED_7:
889 trace("BINDSTATUS_RESERVED_7\n");
890 break;
891 default:
892 ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
893 };
894
895 return S_OK;
896 }
897
898 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
899 ULONG ulProgress, ULONG ulProgressMax)
900 {
901 HRESULT hres;
902
903 static int rec_depth;
904 rec_depth++;
905
906 if(!mimefilter_test && (tested_protocol == FILE_TEST || tested_protocol == ITS_TEST)) {
907 CHECK_EXPECT2(ReportData);
908
909 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
910 ulProgress, ulProgressMax);
911 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
912 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
913 if(tested_protocol == FILE_TEST)
914 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
915 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
916 "grcfBSCF = %08x\n", grfBSCF);
917 else
918 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
919 }else if(bind_from_cache) {
920 CHECK_EXPECT(ReportData);
921
922 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
923 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
924 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
925 }else if(direct_read) {
926 BYTE buf[14096];
927 ULONG read;
928
929 if(!read_report_data && rec_depth == 1) {
930 BOOL reported_all_data = called_ReportData2;
931
932 CHECK_EXPECT2(ReportData);
933
934 if(short_read) {
935 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
936 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
937 "grcfBSCF = %08x\n", grfBSCF);
938 CHECK_CALLED(Read); /* Set in Continue */
939 first_data_notif = FALSE;
940 }else if(first_data_notif) {
941 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
942 first_data_notif = FALSE;
943 }else if(reported_all_data) {
944 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
945 "grcfBSCF = %08x\n", grfBSCF);
946 }else if(!direct_read) {
947 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
948 }
949
950 do {
951 read = 0;
952 if(emulate_prot)
953 SET_EXPECT(Read);
954 else
955 SET_EXPECT(ReportData2);
956 SET_EXPECT(ReportResult);
957 if(!emulate_prot)
958 SET_EXPECT(Switch);
959 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
960 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
961 if(hres == S_OK)
962 ok(read, "read == 0\n");
963 if(reported_all_data)
964 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
965 if(!emulate_prot && hres != E_PENDING)
966 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
967 if(emulate_prot)
968 CHECK_CALLED(Read);
969 if(!reported_all_data && called_ReportData2) {
970 if(!emulate_prot)
971 CHECK_CALLED(ReportData2);
972 CHECK_CALLED(ReportResult);
973 reported_all_data = TRUE;
974 }else {
975 if(!emulate_prot)
976 CHECK_NOT_CALLED(ReportData2);
977 CHECK_NOT_CALLED(ReportResult);
978 }
979 }while(hres == S_OK);
980 if(hres == S_FALSE)
981 wait_for_switch = FALSE;
982 }else {
983 CHECK_EXPECT(ReportData2);
984
985 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
986
987 read = 0xdeadbeef;
988 if(emulate_prot)
989 SET_EXPECT(Read2);
990 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
991 if(emulate_prot)
992 CHECK_CALLED(Read2);
993 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
994 ok(!read, "read = %d\n", read);
995 }
996 }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST
997 || tested_protocol == FTP_TEST)) {
998 if(empty_file)
999 CHECK_EXPECT2(ReportData);
1000 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
1001 CHECK_EXPECT(ReportData);
1002 else if (http_post_test)
1003 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
1004
1005 if(empty_file) {
1006 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
1007 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
1008 }else {
1009 ok(ulProgress, "ulProgress == 0\n");
1010 }
1011
1012 if(empty_file) {
1013 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1014 "grcfBSCF = %08x\n", grfBSCF);
1015 first_data_notif = FALSE;
1016 }else if(first_data_notif) {
1017 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1018 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1019 "grcfBSCF = %08x\n", grfBSCF);
1020 first_data_notif = FALSE;
1021 } else {
1022 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1023 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1024 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1025 "grcfBSCF = %08x\n", grfBSCF);
1026 }
1027
1028 if(!(bindf & BINDF_FROMURLMON) &&
1029 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1030 if(state == STATE_CONNECTING) {
1031 state = STATE_DOWNLOADING;
1032 if(http_is_first) {
1033 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1034 CHECK_CALLED(ReportProgress_CONNECTING);
1035 }
1036 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1037 CHECK_CALLED(OnResponse);
1038 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1039 }
1040 SetEvent(event_complete);
1041 }
1042 }else if(!read_report_data) {
1043 BYTE buf[1000];
1044 ULONG read;
1045 HRESULT hres;
1046
1047 CHECK_EXPECT(ReportData);
1048
1049 if(tested_protocol != BIND_TEST) {
1050 do {
1051 if(mimefilter_test)
1052 SET_EXPECT(MimeFilter_Read);
1053 else if(rec_depth > 1)
1054 SET_EXPECT(Read2);
1055 else
1056 SET_EXPECT(Read);
1057 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1058 if(mimefilter_test)
1059 CHECK_CALLED(MimeFilter_Read);
1060 else if(rec_depth > 1)
1061 CHECK_CALLED(Read2);
1062 else
1063 CHECK_CALLED(Read);
1064 }while(hres == S_OK);
1065 }
1066 }
1067
1068 rec_depth--;
1069 return S_OK;
1070 }
1071
1072 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1073 DWORD dwError, LPCWSTR szResult)
1074 {
1075 CHECK_EXPECT(ReportResult);
1076
1077 if(tested_protocol == FTP_TEST)
1078 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1079 else
1080 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1081 hrResult, expect_hrResult);
1082 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort)
1083 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1084 else
1085 ok(dwError != ERROR_SUCCESS ||
1086 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1087 "dwError == ERROR_SUCCESS\n");
1088 ok(!szResult, "szResult != NULL\n");
1089
1090 if(direct_read)
1091 SET_EXPECT(ReportData); /* checked after main loop */
1092
1093 return S_OK;
1094 }
1095
1096 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1097 ProtocolSink_QueryInterface,
1098 ProtocolSink_AddRef,
1099 ProtocolSink_Release,
1100 ProtocolSink_Switch,
1101 ProtocolSink_ReportProgress,
1102 ProtocolSink_ReportData,
1103 ProtocolSink_ReportResult
1104 };
1105
1106 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
1107
1108 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
1109 {
1110 ok(0, "unexpected call\n");
1111 return E_NOTIMPL;
1112 }
1113
1114 static ULONG WINAPI MimeProtocolSink_AddRef(IInternetProtocolSink *iface)
1115 {
1116 return 2;
1117 }
1118
1119 static ULONG WINAPI MimeProtocolSink_Release(IInternetProtocolSink *iface)
1120 {
1121 return 1;
1122 }
1123
1124 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1125 {
1126 HRESULT hres;
1127
1128 CHECK_EXPECT(MimeFilter_Switch);
1129
1130 SET_EXPECT(Switch);
1131 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1132 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1133 CHECK_CALLED(Switch);
1134
1135 return S_OK;
1136 }
1137
1138 static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
1139 LPCWSTR szStatusText)
1140 {
1141 switch(ulStatusCode) {
1142 case BINDSTATUS_LOADINGMIMEHANDLER:
1143 /*
1144 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1145 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1146 * ProtocolSink_ReportProgress to workaround it.
1147 */
1148 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1149 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1150 break;
1151 default:
1152 ok(0, "Unexpected status code %d\n", ulStatusCode);
1153 }
1154
1155 return S_OK;
1156 }
1157
1158 static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
1159 ULONG ulProgress, ULONG ulProgressMax)
1160 {
1161 DWORD read = 0;
1162 BYTE buf[8192];
1163 HRESULT hres;
1164 BOOL report_mime = FALSE;
1165
1166 CHECK_EXPECT(MimeFilter_ReportData);
1167
1168 if(!filter_state && !no_mime) {
1169 SET_EXPECT(Read);
1170 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1171 if(tested_protocol == HTTP_TEST)
1172 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1173 else
1174 ok(hres == S_OK, "Read failed: %08x\n", hres);
1175 CHECK_CALLED(Read);
1176
1177 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1178 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1179 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1180 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1181
1182 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1183 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1184 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1185 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1186
1187 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1188 }
1189
1190 if(no_mime && prot_read<200) {
1191 SET_EXPECT(Read);
1192 }else if(no_mime && prot_read<300) {
1193 report_mime = TRUE;
1194 SET_EXPECT(Read);
1195 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1196 SET_EXPECT(ReportData);
1197 }else if(!read_report_data) {
1198 SET_EXPECT(ReportData);
1199 }
1200 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1201 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1202 if(no_mime && prot_read<=200) {
1203 CHECK_CALLED(Read);
1204 }else if(report_mime) {
1205 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1206 CHECK_CALLED(ReportData);
1207 }else if(!read_report_data) {
1208 CHECK_CALLED(ReportData);
1209 }
1210
1211 if(!filter_state)
1212 filter_state = 1;
1213
1214 return S_OK;
1215 }
1216
1217 static HRESULT WINAPI MimeProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
1218 DWORD dwError, LPCWSTR szResult)
1219 {
1220 HRESULT hres;
1221
1222 CHECK_EXPECT(MimeFilter_ReportResult);
1223
1224 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1225 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1226 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1227
1228 SET_EXPECT(ReportResult);
1229 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1230 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1231 CHECK_CALLED(ReportResult);
1232
1233 return S_OK;
1234 }
1235
1236 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1237 MimeProtocolSink_QueryInterface,
1238 MimeProtocolSink_AddRef,
1239 MimeProtocolSink_Release,
1240 MimeProtocolSink_Switch,
1241 MimeProtocolSink_ReportProgress,
1242 MimeProtocolSink_ReportData,
1243 MimeProtocolSink_ReportResult
1244 };
1245
1246 static IInternetProtocolSink mime_protocol_sink = { &mime_protocol_sink_vtbl };
1247
1248 static HRESULT QueryInterface(REFIID riid, void **ppv)
1249 {
1250 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1251 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1252
1253 *ppv = NULL;
1254
1255 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1256 *ppv = &protocol_sink;
1257 if(IsEqualGUID(&IID_IServiceProvider, riid))
1258 *ppv = &service_provider;
1259 if(IsEqualGUID(&IID_IUriContainer, riid))
1260 return E_NOINTERFACE; /* TODO */
1261
1262 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1263 if(IsEqualGUID(&IID_undocumented, riid))
1264 return E_NOINTERFACE;
1265 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1266 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1267 return E_NOINTERFACE;
1268
1269 if(*ppv)
1270 return S_OK;
1271
1272 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1273 return E_NOINTERFACE;
1274 }
1275
1276 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
1277 {
1278 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1279 *ppv = iface;
1280 return S_OK;
1281 }
1282 return E_NOINTERFACE;
1283 }
1284
1285 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
1286 {
1287 return 2;
1288 }
1289
1290 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
1291 {
1292 return 1;
1293 }
1294
1295 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1296 {
1297 DWORD cbSize;
1298
1299 CHECK_EXPECT(GetBindInfo);
1300
1301 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1302 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1303 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1304
1305 *grfBINDF = bindf;
1306 if(binding_test)
1307 *grfBINDF |= BINDF_FROMURLMON;
1308 cbSize = pbindinfo->cbSize;
1309 memset(pbindinfo, 0, cbSize);
1310 pbindinfo->cbSize = cbSize;
1311
1312 if(http_post_test)
1313 {
1314 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1315 pbindinfo->dwBindVerb = BINDVERB_POST;
1316 pbindinfo->stgmedData.tymed = http_post_test;
1317
1318 if(http_post_test == TYMED_HGLOBAL) {
1319 HGLOBAL data;
1320
1321 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1322 data = GlobalAlloc(GPTR, sizeof(post_data));
1323 memcpy(data, post_data, sizeof(post_data));
1324 U(pbindinfo->stgmedData).hGlobal = data;
1325 }else {
1326 IStream *post_stream;
1327 HGLOBAL data;
1328 HRESULT hres;
1329
1330 if(0) {
1331 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1332 data = GlobalAlloc(GPTR, sizeof(post_data));
1333 memcpy(data, post_data, sizeof(post_data));
1334 U(pbindinfo->stgmedData).hGlobal = data;
1335
1336 hres = CreateStreamOnHGlobal(data, FALSE, &post_stream);
1337 ok(hres == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hres);
1338
1339 U(pbindinfo->stgmedData).pstm =post_stream;/* &Stream; */
1340 }
1341 U(pbindinfo->stgmedData).pstm = &Stream;
1342 }
1343 }
1344
1345 return S_OK;
1346 }
1347
1348 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
1349 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1350 {
1351 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1352 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1353
1354 switch(ulStringType) {
1355 case BINDSTRING_ACCEPT_MIMES:
1356 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1357 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1358 if(pcElFetched) {
1359 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1360 *pcElFetched = 1;
1361 }
1362 if(ppwzStr) {
1363 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1364 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1365 }
1366 return S_OK;
1367 case BINDSTRING_USER_AGENT:
1368 CHECK_EXPECT(GetBindString_USER_AGENT);
1369 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1370 if(pcElFetched) {
1371 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1372 *pcElFetched = 1;
1373 }
1374 if(ppwzStr) {
1375 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1376 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1377 }
1378 return S_OK;
1379 case BINDSTRING_POST_COOKIE:
1380 CHECK_EXPECT(GetBindString_POST_COOKIE);
1381 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1382 if(pcElFetched)
1383 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1384 return S_OK;
1385 case BINDSTRING_URL: {
1386 DWORD size;
1387
1388 CHECK_EXPECT(GetBindString_URL);
1389 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1390 ok(*pcElFetched == 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched);
1391 *pcElFetched = 1;
1392
1393 size = (lstrlenW(binding_urls[tested_protocol])+1)*sizeof(WCHAR);
1394 *ppwzStr = CoTaskMemAlloc(size);
1395 memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1396 return S_OK;
1397 }
1398 case BINDSTRING_ROOTDOC_URL:
1399 CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1400 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1401 return E_NOTIMPL;
1402 default:
1403 ok(0, "unexpected ulStringType %d\n", ulStringType);
1404 }
1405
1406 return E_NOTIMPL;
1407 }
1408
1409 static IInternetBindInfoVtbl bind_info_vtbl = {
1410 BindInfo_QueryInterface,
1411 BindInfo_AddRef,
1412 BindInfo_Release,
1413 BindInfo_GetBindInfo,
1414 BindInfo_GetBindString
1415 };
1416
1417 static IInternetBindInfo bind_info = { &bind_info_vtbl };
1418
1419 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
1420 REFIID riid, void **ppv)
1421 {
1422 ok(0, "unexpected call\n");
1423 return E_NOINTERFACE;
1424 }
1425
1426 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
1427 {
1428 return 2;
1429 }
1430
1431 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
1432 {
1433 return 1;
1434 }
1435
1436 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
1437 {
1438 CHECK_EXPECT(SetPriority);
1439 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1440 return S_OK;
1441 }
1442
1443 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
1444 {
1445 ok(0, "unexpected call\n");
1446 return E_NOTIMPL;
1447 }
1448
1449
1450 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1451 InternetPriority_QueryInterface,
1452 InternetPriority_AddRef,
1453 InternetPriority_Release,
1454 InternetPriority_SetPriority,
1455 InternetPriority_GetPriority
1456 };
1457
1458 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
1459
1460 static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface)
1461 {
1462 return 2;
1463 }
1464
1465 static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
1466 {
1467 return 1;
1468 }
1469
1470 static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
1471 DWORD dwOptions)
1472 {
1473 HRESULT hres;
1474
1475 CHECK_EXPECT(Abort);
1476
1477 SET_EXPECT(ReportResult);
1478 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1479 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1480 CHECK_CALLED(ReportResult);
1481
1482 return S_OK;
1483 }
1484
1485 static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface)
1486 {
1487 ok(0, "unexpected call\n");
1488 return E_NOTIMPL;
1489 }
1490
1491 static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface)
1492 {
1493 ok(0, "unexpected call\n");
1494 return E_NOTIMPL;
1495 }
1496
1497 static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface,
1498 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1499 {
1500 ok(0, "unexpected call\n");
1501 return E_NOTIMPL;
1502 }
1503
1504 static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
1505 {
1506 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1507
1508 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
1509 *ppv = iface;
1510 return S_OK;
1511 }
1512
1513 if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
1514 if(impl_protex) {
1515 *ppv = iface;
1516 return S_OK;
1517 }
1518 *ppv = NULL;
1519 return E_NOINTERFACE;
1520 }
1521
1522 if(IsEqualGUID(&IID_IInternetPriority, riid)) {
1523 *ppv = &InternetPriority;
1524 return S_OK;
1525 }
1526
1527 if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
1528 CHECK_EXPECT(QueryInterface_IWinInetInfo);
1529 *ppv = NULL;
1530 return E_NOINTERFACE;
1531 }
1532
1533 if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
1534 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
1535 *ppv = NULL;
1536 return E_NOINTERFACE;
1537 }
1538
1539 if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */
1540 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1541 *ppv = NULL;
1542 return E_NOINTERFACE;
1543 }
1544
1545 static DWORD WINAPI thread_proc(PVOID arg)
1546 {
1547 HRESULT hres;
1548
1549 memset(&protocoldata, -1, sizeof(protocoldata));
1550
1551 prot_state = 0;
1552
1553 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1554 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1555 BINDSTATUS_FINDINGRESOURCE, hostW);
1556 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1557 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1558
1559 SET_EXPECT(ReportProgress_CONNECTING);
1560 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1561 BINDSTATUS_CONNECTING, winehq_ipW);
1562 CHECK_CALLED(ReportProgress_CONNECTING);
1563 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1564
1565 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1566 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1567 BINDSTATUS_SENDINGREQUEST, NULL);
1568 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1569 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1570
1571 prot_state = 1;
1572 SET_EXPECT(Switch);
1573 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1574 CHECK_CALLED(Switch);
1575 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1576
1577 if(!short_read) {
1578 prot_state = 2;
1579 if(mimefilter_test)
1580 SET_EXPECT(MimeFilter_Switch);
1581 else
1582 SET_EXPECT(Switch);
1583 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1584 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1585 if(mimefilter_test)
1586 CHECK_CALLED(MimeFilter_Switch);
1587 else
1588 CHECK_CALLED(Switch);
1589
1590 if(test_abort) {
1591 SetEvent(event_complete);
1592 return 0;
1593 }
1594
1595 prot_state = 2;
1596 if(mimefilter_test)
1597 SET_EXPECT(MimeFilter_Switch);
1598 else
1599 SET_EXPECT(Switch);
1600 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1601 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1602 if(mimefilter_test)
1603 CHECK_CALLED(MimeFilter_Switch);
1604 else
1605 CHECK_CALLED(Switch);
1606
1607 prot_state = 3;
1608 if(mimefilter_test)
1609 SET_EXPECT(MimeFilter_Switch);
1610 else
1611 SET_EXPECT(Switch);
1612 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1613 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1614 if(mimefilter_test)
1615 CHECK_CALLED(MimeFilter_Switch);
1616 else
1617 CHECK_CALLED(Switch);
1618 }
1619
1620 SetEvent(event_complete);
1621
1622 return 0;
1623 }
1624
1625 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1626 {
1627 BINDINFO bindinfo, exp_bindinfo;
1628 DWORD cbindf = 0;
1629 HRESULT hres;
1630
1631 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1632 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1633 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1634 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1635 ok(!pi, "pi = %x\n", pi);
1636
1637 if(binding_test)
1638 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1639
1640 memset(&bindinfo, 0, sizeof(bindinfo));
1641 bindinfo.cbSize = sizeof(bindinfo);
1642 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1643 SET_EXPECT(GetBindInfo);
1644 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1645 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1646 CHECK_CALLED(GetBindInfo);
1647 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1648 cbindf, (bindf|BINDF_FROMURLMON));
1649 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1650 pReleaseBindInfo(&bindinfo);
1651
1652 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1653 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1654 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1655 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1656
1657 if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
1658 IServiceProvider *service_provider;
1659 IHttpNegotiate *http_negotiate;
1660 IHttpNegotiate2 *http_negotiate2;
1661 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1662 LPWSTR additional_headers = NULL;
1663 BYTE sec_id[100];
1664 DWORD fetched = 0, size = 100;
1665 DWORD tid;
1666
1667 SET_EXPECT(GetBindString_USER_AGENT);
1668 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1669 &ua, 1, &fetched);
1670 CHECK_CALLED(GetBindString_USER_AGENT);
1671 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1672 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1673 ok(ua != NULL, "ua = %p\n", ua);
1674 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1675 CoTaskMemFree(ua);
1676
1677 fetched = 256;
1678 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1679 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1680 accept_mimes, 256, &fetched);
1681 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1682
1683 ok(hres == S_OK,
1684 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1685 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1686 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1687 CoTaskMemFree(accept_mimes[0]);
1688
1689 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1690 (void**)&service_provider);
1691 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1692
1693 SET_EXPECT(QueryService_HttpNegotiate);
1694 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1695 &IID_IHttpNegotiate, (void**)&http_negotiate);
1696 CHECK_CALLED(QueryService_HttpNegotiate);
1697 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1698
1699 SET_EXPECT(BeginningTransaction);
1700 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1701 NULL, 0, &additional_headers);
1702 CHECK_CALLED(BeginningTransaction);
1703 IHttpNegotiate_Release(http_negotiate);
1704 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1705 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1706
1707 SET_EXPECT(QueryService_HttpNegotiate);
1708 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1709 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1710 CHECK_CALLED(QueryService_HttpNegotiate);
1711 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1712
1713 size = 512;
1714 SET_EXPECT(GetRootSecurityId);
1715 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1716 CHECK_CALLED(GetRootSecurityId);
1717 IHttpNegotiate2_Release(http_negotiate2);
1718 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1719 ok(size == 13, "size=%d\n", size);
1720
1721 IServiceProvider_Release(service_provider);
1722
1723 CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1724 return;
1725 }
1726
1727 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1728 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1729 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1730 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1731 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1732
1733 if(mimefilter_test) {
1734 SET_EXPECT(MimeFilter_CreateInstance);
1735 SET_EXPECT(MimeFilter_Start);
1736 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1737 }
1738 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1739 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1740 mimefilter_test ? pjpegW : (expect_wsz = text_htmlW));
1741 ok(hres == S_OK,
1742 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1743 if(mimefilter_test) {
1744 CHECK_CALLED(MimeFilter_CreateInstance);
1745 CHECK_CALLED(MimeFilter_Start);
1746 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1747 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1748 }else {
1749 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1750 }
1751
1752 if(mimefilter_test)
1753 SET_EXPECT(MimeFilter_ReportData);
1754 else
1755 SET_EXPECT(ReportData);
1756 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1757 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1758 13, 13);
1759 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1760 if(mimefilter_test)
1761 CHECK_CALLED(MimeFilter_ReportData);
1762 else
1763 CHECK_CALLED(ReportData);
1764
1765 if(tested_protocol == ITS_TEST) {
1766 SET_EXPECT(ReportData);
1767 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1768 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1769 CHECK_CALLED(ReportData);
1770 }
1771
1772 if(tested_protocol == BIND_TEST) {
1773 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1774 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1775 }
1776
1777 if(mimefilter_test)
1778 SET_EXPECT(MimeFilter_ReportResult);
1779 else
1780 SET_EXPECT(ReportResult);
1781 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1782 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1783 if(mimefilter_test)
1784 CHECK_CALLED(MimeFilter_ReportResult);
1785 else
1786 CHECK_CALLED(ReportResult);
1787 }
1788
1789 static HRESULT WINAPI ProtocolEmul_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
1790 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1791 DWORD grfPI, HANDLE_PTR dwReserved)
1792 {
1793 CHECK_EXPECT(Start);
1794
1795 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1796 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1797 return S_OK;
1798 }
1799
1800 static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface,
1801 PROTOCOLDATA *pProtocolData)
1802 {
1803 DWORD bscf = 0, pr;
1804 HRESULT hres;
1805
1806 CHECK_EXPECT(Continue);
1807
1808 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1809 if(!pProtocolData || tested_protocol == BIND_TEST)
1810 return S_OK;
1811 if(binding_test) {
1812 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1813 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1814 pProtocolData->grfFlags, protocoldata.grfFlags );
1815 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1816 pProtocolData->dwState, protocoldata.dwState );
1817 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1818 pProtocolData->pData, protocoldata.pData );
1819 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1820 pProtocolData->cbData, protocoldata.cbData );
1821 }
1822
1823 switch(prot_state) {
1824 case 1: {
1825 IServiceProvider *service_provider;
1826 IHttpNegotiate *http_negotiate;
1827 static const WCHAR header[] = {'?',0};
1828
1829 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1830 (void**)&service_provider);
1831 ok(hres == S_OK, "Could not get IServiceProvicder\n");
1832
1833 SET_EXPECT(QueryService_HttpNegotiate);
1834 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1835 &IID_IHttpNegotiate, (void**)&http_negotiate);
1836 IServiceProvider_Release(service_provider);
1837 CHECK_CALLED(QueryService_HttpNegotiate);
1838 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1839
1840 SET_EXPECT(OnResponse);
1841 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1842 IHttpNegotiate_Release(http_negotiate);
1843 CHECK_CALLED(OnResponse);
1844 IHttpNegotiate_Release(http_negotiate);
1845 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1846
1847 if(mimefilter_test) {
1848 SET_EXPECT(MimeFilter_CreateInstance);
1849 SET_EXPECT(MimeFilter_Start);
1850 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1851 }else if(!(pi & PI_MIMEVERIFICATION)) {
1852 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1853 }
1854 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1855 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
1856 if(mimefilter_test) {
1857 CHECK_CALLED(MimeFilter_CreateInstance);
1858 CHECK_CALLED(MimeFilter_Start);
1859 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1860 }else if(!(pi & PI_MIMEVERIFICATION)) {
1861 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1862 }
1863 ok(hres == S_OK,
1864 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1865
1866 bscf |= BSCF_FIRSTDATANOTIFICATION;
1867 break;
1868 }
1869 case 2:
1870 case 3:
1871 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1872 break;
1873 }
1874
1875 pr = prot_read;
1876 if(mimefilter_test)
1877 SET_EXPECT(MimeFilter_ReportData);
1878 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
1879 if(pr < 200)
1880 SET_EXPECT(Read); /* checked in ReportData for short_read */
1881 if(pr == 200) {
1882 if(!mimefilter_test)
1883 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
1884 SET_EXPECT(GetBindInfo);
1885 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1886 }
1887 if(pr >= 200)
1888 SET_EXPECT(ReportData);
1889 }else {
1890 SET_EXPECT(ReportData);
1891 }
1892
1893 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
1894 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1895
1896 if(mimefilter_test) {
1897 SET_EXPECT(MimeFilter_ReportData);
1898 }else if(pi & PI_MIMEVERIFICATION) {
1899 if(!short_read && pr < 200)
1900 CHECK_CALLED(Read);
1901 if(pr == 200) {
1902 CLEAR_CALLED(GetBindInfo); /* IE9 */
1903 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1904 }
1905 }else {
1906 CHECK_CALLED(ReportData);
1907 }
1908
1909 if(prot_state == 3)
1910 prot_state = 4;
1911
1912 return S_OK;
1913 }
1914
1915 static HRESULT WINAPI ProtocolEmul_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
1916 {
1917 CHECK_EXPECT(Terminate);
1918 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
1919 return S_OK;
1920 }
1921
1922 static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv,
1923 ULONG cb, ULONG *pcbRead)
1924 {
1925 if(read_report_data)
1926 CHECK_EXPECT2(Read2);
1927
1928 if(mimefilter_test || short_read) {
1929 if(!read_report_data)
1930 CHECK_EXPECT2(Read);
1931 }else if((pi & PI_MIMEVERIFICATION)) {
1932 if(!read_report_data)
1933 CHECK_EXPECT2(Read);
1934
1935 if(prot_read < 300) {
1936 ok(pv != expect_pv, "pv == expect_pv\n");
1937 if(prot_read < 300)
1938 ok(cb == 2048-prot_read, "cb=%d\n", cb);
1939 else
1940 ok(cb == 700, "cb=%d\n", cb);
1941 }else {
1942 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
1943 }
1944 }else {
1945 if(!read_report_data)
1946 CHECK_EXPECT(Read);
1947
1948 ok(pv == expect_pv, "pv != expect_pv\n");
1949 ok(cb == 1000, "cb=%d\n", cb);
1950 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
1951 }
1952 ok(pcbRead != NULL, "pcbRead == NULL\n");
1953
1954 if(prot_state == 3 || (short_read && prot_state != 4)) {
1955 HRESULT hres;
1956
1957 prot_state = 4;
1958 if(short_read) {
1959 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
1960 SET_EXPECT(GetBindInfo);
1961 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1962 }
1963 if(mimefilter_test)
1964 SET_EXPECT(MimeFilter_ReportData);
1965 else if(direct_read)
1966 SET_EXPECT(ReportData2);
1967 read_report_data++;
1968 hres = IInternetProtocolSink_ReportData(binding_sink,
1969 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
1970 read_report_data--;
1971 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1972 if(short_read) {
1973 CLEAR_CALLED(GetBindInfo); /* IE9 */
1974 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1975 }
1976 if(mimefilter_test)
1977 CHECK_CALLED(MimeFilter_ReportData);
1978 else if(direct_read)
1979 CHECK_CALLED(ReportData2);
1980
1981 if(mimefilter_test)
1982 SET_EXPECT(MimeFilter_ReportResult);
1983 else
1984 SET_EXPECT(ReportResult);
1985 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1986 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1987 if(mimefilter_test)
1988 CHECK_CALLED(MimeFilter_ReportResult);
1989 else
1990 CHECK_CALLED(ReportResult);
1991
1992 if(cb > 100)
1993 cb = 100;
1994 memset(pv, 'x', cb);
1995 if(cb>6)
1996 memcpy(pv, "gif87a", 6);
1997 prot_read += *pcbRead = cb;
1998 return S_OK;
1999 }
2000
2001 if(prot_state == 4) {
2002 *pcbRead = 0;
2003 return S_FALSE;
2004 }
2005
2006 if((async_read_pending = !async_read_pending)) {
2007 *pcbRead = 0;
2008 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
2009 }
2010
2011 if(cb > 100)
2012 cb = 100;
2013 memset(pv, 'x', cb);
2014 if(cb>6)
2015 memcpy(pv, "gif87a", 6);
2016 prot_read += *pcbRead = cb;
2017 return S_OK;
2018 }
2019
2020 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2021 {
2022 CHECK_EXPECT(LockRequest);
2023 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2024 return S_OK;
2025 }
2026
2027 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2028 {
2029 CHECK_EXPECT(UnlockRequest);
2030 return S_OK;
2031 }
2032
2033 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2034 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2035 DWORD grfPI, HANDLE *dwReserved)
2036 {
2037 CHECK_EXPECT(StartEx);
2038 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2039 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2040 return S_OK;
2041 }
2042
2043 static const IInternetProtocolExVtbl ProtocolVtbl = {
2044 ProtocolEmul_QueryInterface,
2045 Protocol_AddRef,
2046 Protocol_Release,
2047 ProtocolEmul_Start,
2048 ProtocolEmul_Continue,
2049 Protocol_Abort,
2050 ProtocolEmul_Terminate,
2051 Protocol_Suspend,
2052 Protocol_Resume,
2053 ProtocolEmul_Read,
2054 Protocol_Seek,
2055 ProtocolEmul_LockRequest,
2056 ProtocolEmul_UnlockRequest,
2057 ProtocolEmul_StartEx
2058 };
2059
2060 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2061
2062 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2063 {
2064 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2065 *ppv = iface;
2066 return S_OK;
2067 }
2068
2069 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2070 *ppv = &mime_protocol_sink;
2071 return S_OK;
2072 }
2073
2074 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2075 *ppv = NULL;
2076 return E_NOINTERFACE;
2077 }
2078
2079 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2080 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2081 DWORD grfPI, HANDLE_PTR dwReserved)
2082 {
2083 PROTOCOLFILTERDATA *data;
2084 LPOLESTR url_str = NULL;
2085 DWORD fetched = 0;
2086 BINDINFO bindinfo;
2087 DWORD cbindf = 0;
2088 HRESULT hres;
2089
2090 CHECK_EXPECT(MimeFilter_Start);
2091
2092 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2093 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2094 ok(dwReserved, "dwReserved == 0\n");
2095 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2096 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2097
2098 if(binding_test) {
2099 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2100 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2101 }else {
2102 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2103 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2104 }
2105
2106 data = (void*)dwReserved;
2107 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2108 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2109 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2110 ok(!data->pUnk, "data->pUnk != NULL\n");
2111 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2112 if(binding_test) {
2113 IInternetProtocolSink *prot_sink;
2114
2115 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2116 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2117 IInternetProtocolSink_Release(prot_sink);
2118
2119 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2120
2121 filtered_protocol = data->pProtocol;
2122 IInternetProtocol_AddRef(filtered_protocol);
2123 }else {
2124 IInternetProtocol *prot;
2125
2126 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2127 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2128 IInternetProtocol_Release(prot);
2129
2130 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2131 }
2132
2133 filtered_sink = pOIProtSink;
2134
2135 SET_EXPECT(ReportProgress_DECODING);
2136 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2137 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2138 CHECK_CALLED(ReportProgress_DECODING);
2139
2140 SET_EXPECT(GetBindInfo);
2141 memset(&bindinfo, 0, sizeof(bindinfo));
2142 bindinfo.cbSize = sizeof(bindinfo);
2143 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2144 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2145 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2146 CHECK_CALLED(GetBindInfo);
2147
2148 SET_EXPECT(GetBindString_URL);
2149 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2150 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2151 ok(fetched == 1, "fetched = %d\n", fetched);
2152 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2153 CoTaskMemFree(url_str);
2154 CHECK_CALLED(GetBindString_URL);
2155
2156 return S_OK;
2157 }
2158
2159 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2160 PROTOCOLDATA *pProtocolData)
2161 {
2162 CHECK_EXPECT(MimeFilter_Continue);
2163 return E_NOTIMPL;
2164 }
2165
2166 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2167 {
2168 HRESULT hres;
2169
2170 CHECK_EXPECT(MimeFilter_Terminate);
2171
2172 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2173
2174 SET_EXPECT(Terminate);
2175 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2176 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2177 CHECK_CALLED(Terminate);
2178
2179 return S_OK;
2180 }
2181
2182 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2183 ULONG cb, ULONG *pcbRead)
2184 {
2185 BYTE buf[2096];
2186 DWORD read = 0;
2187 HRESULT hres;
2188
2189 CHECK_EXPECT(MimeFilter_Read);
2190
2191 ok(pv != NULL, "pv == NULL\n");
2192 ok(cb != 0, "cb == 0\n");
2193 ok(pcbRead != NULL, "pcbRead == NULL\n");
2194
2195 if(read_report_data)
2196 SET_EXPECT(Read2);
2197 else
2198 SET_EXPECT(Read);
2199 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2200 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2201 if(read_report_data)
2202 CHECK_CALLED(Read2);
2203 else
2204 CHECK_CALLED(Read);
2205
2206 if(pcbRead) {
2207 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2208 *pcbRead = read;
2209 }
2210
2211 memset(pv, 'x', read);
2212 return hres;
2213 }
2214
2215 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2216 {
2217 HRESULT hres;
2218
2219 CHECK_EXPECT(MimeFilter_LockRequest);
2220
2221 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2222
2223 SET_EXPECT(LockRequest);
2224 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2225 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2226 CHECK_CALLED(LockRequest);
2227
2228 return S_OK;
2229 }
2230
2231 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2232 {
2233 HRESULT hres;
2234
2235 CHECK_EXPECT(MimeFilter_UnlockRequest);
2236
2237 SET_EXPECT(UnlockRequest);
2238 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2239 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2240 CHECK_CALLED(UnlockRequest);
2241
2242 return S_OK;
2243 }
2244
2245 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2246 MimeProtocol_QueryInterface,
2247 Protocol_AddRef,
2248 Protocol_Release,
2249 MimeProtocol_Start,
2250 Protocol_Continue,
2251 Protocol_Abort,
2252 MimeProtocol_Terminate,
2253 Protocol_Suspend,
2254 Protocol_Resume,
2255 MimeProtocol_Read,
2256 Protocol_Seek,
2257 MimeProtocol_LockRequest,
2258 MimeProtocol_UnlockRequest
2259 };
2260
2261 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2262
2263 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2264 {
2265 ok(0, "unexpected call\n");
2266 return E_NOINTERFACE;
2267 }
2268
2269 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2270 {
2271 return 2;
2272 }
2273
2274 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2275 {
2276 return 1;
2277 }
2278
2279 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2280 REFIID riid, void **ppv)
2281 {
2282 CHECK_EXPECT(CreateInstance);
2283
2284 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2285 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2286 ok(ppv != NULL, "ppv == NULL\n");
2287
2288 *ppv = &Protocol;
2289 return S_OK;
2290 }
2291
2292 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2293 {
2294 ok(0, "unexpected call\n");
2295 return S_OK;
2296 }
2297
2298 static const IClassFactoryVtbl ClassFactoryVtbl = {
2299 ClassFactory_QueryInterface,
2300 ClassFactory_AddRef,
2301 ClassFactory_Release,
2302 ClassFactory_CreateInstance,
2303 ClassFactory_LockServer
2304 };
2305
2306 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2307
2308 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2309 {
2310 CHECK_EXPECT(MimeFilter_CreateInstance);
2311
2312 ok(!outer, "outer = %p\n", outer);
2313 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2314
2315 *ppv = &MimeProtocol;
2316 return S_OK;
2317 }
2318
2319 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2320 ClassFactory_QueryInterface,
2321 ClassFactory_AddRef,
2322 ClassFactory_Release,
2323 MimeFilter_CreateInstance,
2324 ClassFactory_LockServer
2325 };
2326
2327 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2328
2329 #define TEST_BINDING 0x0001
2330 #define TEST_FILTER 0x0002
2331 #define TEST_FIRST_HTTP 0x0004
2332 #define TEST_DIRECT_READ 0x0008
2333 #define TEST_POST 0x0010
2334 #define TEST_EMULATEPROT 0x0020
2335 #define TEST_SHORT_READ 0x0040
2336 #define TEST_REDIRECT 0x0080
2337 #define TEST_ABORT 0x0100
2338 #define TEST_ASYNCREQ 0x0200
2339 #define TEST_USEIURI 0x0400
2340 #define TEST_IMPLPROTEX 0x0800
2341 #define TEST_EMPTY 0x1000
2342 #define TEST_NOMIME 0x2000
2343 #define TEST_FROMCACHE 0x4000
2344
2345 static void register_filter(BOOL do_register)
2346 {
2347 IInternetSession *session;
2348 HRESULT hres;
2349
2350 hres = pCoInternetGetSession(0, &session, 0);
2351 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2352
2353 if(do_register) {
2354 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2355 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2356 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2357 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2358 }else {
2359 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2360 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2361 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2362 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2363 }
2364
2365 IInternetSession_Release(session);
2366 }
2367
2368 static void init_test(int prot, DWORD flags)
2369 {
2370 tested_protocol = prot;
2371 binding_test = (flags & TEST_BINDING) != 0;
2372 first_data_notif = TRUE;
2373 prot_read = 0;
2374 prot_state = 0;
2375 async_read_pending = TRUE;
2376 mimefilter_test = (flags & TEST_FILTER) != 0;
2377 no_mime = (flags & TEST_NOMIME) != 0;
2378 filter_state = 0;
2379 post_stream_read = 0;
2380 ResetEvent(event_complete);
2381 ResetEvent(event_complete2);
2382 ResetEvent(event_continue);
2383 ResetEvent(event_continue_done);
2384 async_protocol = binding_protocol = filtered_protocol = NULL;
2385 filtered_sink = NULL;
2386 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2387 first_data_notif = TRUE;
2388 state = STATE_CONNECTING;
2389 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2390 direct_read = (flags & TEST_DIRECT_READ) != 0;
2391 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2392 wait_for_switch = TRUE;
2393 short_read = (flags & TEST_SHORT_READ) != 0;
2394 http_post_test = TYMED_NULL;
2395 test_redirect = (flags & TEST_REDIRECT) != 0;
2396 test_abort = (flags & TEST_ABORT) != 0;
2397 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2398 empty_file = (flags & TEST_EMPTY) != 0;
2399 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2400
2401 register_filter(mimefilter_test);
2402 }
2403
2404 static void test_priority(IInternetProtocol *protocol)
2405 {
2406 IInternetPriority *priority;
2407 LONG pr;
2408 HRESULT hres;
2409
2410 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2411 (void**)&priority);
2412 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2413 if(FAILED(hres))
2414 return;
2415
2416 hres = IInternetPriority_GetPriority(priority, &pr);
2417 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2418 ok(pr == 0, "pr=%d, expected 0\n", pr);
2419
2420 hres = IInternetPriority_SetPriority(priority, 1);
2421 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2422
2423 hres = IInternetPriority_GetPriority(priority, &pr);
2424 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2425 ok(pr == 1, "pr=%d, expected 1\n", pr);
2426
2427 IInternetPriority_Release(priority);
2428 }
2429
2430 static void test_early_abort(const CLSID *clsid)
2431 {
2432 IInternetProtocol *protocol;
2433 HRESULT hres;
2434
2435 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2436 &IID_IInternetProtocol, (void**)&protocol);
2437 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2438
2439 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2440 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2441
2442 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2443 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2444
2445 IInternetProtocol_Release(protocol);
2446 }
2447
2448 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2449 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2450 {
2451 HRESULT hres;
2452
2453 SET_EXPECT(GetBindInfo);
2454 if(!(bindf & BINDF_FROMURLMON))
2455 SET_EXPECT(ReportProgress_DIRECTBIND);
2456 if(is_first) {
2457 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2458 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2459 if(bindf & BINDF_FROMURLMON)
2460 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2461 else
2462 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2463 }
2464 SET_EXPECT(ReportData);
2465 if(is_first)
2466 SET_EXPECT(ReportResult);
2467
2468 expect_hrResult = S_OK;
2469
2470 if(protocolex) {
2471 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2472 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2473 }else {
2474 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2475 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2476 win_skip("Start failed\n");
2477 return FALSE;
2478 }
2479 ok(hres == S_OK, "Start failed: %08x\n", hres);
2480 }
2481
2482 CHECK_CALLED(GetBindInfo);
2483 if(!(bindf & BINDF_FROMURLMON))
2484 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2485 if(is_first) {
2486 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2487 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2488 if(bindf & BINDF_FROMURLMON)
2489 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2490 else
2491 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2492 }
2493 CHECK_CALLED(ReportData);
2494 if(is_first)
2495 CHECK_CALLED(ReportResult);
2496
2497 return TRUE;
2498 }
2499
2500 static void test_file_protocol_url(LPCWSTR url)
2501 {
2502 IInternetProtocolInfo *protocol_info;
2503 IUnknown *unk;
2504 IClassFactory *factory;
2505 IInternetProtocol *protocol;
2506 BYTE buf[512];
2507 ULONG cb;
2508 HRESULT hres;
2509
2510 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2511 &IID_IUnknown, (void**)&unk);
2512 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2513 if(FAILED(hres))
2514 return;
2515
2516 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2517 ok(hres == E_NOINTERFACE,
2518 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2519
2520 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2521 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2522 IUnknown_Release(unk);
2523 if(FAILED(hres))
2524 return;
2525
2526 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2527 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2528
2529 if(SUCCEEDED(hres)) {
2530 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2531 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2532 ok(hres == S_OK, "Read failed: %08x\n", hres);
2533 ok(cb == 2, "cb=%u expected 2\n", cb);
2534 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2535 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2536 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2537 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2538 ok(cb == 0, "cb=%u expected 0\n", cb);
2539 hres = IInternetProtocol_UnlockRequest(protocol);
2540 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2541 }
2542
2543 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2544 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2545 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2546 hres = IInternetProtocol_LockRequest(protocol, 0);
2547 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2548 hres = IInternetProtocol_UnlockRequest(protocol);
2549 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2550 }
2551
2552 IInternetProtocol_Release(protocol);
2553 }
2554
2555 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2556 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2557 if(SUCCEEDED(hres)) {
2558 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2559 hres = IInternetProtocol_LockRequest(protocol, 0);
2560 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2561 hres = IInternetProtocol_Terminate(protocol, 0);
2562 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2563 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2564 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2565 hres = IInternetProtocol_UnlockRequest(protocol);
2566 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2567 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2568 ok(hres == S_OK, "Read failed: %08x\n", hres);
2569 hres = IInternetProtocol_Terminate(protocol, 0);
2570 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2571 }
2572
2573 IInternetProtocol_Release(protocol);
2574 }
2575
2576 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2577 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2578 if(SUCCEEDED(hres)) {
2579 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2580 hres = IInternetProtocol_Terminate(protocol, 0);
2581 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2582 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2583 ok(hres == S_OK, "Read failed: %08x\n", hres);
2584 ok(cb == 2, "cb=%u expected 2\n", cb);
2585 }
2586
2587 IInternetProtocol_Release(protocol);
2588 }
2589
2590 if(pCreateUri) {
2591 IInternetProtocolEx *protocolex;
2592 IUri *uri;
2593
2594 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2595 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2596
2597 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2598 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2599
2600 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2601 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2602 ok(hres == S_OK, "Read failed: %08x\n", hres);
2603 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2604 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2605 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2606 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2607 }
2608
2609 IUri_Release(uri);
2610 IInternetProtocolEx_Release(protocolex);
2611
2612 hres = pCreateUri(url, 0, 0, &uri);
2613 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2614
2615 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2616 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2617
2618 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2619 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2620 ok(hres == S_OK, "Read failed: %08x\n", hres);
2621 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2622 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2623 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2624 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2625 }
2626
2627 IUri_Release(uri);
2628 IInternetProtocolEx_Release(protocolex);
2629 }else {
2630 win_skip("Skipping file protocol StartEx tests\n");
2631 }
2632
2633 IClassFactory_Release(factory);
2634 }
2635
2636 static void test_file_protocol_fail(void)
2637 {
2638 IInternetProtocol *protocol;
2639 HRESULT hres;
2640
2641 static const WCHAR index_url2[] =
2642 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2643
2644 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2645 &IID_IInternetProtocol, (void**)&protocol);
2646 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2647 if(FAILED(hres))
2648 return;
2649
2650 SET_EXPECT(GetBindInfo);
2651 expect_hrResult = MK_E_SYNTAX;
2652 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2653 ok(hres == MK_E_SYNTAX ||
2654 hres == E_INVALIDARG,
2655 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2656 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2657
2658 SET_EXPECT(GetBindInfo);
2659 if(!(bindf & BINDF_FROMURLMON))
2660 SET_EXPECT(ReportProgress_DIRECTBIND);
2661 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2662 SET_EXPECT(ReportResult);
2663 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2664 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2665 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2666 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2667 CHECK_CALLED(GetBindInfo);
2668 if(!(bindf & BINDF_FROMURLMON))
2669 CHECK_CALLED(ReportProgress_DIRECTBIND);
2670 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2671 CHECK_CALLED(ReportResult);
2672
2673 IInternetProtocol_Release(protocol);
2674
2675 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2676 &IID_IInternetProtocol, (void**)&protocol);
2677 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2678 if(FAILED(hres))
2679 return;
2680
2681 SET_EXPECT(GetBindInfo);
2682 if(!(bindf & BINDF_FROMURLMON))
2683 SET_EXPECT(ReportProgress_DIRECTBIND);
2684 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2685 SET_EXPECT(ReportResult);
2686 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2687
2688 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2689 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2690 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2691 CHECK_CALLED(GetBindInfo);
2692 if(!(bindf & BINDF_FROMURLMON))
2693 CHECK_CALLED(ReportProgress_DIRECTBIND);
2694 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2695 CHECK_CALLED(ReportResult);
2696
2697 SET_EXPECT(GetBindInfo);
2698 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2699 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2700 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2701
2702 SET_EXPECT(GetBindInfo);
2703 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2704 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2705 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2706
2707 IInternetProtocol_Release(protocol);
2708 }
2709
2710 static void test_file_protocol(void) {
2711 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2712 DWORD size;
2713 ULONG len;
2714 HANDLE file;
2715
2716 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2717 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2718 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2719 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2720 static const char html_doc[] = "<HTML></HTML>";
2721
2722 trace("Testing file protocol...\n");
2723 init_test(FILE_TEST, 0);
2724
2725 SetLastError(0xdeadbeef);
2726 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2727 FILE_ATTRIBUTE_NORMAL, NULL);
2728 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2729 if(file == INVALID_HANDLE_VALUE)
2730 return;
2731 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2732 CloseHandle(file);
2733
2734 file_name = wszIndexHtml;
2735 bindf = 0;
2736 test_file_protocol_url(index_url);
2737 bindf = BINDF_FROMURLMON;
2738 test_file_protocol_url(index_url);
2739 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2740 test_file_protocol_url(index_url);
2741
2742 memcpy(buf, wszFile, sizeof(wszFile));
2743 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2744 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2745 buf[len++] = '\\';
2746 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2747
2748 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2749 bindf = 0;
2750 test_file_protocol_url(buf);
2751 bindf = BINDF_FROMURLMON;
2752 test_file_protocol_url(buf);
2753
2754 memcpy(buf, wszFile2, sizeof(wszFile2));
2755 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2756 file_name_buf[len++] = '\\';
2757 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2758 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2759 file_name = file_name_buf;
2760 bindf = 0;
2761 test_file_protocol_url(buf);
2762 bindf = BINDF_FROMURLMON;
2763 test_file_protocol_url(buf);
2764
2765 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2766 test_file_protocol_url(buf);
2767
2768 memcpy(buf, wszFile3, sizeof(wszFile3));
2769 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2770 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2771 buf[len++] = '\\';
2772 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2773
2774 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2775 bindf = 0;
2776 test_file_protocol_url(buf);
2777 bindf = BINDF_FROMURLMON;
2778 test_file_protocol_url(buf);
2779
2780 memcpy(buf, wszFile4, sizeof(wszFile4));
2781 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2782 file_name_buf[len++] = '\\';
2783 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2784 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2785 file_name = file_name_buf;
2786 bindf = 0;
2787 test_file_protocol_url(buf);
2788 bindf = BINDF_FROMURLMON;
2789 test_file_protocol_url(buf);
2790
2791 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2792 test_file_protocol_url(buf);
2793
2794 DeleteFileW(wszIndexHtml);
2795
2796 bindf = 0;
2797 test_file_protocol_fail();
2798 bindf = BINDF_FROMURLMON;
2799 test_file_protocol_fail();
2800 }
2801
2802 static void create_cache_entry(const WCHAR *urlw)
2803 {
2804 FILETIME now, tomorrow, yesterday;
2805 char file_path[MAX_PATH];
2806 BYTE content[1000];
2807 ULARGE_INTEGER li;
2808 const char *url;
2809 HANDLE file;
2810 DWORD size;
2811 unsigned i;
2812 BOOL res;
2813
2814 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2815
2816 trace("Testing cache read...\n");
2817
2818 url = w2a(urlw);
2819
2820 for(i = 0; i < sizeof(content); i++)
2821 content[i] = '0' + (i%10);
2822
2823 GetSystemTimeAsFileTime(&now);
2824 li.u.HighPart = now.dwHighDateTime;
2825 li.u.LowPart = now.dwLowDateTime;
2826 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2827 tomorrow.dwHighDateTime = li.u.HighPart;
2828 tomorrow.dwLowDateTime = li.u.LowPart;
2829 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2830 yesterday.dwHighDateTime = li.u.HighPart;
2831 yesterday.dwLowDateTime = li.u.LowPart;
2832
2833 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2834 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2835
2836 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2837 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2838
2839 WriteFile(file, content, sizeof(content), &size, NULL);
2840 CloseHandle(file);
2841
2842 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2843 cache_headers, sizeof(cache_headers)-1, "", 0);
2844 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2845 }
2846
2847 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2848 {
2849 static BOOL got_user_agent = FALSE;
2850 IUri *uri = NULL;
2851 HRESULT hres;
2852
2853 if(use_iuri && pCreateUri) {
2854 hres = pCreateUri(url, 0, 0, &uri);
2855 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2856 }
2857
2858 SET_EXPECT(GetBindInfo);
2859 if (!(bindf & BINDF_FROMURLMON))
2860 SET_EXPECT(ReportProgress_DIRECTBIND);
2861 if(!got_user_agent)
2862 SET_EXPECT(GetBindString_USER_AGENT);
2863 SET_EXPECT(GetBindString_ROOTDOC_URL);
2864 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2865 SET_EXPECT(QueryService_HttpNegotiate);
2866 SET_EXPECT(BeginningTransaction);
2867 SET_EXPECT(GetRootSecurityId);
2868 if(http_post_test) {
2869 SET_EXPECT(GetBindString_POST_COOKIE);
2870 if(http_post_test == TYMED_ISTREAM)
2871 SET_EXPECT(Stream_Seek);
2872 }
2873 if(bind_from_cache) {
2874 SET_EXPECT(OnResponse);
2875 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2876 SET_EXPECT(ReportData);
2877 }
2878
2879 if(uri) {
2880 IInternetProtocolEx *protocolex;
2881
2882 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2883 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2884
2885 hres = IInternetProtocolEx_StartEx(protocolex, uri