ReactOS  0.4.14-dev-593-g1793dcc
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 
33 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
34 static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
35 static 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 
70 DEFINE_EXPECT(GetBindInfo);
71 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
72 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
73 DEFINE_EXPECT(ReportProgress_RAWMIMETYPE);
74 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE);
75 DEFINE_EXPECT(ReportProgress_CONNECTING);
76 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
77 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
78 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
79 DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID);
80 DEFINE_EXPECT(ReportProgress_COOKIE_SENT);
81 DEFINE_EXPECT(ReportProgress_REDIRECTING);
82 DEFINE_EXPECT(ReportProgress_ENCODING);
83 DEFINE_EXPECT(ReportProgress_ACCEPTRANGES);
84 DEFINE_EXPECT(ReportProgress_PROXYDETECTING);
85 DEFINE_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
86 DEFINE_EXPECT(ReportProgress_DECODING);
87 DEFINE_EXPECT(ReportData);
88 DEFINE_EXPECT(ReportData2);
89 DEFINE_EXPECT(ReportResult);
90 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES);
91 DEFINE_EXPECT(GetBindString_USER_AGENT);
92 DEFINE_EXPECT(GetBindString_POST_COOKIE);
93 DEFINE_EXPECT(GetBindString_URL);
94 DEFINE_EXPECT(GetBindString_ROOTDOC_URL);
95 DEFINE_EXPECT(QueryService_HttpNegotiate);
96 DEFINE_EXPECT(QueryService_InternetProtocol);
97 DEFINE_EXPECT(QueryService_HttpSecurity);
98 DEFINE_EXPECT(QueryService_IBindCallbackRedirect);
99 DEFINE_EXPECT(QueryInterface_IWinInetInfo);
100 DEFINE_EXPECT(QueryInterface_IWinInetHttpInfo);
101 DEFINE_EXPECT(BeginningTransaction);
102 DEFINE_EXPECT(GetRootSecurityId);
103 DEFINE_EXPECT(OnResponse);
104 DEFINE_EXPECT(Switch);
106 DEFINE_EXPECT(CreateInstance);
107 DEFINE_EXPECT(CreateInstance_no_aggregation);
109 DEFINE_EXPECT(StartEx);
110 DEFINE_EXPECT(Terminate);
112 DEFINE_EXPECT(Read2);
116 DEFINE_EXPECT(Abort);
118 DEFINE_EXPECT(MimeFilter_Start);
119 DEFINE_EXPECT(MimeFilter_ReportData);
120 DEFINE_EXPECT(MimeFilter_ReportResult);
121 DEFINE_EXPECT(MimeFilter_Terminate);
122 DEFINE_EXPECT(MimeFilter_LockRequest);
123 DEFINE_EXPECT(MimeFilter_UnlockRequest);
124 DEFINE_EXPECT(MimeFilter_Read);
125 DEFINE_EXPECT(MimeFilter_Switch);
126 DEFINE_EXPECT(MimeFilter_Continue);
129 DEFINE_EXPECT(Redirect);
130 DEFINE_EXPECT(outer_QI_test);
131 DEFINE_EXPECT(Protocol_destructor);
132 
133 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
134 static const WCHAR index_url[] =
135  {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
136 
137 static const WCHAR acc_mimeW[] = {'*','/','*',0};
138 static const WCHAR user_agentW[] = {'W','i','n','e',0};
139 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
140 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
141 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
142 static const WCHAR emptyW[] = {0};
143 static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
144 static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
145 
155 static void *expect_pv;
158 static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
164 
165 enum {
170 } state;
171 
172 static enum {
181 
182 typedef struct {
189 } Protocol;
190 
192 
193 static 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 
203 static 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 
217 static const CHAR post_data[] = "mode=Test";
218 
219 static LONG obj_refcount(void *obj)
220 {
221  IUnknown_AddRef((IUnknown *)obj);
222  return IUnknown_Release((IUnknown *)obj);
223 }
224 
225 static 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 
232 static 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 
261 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
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 */
275  if (security_problem)
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 
286 static 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 
386 static 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 
421 static const IBindCallbackRedirectVtbl BindCallbackRedirectVtbl = {
426 };
427 
429 
430 static 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 
490 static 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 
520 static 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 
541 static 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 
573 static 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 
599 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
600  DWORD dwStatFlag)
601 {
602  ok(0, "unexpected call\n");
603  return E_NOTIMPL;
604 }
605 
606 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
607 {
608  ok(0, "unexpected call\n");
609  return E_NOTIMPL;
610 }
611 
612 static const IStreamVtbl StreamVtbl = {
616  Stream_Read,
617  Stream_Write,
618  Stream_Seek,
625  Stream_Stat,
627 };
628 
629 static IStream Stream = { &StreamVtbl };
630 
632 {
633  return QueryInterface(riid, ppv);
634 }
635 
637 {
638  return 2;
639 }
640 
642 {
643  return 1;
644 }
645 
646 static void call_continue(PROTOCOLDATA *protocol_data)
647 {
648  HRESULT hres;
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 
731 static 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 
769 static 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;
973  HRESULT hres;
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);
983  if(tested_protocol != FTP_TEST) {
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 */
1017  if(tested_protocol == FILE_TEST)
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)
1057  SET_EXPECT(Read);
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)
1072  CHECK_CALLED(Read);
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
1163  SET_EXPECT(Read);
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
1170  CHECK_CALLED(Read);
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 
1184  if(security_problem)
1185  return S_OK;
1186 
1187  if(tested_protocol == FTP_TEST)
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__
1193  if(!winetest_interactive && tested_protocol != FTP_TEST && hrResult != expect_hrResult) {
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 
1216 static 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 
1250 static 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) {
1295  SET_EXPECT(Read);
1296  hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1297  if(tested_protocol == HTTP_TEST)
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);
1301  CHECK_CALLED(Read);
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) {
1317  SET_EXPECT(Read);
1318  }else if(no_mime && prot_read<300) {
1319  report_mime = TRUE;
1320  SET_EXPECT(Read);
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) {
1329  CHECK_CALLED(Read);
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 
1362 static 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))
1384  *ppv = &service_provider;
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 
1421 static 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);
1507  memcpy(*ppwzStr, binding_urls[tested_protocol], 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 
1524 static 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 
1582 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1588 };
1589 
1591 {
1592  return 2;
1593 }
1594 
1596 {
1597  return 1;
1598 }
1599 
1601  DWORD dwOptions)
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 
1773 static 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 
1878  CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
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,
1946  DWORD grfPI, HANDLE_PTR dwReserved)
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 
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 
1986  if(redirect_on_continue) {
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);
1999  SET_EXPECT(Start);
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)
2087  CHECK_CALLED(Read);
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 {
2112  if(read_report_data)
2113  CHECK_EXPECT2(Read2);
2114 
2115  if(mimefilter_test || short_read) {
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)
2133  CHECK_EXPECT(Read);
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);
2154  read_report_data++;
2155  hres = IInternetProtocolSink_ReportData(binding_sink,
2156  BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
2157  read_report_data--;
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 
2230 static const IInternetProtocolExVtbl ProtocolVtbl = {
2241  Protocol_Seek,
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}};
2255  Protocol *This = impl_from_IUnknown(iface);
2256 
2257  if(IsEqualGUID(&IID_IUnknown, riid)) {
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 {
2299  Protocol *This = impl_from_IUnknown(iface);
2300  return ++This->inner_ref;
2301 }
2302 
2304 {
2305  Protocol *This = impl_from_IUnknown(iface);
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 
2321 static 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)) {
2335  *ppv = &mime_protocol_sink;
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,
2346  DWORD grfPI, HANDLE_PTR dwReserved)
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 
2460  if(read_report_data)
2461  SET_EXPECT(Read2);
2462  else
2463  SET_EXPECT(Read);
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);
2466  if(read_report_data)
2467  CHECK_CALLED(Read2);
2468  else
2469  CHECK_CALLED(Read);
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 
2510 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2521  Protocol_Seek,
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 
2575 static 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 
2636  protocol_emul = ret;
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 
2650 static 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 
2671 static 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 
2698 static 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 
2721 static 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;
2729  mimefilter_test = (flags & TEST_FILTER) != 0;
2730  no_mime = (flags & TEST_NOMIME) != 0;
2731  filter_state = 0;
2732  post_stream_read = 0;
2738  filtered_sink = NULL;
2739  http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2742  test_async_req = (flags & TEST_ASYNCREQ) != 0;
2743  direct_read = (flags & TEST_DIRECT_READ) != 0;
2744  emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2746  short_read = (flags & TEST_SHORT_READ) != 0;
2747  http_post_test = TYMED_NULL;
2749  test_abort = (flags & TEST_ABORT) != 0;
2750  impl_protex = (flags & TEST_IMPLPROTEX) != 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 
2790 static 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);
2877  ok(hres == E_NOINTERFACE,
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 
2999 static void test_file_protocol_fail(void)
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 
3073 static 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");
3093  if(file == INVALID_HANDLE_VALUE)
3094  return;
3095  WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
3096  CloseHandle(file);
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++] = '\\';
3110  memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
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++] = '\\';
3136  memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
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);
3169  CloseHandle(file);
3170  file_name_buf[len] = 0;
3171 
3172  file_with_hash = TRUE;
3174 
3176  DeleteFileW(file_name_buf);
3177 
3178  bindf = 0;
3180  bindf = BINDF_FROMURLMON;
3182 }
3183 
3184 static void create_cache_entry(const WCHAR *urlw)
3185 {
3186  FILETIME now, tomorrow, yesterday;
3187  char file_path[MAX_PATH];
3188  BYTE content[1000];
3189  ULARGE_INTEGER li;
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);
3222  CloseHandle(file);
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);
3358  ok(hres == E_NOINTERFACE,
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 && !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
3385  SET_EXPECT(ReportProgress_REDIRECTING);
3386  SET_EXPECT(ReportProgress_PROXYDETECTING);
3387  if(prot == HTTP_TEST)
3388  SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3389  else
3390  SET_EXPECT(QueryService_HttpSecurity);
3391  if(!(bindf & BINDF_FROMURLMON)) {
3392  SET_EXPECT(OnResponse);
3393  SET_EXPECT(ReportProgress_RAWMIMETYPE);
3394  SET_EXPECT(ReportData);
3395  } else {
3396  SET_EXPECT(Switch);
3397  }
3398 
3399  if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3400  IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3401  IInternetProtocol_Release(async_protocol);
3402  return;
3403  }
3404 
3406  SET_EXPECT(ReportResult);
3407 
3409  expect_hrResult = INET_E_REDIRECT_FAILED;
3410  else if(test_abort)
3412  else
3414 
3415  if(direct_read) {
3416  SET_EXPECT(Switch);
3417  while(wait_for_switch) {
3418  ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3419  CHECK_CALLED(Switch); /* Set in ReportData */
3422  }
3423  }else if(bind_from_cache) {
3424  BYTE buf[1500];
3425 
3426  hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3427  ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3428 
3429  SET_EXPECT(ReportResult);
3430  hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3431  ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3432  CHECK_CALLED(ReportResult);
3433 
3434  hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3435  ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3436  }else {
3437  hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3438  ok((hres == E_PENDING && cb==0) ||
3439  (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3440 
3441  ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3442  if(bindf & BINDF_FROMURLMON)
3443  CHECK_CALLED(Switch);
3444  else
3445  CHECK_CALLED(ReportData);
3446  if(prot == HTTPS_TEST)
3447  CLEAR_CALLED(QueryService_HttpSecurity);
3448 
3449  while(1) {
3450  if(bindf & BINDF_FROMURLMON)
3451  SET_EXPECT(Switch);
3452  else
3453  SET_EXPECT(ReportData);
3454  hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3455  if(hres == E_PENDING) {
3456  hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3457  ok((hres == E_PENDING && cb==0) ||
3458  (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3459  ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3460  if(bindf & BINDF_FROMURLMON)
3461  CHECK_CALLED(Switch);
3462  else
3463  CHECK_CALLED(ReportData);
3464 
3465  if(test_abort) {
3466  HRESULT hres;
3467 
3468  SET_EXPECT(ReportResult);
3469  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3470  ok(hres == S_OK, "Abort failed: %08x\n", hres);
3471  CHECK_CALLED(ReportResult);
3472 
3473  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3474  ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3475  break;
3476  }
3477  }else {
3478  if(bindf & BINDF_FROMURLMON)
3479  CHECK_NOT_CALLED(Switch);
3480  else
3481  CHECK_NOT_CALLED(ReportData);
3482  if(cb == 0) break;
3483  }
3484  }
3485  if(!test_abort) {
3486  ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3487  CHECK_CALLED(ReportResult);
3488  }
3489  }
3490  if(prot == HTTPS_TEST)
3491  CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3492 
3493  if (prot == HTTP_TEST || prot == HTTPS_TEST)
3494  CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3495 
3496  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3497  ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3498 
3500 
3501  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3502  ok(hres == S_OK, "Abort failed: %08x\n", hres);
3503 
3504  ref = IInternetProtocol_Release(async_protocol);
3505  ok(!ref, "ref=%x\n", ref);
3506  }
3507 
3508  IClassFactory_Release(factory);
3509 
3510  if(flags & TEST_FROMCACHE) {
3511  BOOL res;
3512 
3514  ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3515  }
3516 }
3517 
3518 static void test_http_protocol(void)
3519 {
3520  static const WCHAR posttest_url[] =
3521  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3522  't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3523  static const WCHAR redirect_url[] =
3524  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3525  't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3526  static const WCHAR winetest_url[] =
3527  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3528  't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3529  static const WCHAR empty_url[] =
3530  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3531  't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3532  static const WCHAR cache_only_url[] =
3533  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3534  't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3535 
3536 
3537  trace("Testing http protocol (not from urlmon)...\n");
3538  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3539  test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3540 
3541  trace("Testing http protocol (from urlmon)...\n");
3542  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3543  test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3544 
3545  trace("Testing http protocol (to file)...\n");
3546  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3547  test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3548 
3549  trace("Testing http protocol (post data)...\n");
3550  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3551  test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3552 
3553  trace("Testing http protocol (post data stream)...\n");
3555 
3556  trace("Testing http protocol (direct read)...\n");
3557  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3558  test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3559 
3560  trace("Testing http protocol (redirected)...\n");
3561  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3562  test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3563 
3564  trace("Testing http protocol (redirected, disable auto redirect)...\n");
3565  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3567 
3568  trace("Testing http protocol empty file...\n");
3569  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3570  test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3571 
3572  /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3573  * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3574  * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3575  * tests work on Windows and have them around for the future.
3576  */
3577  if(broken(1)) {
3578  trace("Testing http protocol (from cache)...\n");
3579  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3580  test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3581  }
3582 
3583  trace("Testing http protocol abort...\n");
3584  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3585  test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3586 
3587  test_early_abort(&CLSID_HttpProtocol);
3588  test_early_abort(&CLSID_HttpSProtocol);
3589 }
3590 
3591 static void test_https_protocol(void)
3592 {
3593  static const WCHAR https_winehq_url[] =
3594  {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3595  't','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
3596 
3597  trace("Testing https protocol (from urlmon)...\n");
3598  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3599  test_http_protocol_url(https_winehq_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3600 }
3601 
3602 
3603 static void test_ftp_protocol(void)
3604 {
3607  IUnknown *unk;
3608  BYTE buf[4096];
3609  ULONG ref;
3610  DWORD cb;
3611  HRESULT hres;
3612 
3613  static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q',