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