ReactOS 0.4.15-dev-8428-g6910fa6
protocol.c
Go to the documentation of this file.
1/*
2 * Copyright 2005-2011 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#define COBJMACROS
20#define CONST_VTABLE
21
22#include <wine/test.h>
23#include <wine/heap.h>
24#include <stdarg.h>
25#include <stdio.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "ole2.h"
30#include "urlmon.h"
31#include "wininet.h"
32
33static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
34static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
35static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
36
37#define DEFINE_EXPECT(func) \
38 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
39
40#define SET_EXPECT(func) \
41 expect_ ## func = TRUE
42
43#define CHECK_EXPECT2(func) \
44 do { \
45 ok(expect_ ##func, "unexpected call " #func "\n"); \
46 called_ ## func = TRUE; \
47 }while(0)
48
49#define CHECK_EXPECT(func) \
50 do { \
51 CHECK_EXPECT2(func); \
52 expect_ ## func = FALSE; \
53 }while(0)
54
55#define CHECK_CALLED(func) \
56 do { \
57 ok(called_ ## func, "expected " #func "\n"); \
58 expect_ ## func = called_ ## func = FALSE; \
59 }while(0)
60
61#define CHECK_NOT_CALLED(func) \
62 do { \
63 ok(!called_ ## func, "unexpected " #func "\n"); \
64 expect_ ## func = called_ ## func = FALSE; \
65 }while(0)
66
67#define CLEAR_CALLED(func) \
68 expect_ ## func = called_ ## func = FALSE
69
70DEFINE_EXPECT(GetBindInfo);
71DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
72DEFINE_EXPECT(ReportProgress_DIRECTBIND);
73DEFINE_EXPECT(ReportProgress_RAWMIMETYPE);
74DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE);
75DEFINE_EXPECT(ReportProgress_CONNECTING);
76DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
77DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
78DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
79DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID);
80DEFINE_EXPECT(ReportProgress_COOKIE_SENT);
81DEFINE_EXPECT(ReportProgress_REDIRECTING);
82DEFINE_EXPECT(ReportProgress_ENCODING);
83DEFINE_EXPECT(ReportProgress_ACCEPTRANGES);
84DEFINE_EXPECT(ReportProgress_PROXYDETECTING);
85DEFINE_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
86DEFINE_EXPECT(ReportProgress_DECODING);
87DEFINE_EXPECT(ReportData);
88DEFINE_EXPECT(ReportData2);
89DEFINE_EXPECT(ReportResult);
90DEFINE_EXPECT(GetBindString_ACCEPT_MIMES);
91DEFINE_EXPECT(GetBindString_USER_AGENT);
92DEFINE_EXPECT(GetBindString_POST_COOKIE);
93DEFINE_EXPECT(GetBindString_URL);
94DEFINE_EXPECT(GetBindString_ROOTDOC_URL);
95DEFINE_EXPECT(QueryService_HttpNegotiate);
96DEFINE_EXPECT(QueryService_InternetProtocol);
97DEFINE_EXPECT(QueryService_HttpSecurity);
98DEFINE_EXPECT(QueryService_IBindCallbackRedirect);
99DEFINE_EXPECT(QueryInterface_IWinInetInfo);
100DEFINE_EXPECT(QueryInterface_IWinInetHttpInfo);
101DEFINE_EXPECT(BeginningTransaction);
102DEFINE_EXPECT(GetRootSecurityId);
103DEFINE_EXPECT(OnResponse);
106DEFINE_EXPECT(CreateInstance);
107DEFINE_EXPECT(CreateInstance_no_aggregation);
110DEFINE_EXPECT(Terminate);
118DEFINE_EXPECT(MimeFilter_Start);
119DEFINE_EXPECT(MimeFilter_ReportData);
120DEFINE_EXPECT(MimeFilter_ReportResult);
121DEFINE_EXPECT(MimeFilter_Terminate);
122DEFINE_EXPECT(MimeFilter_LockRequest);
123DEFINE_EXPECT(MimeFilter_UnlockRequest);
124DEFINE_EXPECT(MimeFilter_Read);
125DEFINE_EXPECT(MimeFilter_Switch);
126DEFINE_EXPECT(MimeFilter_Continue);
130DEFINE_EXPECT(outer_QI_test);
131DEFINE_EXPECT(Protocol_destructor);
132
133static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
134static const WCHAR index_url[] =
135 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
136
137static const WCHAR acc_mimeW[] = {'*','/','*',0};
138static const WCHAR user_agentW[] = {'W','i','n','e',0};
139static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
140static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
141static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
142static const WCHAR emptyW[] = {0};
143static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
144static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
145
155static void *expect_pv;
158static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
164
165enum {
171
172static enum {
181
182typedef struct {
189} Protocol;
190
192
193static const WCHAR protocol_names[][10] = {
194 {'f','i','l','e',0},
195 {'h','t','t','p',0},
196 {'h','t','t','p','s',0},
197 {'f','t','p',0},
198 {'m','k',0},
199 {'i','t','s',0},
200 {'t','e','s','t',0}
201};
202
203static const WCHAR binding_urls[][130] = {
204 {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
205 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
206 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0},
207 {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
208 '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
209 {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
210 '/','p','u','b','/','o','t','h','e','r',
211 '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
212 {'m','k',':','t','e','s','t',0},
213 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0},
214 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
215};
216
217static const CHAR post_data[] = "mode=Test";
218
219static LONG obj_refcount(void *obj)
220{
221 IUnknown_AddRef((IUnknown *)obj);
222 return IUnknown_Release((IUnknown *)obj);
223}
224
225static int strcmp_wa(LPCWSTR strw, const char *stra)
226{
227 CHAR buf[512];
228 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
229 return lstrcmpA(stra, buf);
230}
231
232static const char *w2a(LPCWSTR str)
233{
234 static char buf[INTERNET_MAX_URL_LENGTH];
235 WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
236 return buf;
237}
238
240{
242 || IsEqualGUID(&IID_IHttpSecurity, riid)) {
243 *ppv = iface;
244 return S_OK;
245 }
246
247 ok(0, "unexpected call\n");
248 return E_NOINTERFACE;
249}
250
252{
253 return 2;
254}
255
257{
258 return 1;
259}
260
262{
263 trace("HttpSecurity_GetWindow\n");
264
265 return S_FALSE;
266}
267
269{
270 win_skip("Security problem: %u\n", dwProblem);
272 "Expected got %u security problem\n", dwProblem);
273
274 /* Only retry once */
276 return E_ABORT;
277
279 if(dwProblem == ERROR_INTERNET_INVALID_CA)
280 return E_ABORT;
281 SET_EXPECT(BeginningTransaction);
282
283 return RPC_E_RETRY;
284}
285
286static IHttpSecurityVtbl HttpSecurityVtbl = {
292};
293
295
297{
299 || IsEqualGUID(&IID_IHttpNegotiate, riid)
300 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
301 *ppv = iface;
302 return S_OK;
303 }
304
305 ok(0, "unexpected call\n");
306 return E_NOINTERFACE;
307}
308
310{
311 return 2;
312}
313
315{
316 return 1;
317}
318
320 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
321{
322 LPWSTR addl_headers;
323
324 static const WCHAR wszHeaders[] =
325 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
326 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
327 'd','e','d','\r','\n',0};
328
329 CHECK_EXPECT(BeginningTransaction);
330
331 if(binding_test)
332 ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
333 else
334 ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
335 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
336 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
337 if(pszAdditionalHeaders)
338 {
339 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
340 if (http_post_test)
341 {
342 addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
343 memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
344 *pszAdditionalHeaders = addl_headers;
345 }
346 }
347
348 return S_OK;
349}
350
352 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
353{
354 CHECK_EXPECT(OnResponse);
355
356 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
357 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
358 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
359 ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
360
361 return S_OK;
362}
363
365 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
366{
367 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
368
369 CHECK_EXPECT(GetRootSecurityId);
370
371 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
372 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
373 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
374
375 if(pcbSecurityId) {
376 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
377 *pcbSecurityId = sizeof(sec_id);
378 }
379
380 if(pbSecurityId)
381 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
382
383 return E_FAIL;
384}
385
386static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
393};
394
396
398{
399 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
400 *ppv = NULL;
401 return E_NOINTERFACE;
402}
403
405{
406 return 2;
407}
408
410{
411 return 1;
412}
413
415{
416 CHECK_EXPECT(Redirect);
417 *cancel = VARIANT_FALSE;
418 return S_OK;
419}
420
421static const IBindCallbackRedirectVtbl BindCallbackRedirectVtbl = {
426};
427
429
430static HRESULT QueryInterface(REFIID,void**);
431
433{
434 return QueryInterface(riid, ppv);
435}
436
438{
439 return 2;
440}
441
443{
444 return 1;
445}
446
448 REFIID riid, void **ppv)
449{
450 if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
451 CHECK_EXPECT2(QueryService_HttpNegotiate);
452 return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
453 }
454
455 if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
456 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
457 CHECK_EXPECT(QueryService_InternetProtocol);
458 return E_NOINTERFACE;
459 }
460
461 if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
462 ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
463 CHECK_EXPECT(QueryService_HttpSecurity);
464 return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
465 }
466
467 if(IsEqualGUID(&IID_IBindCallbackRedirect, guidService)) {
468 CHECK_EXPECT(QueryService_IBindCallbackRedirect);
469 ok(IsEqualGUID(&IID_IBindCallbackRedirect, riid), "riid = %s\n", wine_dbgstr_guid(riid));
471 return S_OK;
472 }
473
474 if(IsEqualGUID(&IID_IGetBindHandle, guidService)) {
475 trace("QueryService(IID_IGetBindHandle)\n");
476 *ppv = NULL;
477 return E_NOINTERFACE;
478 }
479
480 if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
481 trace("QueryService(IID_IWindowForBindingUI)\n");
482 *ppv = NULL;
483 return E_NOINTERFACE;
484 }
485
486 ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
487 return E_FAIL;
488}
489
490static const IServiceProviderVtbl ServiceProviderVtbl = {
495};
496
498
500{
501 static const IID IID_strm_unknown = {0x2f68429a,0x199a,0x4043,{0x93,0x11,0xf2,0xfe,0x7c,0x13,0xcc,0xb9}};
502
503 if(!IsEqualGUID(&IID_strm_unknown, riid)) /* IE11 */
504 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
505
506 *ppv = NULL;
507 return E_NOINTERFACE;
508}
509
511{
512 return 2;
513}
514
516{
517 return 1;
518}
519
520static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
521 ULONG cb, ULONG *pcbRead)
522{
524
525 ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
526
527 ok(pv != NULL, "pv == NULL\n");
528 ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
529 ok(pcbRead != NULL, "pcbRead == NULL\n");
530
531 if(post_stream_read) {
532 *pcbRead = 0;
533 return S_FALSE;
534 }
535
536 memcpy(pv, post_data, sizeof(post_data)-1);
537 post_stream_read += *pcbRead = sizeof(post_data)-1;
538 return S_OK;
539}
540
541static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
542 ULONG cb, ULONG *pcbWritten)
543{
544 ok(0, "unexpected call\n");
545 return E_NOTIMPL;
546}
547
549 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
550{
552
553 ok(!dlibMove.QuadPart, "dlibMove != 0\n");
554 ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
555 ok(!plibNewPosition, "plibNewPosition == NULL\n");
556
557 return S_OK;
558}
559
561{
562 ok(0, "unexpected call\n");
563 return E_NOTIMPL;
564}
565
567 ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
568{
569 ok(0, "unexpected call\n");
570 return E_NOTIMPL;
571}
572
573static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
574{
575 ok(0, "unexpected call\n");
576 return E_NOTIMPL;
577}
578
580{
581 ok(0, "unexpected call\n");
582 return E_NOTIMPL;
583}
584
586 ULARGE_INTEGER cb, DWORD dwLockType)
587{
588 ok(0, "unexpected call\n");
589 return E_NOTIMPL;
590}
591
593 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
594{
595 ok(0, "unexpected call\n");
596 return E_NOTIMPL;
597}
598
599static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
600 DWORD dwStatFlag)
601{
602 ok(0, "unexpected call\n");
603 return E_NOTIMPL;
604}
605
607{
608 ok(0, "unexpected call\n");
609 return E_NOTIMPL;
610}
611
612static const IStreamVtbl StreamVtbl = {
627};
628
630
632{
633 return QueryInterface(riid, ppv);
634}
635
637{
638 return 2;
639}
640
642{
643 return 1;
644}
645
646static void call_continue(PROTOCOLDATA *protocol_data)
647{
649
650 if (winetest_debug > 1)
651 trace("continue in state %d\n", state);
652
653 if(state == STATE_CONNECTING) {
655 if (http_is_first){
656 CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
657 CLEAR_CALLED(ReportProgress_PROXYDETECTING);
658 }
659 CLEAR_CALLED(ReportProgress_CONNECTING);
660 }
662 todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
663 else if (tested_protocol != HTTPS_TEST)
664 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
665 if(test_redirect && !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
666 CHECK_CALLED(ReportProgress_REDIRECTING);
668 }
669
670 switch(state) {
673 SET_EXPECT(ReportProgress_SENDINGREQUEST);
674 break;
677 && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))) {
678 SET_EXPECT(OnResponse);
680 SET_EXPECT(ReportProgress_ACCEPTRANGES);
681 SET_EXPECT(ReportProgress_ENCODING);
682 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
683 if(bindf & BINDF_NEEDFILE)
684 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
685 }
686 default:
687 break;
688 }
689
690 if(state != STATE_SENDINGREQUEST && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)))
691 SET_EXPECT(ReportData);
692 hres = IInternetProtocol_Continue(async_protocol, protocol_data);
693 ok(hres == S_OK, "Continue failed: %08x\n", hres);
695 CLEAR_CALLED(ReportData);
696 else if(state != STATE_SENDINGREQUEST && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)))
697 CHECK_CALLED(ReportData);
698
699 switch(state) {
702 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
704 break;
706 if(!security_problem) {
709 && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))) {
710 CHECK_CALLED(OnResponse);
712 CHECK_CALLED(ReportProgress_ACCEPTRANGES);
713 else if(test_redirect || test_abort)
714 CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
715 CLEAR_CALLED(ReportProgress_ENCODING);
716 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
717 if(bindf & BINDF_NEEDFILE)
718 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
719 }
720 }
721 else
722 {
724 SET_EXPECT(ReportProgress_CONNECTING);
725 }
726 default:
727 break;
728 }
729}
730
731static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
732{
734 CHECK_EXPECT2(Switch);
735 else
736 CHECK_EXPECT(Switch);
737
738 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
739 if(binding_test) {
740 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
741 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
742 pProtocolData->grfFlags, protocoldata.grfFlags );
743 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
744 pProtocolData->dwState, protocoldata.dwState );
745 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
746 pProtocolData->pData, protocoldata.pData );
747 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
748 pProtocolData->cbData, protocoldata.cbData );
749 }
750
751 pdata = pProtocolData;
752
753 if(binding_test) {
755 ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
756 return S_OK;
757 }if(direct_read) {
758 continue_protdata = *pProtocolData;
760 ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
761 }else {
762 call_continue(pProtocolData);
764 }
765
766 return S_OK;
767}
768
769static const char *status_names[] =
770{
771 "0",
772 "FINDINGRESOURCE",
773 "CONNECTING",
774 "REDIRECTING",
775 "BEGINDOWNLOADDATA",
776 "DOWNLOADINGDATA",
777 "ENDDOWNLOADDATA",
778 "BEGINDOWNLOADCOMPONENTS",
779 "INSTALLINGCOMPONENTS",
780 "ENDDOWNLOADCOMPONENTS",
781 "USINGCACHEDCOPY",
782 "SENDINGREQUEST",
783 "CLASSIDAVAILABLE",
784 "MIMETYPEAVAILABLE",
785 "CACHEFILENAMEAVAILABLE",
786 "BEGINSYNCOPERATION",
787 "ENDSYNCOPERATION",
788 "BEGINUPLOADDATA",
789 "UPLOADINGDATA",
790 "ENDUPLOADINGDATA",
791 "PROTOCOLCLASSID",
792 "ENCODING",
793 "VERIFIEDMIMETYPEAVAILABLE",
794 "CLASSINSTALLLOCATION",
795 "DECODING",
796 "LOADINGMIMEHANDLER",
797 "CONTENTDISPOSITIONATTACH",
798 "FILTERREPORTMIMETYPE",
799 "CLSIDCANINSTANTIATE",
800 "IUNKNOWNAVAILABLE",
801 "DIRECTBIND",
802 "RAWMIMETYPE",
803 "PROXYDETECTING",
804 "ACCEPTRANGES",
805 "COOKIE_SENT",
806 "COMPACT_POLICY_RECEIVED",
807 "COOKIE_SUPPRESSED",
808 "COOKIE_STATE_UNKNOWN",
809 "COOKIE_STATE_ACCEPT",
810 "COOKIE_STATE_REJECT",
811 "COOKIE_STATE_PROMPT",
812 "COOKIE_STATE_LEASH",
813 "COOKIE_STATE_DOWNGRADE",
814 "POLICY_HREF",
815 "P3P_HEADER",
816 "SESSION_COOKIE_RECEIVED",
817 "PERSISTENT_COOKIE_RECEIVED",
818 "SESSION_COOKIES_ALLOWED",
819 "CACHECONTROL",
820 "CONTENTDISPOSITIONFILENAME",
821 "MIMETEXTPLAINMISMATCH",
822 "PUBLISHERAVAILABLE",
823 "DISPLAYNAMEAVAILABLE"
824};
825
827 LPCWSTR szStatusText)
828{
829 static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
830 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
831 static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
832
833 if (winetest_debug > 1)
834 {
835 if (ulStatusCode < ARRAY_SIZE(status_names))
836 trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
837 else
838 trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
839 }
840
841 switch(ulStatusCode) {
842 case BINDSTATUS_MIMETYPEAVAILABLE:
843 CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
844 if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
845 if(!short_read || !direct_read)
846 CHECK_CALLED(Read); /* set in Continue */
847 else if(short_read)
848 CHECK_CALLED(Read2); /* set in Read */
849 }
850 ok(szStatusText != NULL, "szStatusText == NULL\n");
851 if(szStatusText) {
853 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
854 else if (http_post_test)
855 ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
856 !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
857 "szStatusText != text/plain\n");
858 else if(empty_file)
859 ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
860 else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
862 ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
863 !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
864 "szStatusText != image/gif\n");
865 else if(!mimefilter_test)
866 ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
867 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
868 "szStatusText != text/html\n");
869 }
870 break;
871 case BINDSTATUS_DIRECTBIND:
872 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
873 ok(szStatusText == NULL, "szStatusText != NULL\n");
874 break;
875 case BINDSTATUS_RAWMIMETYPE:
876 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
877 ok(szStatusText != NULL, "szStatusText == NULL\n");
878 if(szStatusText)
879 ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
880 !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
881 "szStatusText != text/html\n");
882 break;
883 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
884 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
885 ok(szStatusText != NULL, "szStatusText == NULL\n");
886 if(szStatusText) {
887 if(binding_test)
888 ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
889 else if(tested_protocol == FILE_TEST)
890 ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
891 else
892 ok(szStatusText != NULL, "szStatusText == NULL\n");
893 }
894 break;
895 case BINDSTATUS_FINDINGRESOURCE:
896 CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
897 ok(szStatusText != NULL, "szStatusText == NULL\n");
898 break;
899 case BINDSTATUS_CONNECTING:
900 CHECK_EXPECT2(ReportProgress_CONNECTING);
901 ok(szStatusText != NULL, "szStatusText == NULL\n");
902 break;
903 case BINDSTATUS_SENDINGREQUEST:
904 CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
906 ok(szStatusText != NULL, "szStatusText == NULL\n");
907 if(szStatusText)
908 ok(!*szStatusText, "wrong szStatusText\n");
909 }
910 break;
911 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
912 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
913 ok(szStatusText != NULL, "szStatusText == NULL\n");
914 if(szStatusText)
915 ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
916 break;
917 case BINDSTATUS_PROTOCOLCLASSID:
918 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
919 ok(szStatusText != NULL, "szStatusText == NULL\n");
920 ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
921 break;
922 case BINDSTATUS_COOKIE_SENT:
923 CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
924 ok(szStatusText == NULL, "szStatusText != NULL\n");
925 break;
926 case BINDSTATUS_REDIRECTING:
927 CHECK_EXPECT(ReportProgress_REDIRECTING);
928 if(test_redirect)
929 ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
930 else
931 ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
932 break;
933 case BINDSTATUS_ENCODING:
934 CHECK_EXPECT(ReportProgress_ENCODING);
935 ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
936 break;
937 case BINDSTATUS_ACCEPTRANGES:
938 CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
939 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
940 break;
941 case BINDSTATUS_PROXYDETECTING:
942 if(!called_ReportProgress_PROXYDETECTING)
943 SET_EXPECT(ReportProgress_CONNECTING);
944 CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
945 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
946 break;
947 case BINDSTATUS_LOADINGMIMEHANDLER:
948 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
949 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
950 break;
951 case BINDSTATUS_DECODING:
952 CHECK_EXPECT(ReportProgress_DECODING);
953 ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
954 break;
955 case BINDSTATUS_RESERVED_7:
956 trace("BINDSTATUS_RESERVED_7\n");
957 break;
958 case BINDSTATUS_RESERVED_8:
959 trace("BINDSTATUS_RESERVED_8\n");
960 break;
961 default:
962 ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
963 };
964
965 return S_OK;
966}
967
969{
971 char buf[1024];
972 DWORD size, len;
974
975 static const WCHAR connectionW[] = {'c','o','n','n','e','c','t','i','o','n',0};
976
977 hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
978 ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
979
980 size = sizeof(buf);
981 strcpy(buf, "connection");
982 hres = IWinInetHttpInfo_QueryInfo(info, HTTP_QUERY_CUSTOM, buf, &size, NULL, NULL);
984 ok(hres == S_OK, "QueryInfo failed: %08x\n", hres);
985
986 ok(!strcmp(buf, "Keep-Alive"), "buf = %s\n", buf);
987 len = strlen(buf);
988 ok(size == len, "size = %u, expected %u\n", size, len);
989
990 size = sizeof(buf);
991 memcpy(buf, connectionW, sizeof(connectionW));
992 hres = IWinInetHttpInfo_QueryInfo(info, HTTP_QUERY_CUSTOM, buf, &size, NULL, NULL);
993 ok(hres == S_FALSE, "QueryInfo returned %08x\n", hres);
994 }else {
995 ok(hres == S_FALSE, "QueryInfo failed: %08x\n", hres);
996 }
997
998 IWinInetHttpInfo_Release(info);
999}
1000
1002 ULONG ulProgress, ULONG ulProgressMax)
1003{
1004 HRESULT hres;
1005
1006 static int rec_depth;
1007 rec_depth++;
1008
1010 CHECK_EXPECT2(ReportData);
1011
1012 ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
1013 ulProgress, ulProgressMax);
1014 if(!file_with_hash)
1015 ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
1016 /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
1018 ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
1019 (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
1020 "grcfBSCF = %08x\n", grfBSCF);
1021 else
1022 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
1023 }else if(bind_from_cache) {
1024 CHECK_EXPECT(ReportData);
1025
1026 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
1027 ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
1028 ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
1029 }else if(direct_read) {
1030 BYTE buf[14096];
1031 ULONG read;
1032
1033 if(!read_report_data && rec_depth == 1) {
1034 BOOL reported_all_data = called_ReportData2;
1035
1036 CHECK_EXPECT2(ReportData);
1037
1038 if(short_read) {
1039 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
1040 || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
1041 "grcfBSCF = %08x\n", grfBSCF);
1042 CHECK_CALLED(Read); /* Set in Continue */
1044 }else if(first_data_notif) {
1045 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
1047 }else if(reported_all_data) {
1048 ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
1049 "grcfBSCF = %08x\n", grfBSCF);
1050 }else if(!direct_read) {
1051 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
1052 }
1053
1054 do {
1055 read = 0;
1056 if(emulate_prot)
1058 else
1059 SET_EXPECT(ReportData2);
1060 SET_EXPECT(ReportResult);
1061 if(!emulate_prot)
1062 SET_EXPECT(Switch);
1063 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
1064 ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
1065 if(hres == S_OK)
1066 ok(read, "read == 0\n");
1067 if(reported_all_data)
1068 ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
1069 if(!emulate_prot && hres != E_PENDING)
1070 CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
1071 if(emulate_prot)
1073 if(!reported_all_data && called_ReportData2) {
1074 if(!emulate_prot)
1075 CHECK_CALLED(ReportData2);
1076 CHECK_CALLED(ReportResult);
1077 reported_all_data = TRUE;
1078 }else {
1079 if(!emulate_prot)
1080 CHECK_NOT_CALLED(ReportData2);
1081 CHECK_NOT_CALLED(ReportResult);
1082 }
1083 }while(hres == S_OK);
1084 if(hres == S_FALSE)
1086 }else {
1087 CHECK_EXPECT(ReportData2);
1088
1089 ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
1090
1091 read = 0xdeadbeef;
1092 if(emulate_prot)
1093 SET_EXPECT(Read2);
1094 hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
1095 if(emulate_prot)
1096 CHECK_CALLED(Read2);
1097 ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
1098 ok(!read, "read = %d\n", read);
1099 }
1101 || tested_protocol == FTP_TEST)) {
1102 if(empty_file)
1103 CHECK_EXPECT2(ReportData);
1104 else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
1105 CHECK_EXPECT(ReportData);
1106 else if (http_post_test)
1107 ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
1108
1109 if(empty_file) {
1110 ok(!ulProgress, "ulProgress = %d\n", ulProgress);
1111 ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
1112 }else {
1113 ok(ulProgress, "ulProgress == 0\n");
1114 }
1115
1116 if(empty_file) {
1117 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1118 "grcfBSCF = %08x\n", grfBSCF);
1120 }else if(first_data_notif) {
1121 ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1122 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1123 "grcfBSCF = %08x\n", grfBSCF);
1125 } else {
1126 ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1127 || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1128 || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1129 "grcfBSCF = %08x\n", grfBSCF);
1130 }
1131
1132 if((grfBSCF & BSCF_FIRSTDATANOTIFICATION) && !binding_test)
1134
1135 if(!(bindf & BINDF_FROMURLMON) &&
1136 !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1137 if(state == STATE_CONNECTING) {
1139 if(http_is_first) {
1140 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1141 CHECK_CALLED(ReportProgress_CONNECTING);
1142 }
1143 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1144 CHECK_CALLED(OnResponse);
1145 CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1146 }
1148 }
1149 }else if(!read_report_data) {
1150 BYTE buf[1000];
1151 ULONG read;
1152 HRESULT hres;
1153
1154 CHECK_EXPECT(ReportData);
1155
1156 if(tested_protocol != BIND_TEST) {
1157 do {
1158 if(mimefilter_test)
1159 SET_EXPECT(MimeFilter_Read);
1160 else if(rec_depth > 1)
1161 SET_EXPECT(Read2);
1162 else
1164 hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1165 if(mimefilter_test)
1166 CHECK_CALLED(MimeFilter_Read);
1167 else if(rec_depth > 1)
1168 CHECK_CALLED(Read2);
1169 else
1171 }while(hres == S_OK);
1172 }
1173 }
1174
1175 rec_depth--;
1176 return S_OK;
1177}
1178
1180 DWORD dwError, LPCWSTR szResult)
1181{
1182 CHECK_EXPECT(ReportResult);
1183
1185 return S_OK;
1186
1188 ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1189 else
1190 ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1191 hrResult, expect_hrResult);
1192#ifdef __REACTOS__
1194 skip("CORE-10360/ROSTESTS-192: Test might hang, skipping the rest!\n");
1195 exit(1);
1196 }
1197#endif
1198 if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort || hrResult == INET_E_REDIRECT_FAILED)
1199 ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1200 else
1201 ok(dwError != ERROR_SUCCESS ||
1202 broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1203 "dwError == ERROR_SUCCESS\n");
1204
1205 if(hrResult == INET_E_REDIRECT_FAILED)
1206 ok(!strcmp_wa(szResult, "http://test.winehq.org/tests/hello.html"), "szResult = %s\n", wine_dbgstr_w(szResult));
1207 else
1208 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1209
1210 if(direct_read)
1211 SET_EXPECT(ReportData); /* checked after main loop */
1212
1213 return S_OK;
1214}
1215
1216static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1224};
1225
1227
1229{
1231 || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
1232 *ppv = iface;
1233 return S_OK;
1234 }
1235
1236 ok(0, "unexpected call\n");
1237 return E_NOTIMPL;
1238}
1239
1241{
1242 return 2;
1243}
1244
1246{
1247 return 1;
1248}
1249
1250static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1251{
1252 HRESULT hres;
1253
1254 CHECK_EXPECT(MimeFilter_Switch);
1255
1256 SET_EXPECT(Switch);
1257 hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1258 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1259 CHECK_CALLED(Switch);
1260
1261 return S_OK;
1262}
1263
1265 LPCWSTR szStatusText)
1266{
1267 switch(ulStatusCode) {
1268 case BINDSTATUS_LOADINGMIMEHANDLER:
1269 /*
1270 * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1271 * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1272 * ProtocolSink_ReportProgress to workaround it.
1273 */
1274 CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1275 ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1276 break;
1277 default:
1278 ok(0, "Unexpected status code %d\n", ulStatusCode);
1279 }
1280
1281 return S_OK;
1282}
1283
1285 ULONG ulProgress, ULONG ulProgressMax)
1286{
1287 DWORD read = 0;
1288 BYTE buf[8192];
1289 HRESULT hres;
1291
1292 CHECK_EXPECT(MimeFilter_ReportData);
1293
1294 if(!filter_state && !no_mime) {
1296 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1298 ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1299 else
1300 ok(hres == S_OK, "Read failed: %08x\n", hres);
1302
1303 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1304 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1305 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1306 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1307
1308 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1309 hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1310 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1311 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1312
1313 /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1314 }
1315
1316 if(no_mime && prot_read<200) {
1318 }else if(no_mime && prot_read<300) {
1319 report_mime = TRUE;
1321 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1322 SET_EXPECT(ReportData);
1323 }else if(!read_report_data) {
1324 SET_EXPECT(ReportData);
1325 }
1326 hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1327 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1328 if(no_mime && prot_read<=200) {
1330 }else if(report_mime) {
1331 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1332 CHECK_CALLED(ReportData);
1333 }else if(!read_report_data) {
1334 CHECK_CALLED(ReportData);
1335 }
1336
1337 if(!filter_state)
1338 filter_state = 1;
1339
1340 return S_OK;
1341}
1342
1344 DWORD dwError, LPCWSTR szResult)
1345{
1346 HRESULT hres;
1347
1348 CHECK_EXPECT(MimeFilter_ReportResult);
1349
1350 ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1351 ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1352 ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1353
1354 SET_EXPECT(ReportResult);
1355 hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1356 ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1357 CHECK_CALLED(ReportResult);
1358
1359 return S_OK;
1360}
1361
1362static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1370};
1371
1373
1375{
1376 static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1377 static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1378
1379 *ppv = NULL;
1380
1381 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1382 *ppv = &protocol_sink;
1383 if(IsEqualGUID(&IID_IServiceProvider, riid))
1385 if(IsEqualGUID(&IID_IUriContainer, riid))
1386 return E_NOINTERFACE; /* TODO */
1387
1388 /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1389 if(IsEqualGUID(&IID_undocumented, riid))
1390 return E_NOINTERFACE;
1391 /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1392 if(IsEqualGUID(&IID_undocumentedIE10, riid))
1393 return E_NOINTERFACE;
1394
1395 if(*ppv)
1396 return S_OK;
1397
1398 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1399 return E_NOINTERFACE;
1400}
1401
1403{
1404 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1405 *ppv = iface;
1406 return S_OK;
1407 }
1408 return E_NOINTERFACE;
1409}
1410
1412{
1413 return 2;
1414}
1415
1417{
1418 return 1;
1419}
1420
1421static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1422{
1423 DWORD cbSize;
1424
1425 CHECK_EXPECT(GetBindInfo);
1426
1427 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1428 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1429 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1430
1431 *grfBINDF = bindf;
1432 if(binding_test)
1433 *grfBINDF |= BINDF_FROMURLMON;
1434 cbSize = pbindinfo->cbSize;
1435 memset(pbindinfo, 0, cbSize);
1436 pbindinfo->cbSize = cbSize;
1437 pbindinfo->dwOptions = bindinfo_options;
1438
1439 if(http_post_test)
1440 {
1441 pbindinfo->cbstgmedData = sizeof(post_data)-1;
1442 pbindinfo->dwBindVerb = BINDVERB_POST;
1443 pbindinfo->stgmedData.tymed = http_post_test;
1444
1445 if(http_post_test == TYMED_HGLOBAL) {
1446 HGLOBAL data;
1447
1448 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1449 data = GlobalAlloc(GPTR, sizeof(post_data));
1450 memcpy(data, post_data, sizeof(post_data));
1451 U(pbindinfo->stgmedData).hGlobal = data;
1452 }else {
1453 U(pbindinfo->stgmedData).pstm = &Stream;
1454 }
1455 }
1456
1457 return S_OK;
1458}
1459
1461 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1462{
1463 ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1464 ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1465
1466 switch(ulStringType) {
1467 case BINDSTRING_ACCEPT_MIMES:
1468 CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1469 ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1470 if(pcElFetched) {
1471 ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1472 *pcElFetched = 1;
1473 }
1474 if(ppwzStr) {
1475 *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1476 memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1477 }
1478 return S_OK;
1479 case BINDSTRING_USER_AGENT:
1480 CHECK_EXPECT(GetBindString_USER_AGENT);
1481 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1482 if(pcElFetched) {
1483 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1484 *pcElFetched = 1;
1485 }
1486 if(ppwzStr) {
1487 *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1488 memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1489 }
1490 return S_OK;
1491 case BINDSTRING_POST_COOKIE:
1492 CHECK_EXPECT(GetBindString_POST_COOKIE);
1493 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1494 if(pcElFetched)
1495 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1496 return S_OK;
1497 case BINDSTRING_URL: {
1498 DWORD size;
1499
1500 CHECK_EXPECT(GetBindString_URL);
1501 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1502 ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1503 *pcElFetched = 1;
1504
1506 *ppwzStr = CoTaskMemAlloc(size);
1508 return S_OK;
1509 }
1510 case BINDSTRING_ROOTDOC_URL:
1511 CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1512 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1513 return E_NOTIMPL;
1514 case BINDSTRING_ENTERPRISE_ID:
1515 ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1516 return E_NOTIMPL;
1517 default:
1518 ok(0, "unexpected ulStringType %d\n", ulStringType);
1519 }
1520
1521 return E_NOTIMPL;
1522}
1523
1524static IInternetBindInfoVtbl bind_info_vtbl = {
1530};
1531
1533
1535{
1536 return CONTAINING_RECORD(iface, Protocol, IInternetPriority_iface);
1537}
1538
1540 REFIID riid, void **ppv)
1541{
1542 ok(0, "unexpected call\n");
1543 return E_NOINTERFACE;
1544}
1545
1547{
1549 if (This->outer)
1550 {
1551 This->outer_ref++;
1552 return IUnknown_AddRef(This->outer);
1553 }
1554 return IUnknown_AddRef(&This->IUnknown_inner);
1555}
1556
1558{
1560 if (This->outer)
1561 {
1562 This->outer_ref--;
1563 return IUnknown_Release(This->outer);
1564 }
1565 return IUnknown_Release(&This->IUnknown_inner);
1566}
1567
1569{
1571 ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1572 return S_OK;
1573}
1574
1576{
1577 ok(0, "unexpected call\n");
1578 return E_NOTIMPL;
1579}
1580
1581
1582static const IInternetPriorityVtbl InternetPriorityVtbl = {
1588};
1589
1591{
1592 return 2;
1593}
1594
1596{
1597 return 1;
1598}
1599
1602{
1603 HRESULT hres;
1604
1605 CHECK_EXPECT(Abort);
1606
1607 SET_EXPECT(ReportResult);
1608 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1609 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1610 CHECK_CALLED(ReportResult);
1611
1612 return S_OK;
1613}
1614
1616{
1617 ok(0, "unexpected call\n");
1618 return E_NOTIMPL;
1619}
1620
1622{
1623 ok(0, "unexpected call\n");
1624 return E_NOTIMPL;
1625}
1626
1628 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1629{
1630 ok(0, "unexpected call\n");
1631 return E_NOTIMPL;
1632}
1633
1635{
1636 return CONTAINING_RECORD(iface, Protocol, IInternetProtocolEx_iface);
1637}
1638
1640{
1642
1643 static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1644 static const IID unknown_iid2 = {0x5b7ebc0c,0xf630,0x4cea,{0x89,0xd3,0x5a,0xf0,0x38,0xed,0x05,0x5c}};
1645
1646 if(IsEqualGUID(riid, &IID_IInternetProtocolEx)) {
1647 *ppv = &This->IInternetProtocolEx_iface;
1648 IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
1649 return S_OK;
1650 }
1651
1652 /* FIXME: Why is it calling here instead of outer IUnknown? */
1653 if(IsEqualGUID(riid, &IID_IInternetPriority)) {
1654 *ppv = &This->IInternetPriority_iface;
1655 IInternetPriority_AddRef(&This->IInternetPriority_iface);
1656 return S_OK;
1657 }
1658 if(!IsEqualGUID(riid, &unknown_iid) && !IsEqualGUID(riid, &unknown_iid2)) /* IE10 */
1659 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1660 *ppv = NULL;
1661 return E_NOINTERFACE;
1662}
1663
1665{
1667 if (This->outer)
1668 {
1669 This->outer_ref++;
1670 return IUnknown_AddRef(This->outer);
1671 }
1672 return IUnknown_AddRef(&This->IUnknown_inner);
1673}
1674
1676{
1678 if (This->outer)
1679 {
1680 This->outer_ref--;
1681 return IUnknown_Release(This->outer);
1682 }
1683 return IUnknown_Release(&This->IUnknown_inner);
1684}
1685
1687{
1688 BOOL redirect = redirect_on_continue;
1689 HRESULT hres;
1690
1691 memset(&protocoldata, -1, sizeof(protocoldata));
1692
1693 while(1) {
1694 prot_state = 0;
1695
1696 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1697 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1698 BINDSTATUS_FINDINGRESOURCE, hostW);
1699 CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1700 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1701
1702 SET_EXPECT(ReportProgress_CONNECTING);
1703 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1704 BINDSTATUS_CONNECTING, winehq_ipW);
1705 CHECK_CALLED(ReportProgress_CONNECTING);
1706 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1707
1708 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1709 hres = IInternetProtocolSink_ReportProgress(binding_sink,
1710 BINDSTATUS_SENDINGREQUEST, NULL);
1711 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1712 ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1713
1714 prot_state = 1;
1715 SET_EXPECT(Switch);
1716 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1717 CHECK_CALLED(Switch);
1718 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1719
1720 if(!redirect)
1721 break;
1722 redirect = FALSE;
1723 }
1724
1725 if(!short_read) {
1726 prot_state = 2;
1727 if(mimefilter_test)
1728 SET_EXPECT(MimeFilter_Switch);
1729 else
1730 SET_EXPECT(Switch);
1731 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1732 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1733 if(mimefilter_test)
1734 CHECK_CALLED(MimeFilter_Switch);
1735 else
1736 CHECK_CALLED(Switch);
1737
1738 if(test_abort) {
1740 return 0;
1741 }
1742
1743 prot_state = 2;
1744 if(mimefilter_test)
1745 SET_EXPECT(MimeFilter_Switch);
1746 else
1747 SET_EXPECT(Switch);
1748 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1749 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1750 if(mimefilter_test)
1751 CHECK_CALLED(MimeFilter_Switch);
1752 else
1753 CHECK_CALLED(Switch);
1754
1755 prot_state = 3;
1756 if(mimefilter_test)
1757 SET_EXPECT(MimeFilter_Switch);
1758 else
1759 SET_EXPECT(Switch);
1760 hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1761 ok(hres == S_OK, "Switch failed: %08x\n", hres);
1762 if(mimefilter_test)
1763 CHECK_CALLED(MimeFilter_Switch);
1764 else
1765 CHECK_CALLED(Switch);
1766 }
1767
1769
1770 return 0;
1771}
1772
1773static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1774{
1775 BINDINFO bindinfo, exp_bindinfo;
1776 DWORD cbindf = 0;
1777 HRESULT hres;
1778
1779 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1780 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1781 ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1782 ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1783 ok(!pi, "pi = %x\n", pi);
1784
1785 if(binding_test)
1786 ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1787
1788 memset(&bindinfo, 0, sizeof(bindinfo));
1789 bindinfo.cbSize = sizeof(bindinfo);
1790 memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1791 if(test_redirect)
1792 exp_bindinfo.dwOptions = bindinfo_options;
1793 SET_EXPECT(GetBindInfo);
1794 if(redirect_on_continue && (bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
1795 SET_EXPECT(QueryService_IBindCallbackRedirect);
1796 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1797 if(redirect_on_continue && (bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
1798 CHECK_CALLED(QueryService_IBindCallbackRedirect);
1799 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1800 CHECK_CALLED(GetBindInfo);
1801 ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1802 cbindf, (bindf|BINDF_FROMURLMON));
1803 ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1804 pReleaseBindInfo(&bindinfo);
1805
1806 SET_EXPECT(ReportProgress_SENDINGREQUEST);
1807 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1808 ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1809 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1810
1814 IHttpNegotiate2 *http_negotiate2;
1815 LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1816 LPWSTR additional_headers = NULL;
1817 BYTE sec_id[100];
1818 DWORD fetched = 0, size = 100;
1819 DWORD tid;
1820
1821 SET_EXPECT(GetBindString_USER_AGENT);
1822 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1823 &ua, 1, &fetched);
1824 CHECK_CALLED(GetBindString_USER_AGENT);
1825 ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1826 ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1827 ok(ua != NULL, "ua = %p\n", ua);
1828 ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1829 CoTaskMemFree(ua);
1830
1831 fetched = 256;
1832 SET_EXPECT(GetBindString_ACCEPT_MIMES);
1833 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1834 accept_mimes, 256, &fetched);
1835 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1836
1837 ok(hres == S_OK,
1838 "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1839 ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1840 ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1841 CoTaskMemFree(accept_mimes[0]);
1842
1843 hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1844 (void**)&service_provider);
1845 ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1846
1847 SET_EXPECT(QueryService_HttpNegotiate);
1848 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1849 &IID_IHttpNegotiate, (void**)&http_negotiate);
1850 CHECK_CALLED(QueryService_HttpNegotiate);
1851 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1852
1853 SET_EXPECT(BeginningTransaction);
1854 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1855 NULL, 0, &additional_headers);
1856 CHECK_CALLED(BeginningTransaction);
1857 IHttpNegotiate_Release(http_negotiate);
1858 ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1859 ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1860
1861 SET_EXPECT(QueryService_HttpNegotiate);
1862 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1863 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1864 CHECK_CALLED(QueryService_HttpNegotiate);
1865 ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1866
1867 size = 512;
1868 SET_EXPECT(GetRootSecurityId);
1869 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1870 CHECK_CALLED(GetRootSecurityId);
1871 IHttpNegotiate2_Release(http_negotiate2);
1872 ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1873 ok(size == 13, "size=%d\n", size);
1874
1875 IServiceProvider_Release(service_provider);
1876
1879 return;
1880 }
1881
1882 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1883 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1884 BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1885 ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1886 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1887
1888 if(mimefilter_test) {
1890 SET_EXPECT(MimeFilter_Start);
1891 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1892 }
1893 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1894 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1896 ok(hres == S_OK,
1897 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1898 if(mimefilter_test) {
1900 CHECK_CALLED(MimeFilter_Start);
1901 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1902 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1903 }else {
1904 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1905 }
1906
1907 if(mimefilter_test)
1908 SET_EXPECT(MimeFilter_ReportData);
1909 else
1910 SET_EXPECT(ReportData);
1911 hres = IInternetProtocolSink_ReportData(pOIProtSink,
1912 BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1913 13, 13);
1914 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1915 if(mimefilter_test)
1916 CHECK_CALLED(MimeFilter_ReportData);
1917 else
1918 CHECK_CALLED(ReportData);
1919
1920 if(tested_protocol == ITS_TEST) {
1921 SET_EXPECT(ReportData);
1922 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1923 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1924 CHECK_CALLED(ReportData);
1925 }
1926
1927 if(tested_protocol == BIND_TEST) {
1928 hres = IInternetProtocol_Terminate(binding_protocol, 0);
1929 ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1930 }
1931
1932 if(mimefilter_test)
1933 SET_EXPECT(MimeFilter_ReportResult);
1934 else
1935 SET_EXPECT(ReportResult);
1936 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1937 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1938 if(mimefilter_test)
1939 CHECK_CALLED(MimeFilter_ReportResult);
1940 else
1941 CHECK_CALLED(ReportResult);
1942}
1943
1945 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1947{
1949
1950 ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1951 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1952 return S_OK;
1953}
1954
1956 PROTOCOLDATA *pProtocolData)
1957{
1958 DWORD bscf = 0, pr;
1959 HRESULT hres;
1960
1961 CHECK_EXPECT(Continue);
1962
1963 ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1964 if(!pProtocolData || tested_protocol == BIND_TEST)
1965 return S_OK;
1966 if(binding_test) {
1967 ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1968 ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1969 pProtocolData->grfFlags, protocoldata.grfFlags );
1970 ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1971 pProtocolData->dwState, protocoldata.dwState );
1972 ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1973 pProtocolData->pData, protocoldata.pData );
1974 ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1975 pProtocolData->cbData, protocoldata.cbData );
1976 }
1977
1978 switch(prot_state) {
1979 case 1: {
1982 static const WCHAR header[] = {'?',0};
1983 static const WCHAR redirect_urlW[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
1984 '/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
1985
1989
1990 if(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)
1991 SET_EXPECT(Redirect);
1992 SET_EXPECT(ReportProgress_REDIRECTING);
1993 SET_EXPECT(Terminate);
1994 SET_EXPECT(Protocol_destructor);
1995 SET_EXPECT(QueryService_InternetProtocol);
1996 SET_EXPECT(CreateInstance);
1997 SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
2000 hres = IInternetProtocolSink_ReportResult(binding_sink, INET_E_REDIRECT_FAILED, ERROR_SUCCESS, redirect_urlW);
2001 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
2002 if(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)
2003 CHECK_CALLED(Redirect);
2004 CHECK_CALLED(ReportProgress_REDIRECTING);
2005 CHECK_CALLED(Terminate);
2006 CHECK_CALLED(Protocol_destructor);
2007 CHECK_CALLED(QueryService_InternetProtocol);
2008 CHECK_CALLED(CreateInstance);
2009 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
2012
2013 return S_OK;
2014 }
2015
2016 hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
2017 (void**)&service_provider);
2018 ok(hres == S_OK, "Could not get IServiceProvicder\n");
2019
2020 SET_EXPECT(QueryService_HttpNegotiate);
2021 hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
2022 &IID_IHttpNegotiate, (void**)&http_negotiate);
2023 IServiceProvider_Release(service_provider);
2024 CHECK_CALLED(QueryService_HttpNegotiate);
2025 ok(hres == S_OK, "Could not get IHttpNegotiate\n");
2026
2027 SET_EXPECT(OnResponse);
2028 hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
2029 IHttpNegotiate_Release(http_negotiate);
2030 CHECK_CALLED(OnResponse);
2031 IHttpNegotiate_Release(http_negotiate);
2032 ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
2033
2034 if(mimefilter_test) {
2036 SET_EXPECT(MimeFilter_Start);
2037 SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
2038 }else if(!(pi & PI_MIMEVERIFICATION)) {
2039 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2040 }
2041 hres = IInternetProtocolSink_ReportProgress(binding_sink,
2042 BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
2043 if(mimefilter_test) {
2045 CHECK_CALLED(MimeFilter_Start);
2046 CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
2047 }else if(!(pi & PI_MIMEVERIFICATION)) {
2048 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2049 }
2050 ok(hres == S_OK,
2051 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
2052
2053 bscf |= BSCF_FIRSTDATANOTIFICATION;
2054 break;
2055 }
2056 case 2:
2057 case 3:
2058 bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
2059 break;
2060 }
2061
2062 pr = prot_read;
2063 if(mimefilter_test)
2064 SET_EXPECT(MimeFilter_ReportData);
2065 if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
2066 if(pr < 200)
2067 SET_EXPECT(Read); /* checked in ReportData for short_read */
2068 if(pr == 200) {
2069 if(!mimefilter_test)
2070 SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
2071 SET_EXPECT(GetBindInfo);
2072 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2073 }
2074 if(pr >= 200)
2075 SET_EXPECT(ReportData);
2076 }else {
2077 SET_EXPECT(ReportData);
2078 }
2079
2080 hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
2081 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
2082
2083 if(mimefilter_test) {
2084 SET_EXPECT(MimeFilter_ReportData);
2085 }else if(pi & PI_MIMEVERIFICATION) {
2086 if(!short_read && pr < 200)
2088 if(pr == 200) {
2089 CLEAR_CALLED(GetBindInfo); /* IE9 */
2090 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2091 }
2092 }else {
2093 CHECK_CALLED(ReportData);
2094 }
2095
2096 if(prot_state == 3)
2097 prot_state = 4;
2098
2099 return S_OK;
2100}
2101
2103{
2104 CHECK_EXPECT(Terminate);
2105 ok(!dwOptions, "dwOptions=%d\n", dwOptions);
2106 return S_OK;
2107}
2108
2110 ULONG cb, ULONG *pcbRead)
2111{
2113 CHECK_EXPECT2(Read2);
2114
2116 if(!read_report_data)
2118 }else if((pi & PI_MIMEVERIFICATION)) {
2119 if(!read_report_data)
2121
2122 if(prot_read < 300) {
2123 ok(pv != expect_pv, "pv == expect_pv\n");
2124 if(prot_read < 300)
2125 ok(cb == 2048-prot_read, "cb=%d\n", cb);
2126 else
2127 ok(cb == 700, "cb=%d\n", cb);
2128 }else {
2129 ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
2130 }
2131 }else {
2132 if(!read_report_data)
2134
2135 ok(pv == expect_pv, "pv != expect_pv\n");
2136 ok(cb == 1000, "cb=%d\n", cb);
2137 ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
2138 }
2139 ok(pcbRead != NULL, "pcbRead == NULL\n");
2140
2141 if(prot_state == 3 || (short_read && prot_state != 4)) {
2142 HRESULT hres;
2143
2144 prot_state = 4;
2145 if(short_read) {
2146 SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
2147 SET_EXPECT(GetBindInfo);
2148 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2149 }
2150 if(mimefilter_test)
2151 SET_EXPECT(MimeFilter_ReportData);
2152 else if(direct_read)
2153 SET_EXPECT(ReportData2);
2155 hres = IInternetProtocolSink_ReportData(binding_sink,
2156 BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
2158 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
2159 if(short_read) {
2160 CLEAR_CALLED(GetBindInfo); /* IE9 */
2161 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2162 }
2163 if(mimefilter_test)
2164 CHECK_CALLED(MimeFilter_ReportData);
2165 else if(direct_read)
2166 CHECK_CALLED(ReportData2);
2167
2168 if(mimefilter_test)
2169 SET_EXPECT(MimeFilter_ReportResult);
2170 else
2171 SET_EXPECT(ReportResult);
2172 hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
2173 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
2174 if(mimefilter_test)
2175 CHECK_CALLED(MimeFilter_ReportResult);
2176 else
2177 CHECK_CALLED(ReportResult);
2178
2179 if(cb > 100)
2180 cb = 100;
2181 memset(pv, 'x', cb);
2182 if(cb>6)
2183 memcpy(pv, "gif87a", 6);
2184 prot_read += *pcbRead = cb;
2185 return S_OK;
2186 }
2187
2188 if(prot_state == 4) {
2189 *pcbRead = 0;
2190 return S_FALSE;
2191 }
2192
2194 *pcbRead = 0;
2196 }
2197
2198 if(cb > 100)
2199 cb = 100;
2200 memset(pv, 'x', cb);
2201 if(cb>6)
2202 memcpy(pv, "gif87a", 6);
2203 prot_read += *pcbRead = cb;
2204 return S_OK;
2205}
2206
2208{
2210 ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2211 return S_OK;
2212}
2213
2215{
2217 return S_OK;
2218}
2219
2221 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2222 DWORD grfPI, HANDLE *dwReserved)
2223{
2224 CHECK_EXPECT(StartEx);
2225 ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2226 protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2227 return S_OK;
2228}
2229
2230static const IInternetProtocolExVtbl ProtocolVtbl = {
2245};
2246
2248{
2249 return CONTAINING_RECORD(iface, Protocol, IUnknown_inner);
2250}
2251
2253{
2254 static const IID IID_undocumentedIE10 = {0x7daf9908,0x8415,0x4005,{0x95,0xae,0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
2256
2258 trace("QI(IUnknown)\n");
2259 *ppv = &This->IUnknown_inner;
2260 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
2261 trace("QI(InternetProtocol)\n");
2262 *ppv = &This->IInternetProtocolEx_iface;
2263 }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
2264 trace("QI(InternetProtocolEx)\n");
2265 if(!impl_protex) {
2266 *ppv = NULL;
2267 return E_NOINTERFACE;
2268 }
2269 *ppv = &This->IInternetProtocolEx_iface;
2270 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
2271 trace("QI(InternetPriority)\n");
2272 *ppv = &This->IInternetPriority_iface;
2273 }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
2274 trace("QI(IWinInetInfo)\n");
2275 CHECK_EXPECT(QueryInterface_IWinInetInfo);
2276 *ppv = NULL;
2277 return E_NOINTERFACE;
2278 }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
2279 trace("QI(IWinInetHttpInfo)\n");
2280 CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
2281 *ppv = NULL;
2282 return E_NOINTERFACE;
2283 }else if(IsEqualGUID(&IID_undocumentedIE10, riid)) {
2284 trace("QI(%s)\n", wine_dbgstr_guid(riid));
2285 *ppv = NULL;
2286 return E_NOINTERFACE;
2287 }else {
2288 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
2289 *ppv = NULL;
2290 return E_NOINTERFACE;
2291 }
2292
2293 IUnknown_AddRef((IUnknown*)*ppv);
2294 return S_OK;
2295}
2296
2298{
2300 return ++This->inner_ref;
2301}
2302
2304{
2306 LONG ref = --This->inner_ref;
2307 if(!ref) {
2308 /* IE9 is broken on redirects. It will cause -1 outer_ref on original protocol handler
2309 * and 1 on redirected handler. */
2310 ok(!This->outer_ref
2311 || broken(test_redirect && (This->outer_ref == -1 || This->outer_ref == 1)),
2312 "outer_ref = %d\n", This->outer_ref);
2313 if(This->outer_ref)
2314 trace("outer_ref %d\n", This->outer_ref);
2315 CHECK_EXPECT(Protocol_destructor);
2316 heap_free(This);
2317 }
2318 return ref;
2319}
2320
2321static const IUnknownVtbl ProtocolUnkVtbl = {
2325};
2326
2328{
2329 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2330 *ppv = iface;
2331 return S_OK;
2332 }
2333
2334 if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2336 return S_OK;
2337 }
2338
2339 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2340 *ppv = NULL;
2341 return E_NOINTERFACE;
2342}
2343
2345 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2347{
2349 LPOLESTR url_str = NULL;
2350 DWORD fetched = 0;
2351 BINDINFO bindinfo;
2352 DWORD cbindf = 0;
2353 HRESULT hres;
2354
2355 CHECK_EXPECT(MimeFilter_Start);
2356
2357 ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2358 ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2359 ok(dwReserved, "dwReserved == 0\n");
2360 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2361 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2362
2363 if(binding_test) {
2364 ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2365 ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2366 }else {
2367 ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2368 ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2369 }
2370
2371 data = (void*)dwReserved;
2372 ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2373 ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2374 ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2375 ok(!data->pUnk, "data->pUnk != NULL\n");
2376 ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2377 if(binding_test) {
2378 IInternetProtocolSink *prot_sink;
2379
2380 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2381 ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2382 IInternetProtocolSink_Release(prot_sink);
2383
2384 ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2385
2386 filtered_protocol = data->pProtocol;
2387 IInternetProtocol_AddRef(filtered_protocol);
2388 }else {
2389 IInternetProtocol *prot;
2390
2391 IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2392 ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2393 IInternetProtocol_Release(prot);
2394
2395 ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2396 }
2397
2398 filtered_sink = pOIProtSink;
2399
2400 SET_EXPECT(ReportProgress_DECODING);
2401 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2402 ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2403 CHECK_CALLED(ReportProgress_DECODING);
2404
2405 SET_EXPECT(GetBindInfo);
2406 memset(&bindinfo, 0, sizeof(bindinfo));
2407 bindinfo.cbSize = sizeof(bindinfo);
2408 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2409 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2410 ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2411 CHECK_CALLED(GetBindInfo);
2412
2413 SET_EXPECT(GetBindString_URL);
2414 hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2415 ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2416 ok(fetched == 1, "fetched = %d\n", fetched);
2417 ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2418 CoTaskMemFree(url_str);
2419 CHECK_CALLED(GetBindString_URL);
2420
2421 return S_OK;
2422}
2423
2425 PROTOCOLDATA *pProtocolData)
2426{
2427 CHECK_EXPECT(MimeFilter_Continue);
2428 return E_NOTIMPL;
2429}
2430
2432{
2433 HRESULT hres;
2434
2435 CHECK_EXPECT(MimeFilter_Terminate);
2436
2437 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2438
2439 SET_EXPECT(Terminate);
2440 hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2441 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2442 CHECK_CALLED(Terminate);
2443
2444 return S_OK;
2445}
2446
2448 ULONG cb, ULONG *pcbRead)
2449{
2450 BYTE buf[2096];
2451 DWORD read = 0;
2452 HRESULT hres;
2453
2454 CHECK_EXPECT(MimeFilter_Read);
2455
2456 ok(pv != NULL, "pv == NULL\n");
2457 ok(cb != 0, "cb == 0\n");
2458 ok(pcbRead != NULL, "pcbRead == NULL\n");
2459
2461 SET_EXPECT(Read2);
2462 else
2464 hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2465 ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2467 CHECK_CALLED(Read2);
2468 else
2470
2471 if(pcbRead) {
2472 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2473 *pcbRead = read;
2474 }
2475
2476 memset(pv, 'x', read);
2477 return hres;
2478}
2479
2481{
2482 HRESULT hres;
2483
2484 CHECK_EXPECT(MimeFilter_LockRequest);
2485
2486 ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2487
2489 hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2490 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2492
2493 return S_OK;
2494}
2495
2497{
2498 HRESULT hres;
2499
2500 CHECK_EXPECT(MimeFilter_UnlockRequest);
2501
2503 hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2504 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2506
2507 return S_OK;
2508}
2509
2510static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2524};
2525
2527
2529{
2530 ok(0, "unexpected call\n");
2531 return E_NOINTERFACE;
2532}
2533
2535{
2536 return 2;
2537}
2538
2540{
2541 return 1;
2542}
2543
2545 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
2546 DWORD *pcchResult, DWORD dwReserved)
2547{
2548 ok(0, "unexpected call %d\n", ParseAction);
2549 return E_NOTIMPL;
2550}
2551
2553 LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
2554 LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
2555{
2556 ok(0, "unexpected call\n");
2557 return E_NOTIMPL;
2558}
2559
2561 LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
2562{
2563 ok(0, "unexpected call\n");
2564 return E_NOTIMPL;
2565}
2566
2568 LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
2569 DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
2570{
2571 ok(0, "unexpected call\n");
2572 return E_NOTIMPL;
2573}
2574
2575static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
2583};
2584
2586
2588{
2589 if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
2590 *ppv = &protocol_info;
2591 return S_OK;
2592 }
2593
2594 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
2595 return E_NOINTERFACE;
2596}
2597
2599{
2600 return 2;
2601}
2602
2604{
2605 return 1;
2606}
2607
2609 REFIID riid, void **ppv)
2610{
2611 Protocol *ret;
2612
2613 ok(ppv != NULL, "ppv == NULL\n");
2614
2615 if(!pOuter) {
2616 CHECK_EXPECT(CreateInstance_no_aggregation);
2617 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2618 }else {
2619 CHECK_EXPECT(CreateInstance);
2620 ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2621 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2622 if (no_aggregation) {
2623 *ppv = NULL;
2624 return CLASS_E_NOAGGREGATION;
2625 }
2626 }
2627
2628 ret = heap_alloc(sizeof(*ret));
2629 ret->IUnknown_inner.lpVtbl = &ProtocolUnkVtbl;
2630 ret->IInternetProtocolEx_iface.lpVtbl = &ProtocolVtbl;
2631 ret->IInternetPriority_iface.lpVtbl = &InternetPriorityVtbl;
2632 ret->outer = pOuter;
2633 ret->inner_ref = 1;
2634 ret->outer_ref = 0;
2635
2637 if (!pOuter)
2638 *ppv = &ret->IInternetProtocolEx_iface;
2639 else
2640 *ppv = &ret->IUnknown_inner;
2641 return S_OK;
2642}
2643
2645{
2646 ok(0, "unexpected call\n");
2647 return S_OK;
2648}
2649
2650static const IClassFactoryVtbl ClassFactoryVtbl = {
2656};
2657
2659
2661{
2663
2664 ok(!outer, "outer = %p\n", outer);
2665 ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2666
2667 *ppv = &MimeProtocol;
2668 return S_OK;
2669}
2670
2671static const IClassFactoryVtbl MimeFilterCFVtbl = {
2677};
2678
2680
2681#define TEST_BINDING 0x0001
2682#define TEST_FILTER 0x0002
2683#define TEST_FIRST_HTTP 0x0004
2684#define TEST_DIRECT_READ 0x0008
2685#define TEST_POST 0x0010
2686#define TEST_EMULATEPROT 0x0020
2687#define TEST_SHORT_READ 0x0040
2688#define TEST_REDIRECT 0x0080
2689#define TEST_ABORT 0x0100
2690#define TEST_ASYNCREQ 0x0200
2691#define TEST_USEIURI 0x0400
2692#define TEST_IMPLPROTEX 0x0800
2693#define TEST_EMPTY 0x1000
2694#define TEST_NOMIME 0x2000
2695#define TEST_FROMCACHE 0x4000
2696#define TEST_DISABLEAUTOREDIRECT 0x8000
2697
2698static void register_filter(BOOL do_register)
2699{
2701 HRESULT hres;
2702
2703 hres = pCoInternetGetSession(0, &session, 0);
2704 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2705
2706 if(do_register) {
2707 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2708 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2709 hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2710 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2711 }else {
2712 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2713 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2714 hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2715 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2716 }
2717
2718 IInternetSession_Release(session);
2719}
2720
2721static void init_test(int prot, DWORD flags)
2722{
2723 tested_protocol = prot;
2724 binding_test = (flags & TEST_BINDING) != 0;
2726 prot_read = 0;
2727 prot_state = 0;
2730 no_mime = (flags & TEST_NOMIME) != 0;
2731 filter_state = 0;
2732 post_stream_read = 0;
2746 short_read = (flags & TEST_SHORT_READ) != 0;
2747 http_post_test = TYMED_NULL;
2749 test_abort = (flags & TEST_ABORT) != 0;
2751 empty_file = (flags & TEST_EMPTY) != 0;
2756
2757 bindinfo_options = 0;
2759 bindinfo_options |= BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS;
2760
2762}
2763
2765{
2767 LONG pr;
2768 HRESULT hres;
2769
2770 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2771 (void**)&priority);
2772 ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2773 if(FAILED(hres))
2774 return;
2775
2776 hres = IInternetPriority_GetPriority(priority, &pr);
2777 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2778 ok(pr == 0, "pr=%d, expected 0\n", pr);
2779
2780 hres = IInternetPriority_SetPriority(priority, 1);
2781 ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2782
2783 hres = IInternetPriority_GetPriority(priority, &pr);
2784 ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2785 ok(pr == 1, "pr=%d, expected 1\n", pr);
2786
2787 IInternetPriority_Release(priority);
2788}
2789
2790static void test_early_abort(const CLSID *clsid)
2791{
2793 HRESULT hres;
2794
2795 hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2796 &IID_IInternetProtocol, (void**)&protocol);
2797 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2798
2799 hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2800 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2801
2802 hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2803 ok(hres == S_OK, "Abort failed: %08x\n", hres);
2804
2805 IInternetProtocol_Release(protocol);
2806}
2807
2809 IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2810{
2811 HRESULT hres;
2812
2813 SET_EXPECT(GetBindInfo);
2814 if(!(bindf & BINDF_FROMURLMON))
2815 SET_EXPECT(ReportProgress_DIRECTBIND);
2816 if(is_first) {
2817 SET_EXPECT(ReportProgress_SENDINGREQUEST);
2818 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2819 if(bindf & BINDF_FROMURLMON)
2820 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2821 else
2822 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2823 }
2824 SET_EXPECT(ReportData);
2825 if(is_first)
2826 SET_EXPECT(ReportResult);
2827
2829
2830 if(protocolex) {
2831 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2832 ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2833 }else {
2834 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2835 if(hres == INET_E_RESOURCE_NOT_FOUND) {
2836 win_skip("Start failed\n");
2837 return FALSE;
2838 }
2839 ok(hres == S_OK, "Start failed: %08x\n", hres);
2840 }
2841
2842 CHECK_CALLED(GetBindInfo);
2843 if(!(bindf & BINDF_FROMURLMON))
2844 CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2845 if(is_first) {
2846 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2847 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2848 if(bindf & BINDF_FROMURLMON)
2849 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2850 else
2851 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2852 }
2853 CHECK_CALLED(ReportData);
2854 if(is_first)
2855 CHECK_CALLED(ReportResult);
2856
2857 return TRUE;
2858}
2859
2861{
2863 IUnknown *unk;
2866 BYTE buf[512];
2867 ULONG cb;
2868 HRESULT hres;
2869
2870 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2871 &IID_IUnknown, (void**)&unk);
2872 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2873 if(FAILED(hres))
2874 return;
2875
2876 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2878 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2879
2880 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2881 ok(hres == S_OK, "Could not get IClassFactory interface\n");
2882 IUnknown_Release(unk);
2883 if(FAILED(hres))
2884 return;
2885
2886 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2887 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2888
2889 if(SUCCEEDED(hres)) {
2891 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2892 ok(hres == S_OK, "Read failed: %08x\n", hres);
2893 ok(cb == 2, "cb=%u expected 2\n", cb);
2894 buf[2] = 0;
2895 ok(!memcmp(buf, file_with_hash ? "XX" : "<H", 2), "Unexpected data %s\n", buf);
2896 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2897 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2898 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2899 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2900 ok(cb == 0, "cb=%u expected 0\n", cb);
2901 hres = IInternetProtocol_UnlockRequest(protocol);
2902 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2903 }
2904
2906 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2907 ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2908 hres = IInternetProtocol_LockRequest(protocol, 0);
2909 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2910 hres = IInternetProtocol_UnlockRequest(protocol);
2911 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2912 }
2913
2914 IInternetProtocol_Release(protocol);
2915 }
2916
2917 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2918 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2919 if(SUCCEEDED(hres)) {
2921 hres = IInternetProtocol_LockRequest(protocol, 0);
2922 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2923 hres = IInternetProtocol_Terminate(protocol, 0);
2924 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2925 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2926 ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2927 hres = IInternetProtocol_UnlockRequest(protocol);
2928 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2929 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2930 todo_wine_if(file_with_hash) /* FIXME: An effect of UnlockRequest call? */
2931 ok(hres == S_OK, "Read failed: %08x\n", hres);
2932 hres = IInternetProtocol_Terminate(protocol, 0);
2933 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2934 }
2935
2936 IInternetProtocol_Release(protocol);
2937 }
2938
2939 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2940 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2941 if(SUCCEEDED(hres)) {
2943 hres = IInternetProtocol_Terminate(protocol, 0);
2944 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2945 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2946 ok(hres == S_OK, "Read failed: %08x\n", hres);
2947 ok(cb == 2, "cb=%u expected 2\n", cb);
2948 }
2949
2950 IInternetProtocol_Release(protocol);
2951 }
2952
2953 if(pCreateUri) {
2954 IInternetProtocolEx *protocolex;
2955 IUri *uri;
2956
2957 hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2958 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2959
2960 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2961 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2962
2963 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2964 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2965 ok(hres == S_OK, "Read failed: %08x\n", hres);
2966 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2967 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2968 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2969 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2970 }
2971
2972 IUri_Release(uri);
2973 IInternetProtocolEx_Release(protocolex);
2974
2975 hres = pCreateUri(url, 0, 0, &uri);
2976 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2977
2978 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2979 ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2980
2981 if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2982 hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2983 ok(hres == S_OK, "Read failed: %08x\n", hres);
2984 hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2985 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2986 hres = IInternetProtocolEx_UnlockRequest(protocolex);
2987 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2988 }
2989
2990 IUri_Release(uri);
2991 IInternetProtocolEx_Release(protocolex);
2992 }else {
2993 win_skip("Skipping file protocol StartEx tests\n");
2994 }
2995
2996 IClassFactory_Release(factory);
2997}
2998
3000{
3002 HRESULT hres;
3003
3004 static const WCHAR index_url2[] =
3005 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
3006
3007 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
3008 &IID_IInternetProtocol, (void**)&protocol);
3009 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
3010 if(FAILED(hres))
3011 return;
3012
3013 SET_EXPECT(GetBindInfo);
3015 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
3016 ok(hres == MK_E_SYNTAX ||
3017 hres == E_INVALIDARG,
3018 "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
3019 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
3020
3021 SET_EXPECT(GetBindInfo);
3022 if(!(bindf & BINDF_FROMURLMON))
3023 SET_EXPECT(ReportProgress_DIRECTBIND);
3024 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3025 SET_EXPECT(ReportResult);
3026 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3027 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
3028 ok(hres == INET_E_RESOURCE_NOT_FOUND,
3029 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
3030 CHECK_CALLED(GetBindInfo);
3031 if(!(bindf & BINDF_FROMURLMON))
3032 CHECK_CALLED(ReportProgress_DIRECTBIND);
3033 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3034 CHECK_CALLED(ReportResult);
3035
3036 IInternetProtocol_Release(protocol);
3037
3038 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
3039 &IID_IInternetProtocol, (void**)&protocol);
3040 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
3041 if(FAILED(hres))
3042 return;
3043
3044 SET_EXPECT(GetBindInfo);
3045 if(!(bindf & BINDF_FROMURLMON))
3046 SET_EXPECT(ReportProgress_DIRECTBIND);
3047 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3048 SET_EXPECT(ReportResult);
3049 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3050
3051 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
3052 ok(hres == INET_E_RESOURCE_NOT_FOUND,
3053 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
3054 CHECK_CALLED(GetBindInfo);
3055 if(!(bindf & BINDF_FROMURLMON))
3056 CHECK_CALLED(ReportProgress_DIRECTBIND);
3057 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3058 CHECK_CALLED(ReportResult);
3059
3060 SET_EXPECT(GetBindInfo);
3061 hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3062 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3063 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
3064
3065 SET_EXPECT(GetBindInfo);
3066 hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
3067 ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3068 CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
3069
3070 IInternetProtocol_Release(protocol);
3071}
3072
3073static void test_file_protocol(void) {
3074 WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
3075 DWORD size;
3076 ULONG len;
3077 HANDLE file;
3078
3079 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
3080 static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
3081 static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
3082 static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
3083 static const char html_doc[] = "<HTML></HTML>";
3084 static const WCHAR fragmentW[] = {'#','f','r','a','g',0};
3085
3086 trace("Testing file protocol...\n");
3087 init_test(FILE_TEST, 0);
3088
3089 SetLastError(0xdeadbeef);
3092 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3094 return;
3095 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
3097
3099 bindf = 0;
3101 bindf = BINDF_FROMURLMON;
3103 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
3105
3106 memcpy(buf, wszFile, sizeof(wszFile));
3107 len = ARRAY_SIZE(wszFile)-1;
3109 buf[len++] = '\\';
3111
3113 bindf = 0;
3115 bindf = BINDF_FROMURLMON;
3117
3118 memcpy(buf, wszFile2, sizeof(wszFile2));
3119 len = GetCurrentDirectoryW(ARRAY_SIZE(file_name_buf), file_name_buf);
3120 file_name_buf[len++] = '\\';
3121 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
3122 lstrcpyW(buf+ARRAY_SIZE(wszFile2)-1, file_name_buf);
3123 file_name = file_name_buf;
3124 bindf = 0;
3126 bindf = BINDF_FROMURLMON;
3128
3129 buf[ARRAY_SIZE(wszFile2)] = '|';
3131
3132 memcpy(buf, wszFile3, sizeof(wszFile3));
3133 len = ARRAY_SIZE(wszFile3)-1;
3135 buf[len++] = '\\';
3137
3138 file_name = buf + ARRAY_SIZE(wszFile3)-1;
3139 bindf = 0;
3141 bindf = BINDF_FROMURLMON;
3143
3144 memcpy(buf, wszFile4, sizeof(wszFile4));
3145 len = GetCurrentDirectoryW(ARRAY_SIZE(file_name_buf), file_name_buf);
3146 file_name_buf[len++] = '\\';
3147 memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
3148 lstrcpyW(buf+ARRAY_SIZE(wszFile4)-1, file_name_buf);
3149 file_name = file_name_buf;
3150 bindf = 0;
3152 bindf = BINDF_FROMURLMON;
3154
3155 buf[ARRAY_SIZE(wszFile4)] = '|';
3157
3158 /* Fragment part of URL is skipped if the file doesn't exist. */
3159 lstrcatW(buf, fragmentW);
3161
3162 /* Fragment part is considered a part of the file name, if the file exsists. */
3163 len = lstrlenW(file_name_buf);
3164 lstrcpyW(file_name_buf+len, fragmentW);
3167 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3168 WriteFile(file, "XXX", 3, &size, NULL);
3170 file_name_buf[len] = 0;
3171
3174
3176 DeleteFileW(file_name_buf);
3177
3178 bindf = 0;
3180 bindf = BINDF_FROMURLMON;
3182}
3183
3184static void create_cache_entry(const WCHAR *urlw)
3185{
3186 FILETIME now, tomorrow, yesterday;
3187 char file_path[MAX_PATH];
3188 BYTE content[1000];
3190 const char *url;
3191 HANDLE file;
3192 DWORD size;
3193 unsigned i;
3194 BOOL res;
3195
3196 BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
3197
3198 trace("Testing cache read...\n");
3199
3200 url = w2a(urlw);
3201
3202 for(i = 0; i < sizeof(content); i++)
3203 content[i] = '0' + (i%10);
3204
3206 li.u.HighPart = now.dwHighDateTime;
3207 li.u.LowPart = now.dwLowDateTime;
3208 li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
3209 tomorrow.dwHighDateTime = li.u.HighPart;
3210 tomorrow.dwLowDateTime = li.u.LowPart;
3211 li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
3212 yesterday.dwHighDateTime = li.u.HighPart;
3213 yesterday.dwLowDateTime = li.u.LowPart;
3214
3215 res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
3216 ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
3217
3219 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3220
3221 WriteFile(file, content, sizeof(content), &size, NULL);
3223
3224 res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
3225 cache_headers, sizeof(cache_headers)-1, "", 0);
3226 ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
3227}
3228
3230{
3231 static BOOL got_user_agent = FALSE;
3232 IUri *uri = NULL;
3233 HRESULT hres;
3234
3235 if(use_iuri && pCreateUri) {
3236 hres = pCreateUri(url, 0, 0, &uri);
3237 ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3238 }
3239
3240 SET_EXPECT(GetBindInfo);
3241 if (!(bindf & BINDF_FROMURLMON))
3242 SET_EXPECT(ReportProgress_DIRECTBIND);
3243 if(!got_user_agent)
3244 SET_EXPECT(GetBindString_USER_AGENT);
3245 SET_EXPECT(GetBindString_ROOTDOC_URL);
3246 SET_EXPECT(GetBindString_ACCEPT_MIMES);
3247 SET_EXPECT(QueryService_HttpNegotiate);
3248 SET_EXPECT(BeginningTransaction);
3249 SET_EXPECT(GetRootSecurityId);
3250 if(http_post_test) {
3251 SET_EXPECT(GetBindString_POST_COOKIE);
3252 if(http_post_test == TYMED_ISTREAM)
3254 }
3255 if(bind_from_cache) {
3256 SET_EXPECT(OnResponse);
3257 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3258 SET_EXPECT(ReportData);
3259 }
3260
3261 if(uri) {
3262 IInternetProtocolEx *protocolex;
3263
3264 hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3265 ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3266
3267 hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
3268 ok(hres == S_OK, "Start failed: %08x\n", hres);
3269
3270 IInternetProtocolEx_Release(protocolex);
3271 IUri_Release(uri);
3272 }else {
3273 hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
3274 ok(hres == S_OK, "Start failed: %08x\n", hres);
3275 }
3276 if(FAILED(hres))
3277 return FALSE;
3278
3279 CHECK_CALLED(GetBindInfo);
3280 if (!(bindf & BINDF_FROMURLMON))
3281 CHECK_CALLED(ReportProgress_DIRECTBIND);
3282 if (!got_user_agent)
3283 {
3284 CHECK_CALLED(GetBindString_USER_AGENT);
3285 got_user_agent = TRUE;
3286 }
3287 CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
3288 CHECK_CALLED(GetBindString_ACCEPT_MIMES);
3289 CHECK_CALLED(QueryService_HttpNegotiate);
3290 CHECK_CALLED(BeginningTransaction);
3291 /* GetRootSecurityId called on WinXP but not on Win98 */
3292 CLEAR_CALLED(GetRootSecurityId);
3293 if(http_post_test) {
3294 CHECK_CALLED(GetBindString_POST_COOKIE);
3295 if(http_post_test == TYMED_ISTREAM)
3297 }
3298 if(bind_from_cache) {
3299 CHECK_CALLED(OnResponse);
3300 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3301 CHECK_CALLED(ReportData);
3302 }
3303
3304 return TRUE;
3305}
3306
3308{
3309 BYTE buf[3600];
3310 DWORD cb;
3311 HRESULT hres;
3312
3313 hres = IInternetProtocol_LockRequest(protocol, 0);
3314 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3315
3316 hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
3317 ok(hres == (test_abort ? S_OK : S_FALSE), "Read failed: %08x\n", hres);
3318
3319 hres = IInternetProtocol_Terminate(protocol, 0);
3320 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3321
3322 /* This wait is to give the internet handles being freed in Terminate
3323 * enough time to actually terminate in all cases. Internet handles
3324 * terminate asynchronously and native reuses the main InternetOpen
3325 * handle. The only case in which this seems to be necessary is on
3326 * wine with native wininet and urlmon, resulting in the next time
3327 * test_http_protocol_url being called the first data notification actually
3328 * being an extra last data notification from the previous connection
3329 * about once out of every ten times. */
3330 Sleep(100);
3331
3332 hres = IInternetProtocol_UnlockRequest(protocol);
3333 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3334}
3335
3336/* is_first refers to whether this is the first call to this function
3337 * _for this url_ */
3339{
3342 IUnknown *unk;
3343 HRESULT hres;
3344
3345 init_test(prot, flags);
3346 http_url = url;
3348 if(flags & TEST_FROMCACHE)
3350
3351 hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
3352 CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3353 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3354 if(FAILED(hres))
3355 return;
3356
3357 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3359 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3360 hres);
3361
3362 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3363 ok(hres == S_OK, "Could not get IClassFactory interface\n");
3364 IUnknown_Release(unk);
3365 if(FAILED(hres))
3366 return;
3367
3368 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3369 (void**)&async_protocol);
3370 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3371 if(SUCCEEDED(hres)) {
3372 BYTE buf[3600];
3373 DWORD cb;
3374 ULONG ref;
3375
3377
3378 SET_EXPECT(ReportProgress_COOKIE_SENT);
3379 if(http_is_first) {
3380 SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3381 SET_EXPECT(ReportProgress_CONNECTING);
3382 }
3383 SET_EXPECT(ReportProgress_SENDINGREQUEST);
3384 if(test_redirect && !(