[URLMON_WINETEST] Sync with Wine Staging 3.3. CORE-14434
[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);