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