2 * Copyright 2005-2007 Jacek Caban for CodeWeavers
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.
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.
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
22 #include <wine/test.h>
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT(func) \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 expect_ ## func = FALSE; \
42 called_ ## func = TRUE; \
45 #define CHECK_EXPECT2(func) \
47 ok(expect_ ##func, "unexpected call " #func "\n"); \
48 called_ ## func = TRUE; \
51 #define CHECK_CALLED(func) \
53 ok(called_ ## func, "expected " #func "\n"); \
54 expect_ ## func = called_ ## func = FALSE; \
57 #define CHECK_NOT_CALLED(func) \
59 ok(!called_ ## func, "unexpected " #func "\n"); \
60 expect_ ## func = called_ ## func = FALSE; \
63 #define CLEAR_CALLED(func) \
64 expect_ ## func = called_ ## func = FALSE
66 DEFINE_EXPECT(GetBindInfo
);
67 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
68 DEFINE_EXPECT(ReportProgress_DIRECTBIND
);
69 DEFINE_EXPECT(ReportProgress_RAWMIMETYPE
);
70 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE
);
71 DEFINE_EXPECT(ReportProgress_CONNECTING
);
72 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST
);
73 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
74 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
75 DEFINE_EXPECT(ReportProgress_PROTOCOLCLASSID
);
76 DEFINE_EXPECT(ReportData
);
77 DEFINE_EXPECT(ReportResult
);
78 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES
);
79 DEFINE_EXPECT(GetBindString_USER_AGENT
);
80 DEFINE_EXPECT(GetBindString_POST_COOKIE
);
81 DEFINE_EXPECT(QueryService_HttpNegotiate
);
82 DEFINE_EXPECT(QueryService_InternetProtocol
);
83 DEFINE_EXPECT(BeginningTransaction
);
84 DEFINE_EXPECT(GetRootSecurityId
);
85 DEFINE_EXPECT(OnResponse
);
86 DEFINE_EXPECT(Switch
);
87 DEFINE_EXPECT(CreateInstance
);
89 DEFINE_EXPECT(Terminate
);
91 DEFINE_EXPECT(SetPriority
);
93 static const WCHAR wszIndexHtml
[] = {'i','n','d','e','x','.','h','t','m','l',0};
94 static const WCHAR index_url
[] =
95 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
97 static HRESULT expect_hrResult
;
98 static LPCWSTR file_name
, http_url
, expect_wsz
;
99 static IInternetProtocol
*http_protocol
= NULL
;
100 static BOOL first_data_notif
= FALSE
, http_is_first
= FALSE
,
101 http_post_test
= FALSE
;
102 static int state
= 0;
103 static DWORD bindf
= 0;
104 static IInternetBindInfo
*prot_bind_info
;
105 static void *expect_pv
;
106 static HANDLE event_complete
;
115 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
, REFIID riid
, void **ppv
)
117 if(IsEqualGUID(&IID_IUnknown
, riid
)
118 || IsEqualGUID(&IID_IHttpNegotiate
, riid
)
119 || IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
124 ok(0, "unexpected call\n");
125 return E_NOINTERFACE
;
128 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
133 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate2
*iface
)
138 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
, LPCWSTR szURL
,
139 LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
143 static const WCHAR wszHeaders
[] =
144 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t',
145 'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o',
146 'd','e','d','\r','\n',0};
148 CHECK_EXPECT(BeginningTransaction
);
150 ok(!lstrcmpW(szURL
, http_url
), "szURL != http_url\n");
151 ok(!dwReserved
, "dwReserved=%d, expected 0\n", dwReserved
);
152 ok(pszAdditionalHeaders
!= NULL
, "pszAdditionalHeaders == NULL\n");
153 if(pszAdditionalHeaders
)
155 ok(*pszAdditionalHeaders
== NULL
, "*pszAdditionalHeaders != NULL\n");
158 addl_headers
= CoTaskMemAlloc(sizeof(wszHeaders
));
161 http_post_test
= FALSE
;
162 skip("Out of memory\n");
163 return E_OUTOFMEMORY
;
165 lstrcpyW(addl_headers
, wszHeaders
);
166 *pszAdditionalHeaders
= addl_headers
;
173 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
174 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
, LPWSTR
*pszAdditionalRequestHeaders
)
176 CHECK_EXPECT(OnResponse
);
178 ok(dwResponseCode
== 200, "dwResponseCode=%d, expected 200\n", dwResponseCode
);
179 ok(szResponseHeaders
!= NULL
, "szResponseHeaders == NULL\n");
180 ok(szRequestHeaders
== NULL
, "szRequestHeaders != NULL\n");
181 ok(pszAdditionalRequestHeaders
== NULL
, "pszAdditionalHeaders != NULL\n");
186 static HRESULT WINAPI
HttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
187 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
189 static const BYTE sec_id
[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
191 CHECK_EXPECT(GetRootSecurityId
);
193 ok(!dwReserved
, "dwReserved=%ld, expected 0\n", dwReserved
);
194 ok(pbSecurityId
!= NULL
, "pbSecurityId == NULL\n");
195 ok(pcbSecurityId
!= NULL
, "pcbSecurityId == NULL\n");
198 ok(*pcbSecurityId
== 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId
);
199 *pcbSecurityId
= sizeof(sec_id
);
203 memcpy(pbSecurityId
, sec_id
, sizeof(sec_id
));
208 static IHttpNegotiate2Vtbl HttpNegotiateVtbl
= {
209 HttpNegotiate_QueryInterface
,
210 HttpNegotiate_AddRef
,
211 HttpNegotiate_Release
,
212 HttpNegotiate_BeginningTransaction
,
213 HttpNegotiate_OnResponse
,
214 HttpNegotiate_GetRootSecurityId
217 static IHttpNegotiate2 http_negotiate
= { &HttpNegotiateVtbl
};
219 static HRESULT
QueryInterface(REFIID
,void**);
221 static HRESULT WINAPI
ServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
223 return QueryInterface(riid
, ppv
);
226 static ULONG WINAPI
ServiceProvider_AddRef(IServiceProvider
*iface
)
231 static ULONG WINAPI
ServiceProvider_Release(IServiceProvider
*iface
)
236 static HRESULT WINAPI
ServiceProvider_QueryService(IServiceProvider
*iface
, REFGUID guidService
,
237 REFIID riid
, void **ppv
)
239 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
) || IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
240 CHECK_EXPECT2(QueryService_HttpNegotiate
);
241 return IHttpNegotiate2_QueryInterface(&http_negotiate
, riid
, ppv
);
244 if(IsEqualGUID(&IID_IInternetProtocol
, guidService
)) {
245 ok(IsEqualGUID(&IID_IInternetProtocol
, riid
), "unexpected riid\n");
246 CHECK_EXPECT(QueryService_InternetProtocol
);
247 return E_NOINTERFACE
;
250 ok(0, "unexpected call\n");
254 static const IServiceProviderVtbl ServiceProviderVtbl
= {
255 ServiceProvider_QueryInterface
,
256 ServiceProvider_AddRef
,
257 ServiceProvider_Release
,
258 ServiceProvider_QueryService
261 static IServiceProvider service_provider
= { &ServiceProviderVtbl
};
263 static HRESULT WINAPI
ProtocolSink_QueryInterface(IInternetProtocolSink
*iface
, REFIID riid
, void **ppv
)
265 return QueryInterface(riid
, ppv
);
268 static ULONG WINAPI
ProtocolSink_AddRef(IInternetProtocolSink
*iface
)
273 static ULONG WINAPI
ProtocolSink_Release(IInternetProtocolSink
*iface
)
278 static HRESULT WINAPI
ProtocolSink_Switch(IInternetProtocolSink
*iface
, PROTOCOLDATA
*pProtocolData
)
282 CHECK_EXPECT(Switch
);
283 ok(pProtocolData
!= NULL
, "pProtocolData == NULL\n");
286 CHECK_CALLED(ReportProgress_FINDINGRESOURCE
);
287 CHECK_CALLED(ReportProgress_CONNECTING
);
289 CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE
);
290 CHECK_NOT_CALLED(ReportProgress_CONNECTING
);
292 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
293 SET_EXPECT(OnResponse
);
294 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
297 SET_EXPECT(ReportData
);
298 hres
= IInternetProtocol_Continue(http_protocol
, pProtocolData
);
299 ok(hres
== S_OK
, "Continue failed: %08x\n", hres
);
300 CHECK_CALLED(ReportData
);
304 CHECK_CALLED(OnResponse
);
305 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE
);
308 SetEvent(event_complete
);
312 static HRESULT WINAPI
ProtocolSink_ReportProgress(IInternetProtocolSink
*iface
, ULONG ulStatusCode
,
313 LPCWSTR szStatusText
)
315 static const WCHAR null_guid
[] = {'{','0','0','0','0','0','0','0','0','-','0','0','0','0','-',
316 '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0};
317 static const WCHAR text_html
[] = {'t','e','x','t','/','h','t','m','l',0};
318 static const WCHAR text_plain
[] = {'t','e','x','t','/','p','l','a','i','n',0};
319 static const WCHAR host
[] =
320 {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
321 static const WCHAR post_host
[] =
322 {'c','r','o','s','s','o','v','e','r','.','c','o','d','e',
323 'w','e','a','v','e','r','s','.','c','o','m',0};
324 static const WCHAR wszWineHQIP
[] =
325 {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
326 static const WCHAR wszCrossoverIP
[] =
327 {'2','0','9','.','4','6','.','2','5','.','1','3','2',0};
328 /* I'm not sure if it's a good idea to hardcode here the IP address... */
330 switch(ulStatusCode
) {
331 case BINDSTATUS_MIMETYPEAVAILABLE
:
332 CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
333 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
335 if(tested_protocol
== BIND_TEST
)
336 ok(szStatusText
== expect_wsz
, "unexpected szStatusText\n");
337 else if (http_post_test
)
338 ok(lstrlenW(text_plain
) <= lstrlenW(szStatusText
) &&
339 !memcmp(szStatusText
, text_plain
, lstrlenW(text_plain
)*sizeof(WCHAR
)),
340 "szStatusText != text/plain\n");
342 ok(lstrlenW(text_html
) <= lstrlenW(szStatusText
) &&
343 !memcmp(szStatusText
, text_html
, lstrlenW(text_html
)*sizeof(WCHAR
)),
344 "szStatusText != text/html\n");
347 case BINDSTATUS_DIRECTBIND
:
348 CHECK_EXPECT2(ReportProgress_DIRECTBIND
);
349 ok(szStatusText
== NULL
, "szStatusText != NULL\n");
351 case BINDSTATUS_RAWMIMETYPE
:
352 CHECK_EXPECT2(ReportProgress_RAWMIMETYPE
);
353 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
355 ok(lstrlenW(szStatusText
) < lstrlenW(text_html
) ||
356 !memcmp(szStatusText
, text_html
, lstrlenW(text_html
)*sizeof(WCHAR
)),
357 "szStatusText != text/html\n");
359 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
360 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
361 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
363 if(tested_protocol
== BIND_TEST
)
364 ok(szStatusText
== expect_wsz
, "unexpected szStatusText\n");
366 ok(!lstrcmpW(szStatusText
, file_name
), "szStatusText != file_name\n");
369 case BINDSTATUS_FINDINGRESOURCE
:
370 CHECK_EXPECT(ReportProgress_FINDINGRESOURCE
);
371 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
375 ok(!lstrcmpW(szStatusText
, host
),
376 "szStatustext != \"www.winehq.org\"\n");
378 ok(!lstrcmpW(szStatusText
, post_host
),
379 "szStatustext != \"crossover.codeweavers.com\"\n");
382 case BINDSTATUS_CONNECTING
:
383 CHECK_EXPECT(ReportProgress_CONNECTING
);
384 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
386 ok(!lstrcmpW(szStatusText
, http_post_test
?
387 wszCrossoverIP
: wszWineHQIP
),
388 "Unexpected szStatusText\n");
390 case BINDSTATUS_SENDINGREQUEST
:
391 CHECK_EXPECT(ReportProgress_SENDINGREQUEST
);
392 if(tested_protocol
== FILE_TEST
) {
393 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
395 ok(!*szStatusText
, "wrong szStatusText\n");
397 ok(szStatusText
== NULL
, "szStatusText != NULL\n");
400 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
401 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
402 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
404 ok(!lstrcmpW(szStatusText
, text_html
), "szStatusText != text/html\n");
406 case BINDSTATUS_PROTOCOLCLASSID
:
407 CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID
);
408 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
409 ok(!lstrcmpW(szStatusText
, null_guid
), "unexpected szStatusText\n");
412 ok(0, "Unexpected call %d\n", ulStatusCode
);
418 static HRESULT WINAPI
ProtocolSink_ReportData(IInternetProtocolSink
*iface
, DWORD grfBSCF
,
419 ULONG ulProgress
, ULONG ulProgressMax
)
421 if(tested_protocol
== FILE_TEST
) {
422 CHECK_EXPECT2(ReportData
);
424 ok(ulProgress
== ulProgressMax
, "ulProgress (%d) != ulProgressMax (%d)\n",
425 ulProgress
, ulProgressMax
);
426 ok(ulProgressMax
== 13, "ulProgressMax=%d, expected 13\n", ulProgressMax
);
427 ok(grfBSCF
== (BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
),
428 "grcfBSCF = %08x\n", grfBSCF
);
429 }else if(tested_protocol
== HTTP_TEST
) {
430 if(!(grfBSCF
& BSCF_LASTDATANOTIFICATION
))
431 CHECK_EXPECT(ReportData
);
432 else if (http_post_test
)
433 ok(ulProgress
== 13, "Read %u bytes instead of 13\n", ulProgress
);
435 ok(ulProgress
, "ulProgress == 0\n");
437 if(first_data_notif
) {
438 ok(grfBSCF
== BSCF_FIRSTDATANOTIFICATION
, "grcfBSCF = %08x\n", grfBSCF
);
439 first_data_notif
= FALSE
;
441 ok(grfBSCF
== BSCF_INTERMEDIATEDATANOTIFICATION
442 || grfBSCF
== (BSCF_LASTDATANOTIFICATION
|BSCF_INTERMEDIATEDATANOTIFICATION
),
443 "grcfBSCF = %08x\n", grfBSCF
);
446 if(!(bindf
& BINDF_FROMURLMON
) &&
447 !(grfBSCF
& BSCF_LASTDATANOTIFICATION
)) {
451 CHECK_CALLED(ReportProgress_FINDINGRESOURCE
);
452 CHECK_CALLED(ReportProgress_CONNECTING
);
454 CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE
);
455 CHECK_NOT_CALLED(ReportProgress_CONNECTING
);
457 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
458 CHECK_CALLED(OnResponse
);
459 CHECK_CALLED(ReportProgress_RAWMIMETYPE
);
461 SetEvent(event_complete
);
467 static HRESULT WINAPI
ProtocolSink_ReportResult(IInternetProtocolSink
*iface
, HRESULT hrResult
,
468 DWORD dwError
, LPCWSTR szResult
)
470 CHECK_EXPECT(ReportResult
);
472 ok(hrResult
== expect_hrResult
, "hrResult = %08x, expected: %08x\n",
473 hrResult
, expect_hrResult
);
474 if(SUCCEEDED(hrResult
))
475 ok(dwError
== ERROR_SUCCESS
, "dwError = %d, expected ERROR_SUCCESS\n", dwError
);
477 ok(dwError
!= ERROR_SUCCESS
, "dwError == ERROR_SUCCESS\n");
478 ok(!szResult
, "szResult != NULL\n");
483 static IInternetProtocolSinkVtbl protocol_sink_vtbl
= {
484 ProtocolSink_QueryInterface
,
486 ProtocolSink_Release
,
488 ProtocolSink_ReportProgress
,
489 ProtocolSink_ReportData
,
490 ProtocolSink_ReportResult
493 static IInternetProtocolSink protocol_sink
= { &protocol_sink_vtbl
};
495 static HRESULT
QueryInterface(REFIID riid
, void **ppv
)
499 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IInternetProtocolSink
, riid
))
500 *ppv
= &protocol_sink
;
501 if(IsEqualGUID(&IID_IServiceProvider
, riid
))
502 *ppv
= &service_provider
;
507 return E_NOINTERFACE
;
510 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
, REFIID riid
, void **ppv
)
512 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
516 return E_NOINTERFACE
;
519 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
524 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
529 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
533 static const CHAR szPostData
[] = "mode=Test";
535 CHECK_EXPECT(GetBindInfo
);
537 ok(grfBINDF
!= NULL
, "grfBINDF == NULL\n");
538 ok(pbindinfo
!= NULL
, "pbindinfo == NULL\n");
539 ok(pbindinfo
->cbSize
== sizeof(BINDINFO
), "wrong size of pbindinfo: %d\n", pbindinfo
->cbSize
);
542 cbSize
= pbindinfo
->cbSize
;
543 memset(pbindinfo
, 0, cbSize
);
544 pbindinfo
->cbSize
= cbSize
;
548 /* Must be GMEM_FIXED, GMEM_MOVABLE does not work properly
549 * with urlmon on native (Win98 and WinXP) */
550 pbindinfo
->stgmedData
.hGlobal
= GlobalAlloc(GPTR
, sizeof(szPostData
));
551 if (!pbindinfo
->stgmedData
.hGlobal
)
553 http_post_test
= FALSE
;
554 skip("Out of memory\n");
555 return E_OUTOFMEMORY
;
557 lstrcpy((LPSTR
)pbindinfo
->stgmedData
.hGlobal
, szPostData
);
558 pbindinfo
->cbstgmedData
= sizeof(szPostData
)-1;
559 pbindinfo
->dwBindVerb
= BINDVERB_POST
;
560 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
566 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
, ULONG ulStringType
,
567 LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
569 static const WCHAR acc_mime
[] = {'*','/','*',0};
570 static const WCHAR user_agent
[] = {'W','i','n','e',0};
572 ok(ppwzStr
!= NULL
, "ppwzStr == NULL\n");
573 ok(pcElFetched
!= NULL
, "pcElFetched == NULL\n");
575 switch(ulStringType
) {
576 case BINDSTRING_ACCEPT_MIMES
:
577 CHECK_EXPECT(GetBindString_ACCEPT_MIMES
);
578 ok(cEl
== 256, "cEl=%d, expected 256\n", cEl
);
580 ok(*pcElFetched
== 256, "*pcElFetched=%d, expected 256\n", *pcElFetched
);
584 *ppwzStr
= CoTaskMemAlloc(sizeof(acc_mime
));
585 memcpy(*ppwzStr
, acc_mime
, sizeof(acc_mime
));
588 case BINDSTRING_USER_AGENT
:
589 CHECK_EXPECT(GetBindString_USER_AGENT
);
590 ok(cEl
== 1, "cEl=%d, expected 1\n", cEl
);
592 ok(*pcElFetched
== 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched
);
596 *ppwzStr
= CoTaskMemAlloc(sizeof(user_agent
));
597 memcpy(*ppwzStr
, user_agent
, sizeof(user_agent
));
600 case BINDSTRING_POST_COOKIE
:
601 CHECK_EXPECT(GetBindString_POST_COOKIE
);
602 ok(cEl
== 1, "cEl=%d, expected 1\n", cEl
);
604 ok(*pcElFetched
== 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched
);
607 ok(0, "unexpected call\n");
613 static IInternetBindInfoVtbl bind_info_vtbl
= {
614 BindInfo_QueryInterface
,
617 BindInfo_GetBindInfo
,
618 BindInfo_GetBindString
621 static IInternetBindInfo bind_info
= { &bind_info_vtbl
};
623 static HRESULT WINAPI
InternetPriority_QueryInterface(IInternetPriority
*iface
,
624 REFIID riid
, void **ppv
)
626 ok(0, "unexpected call\n");
627 return E_NOINTERFACE
;
630 static ULONG WINAPI
InternetPriority_AddRef(IInternetPriority
*iface
)
635 static ULONG WINAPI
InternetPriority_Release(IInternetPriority
*iface
)
640 static HRESULT WINAPI
InternetPriority_SetPriority(IInternetPriority
*iface
, LONG nPriority
)
642 CHECK_EXPECT(SetPriority
);
643 ok(nPriority
== 100, "nPriority=%d\n", nPriority
);
647 static HRESULT WINAPI
InternetPriority_GetPriority(IInternetPriority
*iface
, LONG
*pnPriority
)
649 ok(0, "unexpected call\n");
654 static const IInternetPriorityVtbl InternetPriorityVtbl
= {
655 InternetPriority_QueryInterface
,
656 InternetPriority_AddRef
,
657 InternetPriority_Release
,
658 InternetPriority_SetPriority
,
659 InternetPriority_GetPriority
662 static IInternetPriority InternetPriority
= { &InternetPriorityVtbl
};
664 static HRESULT WINAPI
Protocol_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
666 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
671 if(IsEqualGUID(&IID_IInternetPriority
, riid
)) {
672 *ppv
= &InternetPriority
;
676 ok(0, "unexpected call\n");
678 return E_NOINTERFACE
;
681 static ULONG WINAPI
Protocol_AddRef(IInternetProtocol
*iface
)
686 static ULONG WINAPI
Protocol_Release(IInternetProtocol
*iface
)
691 static HRESULT WINAPI
Protocol_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
692 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
693 DWORD grfPI
, DWORD dwReserved
)
695 BINDINFO bindinfo
, exp_bindinfo
;
699 static const WCHAR wszTextHtml
[] = {'t','e','x','t','/','h','t','m','l',0};
700 static const WCHAR empty_str
[] = {0};
704 ok(pOIProtSink
!= NULL
, "pOIProtSink == NULL\n");
705 ok(pOIBindInfo
!= NULL
, "pOIBindInfo == NULL\n");
706 ok(!grfPI
, "grfPI = %x\n", grfPI
);
707 ok(!dwReserved
, "dwReserved = %d\n", dwReserved
);
709 memset(&bindinfo
, 0, sizeof(bindinfo
));
710 bindinfo
.cbSize
= sizeof(bindinfo
);
711 memcpy(&exp_bindinfo
, &bindinfo
, sizeof(bindinfo
));
712 SET_EXPECT(GetBindInfo
);
713 hres
= IInternetBindInfo_GetBindInfo(pOIBindInfo
, &cbindf
, &bindinfo
);
714 ok(hres
== S_OK
, "GetBindInfo failed: %08x\n", hres
);
715 CHECK_CALLED(GetBindInfo
);
716 ok(cbindf
== (bindf
|BINDF_FROMURLMON
), "bindf = %x, expected %x\n",
717 cbindf
, (bindf
|BINDF_FROMURLMON
));
718 ok(!memcmp(&exp_bindinfo
, &bindinfo
, sizeof(bindinfo
)), "unexpected bindinfo\n");
720 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
721 hres
= IInternetProtocolSink_ReportProgress(pOIProtSink
,
722 BINDSTATUS_SENDINGREQUEST
, empty_str
);
723 ok(hres
== S_OK
, "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres
);
724 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
726 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
727 hres
= IInternetProtocolSink_ReportProgress(pOIProtSink
,
728 BINDSTATUS_CACHEFILENAMEAVAILABLE
, expect_wsz
= empty_str
);
729 ok(hres
== S_OK
, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres
);
730 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE
);
732 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
733 hres
= IInternetProtocolSink_ReportProgress(pOIProtSink
,
734 BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
, expect_wsz
= wszTextHtml
);
736 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres
);
737 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE
);
739 hres
= IInternetProtocolSink_ReportData(pOIProtSink
,
740 BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
, 13, 13);
741 ok(hres
== S_OK
, "ReportData failed: %08x\n", hres
);
743 SET_EXPECT(ReportResult
);
744 hres
= IInternetProtocolSink_ReportResult(pOIProtSink
, S_OK
, 0, NULL
);
745 ok(hres
== S_OK
, "ReportResult failed: %08x\n", hres
);
746 CHECK_CALLED(ReportResult
);
751 static HRESULT WINAPI
Protocol_Continue(IInternetProtocol
*iface
,
752 PROTOCOLDATA
*pProtocolData
)
754 ok(0, "unexpected call\n");
758 static HRESULT WINAPI
Protocol_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
761 ok(0, "unexpected call\n");
765 static HRESULT WINAPI
Protocol_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
767 CHECK_EXPECT(Terminate
);
768 ok(!dwOptions
, "dwOptions=%d\n", dwOptions
);
772 static HRESULT WINAPI
Protocol_Suspend(IInternetProtocol
*iface
)
774 ok(0, "unexpected call\n");
778 static HRESULT WINAPI
Protocol_Resume(IInternetProtocol
*iface
)
780 ok(0, "unexpected call\n");
784 static HRESULT WINAPI
Protocol_Read(IInternetProtocol
*iface
, void *pv
,
785 ULONG cb
, ULONG
*pcbRead
)
791 ok(pv
== expect_pv
, "pv != expect_pv\n");
792 ok(cb
== 1000, "cb=%d\n", cb
);
793 ok(pcbRead
!= NULL
, "pcbRead == NULL\n");
794 ok(!*pcbRead
, "*pcbRead = %d\n", *pcbRead
);
799 memset(pv
, 'x', 100);
800 *pcbRead
= read
= 100;
804 static HRESULT WINAPI
Protocol_Seek(IInternetProtocol
*iface
,
805 LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
807 ok(0, "unexpected call\n");
811 static HRESULT WINAPI
Protocol_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
813 ok(0, "unexpected call\n");
817 static HRESULT WINAPI
Protocol_UnlockRequest(IInternetProtocol
*iface
)
819 ok(0, "unexpected call\n");
823 static const IInternetProtocolVtbl ProtocolVtbl
= {
824 Protocol_QueryInterface
,
835 Protocol_LockRequest
,
836 Protocol_UnlockRequest
839 static IInternetProtocol Protocol
= { &ProtocolVtbl
};
841 static HRESULT WINAPI
ClassFactory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
843 ok(0, "unexpected call\n");
844 return E_NOINTERFACE
;
847 static ULONG WINAPI
ClassFactory_AddRef(IClassFactory
*iface
)
852 static ULONG WINAPI
ClassFactory_Release(IClassFactory
*iface
)
857 static HRESULT WINAPI
ClassFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
858 REFIID riid
, void **ppv
)
860 CHECK_EXPECT(CreateInstance
);
862 ok(pOuter
== (IUnknown
*)prot_bind_info
, "pOuter != protocol_unk\n");
863 ok(IsEqualGUID(&IID_IUnknown
, riid
), "unexpected riid\n");
864 ok(ppv
!= NULL
, "ppv == NULL\n");
870 static HRESULT WINAPI
ClassFactory_LockServer(IClassFactory
*iface
, BOOL dolock
)
872 ok(0, "unexpected call\n");
876 static const IClassFactoryVtbl ClassFactoryVtbl
= {
877 ClassFactory_QueryInterface
,
879 ClassFactory_Release
,
880 ClassFactory_CreateInstance
,
881 ClassFactory_LockServer
884 static IClassFactory ClassFactory
= { &ClassFactoryVtbl
};
886 static void test_priority(IInternetProtocol
*protocol
)
888 IInternetPriority
*priority
;
892 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
,
894 ok(hres
== S_OK
, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres
);
898 hres
= IInternetPriority_GetPriority(priority
, &pr
);
899 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
900 ok(pr
== 0, "pr=%d, expected 0\n", pr
);
902 hres
= IInternetPriority_SetPriority(priority
, 1);
903 ok(hres
== S_OK
, "SetPriority failed: %08x\n", hres
);
905 hres
= IInternetPriority_GetPriority(priority
, &pr
);
906 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
907 ok(pr
== 1, "pr=%d, expected 1\n", pr
);
909 IInternetPriority_Release(priority
);
912 static void file_protocol_start(IInternetProtocol
*protocol
, LPCWSTR url
, BOOL is_first
)
916 SET_EXPECT(GetBindInfo
);
917 if(!(bindf
& BINDF_FROMURLMON
))
918 SET_EXPECT(ReportProgress_DIRECTBIND
);
920 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
921 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
922 if(bindf
& BINDF_FROMURLMON
)
923 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
925 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
927 SET_EXPECT(ReportData
);
929 SET_EXPECT(ReportResult
);
931 expect_hrResult
= S_OK
;
933 hres
= IInternetProtocol_Start(protocol
, url
, &protocol_sink
, &bind_info
, 0, 0);
934 ok(hres
== S_OK
, "Start failed: %08x\n", hres
);
936 CHECK_CALLED(GetBindInfo
);
937 if(!(bindf
& BINDF_FROMURLMON
))
938 CHECK_CALLED(ReportProgress_DIRECTBIND
);
940 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
941 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE
);
942 if(bindf
& BINDF_FROMURLMON
)
943 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
945 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE
);
947 CHECK_CALLED(ReportData
);
949 CHECK_CALLED(ReportResult
);
952 static void test_file_protocol_url(LPCWSTR url
)
954 IInternetProtocolInfo
*protocol_info
;
956 IClassFactory
*factory
;
959 hres
= CoGetClassObject(&CLSID_FileProtocol
, CLSCTX_INPROC_SERVER
, NULL
,
960 &IID_IUnknown
, (void**)&unk
);
961 ok(hres
== S_OK
, "CoGetClassObject failed: %08x\n", hres
);
965 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&protocol_info
);
966 ok(hres
== E_NOINTERFACE
,
967 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres
);
969 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)&factory
);
970 ok(hres
== S_OK
, "Could not get IClassFactory interface\n");
971 if(SUCCEEDED(hres
)) {
972 IInternetProtocol
*protocol
;
975 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
976 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
978 if(SUCCEEDED(hres
)) {
979 file_protocol_start(protocol
, url
, TRUE
);
980 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
981 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
982 ok(cb
== 2, "cb=%u expected 2\n", cb
);
983 hres
= IInternetProtocol_Read(protocol
, buf
, sizeof(buf
), &cb
);
984 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
985 hres
= IInternetProtocol_Read(protocol
, buf
, sizeof(buf
), &cb
);
986 ok(hres
== S_FALSE
, "Read failed: %08x expected S_FALSE\n", hres
);
987 ok(cb
== 0, "cb=%u expected 0\n", cb
);
988 hres
= IInternetProtocol_UnlockRequest(protocol
);
989 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
991 file_protocol_start(protocol
, url
, FALSE
);
992 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
993 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
994 hres
= IInternetProtocol_LockRequest(protocol
, 0);
995 ok(hres
== S_OK
, "LockRequest failed: %08x\n", hres
);
996 hres
= IInternetProtocol_UnlockRequest(protocol
);
997 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
999 IInternetProtocol_Release(protocol
);
1002 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
1003 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
1005 if(SUCCEEDED(hres
)) {
1006 file_protocol_start(protocol
, url
, TRUE
);
1007 hres
= IInternetProtocol_LockRequest(protocol
, 0);
1008 ok(hres
== S_OK
, "LockRequest failed: %08x\n", hres
);
1009 hres
= IInternetProtocol_Terminate(protocol
, 0);
1010 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
1011 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
1012 ok(hres
== S_OK
, "Read failed: %08x\n\n", hres
);
1013 hres
= IInternetProtocol_UnlockRequest(protocol
);
1014 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
1015 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
1016 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
1017 hres
= IInternetProtocol_Terminate(protocol
, 0);
1018 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
1020 IInternetProtocol_Release(protocol
);
1023 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
1024 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
1026 if(SUCCEEDED(hres
)) {
1027 file_protocol_start(protocol
, url
, TRUE
);
1028 hres
= IInternetProtocol_Terminate(protocol
, 0);
1029 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
1030 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
1031 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
1032 ok(cb
== 2, "cb=%u expected 2\n", cb
);
1034 IInternetProtocol_Release(protocol
);
1037 IClassFactory_Release(factory
);
1040 IUnknown_Release(unk
);
1043 static void test_file_protocol_fail(void)
1045 IInternetProtocol
*protocol
;
1048 static const WCHAR index_url2
[] =
1049 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
1051 hres
= CoCreateInstance(&CLSID_FileProtocol
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1052 &IID_IInternetProtocol
, (void**)&protocol
);
1053 ok(hres
== S_OK
, "CoCreateInstance failed: %08x\n", hres
);
1057 SET_EXPECT(GetBindInfo
);
1058 expect_hrResult
= MK_E_SYNTAX
;
1059 hres
= IInternetProtocol_Start(protocol
, wszIndexHtml
, &protocol_sink
, &bind_info
, 0, 0);
1060 ok(hres
== MK_E_SYNTAX
, "Start failed: %08x, expected MK_E_SYNTAX\n", hres
);
1061 CHECK_CALLED(GetBindInfo
);
1063 SET_EXPECT(GetBindInfo
);
1064 if(!(bindf
& BINDF_FROMURLMON
))
1065 SET_EXPECT(ReportProgress_DIRECTBIND
);
1066 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
1067 SET_EXPECT(ReportResult
);
1068 expect_hrResult
= INET_E_RESOURCE_NOT_FOUND
;
1069 hres
= IInternetProtocol_Start(protocol
, index_url
, &protocol_sink
, &bind_info
, 0, 0);
1070 ok(hres
== INET_E_RESOURCE_NOT_FOUND
,
1071 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres
);
1072 CHECK_CALLED(GetBindInfo
);
1073 if(!(bindf
& BINDF_FROMURLMON
))
1074 CHECK_CALLED(ReportProgress_DIRECTBIND
);
1075 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
1076 CHECK_CALLED(ReportResult
);
1078 IInternetProtocol_Release(protocol
);
1080 hres
= CoCreateInstance(&CLSID_FileProtocol
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1081 &IID_IInternetProtocol
, (void**)&protocol
);
1082 ok(hres
== S_OK
, "CoCreateInstance failed: %08x\n", hres
);
1086 SET_EXPECT(GetBindInfo
);
1087 if(!(bindf
& BINDF_FROMURLMON
))
1088 SET_EXPECT(ReportProgress_DIRECTBIND
);
1089 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
1090 SET_EXPECT(ReportResult
);
1091 expect_hrResult
= INET_E_RESOURCE_NOT_FOUND
;
1093 hres
= IInternetProtocol_Start(protocol
, index_url2
, &protocol_sink
, &bind_info
, 0, 0);
1094 ok(hres
== INET_E_RESOURCE_NOT_FOUND
,
1095 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres
);
1096 CHECK_CALLED(GetBindInfo
);
1097 if(!(bindf
& BINDF_FROMURLMON
))
1098 CHECK_CALLED(ReportProgress_DIRECTBIND
);
1099 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
1100 CHECK_CALLED(ReportResult
);
1102 IInternetProtocol_Release(protocol
);
1105 static void test_file_protocol(void) {
1106 WCHAR buf
[MAX_PATH
];
1111 static const WCHAR wszFile
[] = {'f','i','l','e',':',0};
1112 static const WCHAR wszFile2
[] = {'f','i','l','e',':','/','/',0};
1113 static const WCHAR wszFile3
[] = {'f','i','l','e',':','/','/','/',0};
1114 static const char html_doc
[] = "<HTML></HTML>";
1116 trace("Testing file protocol...\n");
1117 tested_protocol
= FILE_TEST
;
1119 file
= CreateFileW(wszIndexHtml
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1120 FILE_ATTRIBUTE_NORMAL
, NULL
);
1121 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
1122 if(file
== INVALID_HANDLE_VALUE
)
1124 WriteFile(file
, html_doc
, sizeof(html_doc
)-1, &size
, NULL
);
1127 file_name
= wszIndexHtml
;
1129 test_file_protocol_url(index_url
);
1130 bindf
= BINDF_FROMURLMON
;
1131 test_file_protocol_url(index_url
);
1133 memcpy(buf
, wszFile
, sizeof(wszFile
));
1134 len
= sizeof(wszFile
)/sizeof(WCHAR
)-1;
1135 len
+= GetCurrentDirectoryW(sizeof(buf
)/sizeof(WCHAR
)-len
, buf
+len
);
1137 memcpy(buf
+len
, wszIndexHtml
, sizeof(wszIndexHtml
));
1139 file_name
= buf
+ sizeof(wszFile
)/sizeof(WCHAR
)-1;
1141 test_file_protocol_url(buf
);
1142 bindf
= BINDF_FROMURLMON
;
1143 test_file_protocol_url(buf
);
1145 memcpy(buf
, wszFile2
, sizeof(wszFile2
));
1146 len
= sizeof(wszFile2
)/sizeof(WCHAR
)-1;
1147 len
+= GetCurrentDirectoryW(sizeof(buf
)/sizeof(WCHAR
)-len
, buf
+len
);
1149 memcpy(buf
+len
, wszIndexHtml
, sizeof(wszIndexHtml
));
1151 file_name
= buf
+ sizeof(wszFile2
)/sizeof(WCHAR
)-1;
1153 test_file_protocol_url(buf
);
1154 bindf
= BINDF_FROMURLMON
;
1155 test_file_protocol_url(buf
);
1157 memcpy(buf
, wszFile3
, sizeof(wszFile3
));
1158 len
= sizeof(wszFile3
)/sizeof(WCHAR
)-1;
1159 len
+= GetCurrentDirectoryW(sizeof(buf
)/sizeof(WCHAR
)-len
, buf
+len
);
1161 memcpy(buf
+len
, wszIndexHtml
, sizeof(wszIndexHtml
));
1163 file_name
= buf
+ sizeof(wszFile3
)/sizeof(WCHAR
)-1;
1165 test_file_protocol_url(buf
);
1166 bindf
= BINDF_FROMURLMON
;
1167 test_file_protocol_url(buf
);
1169 DeleteFileW(wszIndexHtml
);
1172 test_file_protocol_fail();
1173 bindf
= BINDF_FROMURLMON
;
1174 test_file_protocol_fail();
1177 static BOOL
http_protocol_start(LPCWSTR url
, BOOL is_first
)
1179 static BOOL got_user_agent
= FALSE
;
1182 first_data_notif
= TRUE
;
1185 SET_EXPECT(GetBindInfo
);
1186 if (!(bindf
& BINDF_FROMURLMON
))
1187 SET_EXPECT(ReportProgress_DIRECTBIND
);
1188 SET_EXPECT(GetBindString_USER_AGENT
);
1189 SET_EXPECT(GetBindString_ACCEPT_MIMES
);
1190 SET_EXPECT(QueryService_HttpNegotiate
);
1191 SET_EXPECT(BeginningTransaction
);
1192 SET_EXPECT(GetRootSecurityId
);
1194 SET_EXPECT(GetBindString_POST_COOKIE
);
1196 hres
= IInternetProtocol_Start(http_protocol
, url
, &protocol_sink
, &bind_info
, 0, 0);
1197 ok(hres
== S_OK
, "Start failed: %08x\n", hres
);
1201 CHECK_CALLED(GetBindInfo
);
1202 if (!(bindf
& BINDF_FROMURLMON
))
1203 CHECK_CALLED(ReportProgress_DIRECTBIND
);
1204 if (!got_user_agent
)
1206 CHECK_CALLED(GetBindString_USER_AGENT
);
1207 got_user_agent
= TRUE
;
1211 /* user agent only retrieved once, even with different URLs */
1212 CHECK_NOT_CALLED(GetBindString_USER_AGENT
);
1214 CHECK_CALLED(GetBindString_ACCEPT_MIMES
);
1215 CHECK_CALLED(QueryService_HttpNegotiate
);
1216 CHECK_CALLED(BeginningTransaction
);
1217 /* GetRootSecurityId called on WinXP but not on Win98 */
1218 CLEAR_CALLED(GetRootSecurityId
);
1220 CHECK_CALLED(GetBindString_POST_COOKIE
);
1225 /* is_first refers to whether this is the first call to this function
1227 static void test_http_protocol_url(LPCWSTR url
, BOOL is_first
)
1229 IInternetProtocolInfo
*protocol_info
;
1230 IClassFactory
*factory
;
1234 trace("Testing http protocol...\n");
1236 http_is_first
= is_first
;
1238 hres
= CoGetClassObject(&CLSID_HttpProtocol
, CLSCTX_INPROC_SERVER
, NULL
,
1239 &IID_IUnknown
, (void**)&unk
);
1240 ok(hres
== S_OK
, "CoGetClassObject failed: %08x\n", hres
);
1241 if(!SUCCEEDED(hres
))
1244 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&protocol_info
);
1245 ok(hres
== E_NOINTERFACE
,
1246 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
1249 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)&factory
);
1250 ok(hres
== S_OK
, "Could not get IClassFactory interface\n");
1251 IUnknown_Release(unk
);
1255 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
,
1256 (void**)&http_protocol
);
1257 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
1258 if(SUCCEEDED(hres
)) {
1261 int *called
= (bindf
& BINDF_FROMURLMON
) ? &called_Switch
: &called_ReportData
;
1263 test_priority(http_protocol
);
1265 SET_EXPECT(ReportProgress_FINDINGRESOURCE
);
1266 SET_EXPECT(ReportProgress_CONNECTING
);
1267 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
1268 if(!(bindf
& BINDF_FROMURLMON
)) {
1269 SET_EXPECT(OnResponse
);
1270 SET_EXPECT(ReportProgress_RAWMIMETYPE
);
1271 SET_EXPECT(ReportData
);
1276 if(!http_protocol_start(url
, is_first
))
1279 SET_EXPECT(ReportResult
);
1280 expect_hrResult
= S_OK
;
1282 hres
= IInternetProtocol_Read(http_protocol
, buf
, 1, &cb
);
1283 ok((!*called
&& hres
== E_PENDING
&& cb
==0) ||
1284 (*called
&& hres
== S_OK
&& cb
==1), "Read failed: %08x (%d bytes)\n", hres
, cb
);
1286 WaitForSingleObject(event_complete
, INFINITE
);
1287 if(bindf
& BINDF_FROMURLMON
)
1288 CHECK_CALLED(Switch
);
1290 CHECK_CALLED(ReportData
);
1293 if(bindf
& BINDF_FROMURLMON
)
1296 SET_EXPECT(ReportData
);
1297 hres
= IInternetProtocol_Read(http_protocol
, buf
, sizeof(buf
), &cb
);
1298 if(hres
== E_PENDING
) {
1299 hres
= IInternetProtocol_Read(http_protocol
, buf
, 1, &cb
);
1300 ok((!*called
&& hres
== E_PENDING
&& cb
==0) ||
1301 (*called
&& hres
== S_OK
&& cb
==1), "Read failed: %08x (%d bytes)\n", hres
, cb
);
1302 WaitForSingleObject(event_complete
, INFINITE
);
1303 if(bindf
& BINDF_FROMURLMON
)
1304 CHECK_CALLED(Switch
);
1306 CHECK_CALLED(ReportData
);
1308 if(bindf
& BINDF_FROMURLMON
)
1309 CHECK_NOT_CALLED(Switch
);
1311 CHECK_NOT_CALLED(ReportData
);
1315 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
1316 CHECK_CALLED(ReportResult
);
1318 hres
= IInternetProtocol_LockRequest(http_protocol
, 0);
1319 ok(hres
== S_OK
, "LockRequest failed: %08x\n", hres
);
1321 hres
= IInternetProtocol_Read(http_protocol
, buf
, 1, &cb
);
1322 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
1324 hres
= IInternetProtocol_Terminate(http_protocol
, 0);
1325 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
1327 /* This wait is to give the internet handles being freed in Terminate
1328 * enough time to actually terminate in all cases. Internet handles
1329 * terminate asynchronously and native reuses the main InternetOpen
1330 * handle. The only case in which this seems to be necessary is on
1331 * wine with native wininet and urlmon, resulting in the next time
1332 * test_http_protocol_url being called the first data notification actually
1333 * being an extra last data notification from the previous connection
1334 * about once out of every ten times. */
1337 hres
= IInternetProtocol_UnlockRequest(http_protocol
);
1338 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
1340 IInternetProtocol_Release(http_protocol
);
1343 IClassFactory_Release(factory
);
1346 static void test_http_protocol(void)
1348 static const WCHAR winehq_url
[] =
1349 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
1350 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
1351 static const WCHAR posttest_url
[] =
1352 {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
1353 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
1354 'p','o','s','t','t','e','s','t','.','p','h','p',0};
1356 tested_protocol
= HTTP_TEST
;
1357 bindf
= BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
| BINDF_PULLDATA
;
1358 test_http_protocol_url(winehq_url
, TRUE
);
1359 bindf
= BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
| BINDF_PULLDATA
| BINDF_FROMURLMON
;
1360 test_http_protocol_url(winehq_url
, FALSE
);
1362 http_post_test
= TRUE
;
1363 /* Without this flag we get a ReportProgress_CACHEFILENAMEAVAILABLE
1364 * notification with BINDVERB_POST */
1365 bindf
|= BINDF_NOWRITECACHE
;
1366 test_http_protocol_url(posttest_url
, TRUE
);
1367 http_post_test
= FALSE
;
1370 static void test_mk_protocol(void)
1372 IInternetProtocolInfo
*protocol_info
;
1373 IInternetProtocol
*protocol
;
1374 IClassFactory
*factory
;
1378 static const WCHAR wrong_url1
[] = {'t','e','s','t',':','@','M','S','I','T','S','t','o','r','e',
1379 ':',':','/','t','e','s','t','.','h','t','m','l',0};
1380 static const WCHAR wrong_url2
[] = {'m','k',':','/','t','e','s','t','.','h','t','m','l',0};
1382 trace("Testing mk protocol...\n");
1383 tested_protocol
= MK_TEST
;
1385 hres
= CoGetClassObject(&CLSID_MkProtocol
, CLSCTX_INPROC_SERVER
, NULL
,
1386 &IID_IUnknown
, (void**)&unk
);
1387 ok(hres
== S_OK
, "CoGetClassObject failed: %08x\n", hres
);
1389 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&protocol_info
);
1390 ok(hres
== E_NOINTERFACE
,
1391 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
1394 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)&factory
);
1395 ok(hres
== S_OK
, "Could not get IClassFactory interface\n");
1396 IUnknown_Release(unk
);
1400 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
,
1402 IClassFactory_Release(factory
);
1403 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
1405 SET_EXPECT(GetBindInfo
);
1406 hres
= IInternetProtocol_Start(protocol
, wrong_url1
, &protocol_sink
, &bind_info
, 0, 0);
1407 ok(hres
== MK_E_SYNTAX
, "Start failed: %08x, expected MK_E_SYNTAX\n", hres
);
1408 CHECK_CALLED(GetBindInfo
);
1410 SET_EXPECT(GetBindInfo
);
1411 SET_EXPECT(ReportProgress_DIRECTBIND
);
1412 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
1413 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
1414 SET_EXPECT(ReportResult
);
1415 expect_hrResult
= INET_E_RESOURCE_NOT_FOUND
;
1417 hres
= IInternetProtocol_Start(protocol
, wrong_url2
, &protocol_sink
, &bind_info
, 0, 0);
1418 ok(hres
== INET_E_RESOURCE_NOT_FOUND
, "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres
);
1420 CHECK_CALLED(GetBindInfo
);
1421 CHECK_CALLED(ReportProgress_DIRECTBIND
);
1422 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
1423 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE
);
1424 CHECK_CALLED(ReportResult
);
1426 IInternetProtocol_Release(protocol
);
1429 static void test_CreateBinding(void)
1431 IInternetProtocol
*protocol
;
1432 IInternetPriority
*priority
;
1433 IInternetSession
*session
;
1439 static const WCHAR test_url
[] =
1440 {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0};
1441 static const WCHAR wsz_test
[] = {'t','e','s','t',0};
1443 trace("Testing CreateBinding...\n");
1444 tested_protocol
= BIND_TEST
;
1446 hres
= CoInternetGetSession(0, &session
, 0);
1447 ok(hres
== S_OK
, "CoInternetGetSession failed: %08x\n", hres
);
1449 hres
= IInternetSession_RegisterNameSpace(session
, &ClassFactory
, &IID_NULL
, wsz_test
, 0, NULL
, 0);
1450 ok(hres
== S_OK
, "RegisterNameSpace failed: %08x\n", hres
);
1452 hres
= IInternetSession_CreateBinding(session
, NULL
, test_url
, NULL
, NULL
, &protocol
, 0);
1453 ok(hres
== S_OK
, "CreateBinding failed: %08x\n", hres
);
1454 ok(protocol
!= NULL
, "protocol == NULL\n");
1456 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetBindInfo
, (void**)&prot_bind_info
);
1457 ok(hres
== S_OK
, "QueryInterface(IID_IInternetBindInfo) failed: %08x\n", hres
);
1459 hres
= IInternetProtocol_Start(protocol
, test_url
, NULL
, &bind_info
, 0, 0);
1460 ok(hres
== E_INVALIDARG
, "Start failed: %08x, expected E_INVALIDARG\n", hres
);
1461 hres
= IInternetProtocol_Start(protocol
, test_url
, &protocol_sink
, NULL
, 0, 0);
1462 ok(hres
== E_INVALIDARG
, "Start failed: %08x, expected E_INVALIDARG\n", hres
);
1463 hres
= IInternetProtocol_Start(protocol
, NULL
, &protocol_sink
, &bind_info
, 0, 0);
1464 ok(hres
== E_INVALIDARG
, "Start failed: %08x, expected E_INVALIDARG\n", hres
);
1466 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
, (void**)&priority
);
1467 ok(hres
== S_OK
, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres
);
1470 hres
= IInternetPriority_GetPriority(priority
, &p
);
1471 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
1472 ok(!p
, "p=%d\n", p
);
1474 hres
= IInternetPriority_SetPriority(priority
, 100);
1475 ok(hres
== S_OK
, "SetPriority failed: %08x\n", hres
);
1478 hres
= IInternetPriority_GetPriority(priority
, &p
);
1479 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
1480 ok(p
== 100, "p=%d\n", p
);
1482 SET_EXPECT(QueryService_InternetProtocol
);
1483 SET_EXPECT(CreateInstance
);
1484 SET_EXPECT(ReportProgress_PROTOCOLCLASSID
);
1485 SET_EXPECT(SetPriority
);
1488 expect_hrResult
= S_OK
;
1489 hres
= IInternetProtocol_Start(protocol
, test_url
, &protocol_sink
, &bind_info
, 0, 0);
1490 ok(hres
== S_OK
, "Start failed: %08x\n", hres
);
1492 CHECK_CALLED(QueryService_InternetProtocol
);
1493 CHECK_CALLED(CreateInstance
);
1494 CHECK_CALLED(ReportProgress_PROTOCOLCLASSID
);
1495 CHECK_CALLED(SetPriority
);
1496 CHECK_CALLED(Start
);
1500 hres
= IInternetProtocol_Read(protocol
, expect_pv
= buf
, sizeof(buf
), &read
);
1501 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
1502 ok(read
== 100, "read = %d\n", read
);
1507 hres
= IInternetProtocol_Read(protocol
, expect_pv
= buf
, sizeof(buf
), &read
);
1508 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
1509 ok(!read
, "read = %d\n", read
);
1513 hres
= IInternetPriority_GetPriority(priority
, &p
);
1514 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
1515 ok(p
== 100, "p=%d\n", p
);
1517 hres
= IInternetPriority_SetPriority(priority
, 101);
1518 ok(hres
== S_OK
, "SetPriority failed: %08x\n", hres
);
1520 SET_EXPECT(Terminate
);
1521 hres
= IInternetProtocol_Terminate(protocol
, 0xdeadbeef);
1522 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
1523 CHECK_CALLED(Terminate
);
1525 IInternetPriority_Release(priority
);
1526 IInternetBindInfo_Release(prot_bind_info
);
1527 IInternetProtocol_Release(protocol
);
1528 IInternetSession_Release(session
);
1531 START_TEST(protocol
)
1533 OleInitialize(NULL
);
1535 event_complete
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1537 test_file_protocol();
1538 test_http_protocol();
1540 test_CreateBinding();
1542 CloseHandle(event_complete
);