30fa046c67a1bd318e610c3e606d172c5ebaea18
[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 }if(prot_state == 4) {
2000 *pcbRead = 0;
2001 return S_FALSE;
2002 }
2003
2004 if((async_read_pending = !async_read_pending)) {
2005 *pcbRead = 0;
2006 return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE;
2007 }
2008
2009 if(cb > 100)
2010 cb = 100;
2011 memset(pv, 'x', cb);
2012 if(cb>6)
2013 memcpy(pv, "gif87a", 6);
2014 prot_read += *pcbRead = cb;
2015 return S_OK;
2016 }
2017
2018 static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2019 {
2020 CHECK_EXPECT(LockRequest);
2021 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2022 return S_OK;
2023 }
2024
2025 static HRESULT WINAPI ProtocolEmul_UnlockRequest(IInternetProtocolEx *iface)
2026 {
2027 CHECK_EXPECT(UnlockRequest);
2028 return S_OK;
2029 }
2030
2031 static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUri,
2032 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2033 DWORD grfPI, HANDLE *dwReserved)
2034 {
2035 CHECK_EXPECT(StartEx);
2036 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2037 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2038 return S_OK;
2039 }
2040
2041 static const IInternetProtocolExVtbl ProtocolVtbl = {
2042 ProtocolEmul_QueryInterface,
2043 Protocol_AddRef,
2044 Protocol_Release,
2045 ProtocolEmul_Start,
2046 ProtocolEmul_Continue,
2047 Protocol_Abort,
2048 ProtocolEmul_Terminate,
2049 Protocol_Suspend,
2050 Protocol_Resume,
2051 ProtocolEmul_Read,
2052 Protocol_Seek,
2053 ProtocolEmul_LockRequest,
2054 ProtocolEmul_UnlockRequest,
2055 ProtocolEmul_StartEx
2056 };
2057
2058 static IInternetProtocolEx Protocol = { &ProtocolVtbl };
2059
2060 static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
2061 {
2062 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2063 *ppv = iface;
2064 return S_OK;
2065 }
2066
2067 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2068 *ppv = &mime_protocol_sink;
2069 return S_OK;
2070 }
2071
2072 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2073 *ppv = NULL;
2074 return E_NOINTERFACE;
2075 }
2076
2077 static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
2078 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2079 DWORD grfPI, HANDLE_PTR dwReserved)
2080 {
2081 PROTOCOLFILTERDATA *data;
2082 LPOLESTR url_str = NULL;
2083 DWORD fetched = 0;
2084 BINDINFO bindinfo;
2085 DWORD cbindf = 0;
2086 HRESULT hres;
2087
2088 CHECK_EXPECT(MimeFilter_Start);
2089
2090 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2091 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2092 ok(dwReserved, "dwReserved == 0\n");
2093 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2094 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2095
2096 if(binding_test) {
2097 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2098 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2099 }else {
2100 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2101 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2102 }
2103
2104 data = (void*)dwReserved;
2105 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2106 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2107 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2108 ok(!data->pUnk, "data->pUnk != NULL\n");
2109 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2110 if(binding_test) {
2111 IInternetProtocolSink *prot_sink;
2112
2113 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2114 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2115 IInternetProtocolSink_Release(prot_sink);
2116
2117 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2118
2119 filtered_protocol = data->pProtocol;
2120 IInternetProtocol_AddRef(filtered_protocol);
2121 }else {
2122 IInternetProtocol *prot;
2123
2124 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2125 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2126 IInternetProtocol_Release(prot);
2127
2128 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2129 }
2130
2131 filtered_sink = pOIProtSink;
2132
2133 SET_EXPECT(ReportProgress_DECODING);
2134 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2135 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2136 CHECK_CALLED(ReportProgress_DECODING);
2137
2138 SET_EXPECT(GetBindInfo);
2139 memset(&bindinfo, 0, sizeof(bindinfo));
2140 bindinfo.cbSize = sizeof(bindinfo);
2141 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2142 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2143 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2144 CHECK_CALLED(GetBindInfo);
2145
2146 SET_EXPECT(GetBindString_URL);
2147 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2148 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2149 ok(fetched == 1, "fetched = %d\n", fetched);
2150 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2151 CoTaskMemFree(url_str);
2152 CHECK_CALLED(GetBindString_URL);
2153
2154 return S_OK;
2155 }
2156
2157 static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface,
2158 PROTOCOLDATA *pProtocolData)
2159 {
2160 CHECK_EXPECT(MimeFilter_Continue);
2161 return E_NOTIMPL;
2162 }
2163
2164 static HRESULT WINAPI MimeProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
2165 {
2166 HRESULT hres;
2167
2168 CHECK_EXPECT(MimeFilter_Terminate);
2169
2170 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2171
2172 SET_EXPECT(Terminate);
2173 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2174 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2175 CHECK_CALLED(Terminate);
2176
2177 return S_OK;
2178 }
2179
2180 static HRESULT WINAPI MimeProtocol_Read(IInternetProtocolEx *iface, void *pv,
2181 ULONG cb, ULONG *pcbRead)
2182 {
2183 BYTE buf[2096];
2184 DWORD read = 0;
2185 HRESULT hres;
2186
2187 CHECK_EXPECT(MimeFilter_Read);
2188
2189 ok(pv != NULL, "pv == NULL\n");
2190 ok(cb != 0, "cb == 0\n");
2191 ok(pcbRead != NULL, "pcbRead == NULL\n");
2192
2193 if(read_report_data)
2194 SET_EXPECT(Read2);
2195 else
2196 SET_EXPECT(Read);
2197 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2198 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2199 if(read_report_data)
2200 CHECK_CALLED(Read2);
2201 else
2202 CHECK_CALLED(Read);
2203
2204 if(pcbRead) {
2205 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2206 *pcbRead = read;
2207 }
2208
2209 memset(pv, 'x', read);
2210 return hres;
2211 }
2212
2213 static HRESULT WINAPI MimeProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
2214 {
2215 HRESULT hres;
2216
2217 CHECK_EXPECT(MimeFilter_LockRequest);
2218
2219 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2220
2221 SET_EXPECT(LockRequest);
2222 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2223 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2224 CHECK_CALLED(LockRequest);
2225
2226 return S_OK;
2227 }
2228
2229 static HRESULT WINAPI MimeProtocol_UnlockRequest(IInternetProtocolEx *iface)
2230 {
2231 HRESULT hres;
2232
2233 CHECK_EXPECT(MimeFilter_UnlockRequest);
2234
2235 SET_EXPECT(UnlockRequest);
2236 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2237 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2238 CHECK_CALLED(UnlockRequest);
2239
2240 return S_OK;
2241 }
2242
2243 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2244 MimeProtocol_QueryInterface,
2245 Protocol_AddRef,
2246 Protocol_Release,
2247 MimeProtocol_Start,
2248 Protocol_Continue,
2249 Protocol_Abort,
2250 MimeProtocol_Terminate,
2251 Protocol_Suspend,
2252 Protocol_Resume,
2253 MimeProtocol_Read,
2254 Protocol_Seek,
2255 MimeProtocol_LockRequest,
2256 MimeProtocol_UnlockRequest
2257 };
2258
2259 static IInternetProtocolEx MimeProtocol = { &MimeProtocolVtbl };
2260
2261 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2262 {
2263 ok(0, "unexpected call\n");
2264 return E_NOINTERFACE;
2265 }
2266
2267 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2268 {
2269 return 2;
2270 }
2271
2272 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2273 {
2274 return 1;
2275 }
2276
2277 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
2278 REFIID riid, void **ppv)
2279 {
2280 CHECK_EXPECT(CreateInstance);
2281
2282 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2283 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2284 ok(ppv != NULL, "ppv == NULL\n");
2285
2286 *ppv = &Protocol;
2287 return S_OK;
2288 }
2289
2290 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2291 {
2292 ok(0, "unexpected call\n");
2293 return S_OK;
2294 }
2295
2296 static const IClassFactoryVtbl ClassFactoryVtbl = {
2297 ClassFactory_QueryInterface,
2298 ClassFactory_AddRef,
2299 ClassFactory_Release,
2300 ClassFactory_CreateInstance,
2301 ClassFactory_LockServer
2302 };
2303
2304 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
2305
2306 static HRESULT WINAPI MimeFilter_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2307 {
2308 CHECK_EXPECT(MimeFilter_CreateInstance);
2309
2310 ok(!outer, "outer = %p\n", outer);
2311 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2312
2313 *ppv = &MimeProtocol;
2314 return S_OK;
2315 }
2316
2317 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2318 ClassFactory_QueryInterface,
2319 ClassFactory_AddRef,
2320 ClassFactory_Release,
2321 MimeFilter_CreateInstance,
2322 ClassFactory_LockServer
2323 };
2324
2325 static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
2326
2327 #define TEST_BINDING 0x0001
2328 #define TEST_FILTER 0x0002
2329 #define TEST_FIRST_HTTP 0x0004
2330 #define TEST_DIRECT_READ 0x0008
2331 #define TEST_POST 0x0010
2332 #define TEST_EMULATEPROT 0x0020
2333 #define TEST_SHORT_READ 0x0040
2334 #define TEST_REDIRECT 0x0080
2335 #define TEST_ABORT 0x0100
2336 #define TEST_ASYNCREQ 0x0200
2337 #define TEST_USEIURI 0x0400
2338 #define TEST_IMPLPROTEX 0x0800
2339 #define TEST_EMPTY 0x1000
2340 #define TEST_NOMIME 0x2000
2341 #define TEST_FROMCACHE 0x4000
2342
2343 static void register_filter(BOOL do_register)
2344 {
2345 IInternetSession *session;
2346 HRESULT hres;
2347
2348 hres = pCoInternetGetSession(0, &session, 0);
2349 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2350
2351 if(do_register) {
2352 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2353 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2354 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2355 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2356 }else {
2357 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2358 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2359 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2360 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2361 }
2362
2363 IInternetSession_Release(session);
2364 }
2365
2366 static void init_test(int prot, DWORD flags)
2367 {
2368 tested_protocol = prot;
2369 binding_test = (flags & TEST_BINDING) != 0;
2370 first_data_notif = TRUE;
2371 prot_read = 0;
2372 prot_state = 0;
2373 async_read_pending = TRUE;
2374 mimefilter_test = (flags & TEST_FILTER) != 0;
2375 no_mime = (flags & TEST_NOMIME) != 0;
2376 filter_state = 0;
2377 post_stream_read = 0;
2378 ResetEvent(event_complete);
2379 ResetEvent(event_complete2);
2380 ResetEvent(event_continue);
2381 ResetEvent(event_continue_done);
2382 async_protocol = binding_protocol = filtered_protocol = NULL;
2383 filtered_sink = NULL;
2384 http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2385 first_data_notif = TRUE;
2386 state = STATE_CONNECTING;
2387 test_async_req = (flags & TEST_ASYNCREQ) != 0;
2388 direct_read = (flags & TEST_DIRECT_READ) != 0;
2389 emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2390 wait_for_switch = TRUE;
2391 short_read = (flags & TEST_SHORT_READ) != 0;
2392 http_post_test = TYMED_NULL;
2393 test_redirect = (flags & TEST_REDIRECT) != 0;
2394 test_abort = (flags & TEST_ABORT) != 0;
2395 impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2396 empty_file = (flags & TEST_EMPTY) != 0;
2397 bind_from_cache = (flags & TEST_FROMCACHE) != 0;
2398
2399 register_filter(mimefilter_test);
2400 }
2401
2402 static void test_priority(IInternetProtocol *protocol)
2403 {
2404 IInternetPriority *priority;
2405 LONG pr;
2406 HRESULT hres;
2407
2408 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2409 (void**)&priority);
2410 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2411 if(FAILED(hres))
2412 return;
2413
2414 hres = IInternetPriority_GetPriority(priority, &pr);
2415 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2416 ok(pr == 0, "pr=%d, expected 0\n", pr);
2417
2418 hres = IInternetPriority_SetPriority(priority, 1);
2419 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2420
2421 hres = IInternetPriority_GetPriority(priority, &pr);
2422 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2423 ok(pr == 1, "pr=%d, expected 1\n", pr);
2424
2425 IInternetPriority_Release(priority);
2426 }
2427
2428 static void test_early_abort(const CLSID *clsid)
2429 {
2430 IInternetProtocol *protocol;
2431 HRESULT hres;
2432
2433 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2434 &IID_IInternetProtocol, (void**)&protocol);
2435 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2436
2437 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2438 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2439
2440 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2441 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2442
2443 IInternetProtocol_Release(protocol);
2444 }
2445
2446 static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url,
2447 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2448 {
2449 HRESULT hres;
2450
2451 SET_EXPECT(GetBindInfo);
2452 if(!(bindf & BINDF_FROMURLMON))
2453 SET_EXPECT(ReportProgress_DIRECTBIND);
2454 if(is_first) {
2455 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2456 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2457 if(bindf & BINDF_FROMURLMON)
2458 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2459 else
2460 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2461 }
2462 SET_EXPECT(ReportData);
2463 if(is_first)
2464 SET_EXPECT(ReportResult);
2465
2466 expect_hrResult = S_OK;
2467
2468 if(protocolex) {
2469 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2470 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2471 }else {
2472 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2473 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2474 win_skip("Start failed\n");
2475 return FALSE;
2476 }
2477 ok(hres == S_OK, "Start failed: %08x\n", hres);
2478 }
2479
2480 CHECK_CALLED(GetBindInfo);
2481 if(!(bindf & BINDF_FROMURLMON))
2482 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2483 if(is_first) {
2484 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2485 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2486 if(bindf & BINDF_FROMURLMON)
2487 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2488 else
2489 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2490 }
2491 CHECK_CALLED(ReportData);
2492 if(is_first)
2493 CHECK_CALLED(ReportResult);
2494
2495 return TRUE;
2496 }
2497
2498 static void test_file_protocol_url(LPCWSTR url)
2499 {
2500 IInternetProtocolInfo *protocol_info;
2501 IUnknown *unk;
2502 IClassFactory *factory;
2503 IInternetProtocol *protocol;
2504 BYTE buf[512];
2505 ULONG cb;
2506 HRESULT hres;
2507
2508 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2509 &IID_IUnknown, (void**)&unk);
2510 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2511 if(FAILED(hres))
2512 return;
2513
2514 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2515 ok(hres == E_NOINTERFACE,
2516 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2517
2518 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2519 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2520 IUnknown_Release(unk);
2521 if(FAILED(hres))
2522 return;
2523
2524 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2525 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2526
2527 if(SUCCEEDED(hres)) {
2528 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2529 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2530 ok(hres == S_OK, "Read failed: %08x\n", hres);
2531 ok(cb == 2, "cb=%u expected 2\n", cb);
2532 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2533 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2534 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2535 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2536 ok(cb == 0, "cb=%u expected 0\n", cb);
2537 hres = IInternetProtocol_UnlockRequest(protocol);
2538 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2539 }
2540
2541 if(file_protocol_start(protocol, url, NULL, NULL, FALSE)) {
2542 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2543 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2544 hres = IInternetProtocol_LockRequest(protocol, 0);
2545 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2546 hres = IInternetProtocol_UnlockRequest(protocol);
2547 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2548 }
2549
2550 IInternetProtocol_Release(protocol);
2551 }
2552
2553 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2554 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2555 if(SUCCEEDED(hres)) {
2556 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2557 hres = IInternetProtocol_LockRequest(protocol, 0);
2558 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2559 hres = IInternetProtocol_Terminate(protocol, 0);
2560 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2561 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2562 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2563 hres = IInternetProtocol_UnlockRequest(protocol);
2564 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2565 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2566 ok(hres == S_OK, "Read failed: %08x\n", hres);
2567 hres = IInternetProtocol_Terminate(protocol, 0);
2568 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2569 }
2570
2571 IInternetProtocol_Release(protocol);
2572 }
2573
2574 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2575 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2576 if(SUCCEEDED(hres)) {
2577 if(file_protocol_start(protocol, url, NULL, NULL, TRUE)) {
2578 hres = IInternetProtocol_Terminate(protocol, 0);
2579 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2580 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2581 ok(hres == S_OK, "Read failed: %08x\n", hres);
2582 ok(cb == 2, "cb=%u expected 2\n", cb);
2583 }
2584
2585 IInternetProtocol_Release(protocol);
2586 }
2587
2588 if(pCreateUri) {
2589 IInternetProtocolEx *protocolex;
2590 IUri *uri;
2591
2592 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2593 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2594
2595 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2596 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2597
2598 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2599 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2600 ok(hres == S_OK, "Read failed: %08x\n", hres);
2601 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2602 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2603 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2604 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2605 }
2606
2607 IUri_Release(uri);
2608 IInternetProtocolEx_Release(protocolex);
2609
2610 hres = pCreateUri(url, 0, 0, &uri);
2611 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2612
2613 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2614 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2615
2616 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2617 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2618 ok(hres == S_OK, "Read failed: %08x\n", hres);
2619 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2620 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2621 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2622 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2623 }
2624
2625 IUri_Release(uri);
2626 IInternetProtocolEx_Release(protocolex);
2627 }else {
2628 win_skip("Skipping file protocol StartEx tests\n");
2629 }
2630
2631 IClassFactory_Release(factory);
2632 }
2633
2634 static void test_file_protocol_fail(void)
2635 {
2636 IInternetProtocol *protocol;
2637 HRESULT hres;
2638
2639 static const WCHAR index_url2[] =
2640 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2641
2642 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2643 &IID_IInternetProtocol, (void**)&protocol);
2644 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2645 if(FAILED(hres))
2646 return;
2647
2648 SET_EXPECT(GetBindInfo);
2649 expect_hrResult = MK_E_SYNTAX;
2650 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2651 ok(hres == MK_E_SYNTAX ||
2652 hres == E_INVALIDARG,
2653 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2654 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2655
2656 SET_EXPECT(GetBindInfo);
2657 if(!(bindf & BINDF_FROMURLMON))
2658 SET_EXPECT(ReportProgress_DIRECTBIND);
2659 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2660 SET_EXPECT(ReportResult);
2661 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2662 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2663 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2664 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2665 CHECK_CALLED(GetBindInfo);
2666 if(!(bindf & BINDF_FROMURLMON))
2667 CHECK_CALLED(ReportProgress_DIRECTBIND);
2668 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2669 CHECK_CALLED(ReportResult);
2670
2671 IInternetProtocol_Release(protocol);
2672
2673 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2674 &IID_IInternetProtocol, (void**)&protocol);
2675 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2676 if(FAILED(hres))
2677 return;
2678
2679 SET_EXPECT(GetBindInfo);
2680 if(!(bindf & BINDF_FROMURLMON))
2681 SET_EXPECT(ReportProgress_DIRECTBIND);
2682 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2683 SET_EXPECT(ReportResult);
2684 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2685
2686 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
2687 ok(hres == INET_E_RESOURCE_NOT_FOUND,
2688 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2689 CHECK_CALLED(GetBindInfo);
2690 if(!(bindf & BINDF_FROMURLMON))
2691 CHECK_CALLED(ReportProgress_DIRECTBIND);
2692 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2693 CHECK_CALLED(ReportResult);
2694
2695 SET_EXPECT(GetBindInfo);
2696 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
2697 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2698 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2699
2700 SET_EXPECT(GetBindInfo);
2701 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
2702 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
2703 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2704
2705 IInternetProtocol_Release(protocol);
2706 }
2707
2708 static void test_file_protocol(void) {
2709 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
2710 DWORD size;
2711 ULONG len;
2712 HANDLE file;
2713
2714 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
2715 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
2716 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
2717 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
2718 static const char html_doc[] = "<HTML></HTML>";
2719
2720 trace("Testing file protocol...\n");
2721 init_test(FILE_TEST, 0);
2722
2723 SetLastError(0xdeadbeef);
2724 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2725 FILE_ATTRIBUTE_NORMAL, NULL);
2726 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2727 if(file == INVALID_HANDLE_VALUE)
2728 return;
2729 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
2730 CloseHandle(file);
2731
2732 file_name = wszIndexHtml;
2733 bindf = 0;
2734 test_file_protocol_url(index_url);
2735 bindf = BINDF_FROMURLMON;
2736 test_file_protocol_url(index_url);
2737 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
2738 test_file_protocol_url(index_url);
2739
2740 memcpy(buf, wszFile, sizeof(wszFile));
2741 len = sizeof(wszFile)/sizeof(WCHAR)-1;
2742 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2743 buf[len++] = '\\';
2744 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2745
2746 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
2747 bindf = 0;
2748 test_file_protocol_url(buf);
2749 bindf = BINDF_FROMURLMON;
2750 test_file_protocol_url(buf);
2751
2752 memcpy(buf, wszFile2, sizeof(wszFile2));
2753 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2754 file_name_buf[len++] = '\\';
2755 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2756 lstrcpyW(buf+sizeof(wszFile2)/sizeof(WCHAR)-1, file_name_buf);
2757 file_name = file_name_buf;
2758 bindf = 0;
2759 test_file_protocol_url(buf);
2760 bindf = BINDF_FROMURLMON;
2761 test_file_protocol_url(buf);
2762
2763 buf[sizeof(wszFile2)/sizeof(WCHAR)] = '|';
2764 test_file_protocol_url(buf);
2765
2766 memcpy(buf, wszFile3, sizeof(wszFile3));
2767 len = sizeof(wszFile3)/sizeof(WCHAR)-1;
2768 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
2769 buf[len++] = '\\';
2770 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2771
2772 file_name = buf + sizeof(wszFile3)/sizeof(WCHAR)-1;
2773 bindf = 0;
2774 test_file_protocol_url(buf);
2775 bindf = BINDF_FROMURLMON;
2776 test_file_protocol_url(buf);
2777
2778 memcpy(buf, wszFile4, sizeof(wszFile4));
2779 len = GetCurrentDirectoryW(sizeof(file_name_buf)/sizeof(WCHAR), file_name_buf);
2780 file_name_buf[len++] = '\\';
2781 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
2782 lstrcpyW(buf+sizeof(wszFile4)/sizeof(WCHAR)-1, file_name_buf);
2783 file_name = file_name_buf;
2784 bindf = 0;
2785 test_file_protocol_url(buf);
2786 bindf = BINDF_FROMURLMON;
2787 test_file_protocol_url(buf);
2788
2789 buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
2790 test_file_protocol_url(buf);
2791
2792 DeleteFileW(wszIndexHtml);
2793
2794 bindf = 0;
2795 test_file_protocol_fail();
2796 bindf = BINDF_FROMURLMON;
2797 test_file_protocol_fail();
2798 }
2799
2800 static void create_cache_entry(const WCHAR *urlw)
2801 {
2802 FILETIME now, tomorrow, yesterday;
2803 char file_path[MAX_PATH];
2804 BYTE content[1000];
2805 ULARGE_INTEGER li;
2806 const char *url;
2807 HANDLE file;
2808 DWORD size;
2809 unsigned i;
2810 BOOL res;
2811
2812 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
2813
2814 trace("Testing cache read...\n");
2815
2816 url = w2a(urlw);
2817
2818 for(i = 0; i < sizeof(content); i++)
2819 content[i] = '0' + (i%10);
2820
2821 GetSystemTimeAsFileTime(&now);
2822 li.u.HighPart = now.dwHighDateTime;
2823 li.u.LowPart = now.dwLowDateTime;
2824 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
2825 tomorrow.dwHighDateTime = li.u.HighPart;
2826 tomorrow.dwLowDateTime = li.u.LowPart;
2827 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
2828 yesterday.dwHighDateTime = li.u.HighPart;
2829 yesterday.dwLowDateTime = li.u.LowPart;
2830
2831 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
2832 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
2833
2834 file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2835 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2836
2837 WriteFile(file, content, sizeof(content), &size, NULL);
2838 CloseHandle(file);
2839
2840 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
2841 cache_headers, sizeof(cache_headers)-1, "", 0);
2842 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
2843 }
2844
2845 static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
2846 {
2847 static BOOL got_user_agent = FALSE;
2848 IUri *uri = NULL;
2849 HRESULT hres;
2850
2851 if(use_iuri && pCreateUri) {
2852 hres = pCreateUri(url, 0, 0, &uri);
2853 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2854 }
2855
2856 SET_EXPECT(GetBindInfo);
2857 if (!(bindf & BINDF_FROMURLMON))
2858 SET_EXPECT(ReportProgress_DIRECTBIND);
2859 if(!got_user_agent)
2860 SET_EXPECT(GetBindString_USER_AGENT);
2861 SET_EXPECT(GetBindString_ROOTDOC_URL);
2862 SET_EXPECT(GetBindString_ACCEPT_MIMES);
2863 SET_EXPECT(QueryService_HttpNegotiate);
2864 SET_EXPECT(BeginningTransaction);
2865 SET_EXPECT(GetRootSecurityId);
2866 if(http_post_test) {
2867 SET_EXPECT(GetBindString_POST_COOKIE);
2868 if(http_post_test == TYMED_ISTREAM)
2869 SET_EXPECT(Stream_Seek);
2870 }
2871 if(bind_from_cache) {
2872 SET_EXPECT(OnResponse);
2873 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2874 SET_EXPECT(ReportData);
2875 }
2876
2877 if(uri) {
2878 IInternetProtocolEx *protocolex;
2879
2880 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
2881 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
2882
2883 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2884 ok(hres == S_OK, "Start failed: %08x\n", hres);
2885
2886 IInternetProtocolEx_Release(protocolex);
2887 IUri_Release(uri);
2888 }else {
2889 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
2890 ok(hres == S_OK, "Start failed: %08x\n", hres);
2891 }
2892 if(FAILED(hres))
2893 return FALSE;
2894
2895 CHECK_CALLED(GetBindInfo);
2896 if (!(bindf & BINDF_FROMURLMON))
2897 CHECK_CALLED(ReportProgress_DIRECTBIND);
2898 if (!got_user_agent)
2899 {
2900 CHECK_CALLED(GetBindString_USER_AGENT);
2901 got_user_agent = TRUE;
2902 }
2903 CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
2904 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
2905 CHECK_CALLED(QueryService_HttpNegotiate);
2906 CHECK_CALLED(BeginningTransaction);
2907 /* GetRootSecurityId called on WinXP but not on Win98 */
2908 CLEAR_CALLED(GetRootSecurityId);
2909 if(http_post_test) {
2910 CHECK_CALLED(GetBindString_POST_COOKIE);
2911 if(http_post_test == TYMED_ISTREAM)
2912 CHECK_CALLED(Stream_Seek);
2913 }
2914 if(bind_from_cache) {
2915 CHECK_CALLED(OnResponse);
2916 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2917 CHECK_CALLED(ReportData);
2918 }
2919
2920 return TRUE;
2921 }
2922
2923 static void test_protocol_terminate(IInternetProtocol *protocol)
2924 {
2925 BYTE buf[3600];
2926 DWORD cb;
2927 HRESULT hres;
2928
2929 hres = IInternetProtocol_LockRequest(protocol, 0);
2930 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2931
2932 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
2933 ok(hres == test_abort ? S_OK : S_FALSE, "Read failed: %08x\n", hres);
2934
2935 hres = IInternetProtocol_Terminate(protocol, 0);
2936 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2937
2938 /* This wait is to give the internet handles being freed in Terminate
2939 * enough time to actually terminate in all cases. Internet handles
2940 * terminate asynchronously and native reuses the main InternetOpen
2941 * handle. The only case in which this seems to be necessary is on
2942 * wine with native wininet and urlmon, resulting in the next time
2943 * test_http_protocol_url being called the first data notification actually
2944 * being an extra last data notification from the previous connection
2945 * about once out of every ten times. */
2946 Sleep(100);
2947
2948 hres = IInternetProtocol_UnlockRequest(protocol);
2949 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2950 }
2951
2952 static void test_http_info(IInternetProtocol *protocol)
2953 {
2954 IWinInetHttpInfo *info;
2955 HRESULT hres;
2956
2957 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
2958 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
2959
2960 /* TODO */
2961
2962 IWinInetHttpInfo_Release(info);
2963 }
2964
2965 /* is_first refers to whether this is the first call to this function
2966 * _for this url_ */
2967 static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tymed)
2968 {
2969 IInternetProtocolInfo *protocol_info;
2970 IClassFactory *factory;
2971 IUnknown *unk;
2972 HRESULT hres;
2973
2974 init_test(prot, flags);
2975 http_url = url;
2976 http_post_test = tymed;
2977
2978 if(flags & TEST_FROMCACHE)
2979 create_cache_entry(url);
2980
2981 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
2982 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
2983 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2984 if(FAILED(hres))
2985 return;
2986
2987 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2988 ok(hres == E_NOINTERFACE,
2989 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
2990 hres);
2991
2992 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2993 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2994 IUnknown_Release(unk);
2995 if(FAILED(hres))
2996 return;
2997
2998 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
2999 (void**)&async_protocol);
3000 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3001 if(SUCCEEDED(hres)) {
3002 BYTE buf[3600];
3003 DWORD cb;
3004 ULONG ref;
3005
3006 test_priority(async_protocol);
3007 test_http_info(async_protocol);
3008
3009 SET_EXPECT(ReportProgress_COOKIE_SENT);
3010 if(http_is_first) {
3011 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3012 SET_EXPECT(ReportProgress_CONNECTING);
3013 }
3014 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3015 if(test_redirect)
3016 SET_EXPECT(ReportProgress_REDIRECTING);
3017 SET_EXPECT(ReportProgress_PROXYDETECTING);
3018 if(prot == HTTP_TEST)
3019 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3020 else
3021 SET_EXPECT(QueryService_HttpSecurity);
3022 if(!(bindf & BINDF_FROMURLMON)) {
3023 SET_EXPECT(OnResponse);
3024 SET_EXPECT(ReportProgress_RAWMIMETYPE);
3025 SET_EXPECT(ReportData);
3026 } else {
3027 SET_EXPECT(Switch);
3028 }
3029
3030 if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3031 IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3032 IInternetProtocol_Release(async_protocol);
3033 return;
3034 }
3035
3036 if(!direct_read && !test_abort && !bind_from_cache)
3037 SET_EXPECT(ReportResult);
3038 expect_hrResult = test_abort ? E_ABORT : S_OK;
3039
3040 if(direct_read) {
3041 SET_EXPECT(Switch);
3042 while(wait_for_switch) {
3043 ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3044 CHECK_CALLED(Switch); /* Set in ReportData */
3045 call_continue(&continue_protdata);
3046 SetEvent(event_continue_done);
3047 }
3048 }else if(bind_from_cache) {
3049 BYTE buf[1500];
3050
3051 hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3052 ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3053
3054 SET_EXPECT(ReportResult);
3055 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3056 ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3057 CHECK_CALLED(ReportResult);
3058
3059 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3060 ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3061 }else {
3062 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3063 ok((hres == E_PENDING && cb==0) ||
3064 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3065
3066 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3067 if(bindf & BINDF_FROMURLMON)
3068 CHECK_CALLED(Switch);
3069 else
3070 CHECK_CALLED(ReportData);
3071 if(prot == HTTPS_TEST)
3072 CLEAR_CALLED(QueryService_HttpSecurity);
3073
3074 while(1) {
3075 if(bindf & BINDF_FROMURLMON)
3076 SET_EXPECT(Switch);
3077 else
3078 SET_EXPECT(ReportData);
3079 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3080 if(hres == E_PENDING) {
3081 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3082 ok((hres == E_PENDING && cb==0) ||
3083 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3084 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3085 if(bindf & BINDF_FROMURLMON)
3086 CHECK_CALLED(Switch);
3087 else
3088 CHECK_CALLED(ReportData);
3089
3090 if(test_abort) {
3091 HRESULT hres;
3092
3093 SET_EXPECT(ReportResult);
3094 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3095 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3096 CHECK_CALLED(ReportResult);
3097
3098 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3099 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3100 break;
3101 }
3102 }else {
3103 if(bindf & BINDF_FROMURLMON)
3104 CHECK_NOT_CALLED(Switch);
3105 else
3106 CHECK_NOT_CALLED(ReportData);
3107 if(cb == 0) break;
3108 }
3109 }
3110 if(!test_abort) {
3111 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3112 CHECK_CALLED(ReportResult);
3113 }
3114 }
3115 if(prot == HTTPS_TEST)
3116 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3117
3118 if (prot == HTTP_TEST || prot == HTTPS_TEST)
3119 CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3120
3121 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3122 ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3123
3124 test_protocol_terminate(async_protocol);
3125
3126 hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3127 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3128
3129 ref = IInternetProtocol_Release(async_protocol);
3130 ok(!ref, "ref=%x\n", ref);
3131 }
3132
3133 IClassFactory_Release(factory);
3134
3135 if(flags & TEST_FROMCACHE) {
3136 BOOL res;
3137
3138 res = DeleteUrlCacheEntryW(url);
3139 ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3140 }
3141 }
3142
3143 static void test_http_protocol(void)
3144 {
3145 static const WCHAR posttest_url[] =
3146 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3147 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3148 static const WCHAR redirect_url[] =
3149 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3150 't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3151 static const WCHAR winetest_url[] =
3152 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3153 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3154 static const WCHAR empty_url[] =
3155 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3156 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3157 static const WCHAR cache_only_url[] =
3158 {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3159 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3160
3161
3162 trace("Testing http protocol (not from urlmon)...\n");
3163 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3164 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3165
3166 trace("Testing http protocol (from urlmon)...\n");
3167 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3168 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3169
3170 trace("Testing http protocol (to file)...\n");
3171 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3172 test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3173
3174 trace("Testing http protocol (post data)...\n");
3175 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3176 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3177
3178 trace("Testing http protocol (post data stream)...\n");
3179 test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST|TEST_ASYNCREQ, TYMED_ISTREAM);
3180
3181 trace("Testing http protocol (direct read)...\n");
3182 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3183 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3184
3185 trace("Testing http protocol (redirected)...\n");
3186 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3187 test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3188
3189 trace("Testing http protocol empty file...\n");
3190 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3191 test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3192
3193 /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3194 * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3195 * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3196 * tests work on Windows and have them around for the future.
3197 */
3198 if(broken(1)) {
3199 trace("Testing http protocol (from cache)...\n");
3200 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3201 test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3202 }
3203
3204 trace("Testing http protocol abort...\n");
3205 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3206 test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3207
3208 test_early_abort(&CLSID_HttpProtocol);
3209 test_early_abort(&CLSID_HttpSProtocol);
3210 }
3211
3212 static void test_https_protocol(void)
3213 {
3214 static const WCHAR https_winehq_url[] =
3215 {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3216 't','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
3217
3218 trace("Testing https protocol (from urlmon)...\n");
3219 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3220 test_http_protocol_url(https_winehq_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3221 }
3222
3223
3224 static void test_ftp_protocol(void)
3225 {
3226 IInternetProtocolInfo *protocol_info;
3227 IClassFactory *factory;
3228 IUnknown *unk;
3229 BYTE buf[4096];
3230 ULONG ref;
3231 DWORD cb;
3232 HRESULT hres;
3233
3234 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3235 '/','p','u','b','/','o','t','h','e','r','/',
3236 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3237
3238 trace("Testing ftp protocol...\n");
3239
3240 init_test(FTP_TEST, 0);
3241
3242 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3243 state = STATE_STARTDOWNLOADING;
3244 expect_hrResult = E_PENDING;
3245
3246 hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3247 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3248 if(FAILED(hres))
3249 return;
3250
3251 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3252 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3253
3254 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3255 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3256 IUnknown_Release(unk);
3257 if(FAILED(hres))
3258 return;
3259
3260 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3261 (void**)&async_protocol);
3262 IClassFactory_Release(factory);
3263 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3264
3265 test_priority(async_protocol);
3266 test_http_info(async_protocol);
3267
3268 SET_EXPECT(GetBindInfo);
3269 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3270 SET_EXPECT(ReportProgress_CONNECTING);
3271 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3272 SET_EXPECT(Switch);
3273
3274 hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
3275 ok(hres == S_OK, "Start failed: %08x\n", hres);
3276 CHECK_CALLED(GetBindInfo);
3277
3278 SET_EXPECT(ReportResult);
3279
3280 hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3281 ok((hres == E_PENDING && cb==0) ||
3282 (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3283
3284 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3285
3286 while(1) {
3287 hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3288 if(hres == E_PENDING)
3289 {
3290 DWORD ret = WaitForSingleObject(event_complete, 90000);
3291 ok( ret == WAIT_OBJECT_0, "wait timed out\n" );
3292 if (ret != WAIT_OBJECT_0) break;
3293 }
3294 else
3295 if(cb == 0) break;
3296 }
3297
3298 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3299 CHECK_CALLED(ReportResult);
3300 CHECK_CALLED(Switch);
3301
3302 test_protocol_terminate(async_protocol);
3303
3304 if(pCreateUri) {
3305 IInternetProtocolEx *protocolex;
3306
3307 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3308 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3309 IInternetProtocolEx_Release(protocolex);
3310 }
3311
3312 ref = IInternetProtocol_Release(async_protocol);
3313 ok(!ref, "ref=%d\n", ref);
3314
3315 test_early_abort(&CLSID_FtpProtocol);
3316 }
3317
3318 static void test_gopher_protocol(void)
3319 {
3320 IInternetProtocolInfo *protocol_info;
3321 IClassFactory *factory;
3322 IUnknown *unk;
3323 HRESULT hres;
3324
3325 trace("Testing gopher protocol...\n");
3326
3327 hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3328 ok(hres == S_OK ||
3329 broken(hres == REGDB_E_CLASSNOTREG || hres == CLASS_E_CLASSNOTAVAILABLE), /* Gopher protocol has been removed as of Vista */
3330 "CoGetClassObject failed: %08x\n", hres);
3331 if(FAILED(hres))
3332 return;
3333
3334 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3335 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3336
3337 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3338 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3339 IUnknown_Release(unk);
3340 if(FAILED(hres))
3341 return;
3342
3343 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3344 (void**)&async_protocol);
3345 IClassFactory_Release(factory);
3346 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3347
3348 test_priority(async_protocol);
3349
3350 IInternetProtocol_Release(async_protocol);
3351
3352 test_early_abort(&CLSID_GopherProtocol);
3353 }
3354
3355 static void test_mk_protocol(void)
3356 {
3357 IInternetProtocolInfo *protocol_info;
3358 IInternetProtocol *protocol;
3359 IClassFactory *factory;
3360 IUnknown *unk;
3361 HRESULT hres;
3362
3363 static const WCHAR wrong_url1[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
3364 ':',':','/','t','e','s','t','.','h','t','m','l',0};
3365 static const WCHAR wrong_url2[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
3366
3367 trace("Testing mk protocol...\n");
3368 init_test(MK_TEST, 0);
3369
3370 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL,
3371 &IID_IUnknown, (void**)&unk);
3372 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3373
3374 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3375 ok(hres == E_NOINTERFACE,
3376 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3377 hres);
3378
3379 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3380 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3381 IUnknown_Release(unk);
3382 if(FAILED(hres))
3383 return;
3384
3385 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3386 (void**)&protocol);
3387 IClassFactory_Release(factory);
3388 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3389
3390 SET_EXPECT(GetBindInfo);
3391 hres = IInternetProtocol_Start(protocol, wrong_url1, &protocol_sink, &bind_info, 0, 0);
3392 ok(hres == MK_E_SYNTAX || hres == INET_E_INVALID_URL,
3393 "Start failed: %08x, expected MK_E_SYNTAX or INET_E_INVALID_URL\n", hres);
3394 CLEAR_CALLED(GetBindInfo);
3395
3396 SET_EXPECT(GetBindInfo);
3397 SET_EXPECT(ReportProgress_DIRECTBIND);
3398 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3399 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3400 SET_EXPECT(ReportResult);
3401 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3402
3403 hres = IInternetProtocol_Start(protocol, wrong_url2, &protocol_sink, &bind_info, 0, 0);
3404 ok(hres == INET_E_RESOURCE_NOT_FOUND ||
3405 hres == INET_E_INVALID_URL, /* win2k3 */
3406 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND or INET_E_INVALID_URL\n", hres);
3407
3408 if (hres == INET_E_RESOURCE_NOT_FOUND) {
3409 CHECK_CALLED(GetBindInfo);
3410 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3411 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3412 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3413 CHECK_CALLED(ReportResult);
3414 }else {
3415 CLEAR_CALLED(GetBindInfo);
3416 CLEAR_CALLED(ReportProgress_DIRECTBIND);
3417 CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3418 CLEAR_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3419 CLEAR_CALLED(ReportResult);
3420 }
3421
3422 IInternetProtocol_Release(protocol);
3423 }
3424
3425 static void test_CreateBinding(void)
3426 {
3427 IInternetProtocol *protocol;
3428 IInternetPriority *priority;
3429 IInternetSession *session;
3430 IWinInetHttpInfo *http_info;
3431 IWinInetInfo *inet_info;
3432 LONG p;
3433 BYTE buf[1000];
3434 DWORD read;
3435 HRESULT hres;
3436
3437 static const WCHAR test_url[] =
3438 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
3439 static const WCHAR wsz_test[] = {'t','e','s','t',0};
3440
3441 trace("Testing CreateBinding...\n");
3442 init_test(BIND_TEST, TEST_BINDING);
3443
3444 hres = pCoInternetGetSession(0, &session, 0);
3445 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3446
3447 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, wsz_test, 0, NULL, 0);
3448 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3449
3450 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3451 binding_protocol = protocol;
3452 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3453 ok(protocol != NULL, "protocol == NULL\n");
3454
3455 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3456 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3457
3458 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3459 ok(hres == S_OK, "Could not get IInternetProtocolSink: %08x\n", hres);
3460
3461 hres = IInternetProtocol_Start(protocol, test_url, NULL, &bind_info, 0, 0);
3462 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3463 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, NULL, 0, 0);
3464 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3465 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3466 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3467
3468 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
3469 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
3470
3471 p = 0xdeadbeef;
3472 hres = IInternetPriority_GetPriority(priority, &p);
3473 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3474 ok(!p, "p=%d\n", p);
3475
3476 ex_priority = 100;
3477 hres = IInternetPriority_SetPriority(priority, 100);
3478 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3479
3480 p = 0xdeadbeef;
3481 hres = IInternetPriority_GetPriority(priority, &p);
3482 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3483 ok(p == 100, "p=%d\n", p);
3484
3485 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3486 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3487
3488 SET_EXPECT(QueryService_InternetProtocol);
3489 SET_EXPECT(CreateInstance);
3490 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3491 SET_EXPECT(SetPriority);
3492 SET_EXPECT(Start);
3493
3494 expect_hrResult = S_OK;
3495 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3496 ok(hres == S_OK, "Start failed: %08x\n", hres);
3497
3498 CHECK_CALLED(QueryService_InternetProtocol);
3499 CHECK_CALLED(CreateInstance);
3500 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3501 CHECK_CALLED(SetPriority);
3502 CHECK_CALLED(Start);
3503
3504 SET_EXPECT(QueryInterface_IWinInetInfo);
3505 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3506 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3507 CHECK_CALLED(QueryInterface_IWinInetInfo);
3508
3509 SET_EXPECT(QueryInterface_IWinInetInfo);
3510 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&inet_info);
3511 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3512 CHECK_CALLED(QueryInterface_IWinInetInfo);
3513
3514 SET_EXPECT(QueryInterface_IWinInetHttpInfo);
3515 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&http_info);
3516 ok(hres == E_NOINTERFACE, "Could not get IWinInetInfo protocol: %08x\n", hres);
3517 CHECK_CALLED(QueryInterface_IWinInetHttpInfo);
3518
3519 SET_EXPECT(Read);
3520 read = 0xdeadbeef;
3521 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3522 ok(hres == S_OK, "Read failed: %08x\n", hres);
3523 ok(read == 100, "read = %d\n", read);
3524 CHECK_CALLED(Read);
3525
3526 SET_EXPECT(Read);
3527 read = 0xdeadbeef;
3528 hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read);
3529 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3530 ok(!read, "read = %d\n", read);
3531 CHECK_CALLED(Read);
3532
3533 p = 0xdeadbeef;
3534 hres = IInternetPriority_GetPriority(priority, &p);
3535 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
3536 ok(p == 100, "p=%d\n", p);
3537
3538 hres = IInternetPriority_SetPriority(priority, 101);
3539 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
3540
3541 SET_EXPECT(Terminate);
3542 hres = IInternetProtocol_Terminate(protocol, 0xdeadbeef);
3543 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3544 CHECK_CALLED(Terminate);
3545
3546 SET_EXPECT(Continue);
3547 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
3548 ok(hres == S_OK, "Switch failed: %08x\n", hres);
3549 CHECK_CALLED(Continue);
3550
3551 hres = IInternetProtocolSink_ReportProgress(binding_sink,
3552 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
3553 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
3554
3555 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
3556 ok(hres == E_FAIL, "ReportResult failed: %08x, expected E_FAIL\n", hres);
3557
3558 hres = IInternetProtocolSink_ReportData(binding_sink, 0, 0, 0);
3559 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
3560
3561 IInternetProtocolSink_Release(binding_sink);
3562 IInternetPriority_Release(priority);
3563 IInternetBindInfo_Release(prot_bind_info);
3564 IInternetProtocol_Release(protocol);
3565
3566 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3567 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3568 ok(protocol != NULL, "protocol == NULL\n");
3569
3570 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3571 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3572
3573 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
3574 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3575
3576 IInternetProtocol_Release(protocol);
3577
3578 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, wsz_test);
3579 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3580
3581 hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0);
3582 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3583 ok(protocol != NULL, "protocol == NULL\n");
3584
3585 SET_EXPECT(QueryService_InternetProtocol);
3586 hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0);
3587 ok(hres == MK_E_SYNTAX, "Start failed: %08x, expected MK_E_SYNTAX\n", hres);
3588 CHECK_CALLED(QueryService_InternetProtocol);
3589
3590 IInternetProtocol_Release(protocol);
3591
3592 IInternetSession_Release(session);
3593 }
3594
3595 static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
3596 {
3597 IInternetProtocolEx *protocolex = NULL;
3598 IInternetProtocol *protocol;
3599 IInternetSession *session;
3600 IUri *uri = NULL;
3601 ULONG ref;
3602 HRESULT hres;
3603
3604 pi = grf_pi;
3605
3606 init_test(prot, test_flags|TEST_BINDING);
3607
3608 hres = pCoInternetGetSession(0, &session, 0);
3609 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3610
3611 if(test_flags & TEST_EMULATEPROT) {
3612 hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL, protocol_names[prot], 0, NULL, 0);
3613 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3614 }
3615
3616 hres = IInternetSession_CreateBinding(session, NULL, binding_urls[prot], NULL, NULL, &protocol, 0);
3617 binding_protocol = protocol;
3618 ok(hres == S_OK, "CreateBinding failed: %08x\n", hres);
3619 ok(protocol != NULL, "protocol == NULL\n");
3620
3621 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetBindInfo, (void**)&prot_bind_info);
3622 ok(hres == S_OK, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres);
3623
3624 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolSink, (void**)&binding_sink);
3625 ok(hres == S_OK, "QueryInterface(IID_IInternetProtocolSink) failed: %08x\n", hres);
3626
3627 if(test_flags & TEST_USEIURI) {
3628 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3629 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3630
3631 hres = pCreateUri(binding_urls[prot], Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
3632 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3633 }
3634
3635 ex_priority = 0;
3636 SET_EXPECT(QueryService_InternetProtocol);
3637 SET_EXPECT(CreateInstance);
3638 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
3639 SET_EXPECT(SetPriority);
3640 if(impl_protex)
3641 SET_EXPECT(StartEx);
3642 else
3643 SET_EXPECT(Start);
3644
3645 expect_hrResult = S_OK;
3646
3647 if(protocolex) {
3648 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, pi, 0);
3649 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
3650 }else {
3651 hres = IInternetProtocol_Start(protocol, binding_urls[prot], &protocol_sink, &bind_info, pi, 0);
3652 ok(hres == S_OK, "Start failed: %08x\n", hres);
3653 }
3654
3655 CHECK_CALLED(QueryService_InternetProtocol);
3656 CHECK_CALLED(CreateInstance);
3657 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
3658 CLEAR_CALLED(SetPriority); /* IE11 does not call it. */
3659 if(impl_protex)
3660 CHECK_CALLED(StartEx);
3661 else
3662 CHECK_CALLED(Start);
3663
3664 if(protocolex)
3665 IInternetProtocolEx_Release(protocolex);
3666 if(uri)
3667 IUri_Release(uri);
3668
3669 if(prot == HTTP_TEST || prot == HTTPS_TEST) {
3670 while(prot_state < 4) {
3671 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3672 if(mimefilter_test && filtered_protocol) {
3673 SET_EXPECT(Continue);
3674 IInternetProtocol_Continue(filtered_protocol, pdata);
3675 CHECK_CALLED(Continue);
3676 }else {
3677 SET_EXPECT(Continue);
3678 IInternetProtocol_Continue(protocol, pdata);
3679 CHECK_CALLED(Continue);
3680 }
3681 if(test_abort && prot_state == 2) {
3682 SET_EXPECT(Abort);
3683 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3684 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3685 CHECK_CALLED(Abort);
3686
3687 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
3688 ok(hres == S_OK, "Abort failed: %08x\n", hres);
3689 SetEvent(event_complete2);
3690 break;
3691 }
3692 SetEvent(event_complete2);
3693 }
3694 if(direct_read)
3695 CHECK_CALLED(ReportData); /* Set in ReportResult */
3696 ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3697 }else {
3698 if(mimefilter_test)
3699 SET_EXPECT(MimeFilter_LockRequest);
3700 else
3701 SET_EXPECT(LockRequest);
3702 hres = IInternetProtocol_LockRequest(protocol, 0);
3703 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3704 if(mimefilter_test)
3705 CHECK_CALLED(MimeFilter_LockRequest);
3706 else
3707 CHECK_CALLED(LockRequest);
3708
3709 if(mimefilter_test)
3710 SET_EXPECT(MimeFilter_UnlockRequest);
3711 else
3712 SET_EXPECT(UnlockRequest);
3713 hres = IInternetProtocol_UnlockRequest(protocol);
3714 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3715 if(mimefilter_test)
3716 CHECK_CALLED(MimeFilter_UnlockRequest);
3717 else
3718 CHECK_CALLED(UnlockRequest);
3719 }
3720
3721 if(mimefilter_test)
3722 SET_EXPECT(MimeFilter_Terminate);
3723 else
3724 SET_EXPECT(Terminate);
3725 hres = IInternetProtocol_Terminate(protocol, 0);
3726 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3727 if(mimefilter_test)
3728 CLEAR_CALLED(MimeFilter_Terminate);
3729 else
3730 CHECK_CALLED(Terminate);
3731
3732 if(filtered_protocol)
3733 IInternetProtocol_Release(filtered_protocol);
3734 IInternetBindInfo_Release(prot_bind_info);
3735 IInternetProtocolSink_Release(binding_sink);
3736 ref = IInternetProtocol_Release(protocol);
3737 ok(!ref, "ref=%u, expected 0\n", ref);
3738
3739 if(test_flags & TEST_EMULATEPROT) {
3740 hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]);
3741 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
3742 }
3743
3744 IInternetSession_Release(session);
3745 }
3746
3747 START_TEST(protocol)
3748 {
3749 HMODULE hurlmon;
3750
3751 if(!winetest_interactive)
3752 {
3753 skip("protocol test skipped, ROSTESTS-38\n");
3754 return;
3755 }
3756
3757 hurlmon = GetModuleHandleA("urlmon.dll");
3758 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
3759 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
3760 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3761
3762 if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3763 win_skip("Various needed functions not present, too old IE\n");
3764 return;
3765 }
3766
3767 if(!pCreateUri)
3768 win_skip("CreateUri not supported\n");
3769
3770 OleInitialize(NULL);
3771
3772 event_complete = CreateEventW(NULL, FALSE, FALSE, NULL);
3773 event_complete2 = CreateEventW(NULL, FALSE, FALSE, NULL);
3774 event_continue = CreateEventW(NULL, FALSE, FALSE, NULL);
3775 event_continue_done = CreateEventW(NULL, FALSE, FALSE, NULL);
3776 thread_id = GetCurrentThreadId();
3777
3778 test_file_protocol();
3779 test_http_protocol();
3780 if(pCreateUri)
3781 test_https_protocol();
3782 else
3783 win_skip("Skipping https tests on too old platform\n");
3784 test_ftp_protocol();
3785 test_gopher_protocol();
3786 test_mk_protocol();
3787 test_CreateBinding();
3788
3789 bindf &= ~BINDF_FROMURLMON;
3790 trace("Testing file binding (mime verification, emulate prot)...\n");
3791 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3792 trace("Testing http binding (mime verification, emulate prot)...\n");
3793 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3794 trace("Testing its binding (mime verification, emulate prot)...\n");
3795 test_binding(ITS_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
3796 trace("Testing http binding (mime verification, emulate prot, short read, direct read)...\n");
3797 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_SHORT_READ|TEST_DIRECT_READ);
3798 trace("Testing file binding (mime verification, emulate prot, mime filter)...\n");
3799 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3800 trace("Testing http binding (mime verification, emulate prot, mime filter)...\n");
3801 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER);
3802 trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n");
3803 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME);
3804 trace("Testing http binding (mime verification, emulate prot, direct read)...\n");
3805 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
3806 trace("Testing http binding (mime verification, emulate prot, abort)...\n");
3807 test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
3808 if(pCreateUri) {
3809 trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
3810 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);
3811 trace("Testing file binding (use IUri, impl StartEx, mime verification, emulate prot)...\n");
3812 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI|TEST_IMPLPROTEX);
3813 trace("Testing file binding (impl StartEx, mime verification, emulate prot)...\n");
3814 test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_IMPLPROTEX);
3815 }
3816
3817 CloseHandle(event_complete);
3818 CloseHandle(event_complete2);
3819 CloseHandle(event_continue);
3820 CloseHandle(event_continue_done);
3821
3822 OleUninitialize();
3823 }