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