ReactOS  0.4.12-dev-685-gf36cbf7
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);
108 DEFINE_EXPECT(StartEx);
109 DEFINE_EXPECT(Terminate);
111 DEFINE_EXPECT(Read2);
115 DEFINE_EXPECT(Abort);
117 DEFINE_EXPECT(MimeFilter_Start);
118 DEFINE_EXPECT(MimeFilter_ReportData);
119 DEFINE_EXPECT(MimeFilter_ReportResult);
120 DEFINE_EXPECT(MimeFilter_Terminate);
121 DEFINE_EXPECT(MimeFilter_LockRequest);
122 DEFINE_EXPECT(MimeFilter_UnlockRequest);
123 DEFINE_EXPECT(MimeFilter_Read);
124 DEFINE_EXPECT(MimeFilter_Switch);
125 DEFINE_EXPECT(MimeFilter_Continue);
128 DEFINE_EXPECT(Redirect);
129 DEFINE_EXPECT(outer_QI_test);
130 DEFINE_EXPECT(Protocol_destructor);
131 
132 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
133 static const WCHAR index_url[] =
134  {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
135 
136 static const WCHAR acc_mimeW[] = {'*','/','*',0};
137 static const WCHAR user_agentW[] = {'W','i','n','e',0};
138 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
139 static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
140 static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
141 static const WCHAR emptyW[] = {0};
142 static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
143 static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0};
144 
154 static void *expect_pv;
157 static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
162 
163 enum {
168 } state;
169 
170 static enum {
179 
180 typedef struct {
187 } Protocol;
188 
190 
191 static const WCHAR protocol_names[][10] = {
192  {'f','i','l','e',0},
193  {'h','t','t','p',0},
194  {'h','t','t','p','s',0},
195  {'f','t','p',0},
196  {'m','k',0},
197  {'i','t','s',0},
198  {'t','e','s','t',0}
199 };
200 
201 static const WCHAR binding_urls[][130] = {
202  {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
203  {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
204  'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0},
205  {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
206  '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
207  {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
208  '/','p','u','b','/','o','t','h','e','r',
209  '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
210  {'m','k',':','t','e','s','t',0},
211  {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0},
212  {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
213 };
214 
215 static const CHAR post_data[] = "mode=Test";
216 
217 static int strcmp_wa(LPCWSTR strw, const char *stra)
218 {
219  CHAR buf[512];
220  WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
221  return lstrcmpA(stra, buf);
222 }
223 
224 static const char *w2a(LPCWSTR str)
225 {
226  static char buf[INTERNET_MAX_URL_LENGTH];
227  WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
228  return buf;
229 }
230 
232 {
234  || IsEqualGUID(&IID_IHttpSecurity, riid)) {
235  *ppv = iface;
236  return S_OK;
237  }
238 
239  ok(0, "unexpected call\n");
240  return E_NOINTERFACE;
241 }
242 
244 {
245  return 2;
246 }
247 
249 {
250  return 1;
251 }
252 
253 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rguidReason, HWND *phwnd)
254 {
255  trace("HttpSecurity_GetWindow\n");
256 
257  return S_FALSE;
258 }
259 
261 {
262  win_skip("Security problem: %u\n", dwProblem);
264  "Expected got %u security problem\n", dwProblem);
265 
266  /* Only retry once */
267  if (security_problem)
268  return E_ABORT;
269 
271  if(dwProblem == ERROR_INTERNET_INVALID_CA)
272  return E_ABORT;
273  SET_EXPECT(BeginningTransaction);
274 
275  return RPC_E_RETRY;
276 }
277 
278 static IHttpSecurityVtbl HttpSecurityVtbl = {
284 };
285 
287 
289 {
291  || IsEqualGUID(&IID_IHttpNegotiate, riid)
292  || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
293  *ppv = iface;
294  return S_OK;
295  }
296 
297  ok(0, "unexpected call\n");
298  return E_NOINTERFACE;
299 }
300 
302 {
303  return 2;
304 }
305 
307 {
308  return 1;
309 }
310 
312  LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
313 {
314  LPWSTR addl_headers;
315 
316  static const WCHAR wszHeaders[] =
317  {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
318  'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
319  'd','e','d','\r','\n',0};
320 
321  CHECK_EXPECT(BeginningTransaction);
322 
323  if(binding_test)
324  ok(!lstrcmpW(szURL, binding_urls[tested_protocol]), "szURL != http_url\n");
325  else
326  ok(!lstrcmpW(szURL, http_url), "szURL != http_url\n");
327  ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
328  ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
329  if(pszAdditionalHeaders)
330  {
331  ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
332  if (http_post_test)
333  {
334  addl_headers = CoTaskMemAlloc(sizeof(wszHeaders));
335  memcpy(addl_headers, wszHeaders, sizeof(wszHeaders));
336  *pszAdditionalHeaders = addl_headers;
337  }
338  }
339 
340  return S_OK;
341 }
342 
344  LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
345 {
346  CHECK_EXPECT(OnResponse);
347 
348  ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
349  ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
350  ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
351  ok(pszAdditionalRequestHeaders == NULL, "pszAdditionalHeaders != NULL\n");
352 
353  return S_OK;
354 }
355 
357  BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
358 {
359  static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
360 
361  CHECK_EXPECT(GetRootSecurityId);
362 
363  ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
364  ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
365  ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
366 
367  if(pcbSecurityId) {
368  ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
369  *pcbSecurityId = sizeof(sec_id);
370  }
371 
372  if(pbSecurityId)
373  memcpy(pbSecurityId, sec_id, sizeof(sec_id));
374 
375  return E_FAIL;
376 }
377 
378 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
385 };
386 
388 
390 {
391  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
392  *ppv = NULL;
393  return E_NOINTERFACE;
394 }
395 
397 {
398  return 2;
399 }
400 
402 {
403  return 1;
404 }
405 
407 {
408  CHECK_EXPECT(Redirect);
409  *cancel = VARIANT_FALSE;
410  return S_OK;
411 }
412 
413 static const IBindCallbackRedirectVtbl BindCallbackRedirectVtbl = {
418 };
419 
421 
422 static HRESULT QueryInterface(REFIID,void**);
423 
425 {
426  return QueryInterface(riid, ppv);
427 }
428 
430 {
431  return 2;
432 }
433 
435 {
436  return 1;
437 }
438 
440  REFIID riid, void **ppv)
441 {
442  if(IsEqualGUID(&IID_IHttpNegotiate, guidService) || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
443  CHECK_EXPECT2(QueryService_HttpNegotiate);
444  return IHttpNegotiate2_QueryInterface(&http_negotiate, riid, ppv);
445  }
446 
447  if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
448  ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid\n");
449  CHECK_EXPECT(QueryService_InternetProtocol);
450  return E_NOINTERFACE;
451  }
452 
453  if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
454  ok(IsEqualGUID(&IID_IHttpSecurity, riid), "unexpected riid\n");
455  CHECK_EXPECT(QueryService_HttpSecurity);
456  return IHttpSecurity_QueryInterface(&http_security, riid, ppv);
457  }
458 
459  if(IsEqualGUID(&IID_IBindCallbackRedirect, guidService)) {
460  CHECK_EXPECT(QueryService_IBindCallbackRedirect);
461  ok(IsEqualGUID(&IID_IBindCallbackRedirect, riid), "riid = %s\n", wine_dbgstr_guid(riid));
463  return S_OK;
464  }
465 
466  if(IsEqualGUID(&IID_IGetBindHandle, guidService)) {
467  trace("QueryService(IID_IGetBindHandle)\n");
468  *ppv = NULL;
469  return E_NOINTERFACE;
470  }
471 
472  if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
473  trace("QueryService(IID_IWindowForBindingUI)\n");
474  *ppv = NULL;
475  return E_NOINTERFACE;
476  }
477 
478  ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
479  return E_FAIL;
480 }
481 
482 static const IServiceProviderVtbl ServiceProviderVtbl = {
487 };
488 
490 
492 {
493  static const IID IID_strm_unknown = {0x2f68429a,0x199a,0x4043,{0x93,0x11,0xf2,0xfe,0x7c,0x13,0xcc,0xb9}};
494 
495  if(!IsEqualGUID(&IID_strm_unknown, riid)) /* IE11 */
496  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
497 
498  *ppv = NULL;
499  return E_NOINTERFACE;
500 }
501 
503 {
504  return 2;
505 }
506 
508 {
509  return 1;
510 }
511 
512 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
513  ULONG cb, ULONG *pcbRead)
514 {
516 
517  ok(GetCurrentThreadId() != thread_id, "wrong thread %d\n", GetCurrentThreadId());
518 
519  ok(pv != NULL, "pv == NULL\n");
520  ok(cb == 0x20000 || broken(cb == 0x2000), "cb = %d\n", cb);
521  ok(pcbRead != NULL, "pcbRead == NULL\n");
522 
523  if(post_stream_read) {
524  *pcbRead = 0;
525  return S_FALSE;
526  }
527 
528  memcpy(pv, post_data, sizeof(post_data)-1);
529  post_stream_read += *pcbRead = sizeof(post_data)-1;
530  return S_OK;
531 }
532 
533 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
534  ULONG cb, ULONG *pcbWritten)
535 {
536  ok(0, "unexpected call\n");
537  return E_NOTIMPL;
538 }
539 
541  DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
542 {
544 
545  ok(!dlibMove.QuadPart, "dlibMove != 0\n");
546  ok(dwOrigin == STREAM_SEEK_SET, "dwOrigin = %d\n", dwOrigin);
547  ok(!plibNewPosition, "plibNewPosition == NULL\n");
548 
549  return S_OK;
550 }
551 
553 {
554  ok(0, "unexpected call\n");
555  return E_NOTIMPL;
556 }
557 
559  ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
560 {
561  ok(0, "unexpected call\n");
562  return E_NOTIMPL;
563 }
564 
565 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
566 {
567  ok(0, "unexpected call\n");
568  return E_NOTIMPL;
569 }
570 
572 {
573  ok(0, "unexpected call\n");
574  return E_NOTIMPL;
575 }
576 
578  ULARGE_INTEGER cb, DWORD dwLockType)
579 {
580  ok(0, "unexpected call\n");
581  return E_NOTIMPL;
582 }
583 
585  ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
586 {
587  ok(0, "unexpected call\n");
588  return E_NOTIMPL;
589 }
590 
591 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
592  DWORD dwStatFlag)
593 {
594  ok(0, "unexpected call\n");
595  return E_NOTIMPL;
596 }
597 
598 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
599 {
600  ok(0, "unexpected call\n");
601  return E_NOTIMPL;
602 }
603 
604 static const IStreamVtbl StreamVtbl = {
608  Stream_Read,
609  Stream_Write,
610  Stream_Seek,
617  Stream_Stat,
619 };
620 
621 static IStream Stream = { &StreamVtbl };
622 
624 {
625  return QueryInterface(riid, ppv);
626 }
627 
629 {
630  return 2;
631 }
632 
634 {
635  return 1;
636 }
637 
638 static void call_continue(PROTOCOLDATA *protocol_data)
639 {
640  HRESULT hres;
641 
642  if (winetest_debug > 1)
643  trace("continue in state %d\n", state);
644 
645  if(state == STATE_CONNECTING) {
647  if (http_is_first){
648  CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
649  CLEAR_CALLED(ReportProgress_PROXYDETECTING);
650  }
651  CLEAR_CALLED(ReportProgress_CONNECTING);
652  }
654  todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
655  else if (tested_protocol != HTTPS_TEST)
656  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
657  if(test_redirect && !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
658  CHECK_CALLED(ReportProgress_REDIRECTING);
660  }
661 
662  switch(state) {
665  SET_EXPECT(ReportProgress_SENDINGREQUEST);
666  break;
669  && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))) {
670  SET_EXPECT(OnResponse);
672  SET_EXPECT(ReportProgress_ACCEPTRANGES);
673  SET_EXPECT(ReportProgress_ENCODING);
674  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
675  if(bindf & BINDF_NEEDFILE)
676  SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
677  }
678  default:
679  break;
680  }
681 
682  if(state != STATE_SENDINGREQUEST && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)))
683  SET_EXPECT(ReportData);
684  hres = IInternetProtocol_Continue(async_protocol, protocol_data);
685  ok(hres == S_OK, "Continue failed: %08x\n", hres);
687  CLEAR_CALLED(ReportData);
688  else if(state != STATE_SENDINGREQUEST && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)))
689  CHECK_CALLED(ReportData);
690 
691  switch(state) {
694  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
696  break;
698  if(!security_problem) {
701  && (!test_redirect || !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))) {
702  CHECK_CALLED(OnResponse);
704  CHECK_CALLED(ReportProgress_ACCEPTRANGES);
705  else if(test_redirect || test_abort)
706  CLEAR_CALLED(ReportProgress_ACCEPTRANGES);
707  CLEAR_CALLED(ReportProgress_ENCODING);
708  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
709  if(bindf & BINDF_NEEDFILE)
710  CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
711  }
712  }
713  else
714  {
716  SET_EXPECT(ReportProgress_CONNECTING);
717  }
718  default:
719  break;
720  }
721 }
722 
723 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
724 {
726  CHECK_EXPECT2(Switch);
727  else
728  CHECK_EXPECT(Switch);
729 
730  ok(pProtocolData != NULL, "pProtocolData == NULL\n");
731  if(binding_test) {
732  ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
733  ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
734  pProtocolData->grfFlags, protocoldata.grfFlags );
735  ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
736  pProtocolData->dwState, protocoldata.dwState );
737  ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
738  pProtocolData->pData, protocoldata.pData );
739  ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
740  pProtocolData->cbData, protocoldata.cbData );
741  }
742 
743  pdata = pProtocolData;
744 
745  if(binding_test) {
747  ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
748  return S_OK;
749  }if(direct_read) {
750  continue_protdata = *pProtocolData;
752  ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
753  }else {
754  call_continue(pProtocolData);
756  }
757 
758  return S_OK;
759 }
760 
761 static const char *status_names[] =
762 {
763  "0",
764  "FINDINGRESOURCE",
765  "CONNECTING",
766  "REDIRECTING",
767  "BEGINDOWNLOADDATA",
768  "DOWNLOADINGDATA",
769  "ENDDOWNLOADDATA",
770  "BEGINDOWNLOADCOMPONENTS",
771  "INSTALLINGCOMPONENTS",
772  "ENDDOWNLOADCOMPONENTS",
773  "USINGCACHEDCOPY",
774  "SENDINGREQUEST",
775  "CLASSIDAVAILABLE",
776  "MIMETYPEAVAILABLE",
777  "CACHEFILENAMEAVAILABLE",
778  "BEGINSYNCOPERATION",
779  "ENDSYNCOPERATION",
780  "BEGINUPLOADDATA",
781  "UPLOADINGDATA",
782  "ENDUPLOADINGDATA",
783  "PROTOCOLCLASSID",
784  "ENCODING",
785  "VERIFIEDMIMETYPEAVAILABLE",
786  "CLASSINSTALLLOCATION",
787  "DECODING",
788  "LOADINGMIMEHANDLER",
789  "CONTENTDISPOSITIONATTACH",
790  "FILTERREPORTMIMETYPE",
791  "CLSIDCANINSTANTIATE",
792  "IUNKNOWNAVAILABLE",
793  "DIRECTBIND",
794  "RAWMIMETYPE",
795  "PROXYDETECTING",
796  "ACCEPTRANGES",
797  "COOKIE_SENT",
798  "COMPACT_POLICY_RECEIVED",
799  "COOKIE_SUPPRESSED",
800  "COOKIE_STATE_UNKNOWN",
801  "COOKIE_STATE_ACCEPT",
802  "COOKIE_STATE_REJECT",
803  "COOKIE_STATE_PROMPT",
804  "COOKIE_STATE_LEASH",
805  "COOKIE_STATE_DOWNGRADE",
806  "POLICY_HREF",
807  "P3P_HEADER",
808  "SESSION_COOKIE_RECEIVED",
809  "PERSISTENT_COOKIE_RECEIVED",
810  "SESSION_COOKIES_ALLOWED",
811  "CACHECONTROL",
812  "CONTENTDISPOSITIONFILENAME",
813  "MIMETEXTPLAINMISMATCH",
814  "PUBLISHERAVAILABLE",
815  "DISPLAYNAMEAVAILABLE"
816 };
817 
819  LPCWSTR szStatusText)
820 {
821  static const WCHAR null_guid[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
822  '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
823  static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0};
824 
825  if (winetest_debug > 1)
826  {
827  if (ulStatusCode < ARRAY_SIZE(status_names))
828  trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) );
829  else
830  trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) );
831  }
832 
833  switch(ulStatusCode) {
834  case BINDSTATUS_MIMETYPEAVAILABLE:
835  CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE);
836  if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) {
837  if(!short_read || !direct_read)
838  CHECK_CALLED(Read); /* set in Continue */
839  else if(short_read)
840  CHECK_CALLED(Read2); /* set in Read */
841  }
842  ok(szStatusText != NULL, "szStatusText == NULL\n");
843  if(szStatusText) {
845  ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText));
846  else if (http_post_test)
847  ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) &&
848  !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)),
849  "szStatusText != text/plain\n");
850  else if(empty_file)
851  ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
852  else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test
854  ok(lstrlenW(gifW) <= lstrlenW(szStatusText) &&
855  !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)),
856  "szStatusText != image/gif\n");
857  else if(!mimefilter_test)
858  ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) &&
859  !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
860  "szStatusText != text/html\n");
861  }
862  break;
863  case BINDSTATUS_DIRECTBIND:
864  CHECK_EXPECT2(ReportProgress_DIRECTBIND);
865  ok(szStatusText == NULL, "szStatusText != NULL\n");
866  break;
867  case BINDSTATUS_RAWMIMETYPE:
868  CHECK_EXPECT2(ReportProgress_RAWMIMETYPE);
869  ok(szStatusText != NULL, "szStatusText == NULL\n");
870  if(szStatusText)
871  ok(lstrlenW(szStatusText) < lstrlenW(text_htmlW) ||
872  !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)),
873  "szStatusText != text/html\n");
874  break;
875  case BINDSTATUS_CACHEFILENAMEAVAILABLE:
876  CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
877  ok(szStatusText != NULL, "szStatusText == NULL\n");
878  if(szStatusText) {
879  if(binding_test)
880  ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText\n");
881  else if(tested_protocol == FILE_TEST)
882  ok(!lstrcmpW(szStatusText, file_name), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
883  else
884  ok(szStatusText != NULL, "szStatusText == NULL\n");
885  }
886  break;
887  case BINDSTATUS_FINDINGRESOURCE:
888  CHECK_EXPECT2(ReportProgress_FINDINGRESOURCE);
889  ok(szStatusText != NULL, "szStatusText == NULL\n");
890  break;
891  case BINDSTATUS_CONNECTING:
892  CHECK_EXPECT2(ReportProgress_CONNECTING);
893  ok(szStatusText != NULL, "szStatusText == NULL\n");
894  break;
895  case BINDSTATUS_SENDINGREQUEST:
896  CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
898  ok(szStatusText != NULL, "szStatusText == NULL\n");
899  if(szStatusText)
900  ok(!*szStatusText, "wrong szStatusText\n");
901  }
902  break;
903  case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
904  CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
905  ok(szStatusText != NULL, "szStatusText == NULL\n");
906  if(szStatusText)
907  ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n");
908  break;
909  case BINDSTATUS_PROTOCOLCLASSID:
910  CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID);
911  ok(szStatusText != NULL, "szStatusText == NULL\n");
912  ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText));
913  break;
914  case BINDSTATUS_COOKIE_SENT:
915  CHECK_EXPECT2(ReportProgress_COOKIE_SENT);
916  ok(szStatusText == NULL, "szStatusText != NULL\n");
917  break;
918  case BINDSTATUS_REDIRECTING:
919  CHECK_EXPECT(ReportProgress_REDIRECTING);
920  if(test_redirect)
921  ok(!strcmp_wa(szStatusText, "http://test.winehq.org/tests/hello.html"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
922  else
923  ok(szStatusText == NULL, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
924  break;
925  case BINDSTATUS_ENCODING:
926  CHECK_EXPECT(ReportProgress_ENCODING);
927  ok(!strcmp_wa(szStatusText, "gzip"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
928  break;
929  case BINDSTATUS_ACCEPTRANGES:
930  CHECK_EXPECT(ReportProgress_ACCEPTRANGES);
931  ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
932  break;
933  case BINDSTATUS_PROXYDETECTING:
934  if(!called_ReportProgress_PROXYDETECTING)
935  SET_EXPECT(ReportProgress_CONNECTING);
936  CHECK_EXPECT2(ReportProgress_PROXYDETECTING);
937  ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
938  break;
939  case BINDSTATUS_LOADINGMIMEHANDLER:
940  CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
941  ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
942  break;
943  case BINDSTATUS_DECODING:
944  CHECK_EXPECT(ReportProgress_DECODING);
945  ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
946  break;
947  case BINDSTATUS_RESERVED_7:
948  trace("BINDSTATUS_RESERVED_7\n");
949  break;
950  case BINDSTATUS_RESERVED_8:
951  trace("BINDSTATUS_RESERVED_8\n");
952  break;
953  default:
954  ok(0, "Unexpected status %d (%d)\n", ulStatusCode, ulStatusCode-BINDSTATUS_LAST);
955  };
956 
957  return S_OK;
958 }
959 
961 {
963  char buf[1024];
964  DWORD size, len;
965  HRESULT hres;
966 
967  static const WCHAR connectionW[] = {'c','o','n','n','e','c','t','i','o','n',0};
968 
969  hres = IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&info);
970  ok(hres == S_OK, "Could not get IWinInterHttpInfo iface: %08x\n", hres);
971 
972  size = sizeof(buf);
973  strcpy(buf, "connection");
974  hres = IWinInetHttpInfo_QueryInfo(info, HTTP_QUERY_CUSTOM, buf, &size, NULL, NULL);
975  if(tested_protocol != FTP_TEST) {
976  ok(hres == S_OK, "QueryInfo failed: %08x\n", hres);
977 
978  ok(!strcmp(buf, "Keep-Alive"), "buf = %s\n", buf);
979  len = strlen(buf);
980  ok(size == len, "size = %u, expected %u\n", size, len);
981 
982  size = sizeof(buf);
983  memcpy(buf, connectionW, sizeof(connectionW));
984  hres = IWinInetHttpInfo_QueryInfo(info, HTTP_QUERY_CUSTOM, buf, &size, NULL, NULL);
985  ok(hres == S_FALSE, "QueryInfo returned %08x\n", hres);
986  }else {
987  ok(hres == S_FALSE, "QueryInfo failed: %08x\n", hres);
988  }
989 
990  IWinInetHttpInfo_Release(info);
991 }
992 
994  ULONG ulProgress, ULONG ulProgressMax)
995 {
996  HRESULT hres;
997 
998  static int rec_depth;
999  rec_depth++;
1000 
1002  CHECK_EXPECT2(ReportData);
1003 
1004  ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
1005  ulProgress, ulProgressMax);
1006  if(!file_with_hash)
1007  ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
1008  /* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
1009  if(tested_protocol == FILE_TEST)
1010  ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
1011  (grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_SKIPDRAINDATAFORFILEURLS)),
1012  "grcfBSCF = %08x\n", grfBSCF);
1013  else
1014  ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
1015  }else if(bind_from_cache) {
1016  CHECK_EXPECT(ReportData);
1017 
1018  ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF);
1019  ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress);
1020  ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax);
1021  }else if(direct_read) {
1022  BYTE buf[14096];
1023  ULONG read;
1024 
1025  if(!read_report_data && rec_depth == 1) {
1026  BOOL reported_all_data = called_ReportData2;
1027 
1028  CHECK_EXPECT2(ReportData);
1029 
1030  if(short_read) {
1031  ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE)
1032  || grfBSCF == BSCF_FIRSTDATANOTIFICATION, /* < IE8 */
1033  "grcfBSCF = %08x\n", grfBSCF);
1034  CHECK_CALLED(Read); /* Set in Continue */
1036  }else if(first_data_notif) {
1037  ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
1039  }else if(reported_all_data) {
1040  ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION),
1041  "grcfBSCF = %08x\n", grfBSCF);
1042  }else if(!direct_read) {
1043  ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION, "grcfBSCF = %08x\n", grfBSCF);
1044  }
1045 
1046  do {
1047  read = 0;
1048  if(emulate_prot)
1049  SET_EXPECT(Read);
1050  else
1051  SET_EXPECT(ReportData2);
1052  SET_EXPECT(ReportResult);
1053  if(!emulate_prot)
1054  SET_EXPECT(Switch);
1055  hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
1056  ok(hres == E_PENDING || hres == S_FALSE || hres == S_OK, "Read failed: %08x\n", hres);
1057  if(hres == S_OK)
1058  ok(read, "read == 0\n");
1059  if(reported_all_data)
1060  ok(hres == S_FALSE, "Read failed: %08x, expected S_FALSE\n", hres);
1061  if(!emulate_prot && hres != E_PENDING)
1062  CHECK_NOT_CALLED(Switch); /* otherwise checked in wait_for_switch loop */
1063  if(emulate_prot)
1064  CHECK_CALLED(Read);
1065  if(!reported_all_data && called_ReportData2) {
1066  if(!emulate_prot)
1067  CHECK_CALLED(ReportData2);
1068  CHECK_CALLED(ReportResult);
1069  reported_all_data = TRUE;
1070  }else {
1071  if(!emulate_prot)
1072  CHECK_NOT_CALLED(ReportData2);
1073  CHECK_NOT_CALLED(ReportResult);
1074  }
1075  }while(hres == S_OK);
1076  if(hres == S_FALSE)
1078  }else {
1079  CHECK_EXPECT(ReportData2);
1080 
1081  ok(grfBSCF & BSCF_LASTDATANOTIFICATION, "grfBSCF = %08x\n", grfBSCF);
1082 
1083  read = 0xdeadbeef;
1084  if(emulate_prot)
1085  SET_EXPECT(Read2);
1086  hres = IInternetProtocol_Read(binding_test ? binding_protocol : async_protocol, expect_pv = buf, sizeof(buf), &read);
1087  if(emulate_prot)
1088  CHECK_CALLED(Read2);
1089  ok(hres == S_FALSE, "Read returned: %08x, expected E_FALSE\n", hres);
1090  ok(!read, "read = %d\n", read);
1091  }
1093  || tested_protocol == FTP_TEST)) {
1094  if(empty_file)
1095  CHECK_EXPECT2(ReportData);
1096  else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
1097  CHECK_EXPECT(ReportData);
1098  else if (http_post_test)
1099  ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress);
1100 
1101  if(empty_file) {
1102  ok(!ulProgress, "ulProgress = %d\n", ulProgress);
1103  ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax);
1104  }else {
1105  ok(ulProgress, "ulProgress == 0\n");
1106  }
1107 
1108  if(empty_file) {
1109  ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION),
1110  "grcfBSCF = %08x\n", grfBSCF);
1112  }else if(first_data_notif) {
1113  ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION
1114  || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE),
1115  "grcfBSCF = %08x\n", grfBSCF);
1117  } else {
1118  ok(grfBSCF == BSCF_INTERMEDIATEDATANOTIFICATION
1119  || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION)
1120  || broken(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION)),
1121  "grcfBSCF = %08x\n", grfBSCF);
1122  }
1123 
1124  if((grfBSCF & BSCF_FIRSTDATANOTIFICATION) && !binding_test)
1126 
1127  if(!(bindf & BINDF_FROMURLMON) &&
1128  !(grfBSCF & BSCF_LASTDATANOTIFICATION)) {
1129  if(state == STATE_CONNECTING) {
1131  if(http_is_first) {
1132  CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1133  CHECK_CALLED(ReportProgress_CONNECTING);
1134  }
1135  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1136  CHECK_CALLED(OnResponse);
1137  CHECK_CALLED(ReportProgress_RAWMIMETYPE);
1138  }
1140  }
1141  }else if(!read_report_data) {
1142  BYTE buf[1000];
1143  ULONG read;
1144  HRESULT hres;
1145 
1146  CHECK_EXPECT(ReportData);
1147 
1148  if(tested_protocol != BIND_TEST) {
1149  do {
1150  if(mimefilter_test)
1151  SET_EXPECT(MimeFilter_Read);
1152  else if(rec_depth > 1)
1153  SET_EXPECT(Read2);
1154  else
1155  SET_EXPECT(Read);
1156  hres = IInternetProtocol_Read(binding_protocol, expect_pv=buf, sizeof(buf), &read);
1157  if(mimefilter_test)
1158  CHECK_CALLED(MimeFilter_Read);
1159  else if(rec_depth > 1)
1160  CHECK_CALLED(Read2);
1161  else
1162  CHECK_CALLED(Read);
1163  }while(hres == S_OK);
1164  }
1165  }
1166 
1167  rec_depth--;
1168  return S_OK;
1169 }
1170 
1172  DWORD dwError, LPCWSTR szResult)
1173 {
1174  CHECK_EXPECT(ReportResult);
1175 
1176  if(security_problem)
1177  return S_OK;
1178 
1179  if(tested_protocol == FTP_TEST)
1180  ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
1181  else
1182  ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
1183  hrResult, expect_hrResult);
1184 #ifdef __REACTOS__
1185  if(!winetest_interactive && tested_protocol != FTP_TEST && hrResult != expect_hrResult) {
1186  skip("CORE-10360/ROSTESTS-192: Test might hang, skipping the rest!\n");
1187  exit(1);
1188  }
1189 #endif
1190  if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST || test_abort || hrResult == INET_E_REDIRECT_FAILED)
1191  ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
1192  else
1193  ok(dwError != ERROR_SUCCESS ||
1194  broken(tested_protocol == MK_TEST), /* WinME and NT4 */
1195  "dwError == ERROR_SUCCESS\n");
1196 
1197  if(hrResult == INET_E_REDIRECT_FAILED)
1198  ok(!strcmp_wa(szResult, "http://test.winehq.org/tests/hello.html"), "szResult = %s\n", wine_dbgstr_w(szResult));
1199  else
1200  ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1201 
1202  if(direct_read)
1203  SET_EXPECT(ReportData); /* checked after main loop */
1204 
1205  return S_OK;
1206 }
1207 
1208 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
1216 };
1217 
1219 
1221 {
1223  || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
1224  *ppv = iface;
1225  return S_OK;
1226  }
1227 
1228  ok(0, "unexpected call\n");
1229  return E_NOTIMPL;
1230 }
1231 
1233 {
1234  return 2;
1235 }
1236 
1238 {
1239  return 1;
1240 }
1241 
1242 static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
1243 {
1244  HRESULT hres;
1245 
1246  CHECK_EXPECT(MimeFilter_Switch);
1247 
1248  SET_EXPECT(Switch);
1249  hres = IInternetProtocolSink_Switch(filtered_sink, pProtocolData);
1250  ok(hres == S_OK, "Switch failed: %08x\n", hres);
1251  CHECK_CALLED(Switch);
1252 
1253  return S_OK;
1254 }
1255 
1257  LPCWSTR szStatusText)
1258 {
1259  switch(ulStatusCode) {
1260  case BINDSTATUS_LOADINGMIMEHANDLER:
1261  /*
1262  * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the
1263  * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in
1264  * ProtocolSink_ReportProgress to workaround it.
1265  */
1266  CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1267  ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText));
1268  break;
1269  default:
1270  ok(0, "Unexpected status code %d\n", ulStatusCode);
1271  }
1272 
1273  return S_OK;
1274 }
1275 
1277  ULONG ulProgress, ULONG ulProgressMax)
1278 {
1279  DWORD read = 0;
1280  BYTE buf[8192];
1281  HRESULT hres;
1283 
1284  CHECK_EXPECT(MimeFilter_ReportData);
1285 
1286  if(!filter_state && !no_mime) {
1287  SET_EXPECT(Read);
1288  hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
1289  if(tested_protocol == HTTP_TEST)
1290  ok(hres == S_OK || hres == E_PENDING || hres == S_FALSE, "Read failed: %08x\n", hres);
1291  else
1292  ok(hres == S_OK, "Read failed: %08x\n", hres);
1293  CHECK_CALLED(Read);
1294 
1295  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1296  hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, text_htmlW);
1297  ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1298  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1299 
1300  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1301  hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW);
1302  ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1303  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1304 
1305  /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */
1306  }
1307 
1308  if(no_mime && prot_read<200) {
1309  SET_EXPECT(Read);
1310  }else if(no_mime && prot_read<300) {
1311  report_mime = TRUE;
1312  SET_EXPECT(Read);
1313  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1314  SET_EXPECT(ReportData);
1315  }else if(!read_report_data) {
1316  SET_EXPECT(ReportData);
1317  }
1318  hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax);
1319  ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1320  if(no_mime && prot_read<=200) {
1321  CHECK_CALLED(Read);
1322  }else if(report_mime) {
1323  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1324  CHECK_CALLED(ReportData);
1325  }else if(!read_report_data) {
1326  CHECK_CALLED(ReportData);
1327  }
1328 
1329  if(!filter_state)
1330  filter_state = 1;
1331 
1332  return S_OK;
1333 }
1334 
1336  DWORD dwError, LPCWSTR szResult)
1337 {
1338  HRESULT hres;
1339 
1340  CHECK_EXPECT(MimeFilter_ReportResult);
1341 
1342  ok(hrResult == S_OK, "hrResult = %08x\n", hrResult);
1343  ok(dwError == ERROR_SUCCESS, "dwError = %u\n", dwError);
1344  ok(!szResult, "szResult = %s\n", wine_dbgstr_w(szResult));
1345 
1346  SET_EXPECT(ReportResult);
1347  hres = IInternetProtocolSink_ReportResult(filtered_sink, hrResult, dwError, szResult);
1348  ok(SUCCEEDED(hres), "ReportResult failed: %08x\n", hres);
1349  CHECK_CALLED(ReportResult);
1350 
1351  return S_OK;
1352 }
1353 
1354 static IInternetProtocolSinkVtbl mime_protocol_sink_vtbl = {
1362 };
1363 
1365 
1367 {
1368  static const IID IID_undocumented = {0x58DFC7D0,0x5381,0x43E5,{0x9D,0x72,0x4C,0xDD,0xE4,0xCB,0x0F,0x1A}};
1369  static const IID IID_undocumentedIE10 = {0xc28722e5,0xbc1a,0x4c55,{0xa6,0x8d,0x33,0x21,0x9f,0x69,0x89,0x10}};
1370 
1371  *ppv = NULL;
1372 
1373  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid))
1374  *ppv = &protocol_sink;
1375  if(IsEqualGUID(&IID_IServiceProvider, riid))
1376  *ppv = &service_provider;
1377  if(IsEqualGUID(&IID_IUriContainer, riid))
1378  return E_NOINTERFACE; /* TODO */
1379 
1380  /* NOTE: IE8 queries for undocumented {58DFC7D0-5381-43E5-9D72-4CDDE4CB0F1A} interface. */
1381  if(IsEqualGUID(&IID_undocumented, riid))
1382  return E_NOINTERFACE;
1383  /* NOTE: IE10 queries for undocumented {c28722e5-bc1a-4c55-a68d-33219f698910} interface. */
1384  if(IsEqualGUID(&IID_undocumentedIE10, riid))
1385  return E_NOINTERFACE;
1386 
1387  if(*ppv)
1388  return S_OK;
1389 
1390  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
1391  return E_NOINTERFACE;
1392 }
1393 
1395 {
1396  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
1397  *ppv = iface;
1398  return S_OK;
1399  }
1400  return E_NOINTERFACE;
1401 }
1402 
1404 {
1405  return 2;
1406 }
1407 
1409 {
1410  return 1;
1411 }
1412 
1413 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1414 {
1415  DWORD cbSize;
1416 
1417  CHECK_EXPECT(GetBindInfo);
1418 
1419  ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1420  ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1421  ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
1422 
1423  *grfBINDF = bindf;
1424  if(binding_test)
1425  *grfBINDF |= BINDF_FROMURLMON;
1426  cbSize = pbindinfo->cbSize;
1427  memset(pbindinfo, 0, cbSize);
1428  pbindinfo->cbSize = cbSize;
1429  pbindinfo->dwOptions = bindinfo_options;
1430 
1431  if(http_post_test)
1432  {
1433  pbindinfo->cbstgmedData = sizeof(post_data)-1;
1434  pbindinfo->dwBindVerb = BINDVERB_POST;
1435  pbindinfo->stgmedData.tymed = http_post_test;
1436 
1437  if(http_post_test == TYMED_HGLOBAL) {
1438  HGLOBAL data;
1439 
1440  /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly */
1441  data = GlobalAlloc(GPTR, sizeof(post_data));
1442  memcpy(data, post_data, sizeof(post_data));
1443  U(pbindinfo->stgmedData).hGlobal = data;
1444  }else {
1445  U(pbindinfo->stgmedData).pstm = &Stream;
1446  }
1447  }
1448 
1449  return S_OK;
1450 }
1451 
1453  LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1454 {
1455  ok(ppwzStr != NULL, "ppwzStr == NULL\n");
1456  ok(pcElFetched != NULL, "pcElFetched == NULL\n");
1457 
1458  switch(ulStringType) {
1459  case BINDSTRING_ACCEPT_MIMES:
1460  CHECK_EXPECT(GetBindString_ACCEPT_MIMES);
1461  ok(cEl == 256, "cEl=%d, expected 256\n", cEl);
1462  if(pcElFetched) {
1463  ok(*pcElFetched == 256, "*pcElFetched=%d, expected 256\n", *pcElFetched);
1464  *pcElFetched = 1;
1465  }
1466  if(ppwzStr) {
1467  *ppwzStr = CoTaskMemAlloc(sizeof(acc_mimeW));
1468  memcpy(*ppwzStr, acc_mimeW, sizeof(acc_mimeW));
1469  }
1470  return S_OK;
1471  case BINDSTRING_USER_AGENT:
1472  CHECK_EXPECT(GetBindString_USER_AGENT);
1473  ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1474  if(pcElFetched) {
1475  ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1476  *pcElFetched = 1;
1477  }
1478  if(ppwzStr) {
1479  *ppwzStr = CoTaskMemAlloc(sizeof(user_agentW));
1480  memcpy(*ppwzStr, user_agentW, sizeof(user_agentW));
1481  }
1482  return S_OK;
1483  case BINDSTRING_POST_COOKIE:
1484  CHECK_EXPECT(GetBindString_POST_COOKIE);
1485  ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1486  if(pcElFetched)
1487  ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1488  return S_OK;
1489  case BINDSTRING_URL: {
1490  DWORD size;
1491 
1492  CHECK_EXPECT(GetBindString_URL);
1493  ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1494  ok(*pcElFetched == 0, "*pcElFetch=%d, expected 0\n", *pcElFetched);
1495  *pcElFetched = 1;
1496 
1498  *ppwzStr = CoTaskMemAlloc(size);
1499  memcpy(*ppwzStr, binding_urls[tested_protocol], size);
1500  return S_OK;
1501  }
1502  case BINDSTRING_ROOTDOC_URL:
1503  CHECK_EXPECT(GetBindString_ROOTDOC_URL);
1504  ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1505  return E_NOTIMPL;
1506  case BINDSTRING_ENTERPRISE_ID:
1507  ok(cEl == 1, "cEl=%d, expected 1\n", cEl);
1508  return E_NOTIMPL;
1509  default:
1510  ok(0, "unexpected ulStringType %d\n", ulStringType);
1511  }
1512 
1513  return E_NOTIMPL;
1514 }
1515 
1516 static IInternetBindInfoVtbl bind_info_vtbl = {
1522 };
1523 
1525 
1527 {
1528  return CONTAINING_RECORD(iface, Protocol, IInternetPriority_iface);
1529 }
1530 
1532  REFIID riid, void **ppv)
1533 {
1534  ok(0, "unexpected call\n");
1535  return E_NOINTERFACE;
1536 }
1537 
1539 {
1541  This->outer_ref++;
1542  return IUnknown_AddRef(This->outer);
1543 }
1544 
1546 {
1548  This->outer_ref--;
1549  return IUnknown_Release(This->outer);
1550 }
1551 
1553 {
1555  ok(nPriority == ex_priority, "nPriority=%d\n", nPriority);
1556  return S_OK;
1557 }
1558 
1560 {
1561  ok(0, "unexpected call\n");
1562  return E_NOTIMPL;
1563 }
1564 
1565 
1566 static const IInternetPriorityVtbl InternetPriorityVtbl = {
1572 };
1573 
1575 {
1576  return 2;
1577 }
1578 
1580 {
1581  return 1;
1582 }
1583 
1585  DWORD dwOptions)
1586 {
1587  HRESULT hres;
1588 
1589  CHECK_EXPECT(Abort);
1590 
1591  SET_EXPECT(ReportResult);
1592  hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
1593  ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1594  CHECK_CALLED(ReportResult);
1595 
1596  return S_OK;
1597 }
1598 
1600 {
1601  ok(0, "unexpected call\n");
1602  return E_NOTIMPL;
1603 }
1604 
1606 {
1607  ok(0, "unexpected call\n");
1608  return E_NOTIMPL;
1609 }
1610 
1612  LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1613 {
1614  ok(0, "unexpected call\n");
1615  return E_NOTIMPL;
1616 }
1617 
1619 {
1620  return CONTAINING_RECORD(iface, Protocol, IInternetProtocolEx_iface);
1621 }
1622 
1624 {
1626 
1627  static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}};
1628  static const IID unknown_iid2 = {0x5b7ebc0c,0xf630,0x4cea,{0x89,0xd3,0x5a,0xf0,0x38,0xed,0x05,0x5c}};
1629 
1630  /* FIXME: Why is it calling here instead of outer IUnknown? */
1631  if(IsEqualGUID(riid, &IID_IInternetPriority)) {
1632  *ppv = &This->IInternetPriority_iface;
1633  IInternetPriority_AddRef(&This->IInternetPriority_iface);
1634  return S_OK;
1635  }
1636  if(!IsEqualGUID(riid, &unknown_iid) && !IsEqualGUID(riid, &unknown_iid2)) /* IE10 */
1637  ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
1638  *ppv = NULL;
1639  return E_NOINTERFACE;
1640 }
1641 
1643 {
1645  This->outer_ref++;
1646  return IUnknown_AddRef(This->outer);
1647 }
1648 
1650 {
1652  This->outer_ref--;
1653  return IUnknown_Release(This->outer);
1654 }
1655 
1657 {
1658  BOOL redirect = redirect_on_continue;
1659  HRESULT hres;
1660 
1661  memset(&protocoldata, -1, sizeof(protocoldata));
1662 
1663  while(1) {
1664  prot_state = 0;
1665 
1666  SET_EXPECT(ReportProgress_FINDINGRESOURCE);
1667  hres = IInternetProtocolSink_ReportProgress(binding_sink,
1668  BINDSTATUS_FINDINGRESOURCE, hostW);
1669  CHECK_CALLED(ReportProgress_FINDINGRESOURCE);
1670  ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1671 
1672  SET_EXPECT(ReportProgress_CONNECTING);
1673  hres = IInternetProtocolSink_ReportProgress(binding_sink,
1674  BINDSTATUS_CONNECTING, winehq_ipW);
1675  CHECK_CALLED(ReportProgress_CONNECTING);
1676  ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1677 
1678  SET_EXPECT(ReportProgress_SENDINGREQUEST);
1679  hres = IInternetProtocolSink_ReportProgress(binding_sink,
1680  BINDSTATUS_SENDINGREQUEST, NULL);
1681  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1682  ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
1683 
1684  prot_state = 1;
1685  SET_EXPECT(Switch);
1686  hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1687  CHECK_CALLED(Switch);
1688  ok(hres == S_OK, "Switch failed: %08x\n", hres);
1689 
1690  if(!redirect)
1691  break;
1692  redirect = FALSE;
1693  }
1694 
1695  if(!short_read) {
1696  prot_state = 2;
1697  if(mimefilter_test)
1698  SET_EXPECT(MimeFilter_Switch);
1699  else
1700  SET_EXPECT(Switch);
1701  hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1702  ok(hres == S_OK, "Switch failed: %08x\n", hres);
1703  if(mimefilter_test)
1704  CHECK_CALLED(MimeFilter_Switch);
1705  else
1706  CHECK_CALLED(Switch);
1707 
1708  if(test_abort) {
1710  return 0;
1711  }
1712 
1713  prot_state = 2;
1714  if(mimefilter_test)
1715  SET_EXPECT(MimeFilter_Switch);
1716  else
1717  SET_EXPECT(Switch);
1718  hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1719  ok(hres == S_OK, "Switch failed: %08x\n", hres);
1720  if(mimefilter_test)
1721  CHECK_CALLED(MimeFilter_Switch);
1722  else
1723  CHECK_CALLED(Switch);
1724 
1725  prot_state = 3;
1726  if(mimefilter_test)
1727  SET_EXPECT(MimeFilter_Switch);
1728  else
1729  SET_EXPECT(Switch);
1730  hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
1731  ok(hres == S_OK, "Switch failed: %08x\n", hres);
1732  if(mimefilter_test)
1733  CHECK_CALLED(MimeFilter_Switch);
1734  else
1735  CHECK_CALLED(Switch);
1736  }
1737 
1739 
1740  return 0;
1741 }
1742 
1743 static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD pi)
1744 {
1745  BINDINFO bindinfo, exp_bindinfo;
1746  DWORD cbindf = 0;
1747  HRESULT hres;
1748 
1749  ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
1750  ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
1751  ok(pOIProtSink != &protocol_sink, "unexpected pOIProtSink\n");
1752  ok(pOIBindInfo != &bind_info, "unexpected pOIBindInfo\n");
1753  ok(!pi, "pi = %x\n", pi);
1754 
1755  if(binding_test)
1756  ok(pOIProtSink == binding_sink, "pOIProtSink != binding_sink\n");
1757 
1758  memset(&bindinfo, 0, sizeof(bindinfo));
1759  bindinfo.cbSize = sizeof(bindinfo);
1760  memcpy(&exp_bindinfo, &bindinfo, sizeof(bindinfo));
1761  if(test_redirect)
1762  exp_bindinfo.dwOptions = bindinfo_options;
1763  SET_EXPECT(GetBindInfo);
1764  if(redirect_on_continue && (bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
1765  SET_EXPECT(QueryService_IBindCallbackRedirect);
1766  hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
1767  if(redirect_on_continue && (bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
1768  CHECK_CALLED(QueryService_IBindCallbackRedirect);
1769  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1770  CHECK_CALLED(GetBindInfo);
1771  ok(cbindf == (bindf|BINDF_FROMURLMON), "bindf = %x, expected %x\n",
1772  cbindf, (bindf|BINDF_FROMURLMON));
1773  ok(!memcmp(&exp_bindinfo, &bindinfo, sizeof(bindinfo)), "unexpected bindinfo\n");
1774  pReleaseBindInfo(&bindinfo);
1775 
1776  SET_EXPECT(ReportProgress_SENDINGREQUEST);
1777  hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, emptyW);
1778  ok(hres == S_OK, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
1779  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
1780 
1784  IHttpNegotiate2 *http_negotiate2;
1785  LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
1786  LPWSTR additional_headers = NULL;
1787  BYTE sec_id[100];
1788  DWORD fetched = 0, size = 100;
1789  DWORD tid;
1790 
1791  SET_EXPECT(GetBindString_USER_AGENT);
1792  hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
1793  &ua, 1, &fetched);
1794  CHECK_CALLED(GetBindString_USER_AGENT);
1795  ok(hres == S_OK, "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
1796  ok(fetched == 1, "fetched = %d, expected 254\n", fetched);
1797  ok(ua != NULL, "ua = %p\n", ua);
1798  ok(!lstrcmpW(ua, user_agentW), "unexpected user agent %s\n", wine_dbgstr_w(ua));
1799  CoTaskMemFree(ua);
1800 
1801  fetched = 256;
1802  SET_EXPECT(GetBindString_ACCEPT_MIMES);
1803  hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
1804  accept_mimes, 256, &fetched);
1805  CHECK_CALLED(GetBindString_ACCEPT_MIMES);
1806 
1807  ok(hres == S_OK,
1808  "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
1809  ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
1810  ok(!lstrcmpW(acc_mimeW, accept_mimes[0]), "unexpected mimes %s\n", wine_dbgstr_w(accept_mimes[0]));
1811  CoTaskMemFree(accept_mimes[0]);
1812 
1813  hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
1814  (void**)&service_provider);
1815  ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1816 
1817  SET_EXPECT(QueryService_HttpNegotiate);
1818  hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1819  &IID_IHttpNegotiate, (void**)&http_negotiate);
1820  CHECK_CALLED(QueryService_HttpNegotiate);
1821  ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1822 
1823  SET_EXPECT(BeginningTransaction);
1824  hres = IHttpNegotiate_BeginningTransaction(http_negotiate, binding_urls[tested_protocol],
1825  NULL, 0, &additional_headers);
1826  CHECK_CALLED(BeginningTransaction);
1827  IHttpNegotiate_Release(http_negotiate);
1828  ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
1829  ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
1830 
1831  SET_EXPECT(QueryService_HttpNegotiate);
1832  hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
1833  &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1834  CHECK_CALLED(QueryService_HttpNegotiate);
1835  ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1836 
1837  size = 512;
1838  SET_EXPECT(GetRootSecurityId);
1839  hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
1840  CHECK_CALLED(GetRootSecurityId);
1841  IHttpNegotiate2_Release(http_negotiate2);
1842  ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
1843  ok(size == 13, "size=%d\n", size);
1844 
1845  IServiceProvider_Release(service_provider);
1846 
1848  CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
1849  return;
1850  }
1851 
1852  SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
1853  hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
1854  BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW);
1855  ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1856  CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
1857 
1858  if(mimefilter_test) {
1860  SET_EXPECT(MimeFilter_Start);
1861  SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
1862  }
1863  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
1864  hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE,
1866  ok(hres == S_OK,
1867  "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
1868  if(mimefilter_test) {
1870  CHECK_CALLED(MimeFilter_Start);
1871  CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
1872  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1873  }else {
1874  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
1875  }
1876 
1877  if(mimefilter_test)
1878  SET_EXPECT(MimeFilter_ReportData);
1879  else
1880  SET_EXPECT(ReportData);
1881  hres = IInternetProtocolSink_ReportData(pOIProtSink,
1882  BSCF_FIRSTDATANOTIFICATION | (tested_protocol == ITS_TEST ? BSCF_DATAFULLYAVAILABLE : BSCF_LASTDATANOTIFICATION),
1883  13, 13);
1884  ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1885  if(mimefilter_test)
1886  CHECK_CALLED(MimeFilter_ReportData);
1887  else
1888  CHECK_CALLED(ReportData);
1889 
1890  if(tested_protocol == ITS_TEST) {
1891  SET_EXPECT(ReportData);
1892  hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
1893  ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
1894  CHECK_CALLED(ReportData);
1895  }
1896 
1897  if(tested_protocol == BIND_TEST) {
1898  hres = IInternetProtocol_Terminate(binding_protocol, 0);
1899  ok(hres == E_FAIL, "Termiante failed: %08x\n", hres);
1900  }
1901 
1902  if(mimefilter_test)
1903  SET_EXPECT(MimeFilter_ReportResult);
1904  else
1905  SET_EXPECT(ReportResult);
1906  hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
1907  ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1908  if(mimefilter_test)
1909  CHECK_CALLED(MimeFilter_ReportResult);
1910  else
1911  CHECK_CALLED(ReportResult);
1912 }
1913 
1915  IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
1916  DWORD grfPI, HANDLE_PTR dwReserved)
1917 {
1919 
1920  ok(!dwReserved, "dwReserved = %lx\n", dwReserved);
1921  protocol_start(pOIProtSink, pOIBindInfo, grfPI);
1922  return S_OK;
1923 }
1924 
1926  PROTOCOLDATA *pProtocolData)
1927 {
1928  DWORD bscf = 0, pr;
1929  HRESULT hres;
1930 
1932 
1933  ok(pProtocolData != NULL, "pProtocolData == NULL\n");
1934  if(!pProtocolData || tested_protocol == BIND_TEST)
1935  return S_OK;
1936  if(binding_test) {
1937  ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
1938  ok(pProtocolData->grfFlags == protocoldata.grfFlags, "grfFlags wrong %x/%x\n",
1939  pProtocolData->grfFlags, protocoldata.grfFlags );
1940  ok(pProtocolData->dwState == protocoldata.dwState, "dwState wrong %x/%x\n",
1941  pProtocolData->dwState, protocoldata.dwState );
1942  ok(pProtocolData->pData == protocoldata.pData, "pData wrong %p/%p\n",
1943  pProtocolData->pData, protocoldata.pData );
1944  ok(pProtocolData->cbData == protocoldata.cbData, "cbData wrong %x/%x\n",
1945  pProtocolData->cbData, protocoldata.cbData );
1946  }
1947 
1948  switch(prot_state) {
1949  case 1: {
1952  static const WCHAR header[] = {'?',0};
1953  static const WCHAR redirect_urlW[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
1954  '/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
1955 
1956  if(redirect_on_continue) {
1959 
1960  if(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)
1961  SET_EXPECT(Redirect);
1962  SET_EXPECT(ReportProgress_REDIRECTING);
1963  SET_EXPECT(Terminate);
1964  SET_EXPECT(Protocol_destructor);
1965  SET_EXPECT(QueryService_InternetProtocol);
1966  SET_EXPECT(CreateInstance);
1967  SET_EXPECT(ReportProgress_PROTOCOLCLASSID);
1969  SET_EXPECT(Start);
1970  hres = IInternetProtocolSink_ReportResult(binding_sink, INET_E_REDIRECT_FAILED, ERROR_SUCCESS, redirect_urlW);
1971  ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1972  if(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS)
1973  CHECK_CALLED(Redirect);
1974  CHECK_CALLED(ReportProgress_REDIRECTING);
1975  CHECK_CALLED(Terminate);
1976  CHECK_CALLED(Protocol_destructor);
1977  CHECK_CALLED(QueryService_InternetProtocol);
1978  CHECK_CALLED(CreateInstance);
1979  CHECK_CALLED(ReportProgress_PROTOCOLCLASSID);
1982 
1983  return S_OK;
1984  }
1985 
1986  hres = IInternetProtocolSink_QueryInterface(binding_sink, &IID_IServiceProvider,
1987  (void**)&service_provider);
1988  ok(hres == S_OK, "Could not get IServiceProvicder\n");
1989 
1990  SET_EXPECT(QueryService_HttpNegotiate);
1991  hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
1992  &IID_IHttpNegotiate, (void**)&http_negotiate);
1993  IServiceProvider_Release(service_provider);
1994  CHECK_CALLED(QueryService_HttpNegotiate);
1995  ok(hres == S_OK, "Could not get IHttpNegotiate\n");
1996 
1997  SET_EXPECT(OnResponse);
1998  hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
1999  IHttpNegotiate_Release(http_negotiate);
2000  CHECK_CALLED(OnResponse);
2001  IHttpNegotiate_Release(http_negotiate);
2002  ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
2003 
2004  if(mimefilter_test) {
2006  SET_EXPECT(MimeFilter_Start);
2007  SET_EXPECT(ReportProgress_LOADINGMIMEHANDLER);
2008  }else if(!(pi & PI_MIMEVERIFICATION)) {
2009  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2010  }
2011  hres = IInternetProtocolSink_ReportProgress(binding_sink,
2012  BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW);
2013  if(mimefilter_test) {
2015  CHECK_CALLED(MimeFilter_Start);
2016  CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER);
2017  }else if(!(pi & PI_MIMEVERIFICATION)) {
2018  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2019  }
2020  ok(hres == S_OK,
2021  "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
2022 
2023  bscf |= BSCF_FIRSTDATANOTIFICATION;
2024  break;
2025  }
2026  case 2:
2027  case 3:
2028  bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
2029  break;
2030  }
2031 
2032  pr = prot_read;
2033  if(mimefilter_test)
2034  SET_EXPECT(MimeFilter_ReportData);
2035  if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) {
2036  if(pr < 200)
2037  SET_EXPECT(Read); /* checked in ReportData for short_read */
2038  if(pr == 200) {
2039  if(!mimefilter_test)
2040  SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */
2041  SET_EXPECT(GetBindInfo);
2042  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2043  }
2044  if(pr >= 200)
2045  SET_EXPECT(ReportData);
2046  }else {
2047  SET_EXPECT(ReportData);
2048  }
2049 
2050  hres = IInternetProtocolSink_ReportData(binding_sink, bscf, pr, 400);
2051  ok(hres == S_OK, "ReportData failed: %08x\n", hres);
2052 
2053  if(mimefilter_test) {
2054  SET_EXPECT(MimeFilter_ReportData);
2055  }else if(pi & PI_MIMEVERIFICATION) {
2056  if(!short_read && pr < 200)
2057  CHECK_CALLED(Read);
2058  if(pr == 200) {
2059  CLEAR_CALLED(GetBindInfo); /* IE9 */
2060  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2061  }
2062  }else {
2063  CHECK_CALLED(ReportData);
2064  }
2065 
2066  if(prot_state == 3)
2067  prot_state = 4;
2068 
2069  return S_OK;
2070 }
2071 
2073 {
2074  CHECK_EXPECT(Terminate);
2075  ok(!dwOptions, "dwOptions=%d\n", dwOptions);
2076  return S_OK;
2077 }
2078 
2080  ULONG cb, ULONG *pcbRead)
2081 {
2082  if(read_report_data)
2083  CHECK_EXPECT2(Read2);
2084 
2085  if(mimefilter_test || short_read) {
2086  if(!read_report_data)
2088  }else if((pi & PI_MIMEVERIFICATION)) {
2089  if(!read_report_data)
2091 
2092  if(prot_read < 300) {
2093  ok(pv != expect_pv, "pv == expect_pv\n");
2094  if(prot_read < 300)
2095  ok(cb == 2048-prot_read, "cb=%d\n", cb);
2096  else
2097  ok(cb == 700, "cb=%d\n", cb);
2098  }else {
2099  ok(expect_pv <= pv && (BYTE*)pv < (BYTE*)expect_pv + cb, "pv != expect_pv\n");
2100  }
2101  }else {
2102  if(!read_report_data)
2103  CHECK_EXPECT(Read);
2104 
2105  ok(pv == expect_pv, "pv != expect_pv\n");
2106  ok(cb == 1000, "cb=%d\n", cb);
2107  ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
2108  }
2109  ok(pcbRead != NULL, "pcbRead == NULL\n");
2110 
2111  if(prot_state == 3 || (short_read && prot_state != 4)) {
2112  HRESULT hres;
2113 
2114  prot_state = 4;
2115  if(short_read) {
2116  SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */
2117  SET_EXPECT(GetBindInfo);
2118  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2119  }
2120  if(mimefilter_test)
2121  SET_EXPECT(MimeFilter_ReportData);
2122  else if(direct_read)
2123  SET_EXPECT(ReportData2);
2124  read_report_data++;
2125  hres = IInternetProtocolSink_ReportData(binding_sink,
2126  BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0);
2127  read_report_data--;
2128  ok(hres == S_OK, "ReportData failed: %08x\n", hres);
2129  if(short_read) {
2130  CLEAR_CALLED(GetBindInfo); /* IE9 */
2131  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2132  }
2133  if(mimefilter_test)
2134  CHECK_CALLED(MimeFilter_ReportData);
2135  else if(direct_read)
2136  CHECK_CALLED(ReportData2);
2137 
2138  if(mimefilter_test)
2139  SET_EXPECT(MimeFilter_ReportResult);
2140  else
2141  SET_EXPECT(ReportResult);
2142  hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
2143  ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
2144  if(mimefilter_test)
2145  CHECK_CALLED(MimeFilter_ReportResult);
2146  else
2147  CHECK_CALLED(ReportResult);
2148 
2149  if(cb > 100)
2150  cb = 100;
2151  memset(pv, 'x', cb);
2152  if(cb>6)
2153  memcpy(pv, "gif87a", 6);
2154  prot_read += *pcbRead = cb;
2155  return S_OK;
2156  }
2157 
2158  if(prot_state == 4) {
2159  *pcbRead = 0;
2160  return S_FALSE;
2161  }
2162 
2164  *pcbRead = 0;
2166  }
2167 
2168  if(cb > 100)
2169  cb = 100;
2170  memset(pv, 'x', cb);
2171  if(cb>6)
2172  memcpy(pv, "gif87a", 6);
2173  prot_read += *pcbRead = cb;
2174  return S_OK;
2175 }
2176 
2178 {
2180  ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
2181  return S_OK;
2182 }
2183 
2185 {
2187  return S_OK;
2188 }
2189 
2191  IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2192  DWORD grfPI, HANDLE *dwReserved)
2193 {
2194  CHECK_EXPECT(StartEx);
2195  ok(!dwReserved, "dwReserved = %p\n", dwReserved);
2196  protocol_start(pOIProtSink, pOIBindInfo, grfPI);
2197  return S_OK;
2198 }
2199 
2200 static const IInternetProtocolExVtbl ProtocolVtbl = {
2211  Protocol_Seek,
2215 };
2216 
2218 {
2219  return CONTAINING_RECORD(iface, Protocol, IUnknown_inner);
2220 }
2221 
2223 {
2224  Protocol *This = impl_from_IUnknown(iface);
2225 
2226  if(IsEqualGUID(&IID_IUnknown, riid)) {
2227  trace("QI(IUnknown)\n");
2228  *ppv = &This->IUnknown_inner;
2229  }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
2230  trace("QI(InternetProtocol)\n");
2231  *ppv = &This->IInternetProtocolEx_iface;
2232  }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
2233  trace("QI(InternetProtocolEx)\n");
2234  if(!impl_protex) {
2235  *ppv = NULL;
2236  return E_NOINTERFACE;
2237  }
2238  *ppv = &This->IInternetProtocolEx_iface;
2239  }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
2240  trace("QI(InternetPriority)\n");
2241  *ppv = &This->IInternetPriority_iface;
2242  }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
2243  trace("QI(IWinInetInfo)\n");
2244  CHECK_EXPECT(QueryInterface_IWinInetInfo);
2245  *ppv = NULL;
2246  return E_NOINTERFACE;
2247  }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
2248  trace("QI(IWinInetHttpInfo)\n");
2249  CHECK_EXPECT(QueryInterface_IWinInetHttpInfo);
2250  *ppv = NULL;
2251  return E_NOINTERFACE;
2252  }else {
2253  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
2254  *ppv = NULL;
2255  return E_NOINTERFACE;
2256  }
2257 
2258  IUnknown_AddRef((IUnknown*)*ppv);
2259  return S_OK;
2260 }
2261 
2263 {
2264  Protocol *This = impl_from_IUnknown(iface);
2265  return ++This->inner_ref;
2266 }
2267 
2269 {
2270  Protocol *This = impl_from_IUnknown(iface);
2271  LONG ref = --This->inner_ref;
2272  if(!ref) {
2273  /* IE9 is broken on redirects. It will cause -1 outer_ref on original protocol handler
2274  * and 1 on redirected handler. */
2275  ok(!This->outer_ref
2276  || broken(test_redirect && (This->outer_ref == -1 || This->outer_ref == 1)),
2277  "outer_ref = %d\n", This->outer_ref);
2278  if(This->outer_ref)
2279  trace("outer_ref %d\n", This->outer_ref);
2280  CHECK_EXPECT(Protocol_destructor);
2281  heap_free(This);
2282  }
2283  return ref;
2284 }
2285 
2286 static const IUnknownVtbl ProtocolUnkVtbl = {
2290 };
2291 
2293 {
2294  if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
2295  *ppv = iface;
2296  return S_OK;
2297  }
2298 
2299  if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
2300  *ppv = &mime_protocol_sink;
2301  return S_OK;
2302  }
2303 
2304  ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
2305  *ppv = NULL;
2306  return E_NOINTERFACE;
2307 }
2308 
2310  IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
2311  DWORD grfPI, HANDLE_PTR dwReserved)
2312 {
2314  LPOLESTR url_str = NULL;
2315  DWORD fetched = 0;
2316  BINDINFO bindinfo;
2317  DWORD cbindf = 0;
2318  HRESULT hres;
2319 
2320  CHECK_EXPECT(MimeFilter_Start);
2321 
2322  ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl));
2323  ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI);
2324  ok(dwReserved, "dwReserved == 0\n");
2325  ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
2326  ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
2327 
2328  if(binding_test) {
2329  ok(pOIProtSink != binding_sink, "pOIProtSink == protocol_sink\n");
2330  ok(pOIBindInfo == prot_bind_info, "pOIBindInfo != bind_info\n");
2331  }else {
2332  ok(pOIProtSink == &protocol_sink, "pOIProtSink != protocol_sink\n");
2333  ok(pOIBindInfo == &bind_info, "pOIBindInfo != bind_info\n");
2334  }
2335 
2336  data = (void*)dwReserved;
2337  ok(data->cbSize == sizeof(*data), "data->cbSize = %d\n", data->cbSize);
2338  ok(!data->pProtocolSink, "data->pProtocolSink != NULL\n");
2339  ok(data->pProtocol != NULL, "data->pProtocol == NULL\n");
2340  ok(!data->pUnk, "data->pUnk != NULL\n");
2341  ok(!data->dwFilterFlags, "data->dwProtocolFlags = %x\n", data->dwFilterFlags);
2342  if(binding_test) {
2343  IInternetProtocolSink *prot_sink;
2344 
2345  IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocolSink, (void**)&prot_sink);
2346  ok(prot_sink == pOIProtSink, "QI(data->pProtocol, IID_IInternetProtocolSink) != pOIProtSink\n");
2347  IInternetProtocolSink_Release(prot_sink);
2348 
2349  ok(data->pProtocol != binding_protocol, "data->pProtocol == binding_protocol\n");
2350 
2351  filtered_protocol = data->pProtocol;
2352  IInternetProtocol_AddRef(filtered_protocol);
2353  }else {
2354  IInternetProtocol *prot;
2355 
2356  IInternetProtocol_QueryInterface(data->pProtocol, &IID_IInternetProtocol, (void**)&prot);
2357  ok(prot == async_protocol, "QI(data->pProtocol, IID_IInternetProtocol) != async_protocol\n");
2358  IInternetProtocol_Release(prot);
2359 
2360  ok(data->pProtocol != async_protocol, "data->pProtocol == async_protocol\n");
2361  }
2362 
2363  filtered_sink = pOIProtSink;
2364 
2365  SET_EXPECT(ReportProgress_DECODING);
2366  hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW);
2367  ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres);
2368  CHECK_CALLED(ReportProgress_DECODING);
2369 
2370  SET_EXPECT(GetBindInfo);
2371  memset(&bindinfo, 0, sizeof(bindinfo));
2372  bindinfo.cbSize = sizeof(bindinfo);
2373  hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &cbindf, &bindinfo);
2374  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2375  ok(cbindf == (bindf|BINDF_FROMURLMON), "cbindf = %x, expected %x\n", cbindf, bindf);
2376  CHECK_CALLED(GetBindInfo);
2377 
2378  SET_EXPECT(GetBindString_URL);
2379  hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_URL, &url_str, 1, &fetched);
2380  ok(hres == S_OK, "GetBindString(BINDSTRING_URL) failed: %08x\n", hres);
2381  ok(fetched == 1, "fetched = %d\n", fetched);
2382  ok(!lstrcmpW(url_str, binding_urls[tested_protocol]), "wrong url_str %s\n", wine_dbgstr_w(url_str));
2383  CoTaskMemFree(url_str);
2384  CHECK_CALLED(GetBindString_URL);
2385 
2386  return S_OK;
2387 }
2388 
2390  PROTOCOLDATA *pProtocolData)
2391 {
2392  CHECK_EXPECT(MimeFilter_Continue);
2393  return E_NOTIMPL;
2394 }
2395 
2397 {
2398  HRESULT hres;
2399 
2400  CHECK_EXPECT(MimeFilter_Terminate);
2401 
2402  ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2403 
2404  SET_EXPECT(Terminate);
2405  hres = IInternetProtocol_Terminate(filtered_protocol, dwOptions);
2406  ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2407  CHECK_CALLED(Terminate);
2408 
2409  return S_OK;
2410 }
2411 
2413  ULONG cb, ULONG *pcbRead)
2414 {
2415  BYTE buf[2096];
2416  DWORD read = 0;
2417  HRESULT hres;
2418 
2419  CHECK_EXPECT(MimeFilter_Read);
2420 
2421  ok(pv != NULL, "pv == NULL\n");
2422  ok(cb != 0, "cb == 0\n");
2423  ok(pcbRead != NULL, "pcbRead == NULL\n");
2424 
2425  if(read_report_data)
2426  SET_EXPECT(Read2);
2427  else
2428  SET_EXPECT(Read);
2429  hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read);
2430  ok(hres == S_OK || hres == S_FALSE || hres == E_PENDING, "Read failed: %08x\n", hres);
2431  if(read_report_data)
2432  CHECK_CALLED(Read2);
2433  else
2434  CHECK_CALLED(Read);
2435 
2436  if(pcbRead) {
2437  ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
2438  *pcbRead = read;
2439  }
2440 
2441  memset(pv, 'x', read);
2442  return hres;
2443 }
2444 
2446 {
2447  HRESULT hres;
2448 
2449  CHECK_EXPECT(MimeFilter_LockRequest);
2450 
2451  ok(!dwOptions, "dwOptions = %x\n", dwOptions);
2452 
2454  hres = IInternetProtocol_LockRequest(filtered_protocol, dwOptions);
2455  ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2457 
2458  return S_OK;
2459 }
2460 
2462 {
2463  HRESULT hres;
2464 
2465  CHECK_EXPECT(MimeFilter_UnlockRequest);
2466 
2468  hres = IInternetProtocol_UnlockRequest(filtered_protocol);
2469  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2471 
2472  return S_OK;
2473 }
2474 
2475 static const IInternetProtocolExVtbl MimeProtocolVtbl = {
2486  Protocol_Seek,
2489 };
2490 
2492 
2494 {
2495  ok(0, "unexpected call\n");
2496  return E_NOINTERFACE;
2497 }
2498 
2500 {
2501  return 2;
2502 }
2503 
2505 {
2506  return 1;
2507 }
2508 
2510  PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
2511  DWORD *pcchResult, DWORD dwReserved)
2512 {
2513  ok(0, "unexpected call %d\n", ParseAction);
2514  return E_NOTIMPL;
2515 }
2516 
2518  LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
2519  LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
2520 {
2521  ok(0, "unexpected call\n");
2522  return E_NOTIMPL;
2523 }
2524 
2526  LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
2527 {
2528  ok(0, "unexpected call\n");
2529  return E_NOTIMPL;
2530 }
2531 
2533  LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
2534  DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
2535 {
2536  ok(0, "unexpected call\n");
2537  return E_NOTIMPL;
2538 }
2539 
2540 static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
2548 };
2549 
2551 
2553 {
2554  if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
2555  *ppv = &protocol_info;
2556  return S_OK;
2557  }
2558 
2559  ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
2560  return E_NOINTERFACE;
2561 }
2562 
2564 {
2565  return 2;
2566 }
2567 
2569 {
2570  return 1;
2571 }
2572 
2574  REFIID riid, void **ppv)
2575 {
2576  Protocol *ret;
2577 
2578  CHECK_EXPECT(CreateInstance);
2579 
2580  ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n");
2581  ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2582  ok(ppv != NULL, "ppv == NULL\n");
2583 
2584  ret = heap_alloc(sizeof(*ret));
2585  ret->IUnknown_inner.lpVtbl = &ProtocolUnkVtbl;
2586  ret->IInternetProtocolEx_iface.lpVtbl = &ProtocolVtbl;
2587  ret->IInternetPriority_iface.lpVtbl = &InternetPriorityVtbl;
2588  ret->outer = pOuter;
2589  ret->inner_ref = 1;
2590  ret->outer_ref = 0;
2591 
2592  protocol_emul = ret;
2593  *ppv = &ret->IUnknown_inner;
2594  return S_OK;
2595 }
2596 
2598 {
2599  ok(0, "unexpected call\n");
2600  return S_OK;
2601 }
2602 
2603 static const IClassFactoryVtbl ClassFactoryVtbl = {
2609 };
2610 
2612 
2614 {
2616 
2617  ok(!outer, "outer = %p\n", outer);
2618  ok(IsEqualGUID(&IID_IInternetProtocol, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
2619 
2620  *ppv = &MimeProtocol;
2621  return S_OK;
2622 }
2623 
2624 static const IClassFactoryVtbl MimeFilterCFVtbl = {
2630 };
2631 
2633 
2634 #define TEST_BINDING 0x0001
2635 #define TEST_FILTER 0x0002
2636 #define TEST_FIRST_HTTP 0x0004
2637 #define TEST_DIRECT_READ 0x0008
2638 #define TEST_POST 0x0010
2639 #define TEST_EMULATEPROT 0x0020
2640 #define TEST_SHORT_READ 0x0040
2641 #define TEST_REDIRECT 0x0080
2642 #define TEST_ABORT 0x0100
2643 #define TEST_ASYNCREQ 0x0200
2644 #define TEST_USEIURI 0x0400
2645 #define TEST_IMPLPROTEX 0x0800
2646 #define TEST_EMPTY 0x1000
2647 #define TEST_NOMIME 0x2000
2648 #define TEST_FROMCACHE 0x4000
2649 #define TEST_DISABLEAUTOREDIRECT 0x8000
2650 
2651 static void register_filter(BOOL do_register)
2652 {
2653  IInternetSession *session;
2654  HRESULT hres;
2655 
2656  hres = pCoInternetGetSession(0, &session, 0);
2657  ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
2658 
2659  if(do_register) {
2660  hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW);
2661  ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2662  hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW);
2663  ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2664  }else {
2665  hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW);
2666  ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2667  hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW);
2668  ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
2669  }
2670 
2671  IInternetSession_Release(session);
2672 }
2673 
2674 static void init_test(int prot, DWORD flags)
2675 {
2676  tested_protocol = prot;
2677  binding_test = (flags & TEST_BINDING) != 0;
2679  prot_read = 0;
2680  prot_state = 0;
2682  mimefilter_test = (flags & TEST_FILTER) != 0;
2683  no_mime = (flags & TEST_NOMIME) != 0;
2684  filter_state = 0;
2685  post_stream_read = 0;
2691  filtered_sink = NULL;
2692  http_is_first = (flags & TEST_FIRST_HTTP) != 0;
2695  test_async_req = (flags & TEST_ASYNCREQ) != 0;
2696  direct_read = (flags & TEST_DIRECT_READ) != 0;
2697  emulate_prot = (flags & TEST_EMULATEPROT) != 0;
2699  short_read = (flags & TEST_SHORT_READ) != 0;
2700  http_post_test = TYMED_NULL;
2702  test_abort = (flags & TEST_ABORT) != 0;
2703  impl_protex = (flags & TEST_IMPLPROTEX) != 0;
2704  empty_file = (flags & TEST_EMPTY) != 0;
2709 
2710  bindinfo_options = 0;
2712  bindinfo_options |= BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS;
2713 
2715 }
2716 
2718 {
2720  LONG pr;
2721  HRESULT hres;
2722 
2723  hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority,
2724  (void**)&priority);
2725  ok(hres == S_OK, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres);
2726  if(FAILED(hres))
2727  return;
2728 
2729  hres = IInternetPriority_GetPriority(priority, &pr);
2730  ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2731  ok(pr == 0, "pr=%d, expected 0\n", pr);
2732 
2733  hres = IInternetPriority_SetPriority(priority, 1);
2734  ok(hres == S_OK, "SetPriority failed: %08x\n", hres);
2735 
2736  hres = IInternetPriority_GetPriority(priority, &pr);
2737  ok(hres == S_OK, "GetPriority failed: %08x\n", hres);
2738  ok(pr == 1, "pr=%d, expected 1\n", pr);
2739 
2740  IInternetPriority_Release(priority);
2741 }
2742 
2743 static void test_early_abort(const CLSID *clsid)
2744 {
2746  HRESULT hres;
2747 
2748  hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2749  &IID_IInternetProtocol, (void**)&protocol);
2750  ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2751 
2752  hres = IInternetProtocol_Abort(protocol, E_ABORT, 0);
2753  ok(hres == S_OK, "Abort failed: %08x\n", hres);
2754 
2755  hres = IInternetProtocol_Abort(protocol, E_FAIL, 0);
2756  ok(hres == S_OK, "Abort failed: %08x\n", hres);
2757 
2758  IInternetProtocol_Release(protocol);
2759 }
2760 
2762  IInternetProtocolEx *protocolex, IUri *uri, BOOL is_first)
2763 {
2764  HRESULT hres;
2765 
2766  SET_EXPECT(GetBindInfo);
2767  if(!(bindf & BINDF_FROMURLMON))
2768  SET_EXPECT(ReportProgress_DIRECTBIND);
2769  if(is_first) {
2770  SET_EXPECT(ReportProgress_SENDINGREQUEST);
2771  SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
2772  if(bindf & BINDF_FROMURLMON)
2773  SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2774  else
2775  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
2776  }
2777  SET_EXPECT(ReportData);
2778  if(is_first)
2779  SET_EXPECT(ReportResult);
2780 
2782 
2783  if(protocolex) {
2784  hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
2785  ok(hres == S_OK, "StartEx failed: %08x\n", hres);
2786  }else {
2787  hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
2788  if(hres == INET_E_RESOURCE_NOT_FOUND) {
2789  win_skip("Start failed\n");
2790  return FALSE;
2791  }
2792  ok(hres == S_OK, "Start failed: %08x\n", hres);
2793  }
2794 
2795  CHECK_CALLED(GetBindInfo);
2796  if(!(bindf & BINDF_FROMURLMON))
2797  CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */
2798  if(is_first) {
2799  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2800  CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
2801  if(bindf & BINDF_FROMURLMON)
2802  CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE);
2803  else
2804  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
2805  }
2806  CHECK_CALLED(ReportData);
2807  if(is_first)
2808  CHECK_CALLED(ReportResult);
2809 
2810  return TRUE;
2811 }
2812 
2814 {
2816  IUnknown *unk;
2819  BYTE buf[512];
2820  ULONG cb;
2821  HRESULT hres;
2822 
2823  hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
2824  &IID_IUnknown, (void**)&unk);
2825  ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
2826  if(FAILED(hres))
2827  return;
2828 
2829  hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
2830  ok(hres == E_NOINTERFACE,
2831  "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
2832 
2833  hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
2834  ok(hres == S_OK, "Could not get IClassFactory interface\n");
2835  IUnknown_Release(unk);
2836  if(FAILED(hres))
2837  return;
2838 
2839  hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2840  ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2841 
2842  if(SUCCEEDED(hres)) {
2844  hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2845  ok(hres == S_OK, "Read failed: %08x\n", hres);
2846  ok(cb == 2, "cb=%u expected 2\n", cb);
2847  buf[2] = 0;
2848  ok(!memcmp(buf, file_with_hash ? "XX" : "<H", 2), "Unexpected data %s\n", buf);
2849  hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2850  ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2851  hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
2852  ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
2853  ok(cb == 0, "cb=%u expected 0\n", cb);
2854  hres = IInternetProtocol_UnlockRequest(protocol);
2855  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2856  }
2857 
2859  hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2860  ok(hres == S_FALSE, "Read failed: %08x\n", hres);
2861  hres = IInternetProtocol_LockRequest(protocol, 0);
2862  ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2863  hres = IInternetProtocol_UnlockRequest(protocol);
2864  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2865  }
2866 
2867  IInternetProtocol_Release(protocol);
2868  }
2869 
2870  hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2871  ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2872  if(SUCCEEDED(hres)) {
2874  hres = IInternetProtocol_LockRequest(protocol, 0);
2875  ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2876  hres = IInternetProtocol_Terminate(protocol, 0);
2877  ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2878  hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2879  ok(hres == S_OK, "Read failed: %08x\n\n", hres);
2880  hres = IInternetProtocol_UnlockRequest(protocol);
2881  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2882  hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2883  todo_wine_if(file_with_hash) /* FIXME: An effect of UnlockRequest call? */
2884  ok(hres == S_OK, "Read failed: %08x\n", hres);
2885  hres = IInternetProtocol_Terminate(protocol, 0);
2886  ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2887  }
2888 
2889  IInternetProtocol_Release(protocol);
2890  }
2891 
2892  hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
2893  ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
2894  if(SUCCEEDED(hres)) {
2896  hres = IInternetProtocol_Terminate(protocol, 0);
2897  ok(hres == S_OK, "Terminate failed: %08x\n", hres);
2898  hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
2899  ok(hres == S_OK, "Read failed: %08x\n", hres);
2900  ok(cb == 2, "cb=%u expected 2\n", cb);
2901  }
2902 
2903  IInternetProtocol_Release(protocol);
2904  }
2905 
2906  if(pCreateUri) {
2907  IInternetProtocolEx *protocolex;
2908  IUri *uri;
2909 
2910  hres = pCreateUri(url, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
2911  ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2912 
2913  hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2914  ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2915 
2916  if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2917  hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2918  ok(hres == S_OK, "Read failed: %08x\n", hres);
2919  hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2920  ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2921  hres = IInternetProtocolEx_UnlockRequest(protocolex);
2922  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2923  }
2924 
2925  IUri_Release(uri);
2926  IInternetProtocolEx_Release(protocolex);
2927 
2928  hres = pCreateUri(url, 0, 0, &uri);
2929  ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
2930 
2931  hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex);
2932  ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres);
2933 
2934  if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) {
2935  hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb);
2936  ok(hres == S_OK, "Read failed: %08x\n", hres);
2937  hres = IInternetProtocolEx_LockRequest(protocolex, 0);
2938  ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
2939  hres = IInternetProtocolEx_UnlockRequest(protocolex);
2940  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
2941  }
2942 
2943  IUri_Release(uri);
2944  IInternetProtocolEx_Release(protocolex);
2945  }else {
2946  win_skip("Skipping file protocol StartEx tests\n");
2947  }
2948 
2949  IClassFactory_Release(factory);
2950 }
2951 
2952 static void test_file_protocol_fail(void)
2953 {
2955  HRESULT hres;
2956 
2957  static const WCHAR index_url2[] =
2958  {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
2959 
2960  hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2961  &IID_IInternetProtocol, (void**)&protocol);
2962  ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2963  if(FAILED(hres))
2964  return;
2965 
2966  SET_EXPECT(GetBindInfo);
2968  hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
2969  ok(hres == MK_E_SYNTAX ||
2970  hres == E_INVALIDARG,
2971  "Start failed: %08x, expected MK_E_SYNTAX or E_INVALIDARG\n", hres);
2972  CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
2973 
2974  SET_EXPECT(GetBindInfo);
2975  if(!(bindf & BINDF_FROMURLMON))
2976  SET_EXPECT(ReportProgress_DIRECTBIND);
2977  SET_EXPECT(ReportProgress_SENDINGREQUEST);
2978  SET_EXPECT(ReportResult);
2979  expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
2980  hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
2981  ok(hres == INET_E_RESOURCE_NOT_FOUND,
2982  "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres);
2983  CHECK_CALLED(GetBindInfo);
2984  if(!(bindf & BINDF_FROMURLMON))
2985  CHECK_CALLED(ReportProgress_DIRECTBIND);
2986  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
2987  CHECK_CALLED(ReportResult);
2988 
2989  IInternetProtocol_Release(protocol);
2990 
2991  hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2992  &IID_IInternetProtocol, (void**)&protocol);
2993  ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2994  if(FAILED(hres))
2995  return;
2996 
2997  SET_EXPECT(GetBindInfo);
2998  if(!(bindf & BINDF_FROMURLMON))
2999  SET_EXPECT(ReportProgress_DIRECTBIND);
3000  SET_EXPECT(ReportProgress_SENDINGREQUEST);
3001  SET_EXPECT(ReportResult);
3002  expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
3003 
3004  hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
3005  ok(hres == INET_E_RESOURCE_NOT_FOUND,
3006  "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
3007  CHECK_CALLED(GetBindInfo);
3008  if(!(bindf & BINDF_FROMURLMON))
3009  CHECK_CALLED(ReportProgress_DIRECTBIND);
3010  CHECK_CALLED(ReportProgress_SENDINGREQUEST);
3011  CHECK_CALLED(ReportResult);
3012 
3013  SET_EXPECT(GetBindInfo);
3014  hres = IInternetProtocol_Start(protocol, NULL, &protocol_sink, &bind_info, 0, 0);
3015  ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3016  CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
3017 
3018  SET_EXPECT(GetBindInfo);
3019  hres = IInternetProtocol_Start(protocol, emptyW, &protocol_sink, &bind_info, 0, 0);
3020  ok(hres == E_INVALIDARG, "Start failed: %08x, expected E_INVALIDARG\n", hres);
3021  CLEAR_CALLED(GetBindInfo); /* GetBindInfo not called in IE7 */
3022 
3023  IInternetProtocol_Release(protocol);
3024 }
3025 
3026 static void test_file_protocol(void) {
3027  WCHAR buf[INTERNET_MAX_URL_LENGTH], file_name_buf[MAX_PATH];
3028  DWORD size;
3029  ULONG len;
3030  HANDLE file;
3031 
3032  static const WCHAR wszFile[] = {'f','i','l','e',':',0};
3033  static const WCHAR wszFile2[] = {'f','i','l','e',':','/','/',0};
3034  static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
3035  static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
3036  static const char html_doc[] = "<HTML></HTML>";
3037  static const WCHAR fragmentW[] = {'#','f','r','a','g',0};
3038 
3039  trace("Testing file protocol...\n");
3040  init_test(FILE_TEST, 0);
3041 
3042  SetLastError(0xdeadbeef);
3045  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3046  if(file == INVALID_HANDLE_VALUE)
3047  return;
3048  WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
3049  CloseHandle(file);
3050 
3052  bindf = 0;
3054  bindf = BINDF_FROMURLMON;
3056  bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
3058 
3059  memcpy(buf, wszFile, sizeof(wszFile));
3060  len = ARRAY_SIZE(wszFile)-1;
3062  buf[len++] = '\\';
3063  memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
3064 
3066  bindf = 0;
3068  bindf = BINDF_FROMURLMON;
3070 
3071  memcpy(buf, wszFile2, sizeof(wszFile2));
3072  len = GetCurrentDirectoryW(ARRAY_SIZE(file_name_buf), file_name_buf);
3073  file_name_buf[len++] = '\\';
3074  memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
3075  lstrcpyW(buf+ARRAY_SIZE(wszFile2)-1, file_name_buf);
3076  file_name = file_name_buf;
3077  bindf = 0;
3079  bindf = BINDF_FROMURLMON;
3081 
3082  buf[ARRAY_SIZE(wszFile2)] = '|';
3084 
3085  memcpy(buf, wszFile3, sizeof(wszFile3));
3086  len = ARRAY_SIZE(wszFile3)-1;
3088  buf[len++] = '\\';
3089  memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
3090 
3091  file_name = buf + ARRAY_SIZE(wszFile3)-1;
3092  bindf = 0;
3094  bindf = BINDF_FROMURLMON;
3096 
3097  memcpy(buf, wszFile4, sizeof(wszFile4));
3098  len = GetCurrentDirectoryW(ARRAY_SIZE(file_name_buf), file_name_buf);
3099  file_name_buf[len++] = '\\';
3100  memcpy(file_name_buf+len, wszIndexHtml, sizeof(wszIndexHtml));
3101  lstrcpyW(buf+ARRAY_SIZE(wszFile4)-1, file_name_buf);
3102  file_name = file_name_buf;
3103  bindf = 0;
3105  bindf = BINDF_FROMURLMON;
3107 
3108  buf[ARRAY_SIZE(wszFile4)] = '|';
3110 
3111  /* Fragment part of URL is skipped if the file doesn't exist. */
3112  lstrcatW(buf, fragmentW);
3114 
3115  /* Fragment part is considered a part of the file name, if the file exsists. */
3116  len = lstrlenW(file_name_buf);
3117  lstrcpyW(file_name_buf+len, fragmentW);
3120  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3121  WriteFile(file, "XXX", 3, &size, NULL);
3122  CloseHandle(file);
3123  file_name_buf[len] = 0;
3124 
3125  file_with_hash = TRUE;
3127 
3129  DeleteFileW(file_name_buf);
3130 
3131  bindf = 0;
3133  bindf = BINDF_FROMURLMON;
3135 }
3136 
3137 static void create_cache_entry(const WCHAR *urlw)
3138 {
3139  FILETIME now, tomorrow, yesterday;
3140  char file_path[MAX_PATH];
3141  BYTE content[1000];
3142  ULARGE_INTEGER li;
3143  const char *url;
3144  HANDLE file;
3145  DWORD size;
3146  unsigned i;
3147  BOOL res;
3148 
3149  BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
3150 
3151  trace("Testing cache read...\n");
3152 
3153  url = w2a(urlw);
3154 
3155  for(i = 0; i < sizeof(content); i++)
3156  content[i] = '0' + (i%10);
3157 
3159  li.u.HighPart = now.dwHighDateTime;
3160  li.u.LowPart = now.dwLowDateTime;
3161  li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
3162  tomorrow.dwHighDateTime = li.u.HighPart;
3163  tomorrow.dwLowDateTime = li.u.LowPart;
3164  li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
3165  yesterday.dwHighDateTime = li.u.HighPart;
3166  yesterday.dwLowDateTime = li.u.LowPart;
3167 
3168  res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0);
3169  ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
3170 
3172  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3173 
3174  WriteFile(file, content, sizeof(content), &size, NULL);
3175  CloseHandle(file);
3176 
3177  res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
3178  cache_headers, sizeof(cache_headers)-1, "", 0);
3179  ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
3180 }
3181 
3183 {
3184  static BOOL got_user_agent = FALSE;
3185  IUri *uri = NULL;
3186  HRESULT hres;
3187 
3188  if(use_iuri && pCreateUri) {
3189  hres = pCreateUri(url, 0, 0, &uri);
3190  ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
3191  }
3192 
3193  SET_EXPECT(GetBindInfo);
3194  if (!(bindf & BINDF_FROMURLMON))
3195  SET_EXPECT(ReportProgress_DIRECTBIND);
3196  if(!got_user_agent)
3197  SET_EXPECT(GetBindString_USER_AGENT);
3198  SET_EXPECT(GetBindString_ROOTDOC_URL);
3199  SET_EXPECT(GetBindString_ACCEPT_MIMES);
3200  SET_EXPECT(QueryService_HttpNegotiate);
3201  SET_EXPECT(BeginningTransaction);
3202  SET_EXPECT(GetRootSecurityId);
3203  if(http_post_test) {
3204  SET_EXPECT(GetBindString_POST_COOKIE);
3205  if(http_post_test == TYMED_ISTREAM)
3207  }
3208  if(bind_from_cache) {
3209  SET_EXPECT(OnResponse);
3210  SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
3211  SET_EXPECT(ReportData);
3212  }
3213 
3214  if(uri) {
3215  IInternetProtocolEx *protocolex;
3216 
3217  hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
3218  ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
3219 
3220  hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
3221  ok(hres == S_OK, "Start failed: %08x\n", hres);
3222 
3223  IInternetProtocolEx_Release(protocolex);
3224  IUri_Release(uri);
3225  }else {
3226  hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
3227  ok(hres == S_OK, "Start failed: %08x\n", hres);
3228  }
3229  if(FAILED(hres))
3230  return FALSE;
3231 
3232  CHECK_CALLED(GetBindInfo);
3233  if (!(bindf & BINDF_FROMURLMON))
3234  CHECK_CALLED(ReportProgress_DIRECTBIND);
3235  if (!got_user_agent)
3236  {
3237  CHECK_CALLED(GetBindString_USER_AGENT);
3238  got_user_agent = TRUE;
3239  }
3240  CLEAR_CALLED(GetBindString_ROOTDOC_URL); /* New in IE11 */
3241  CHECK_CALLED(GetBindString_ACCEPT_MIMES);
3242  CHECK_CALLED(QueryService_HttpNegotiate);
3243  CHECK_CALLED(BeginningTransaction);
3244  /* GetRootSecurityId called on WinXP but not on Win98 */
3245  CLEAR_CALLED(GetRootSecurityId);
3246  if(http_post_test) {
3247  CHECK_CALLED(GetBindString_POST_COOKIE);
3248  if(http_post_test == TYMED_ISTREAM)
3250  }
3251  if(bind_from_cache) {
3252  CHECK_CALLED(OnResponse);
3253  CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
3254  CHECK_CALLED(ReportData);
3255  }
3256 
3257  return TRUE;
3258 }
3259 
3261 {
3262  BYTE buf[3600];
3263  DWORD cb;
3264  HRESULT hres;
3265 
3266  hres = IInternetProtocol_LockRequest(protocol, 0);
3267  ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
3268 
3269  hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
3270  ok(hres == (test_abort ? S_OK : S_FALSE), "Read failed: %08x\n", hres);
3271 
3272  hres = IInternetProtocol_Terminate(protocol, 0);
3273  ok(hres == S_OK, "Terminate failed: %08x\n", hres);
3274 
3275  /* This wait is to give the internet handles being freed in Terminate
3276  * enough time to actually terminate in all cases. Internet handles
3277  * terminate asynchronously and native reuses the main InternetOpen
3278  * handle. The only case in which this seems to be necessary is on
3279  * wine with native wininet and urlmon, resulting in the next time
3280  * test_http_protocol_url being called the first data notification actually
3281  * being an extra last data notification from the previous connection
3282  * about once out of every ten times. */
3283  Sleep(100);
3284 
3285  hres = IInternetProtocol_UnlockRequest(protocol);
3286  ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
3287 }
3288 
3289 /* is_first refers to whether this is the first call to this function
3290  * _for this url_ */
3292 {
3295  IUnknown *unk;
3296  HRESULT hres;
3297 
3298  init_test(prot, flags);
3299  http_url = url;
3301  if(flags & TEST_FROMCACHE)
3303 
3304  hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol,
3305  CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3306  ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3307  if(FAILED(hres))
3308  return;
3309 
3310  hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3311  ok(hres == E_NOINTERFACE,
3312  "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
3313  hres);
3314 
3315  hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3316  ok(hres == S_OK, "Could not get IClassFactory interface\n");
3317  IUnknown_Release(unk);
3318  if(FAILED(hres))
3319  return;
3320 
3321  hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
3322  (void**)&async_protocol);
3323  ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
3324  if(SUCCEEDED(hres)) {
3325  BYTE buf[3600];
3326  DWORD cb;
3327  ULONG ref;
3328 
3330 
3331  SET_EXPECT(ReportProgress_COOKIE_SENT);
3332  if(http_is_first) {
3333  SET_EXPECT(ReportProgress_FINDINGRESOURCE);
3334  SET_EXPECT(ReportProgress_CONNECTING);
3335  }
3336  SET_EXPECT(ReportProgress_SENDINGREQUEST);
3337  if(test_redirect && !(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS))
3338  SET_EXPECT(ReportProgress_REDIRECTING);
3339  SET_EXPECT(ReportProgress_PROXYDETECTING);
3340  if(prot == HTTP_TEST)
3341  SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
3342  else
3343  SET_EXPECT(QueryService_HttpSecurity);
3344  if(!(bindf & BINDF_FROMURLMON)) {
3345  SET_EXPECT(OnResponse);
3346  SET_EXPECT(ReportProgress_RAWMIMETYPE);
3347  SET_EXPECT(ReportData);
3348  } else {
3349  SET_EXPECT(Switch);
3350  }
3351 
3352  if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) {
3353  IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3354  IInternetProtocol_Release(async_protocol);
3355  return;
3356  }
3357 
3359  SET_EXPECT(ReportResult);
3360 
3362  expect_hrResult = INET_E_REDIRECT_FAILED;
3363  else if(test_abort)
3365  else
3367 
3368  if(direct_read) {
3369  SET_EXPECT(Switch);
3370  while(wait_for_switch) {
3371  ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3372  CHECK_CALLED(Switch); /* Set in ReportData */
3375  }
3376  }else if(bind_from_cache) {
3377  BYTE buf[1500];
3378 
3379  hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb);
3380  ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb);
3381 
3382  SET_EXPECT(ReportResult);
3383  hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3384  ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb);
3385  CHECK_CALLED(ReportResult);
3386 
3387  hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3388  ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb);
3389  }else {
3390  hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3391  ok((hres == E_PENDING && cb==0) ||
3392  (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3393 
3394  ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3395  if(bindf & BINDF_FROMURLMON)
3396  CHECK_CALLED(Switch);
3397  else
3398  CHECK_CALLED(ReportData);
3399  if(prot == HTTPS_TEST)
3400  CLEAR_CALLED(QueryService_HttpSecurity);
3401 
3402  while(1) {
3403  if(bindf & BINDF_FROMURLMON)
3404  SET_EXPECT(Switch);
3405  else
3406  SET_EXPECT(ReportData);
3407  hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
3408  if(hres == E_PENDING) {
3409  hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
3410  ok((hres == E_PENDING && cb==0) ||
3411  (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
3412  ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
3413  if(bindf & BINDF_FROMURLMON)
3414  CHECK_CALLED(Switch);
3415  else
3416  CHECK_CALLED(ReportData);
3417 
3418  if(test_abort) {
3419  HRESULT hres;
3420 
3421  SET_EXPECT(ReportResult);
3422  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3423  ok(hres == S_OK, "Abort failed: %08x\n", hres);
3424  CHECK_CALLED(ReportResult);
3425 
3426  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3427  ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3428  break;
3429  }
3430  }else {
3431  if(bindf & BINDF_FROMURLMON)
3432  CHECK_NOT_CALLED(Switch);
3433  else
3434  CHECK_NOT_CALLED(ReportData);
3435  if(cb == 0) break;
3436  }
3437  }
3438  if(!test_abort) {
3439  ok(hres == S_FALSE, "Read failed: %08x\n", hres);
3440  CHECK_CALLED(ReportResult);
3441  }
3442  }
3443  if(prot == HTTPS_TEST)
3444  CLEAR_CALLED(ReportProgress_SENDINGREQUEST);
3445 
3446  if (prot == HTTP_TEST || prot == HTTPS_TEST)
3447  CLEAR_CALLED(ReportProgress_COOKIE_SENT);
3448 
3449  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3450  ok(hres == INET_E_RESULT_DISPATCHED || hres == S_OK /* IE10 */, "Abort failed: %08x\n", hres);
3451 
3453 
3454  hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0);
3455  ok(hres == S_OK, "Abort failed: %08x\n", hres);
3456 
3457  ref = IInternetProtocol_Release(async_protocol);
3458  ok(!ref, "ref=%x\n", ref);
3459  }
3460 
3461  IClassFactory_Release(factory);
3462 
3463  if(flags & TEST_FROMCACHE) {
3464  BOOL res;
3465 
3467  ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
3468  }
3469 }
3470 
3471 static void test_http_protocol(void)
3472 {
3473  static const WCHAR posttest_url[] =
3474  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3475  't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3476  static const WCHAR redirect_url[] =
3477  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3478  't','e','s','t','s','/','r','e','d','i','r','e','c','t',0};
3479  static const WCHAR winetest_url[] =
3480  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3481  't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
3482  static const WCHAR empty_url[] =
3483  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3484  't','e','s','t','s','/','e','m','p','t','y','.','j','s',0};
3485  static const WCHAR cache_only_url[] =
3486  {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3487  't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0};
3488 
3489 
3490  trace("Testing http protocol (not from urlmon)...\n");
3491  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3492  test_http_protocol_url(winetest_url, HTTP_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3493 
3494  trace("Testing http protocol (from urlmon)...\n");
3495  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3496  test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3497 
3498  trace("Testing http protocol (to file)...\n");
3499  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE;
3500  test_http_protocol_url(winetest_url, HTTP_TEST, 0, TYMED_NULL);
3501 
3502  trace("Testing http protocol (post data)...\n");
3503  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3504  test_http_protocol_url(posttest_url, HTTP_TEST, TEST_FIRST_HTTP|TEST_POST, TYMED_HGLOBAL);
3505 
3506  trace("Testing http protocol (post data stream)...\n");
3508 
3509  trace("Testing http protocol (direct read)...\n");
3510  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3511  test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
3512 
3513  trace("Testing http protocol (redirected)...\n");
3514  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3515  test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL);
3516 
3517  trace("Testing http protocol (redirected, disable auto redirect)...\n");
3518  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3520 
3521  trace("Testing http protocol empty file...\n");
3522  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3523  test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL);
3524 
3525  /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have
3526  * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting
3527  * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those
3528  * tests work on Windows and have them around for the future.
3529  */
3530  if(broken(1)) {
3531  trace("Testing http protocol (from cache)...\n");
3532  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
3533  test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL);
3534  }
3535 
3536  trace("Testing http protocol abort...\n");
3537  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3538  test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL);
3539 
3540  test_early_abort(&CLSID_HttpProtocol);
3541  test_early_abort(&CLSID_HttpSProtocol);
3542 }
3543 
3544 static void test_https_protocol(void)
3545 {
3546  static const WCHAR https_winehq_url[] =
3547  {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
3548  't','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
3549 
3550  trace("Testing https protocol (from urlmon)...\n");
3551  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3552  test_http_protocol_url(https_winehq_url, HTTPS_TEST, TEST_FIRST_HTTP, TYMED_NULL);
3553 }
3554 
3555 
3556 static void test_ftp_protocol(void)
3557 {
3560  IUnknown *unk;
3561  BYTE buf[4096];
3562  ULONG ref;
3563  DWORD cb;
3564  HRESULT hres;
3565 
3566  static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
3567  '/','p','u','b','/','o','t','h','e','r','/',
3568  'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
3569 
3570  trace("Testing ftp protocol...\n");
3571 
3572  init_test(FTP_TEST, 0);
3573 
3574  bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
3577 
3578  hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
3579  ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
3580  if(FAILED(hres))
3581  return;
3582 
3583  hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
3584  ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
3585 
3586  hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
3587  ok(hres ==