2 * Copyright 2005 Jacek Caban
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_EXPECT(GetBindInfo
);
58 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
59 DEFINE_EXPECT(ReportProgress_DIRECTBIND
);
60 DEFINE_EXPECT(ReportProgress_FINDINGRESOURCE
);
61 DEFINE_EXPECT(ReportProgress_CONNECTING
);
62 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST
);
63 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
64 DEFINE_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
65 DEFINE_EXPECT(ReportData
);
66 DEFINE_EXPECT(ReportResult
);
67 DEFINE_EXPECT(GetBindString_ACCEPT_MIMES
);
68 DEFINE_EXPECT(GetBindString_USER_AGENT
);
69 DEFINE_EXPECT(QueryService_HttpNegotiate
);
70 DEFINE_EXPECT(BeginningTransaction
);
71 DEFINE_EXPECT(GetRootSecurityId
);
72 DEFINE_EXPECT(OnResponse
);
73 DEFINE_EXPECT(Switch
);
75 static const WCHAR wszIndexHtml
[] = {'i','n','d','e','x','.','h','t','m','l',0};
76 static const WCHAR index_url
[] =
77 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
79 static HRESULT expect_hrResult
;
80 static LPCWSTR file_name
, http_url
;
81 static IInternetProtocol
*http_protocol
= NULL
;
82 static BOOL first_data_notif
= FALSE
;
83 static HWND protocol_hwnd
;
85 static DWORD bindf
= 0;
92 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
, REFIID riid
, void **ppv
)
94 if(IsEqualGUID(&IID_IUnknown
, riid
)
95 || IsEqualGUID(&IID_IHttpNegotiate
, riid
)
96 || IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
101 ok(0, "unexpected call\n");
102 return E_NOINTERFACE
;
105 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
110 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate2
*iface
)
115 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
, LPCWSTR szURL
,
116 LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
118 CHECK_EXPECT(BeginningTransaction
);
120 ok(!lstrcmpW(szURL
, http_url
), "szURL != http_url\n");
121 ok(!dwReserved
, "dwReserved=%d, expected 0\n", dwReserved
);
122 ok(pszAdditionalHeaders
!= NULL
, "pszAdditionalHeaders == NULL\n");
123 if(pszAdditionalHeaders
)
124 ok(*pszAdditionalHeaders
== NULL
, "*pszAdditionalHeaders != NULL\n");
129 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
130 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
, LPWSTR
*pszAdditionalRequestHeaders
)
132 CHECK_EXPECT(OnResponse
);
134 ok(dwResponseCode
== 200, "dwResponseCode=%d, expected 200\n", dwResponseCode
);
135 ok(szResponseHeaders
!= NULL
, "szResponseHeaders == NULL\n");
136 ok(szRequestHeaders
== NULL
, "szRequestHeaders != NULL\n");
137 ok(pszAdditionalRequestHeaders
== NULL
, "pszAdditionalHeaders != NULL\n");
142 static HRESULT WINAPI
HttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
143 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
145 static const BYTE sec_id
[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
147 CHECK_EXPECT(GetRootSecurityId
);
149 ok(!dwReserved
, "dwReserved=%ld, expected 0\n", dwReserved
);
150 ok(pbSecurityId
!= NULL
, "pbSecurityId == NULL\n");
151 ok(pcbSecurityId
!= NULL
, "pcbSecurityId == NULL\n");
154 ok(*pcbSecurityId
== 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId
);
155 *pcbSecurityId
= sizeof(sec_id
);
159 memcpy(pbSecurityId
, sec_id
, sizeof(sec_id
));
164 static IHttpNegotiate2Vtbl HttpNegotiateVtbl
= {
165 HttpNegotiate_QueryInterface
,
166 HttpNegotiate_AddRef
,
167 HttpNegotiate_Release
,
168 HttpNegotiate_BeginningTransaction
,
169 HttpNegotiate_OnResponse
,
170 HttpNegotiate_GetRootSecurityId
173 static IHttpNegotiate2 http_negotiate
= { &HttpNegotiateVtbl
};
175 static HRESULT
QueryInterface(REFIID
,void**);
177 static HRESULT WINAPI
ServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
179 return QueryInterface(riid
, ppv
);
182 static ULONG WINAPI
ServiceProvider_AddRef(IServiceProvider
*iface
)
187 static ULONG WINAPI
ServiceProvider_Release(IServiceProvider
*iface
)
192 static HRESULT WINAPI
ServiceProvider_QueryService(IServiceProvider
*iface
, REFGUID guidService
,
193 REFIID riid
, void **ppv
)
195 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
) || IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
196 CHECK_EXPECT2(QueryService_HttpNegotiate
);
197 return IHttpNegotiate2_QueryInterface(&http_negotiate
, riid
, ppv
);
200 ok(0, "unexpected call\n");
204 static const IServiceProviderVtbl ServiceProviderVtbl
= {
205 ServiceProvider_QueryInterface
,
206 ServiceProvider_AddRef
,
207 ServiceProvider_Release
,
208 ServiceProvider_QueryService
211 static IServiceProvider service_provider
= { &ServiceProviderVtbl
};
213 static HRESULT WINAPI
ProtocolSink_QueryInterface(IInternetProtocolSink
*iface
, REFIID riid
, void **ppv
)
215 return QueryInterface(riid
, ppv
);
218 static ULONG WINAPI
ProtocolSink_AddRef(IInternetProtocolSink
*iface
)
223 static ULONG WINAPI
ProtocolSink_Release(IInternetProtocolSink
*iface
)
228 static HRESULT WINAPI
ProtocolSink_Switch(IInternetProtocolSink
*iface
, PROTOCOLDATA
*pProtocolData
)
230 CHECK_EXPECT2(Switch
);
231 ok(pProtocolData
!= NULL
, "pProtocolData == NULL\n");
232 SendMessageW(protocol_hwnd
, WM_USER
, 0, (LPARAM
)pProtocolData
);
236 static HRESULT WINAPI
ProtocolSink_ReportProgress(IInternetProtocolSink
*iface
, ULONG ulStatusCode
,
237 LPCWSTR szStatusText
)
239 static const WCHAR text_html
[] = {'t','e','x','t','/','h','t','m','l',0};
240 static const WCHAR host
[] =
241 {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
242 static const WCHAR wszWineHQIP
[] =
243 {'2','0','9','.','4','6','.','2','5','.','1','3','4',0};
244 /* I'm not sure if it's a good idea to hardcode here the IP address... */
246 switch(ulStatusCode
) {
247 case BINDSTATUS_MIMETYPEAVAILABLE
:
248 CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
249 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
251 ok(!lstrcmpW(szStatusText
, text_html
), "szStatusText != text/html\n");
253 case BINDSTATUS_DIRECTBIND
:
254 CHECK_EXPECT2(ReportProgress_DIRECTBIND
);
255 ok(szStatusText
== NULL
, "szStatusText != NULL\n");
257 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
258 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
259 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
261 ok(!lstrcmpW(szStatusText
, file_name
), "szStatusText != file_name\n");
263 case BINDSTATUS_FINDINGRESOURCE
:
264 CHECK_EXPECT(ReportProgress_FINDINGRESOURCE
);
265 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
267 ok(!lstrcmpW(szStatusText
, host
), "szStatustext != \"www.winehq.org\"\n");
269 case BINDSTATUS_CONNECTING
:
270 CHECK_EXPECT(ReportProgress_CONNECTING
);
271 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
273 ok(!lstrcmpW(szStatusText
, wszWineHQIP
), "Unexpected szStatusText\n");
275 case BINDSTATUS_SENDINGREQUEST
:
276 CHECK_EXPECT(ReportProgress_SENDINGREQUEST
);
277 if(tested_protocol
== FILE_TEST
) {
278 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
280 ok(!*szStatusText
, "wrong szStatusText\n");
282 ok(szStatusText
== NULL
, "szStatusText != NULL\n");
285 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
286 CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
287 ok(szStatusText
!= NULL
, "szStatusText == NULL\n");
289 ok(!lstrcmpW(szStatusText
, text_html
), "szStatusText != text/html\n");
292 ok(0, "Unexpected call %d\n", ulStatusCode
);
298 static HRESULT WINAPI
ProtocolSink_ReportData(IInternetProtocolSink
*iface
, DWORD grfBSCF
,
299 ULONG ulProgress
, ULONG ulProgressMax
)
301 if(tested_protocol
== FILE_TEST
) {
302 CHECK_EXPECT2(ReportData
);
304 ok(ulProgress
== ulProgressMax
, "ulProgress (%d) != ulProgressMax (%d)\n",
305 ulProgress
, ulProgressMax
);
306 ok(ulProgressMax
== 13, "ulProgressMax=%d, expected 13\n", ulProgressMax
);
307 ok(grfBSCF
== (BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
),
308 "grcfBSCF = %08x\n", grfBSCF
);
309 }else if(tested_protocol
== HTTP_TEST
) {
310 if(!(grfBSCF
& BSCF_LASTDATANOTIFICATION
))
311 CHECK_EXPECT(ReportData
);
313 ok(ulProgress
, "ulProgress == 0\n");
315 if(first_data_notif
) {
316 ok(grfBSCF
== BSCF_FIRSTDATANOTIFICATION
, "grcfBSCF = %08x\n", grfBSCF
);
317 first_data_notif
= FALSE
;
319 ok(grfBSCF
== BSCF_INTERMEDIATEDATANOTIFICATION
320 || grfBSCF
== (BSCF_LASTDATANOTIFICATION
|BSCF_INTERMEDIATEDATANOTIFICATION
),
321 "grcfBSCF = %08x\n", grfBSCF
);
327 static HRESULT WINAPI
ProtocolSink_ReportResult(IInternetProtocolSink
*iface
, HRESULT hrResult
,
328 DWORD dwError
, LPCWSTR szResult
)
330 CHECK_EXPECT(ReportResult
);
332 ok(hrResult
== expect_hrResult
, "hrResult = %08x, expected: %08x\n",
333 hrResult
, expect_hrResult
);
334 if(SUCCEEDED(hrResult
))
335 ok(dwError
== ERROR_SUCCESS
, "dwError = %d, expected ERROR_SUCCESS\n", dwError
);
337 ok(dwError
!= ERROR_SUCCESS
, "dwError == ERROR_SUCCESS\n");
338 ok(!szResult
, "szResult != NULL\n");
343 static IInternetProtocolSinkVtbl protocol_sink_vtbl
= {
344 ProtocolSink_QueryInterface
,
346 ProtocolSink_Release
,
348 ProtocolSink_ReportProgress
,
349 ProtocolSink_ReportData
,
350 ProtocolSink_ReportResult
353 static IInternetProtocolSink protocol_sink
= { &protocol_sink_vtbl
};
355 static HRESULT
QueryInterface(REFIID riid
, void **ppv
)
359 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IInternetProtocolSink
, riid
))
360 *ppv
= &protocol_sink
;
361 if(IsEqualGUID(&IID_IServiceProvider
, riid
))
362 *ppv
= &service_provider
;
367 return E_NOINTERFACE
;
370 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
, REFIID riid
, void **ppv
)
372 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
376 return E_NOINTERFACE
;
379 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
384 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
389 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
393 CHECK_EXPECT(GetBindInfo
);
395 ok(grfBINDF
!= NULL
, "grfBINDF == NULL\n");
396 ok(pbindinfo
!= NULL
, "pbindinfo == NULL\n");
397 ok(pbindinfo
->cbSize
== sizeof(BINDINFO
), "wrong size of pbindinfo: %d\n", pbindinfo
->cbSize
);
400 cbSize
= pbindinfo
->cbSize
;
401 memset(pbindinfo
, 0, cbSize
);
402 pbindinfo
->cbSize
= cbSize
;
407 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
, ULONG ulStringType
,
408 LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
410 static const WCHAR acc_mime
[] = {'*','/','*',0};
411 static const WCHAR user_agent
[] = {'W','i','n','e',0};
413 ok(ppwzStr
!= NULL
, "ppwzStr == NULL\n");
414 ok(pcElFetched
!= NULL
, "pcElFetched == NULL\n");
416 switch(ulStringType
) {
417 case BINDSTRING_ACCEPT_MIMES
:
418 CHECK_EXPECT(GetBindString_ACCEPT_MIMES
);
419 ok(cEl
== 256, "cEl=%d, expected 256\n", cEl
);
421 ok(*pcElFetched
== 256, "*pcElFetched=%d, expected 256\n", *pcElFetched
);
425 *ppwzStr
= CoTaskMemAlloc(sizeof(acc_mime
));
426 memcpy(*ppwzStr
, acc_mime
, sizeof(acc_mime
));
429 case BINDSTRING_USER_AGENT
:
430 CHECK_EXPECT(GetBindString_USER_AGENT
);
431 ok(cEl
== 1, "cEl=%d, expected 1\n", cEl
);
433 ok(*pcElFetched
== 0, "*pcElFetch=%d, expectd 0\n", *pcElFetched
);
437 *ppwzStr
= CoTaskMemAlloc(sizeof(user_agent
));
438 memcpy(*ppwzStr
, user_agent
, sizeof(user_agent
));
442 ok(0, "unexpected call\n");
448 static IInternetBindInfoVtbl bind_info_vtbl
= {
449 BindInfo_QueryInterface
,
452 BindInfo_GetBindInfo
,
453 BindInfo_GetBindString
456 static IInternetBindInfo bind_info
= { &bind_info_vtbl
};
458 static void test_priority(IInternetProtocol
*protocol
)
460 IInternetPriority
*priority
;
464 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
,
466 ok(hres
== S_OK
, "QueryInterface(IID_IInternetPriority) failed: %08x\n", hres
);
470 hres
= IInternetPriority_GetPriority(priority
, &pr
);
471 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
472 ok(pr
== 0, "pr=%d, expected 0\n", pr
);
474 hres
= IInternetPriority_SetPriority(priority
, 1);
475 ok(hres
== S_OK
, "SetPriority failed: %08x\n", hres
);
477 hres
= IInternetPriority_GetPriority(priority
, &pr
);
478 ok(hres
== S_OK
, "GetPriority failed: %08x\n", hres
);
479 ok(pr
== 1, "pr=%d, expected 1\n", pr
);
481 IInternetPriority_Release(priority
);
484 static void file_protocol_start(IInternetProtocol
*protocol
, LPCWSTR url
, BOOL is_first
)
488 SET_EXPECT(GetBindInfo
);
489 if(!(bindf
& BINDF_FROMURLMON
))
490 SET_EXPECT(ReportProgress_DIRECTBIND
);
492 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
493 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE
);
494 if(bindf
& BINDF_FROMURLMON
)
495 SET_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
497 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
499 SET_EXPECT(ReportData
);
501 SET_EXPECT(ReportResult
);
503 expect_hrResult
= S_OK
;
505 hres
= IInternetProtocol_Start(protocol
, url
, &protocol_sink
, &bind_info
, 0, 0);
506 ok(hres
== S_OK
, "Start failed: %08x\n", hres
);
508 CHECK_CALLED(GetBindInfo
);
509 if(!(bindf
& BINDF_FROMURLMON
))
510 CHECK_CALLED(ReportProgress_DIRECTBIND
);
512 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
513 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE
);
514 if(bindf
& BINDF_FROMURLMON
)
515 CHECK_CALLED(ReportProgress_VERIFIEDMIMETYPEAVAILABLE
);
517 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE
);
519 CHECK_CALLED(ReportData
);
521 CHECK_CALLED(ReportResult
);
524 static void test_file_protocol_url(LPCWSTR url
)
526 IInternetProtocolInfo
*protocol_info
;
528 IClassFactory
*factory
;
531 hres
= CoGetClassObject(&CLSID_FileProtocol
, CLSCTX_INPROC_SERVER
, NULL
,
532 &IID_IUnknown
, (void**)&unk
);
533 ok(hres
== S_OK
, "CoGetClassObject failed: %08x\n", hres
);
537 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&protocol_info
);
538 ok(hres
== E_NOINTERFACE
,
539 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres
);
541 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)&factory
);
542 ok(hres
== S_OK
, "Could not get IClassFactory interface\n");
543 if(SUCCEEDED(hres
)) {
544 IInternetProtocol
*protocol
;
547 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
548 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
550 if(SUCCEEDED(hres
)) {
551 file_protocol_start(protocol
, url
, TRUE
);
552 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
553 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
554 ok(cb
== 2, "cb=%u expected 2\n", cb
);
555 hres
= IInternetProtocol_Read(protocol
, buf
, sizeof(buf
), &cb
);
556 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
557 hres
= IInternetProtocol_Read(protocol
, buf
, sizeof(buf
), &cb
);
558 ok(hres
== S_FALSE
, "Read failed: %08x expected S_FALSE\n", hres
);
559 ok(cb
== 0, "cb=%u expected 0\n", cb
);
560 hres
= IInternetProtocol_UnlockRequest(protocol
);
561 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
563 file_protocol_start(protocol
, url
, FALSE
);
564 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
565 ok(hres
== S_FALSE
, "Read failed: %08x\n", hres
);
566 hres
= IInternetProtocol_LockRequest(protocol
, 0);
567 ok(hres
== S_OK
, "LockRequest failed: %08x\n", hres
);
568 hres
= IInternetProtocol_UnlockRequest(protocol
);
569 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
571 IInternetProtocol_Release(protocol
);
574 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
575 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
577 if(SUCCEEDED(hres
)) {
578 file_protocol_start(protocol
, url
, TRUE
);
579 hres
= IInternetProtocol_LockRequest(protocol
, 0);
580 ok(hres
== S_OK
, "LockRequest failed: %08x\n", hres
);
581 hres
= IInternetProtocol_Terminate(protocol
, 0);
582 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
583 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
584 ok(hres
== S_OK
, "Read failed: %08x\n\n", hres
);
585 hres
= IInternetProtocol_UnlockRequest(protocol
);
586 ok(hres
== S_OK
, "UnlockRequest failed: %08x\n", hres
);
587 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
588 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
589 hres
= IInternetProtocol_Terminate(protocol
, 0);
590 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
592 IInternetProtocol_Release(protocol
);
595 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
596 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
598 if(SUCCEEDED(hres
)) {
599 file_protocol_start(protocol
, url
, TRUE
);
600 hres
= IInternetProtocol_Terminate(protocol
, 0);
601 ok(hres
== S_OK
, "Terminate failed: %08x\n", hres
);
602 hres
= IInternetProtocol_Read(protocol
, buf
, 2, &cb
);
603 ok(hres
== S_OK
, "Read failed: %08x\n", hres
);
604 ok(cb
== 2, "cb=%u expected 2\n", cb
);
606 IInternetProtocol_Release(protocol
);
609 IClassFactory_Release(factory
);
612 IUnknown_Release(unk
);
615 static void test_file_protocol_fail(void)
617 IInternetProtocol
*protocol
;
620 static const WCHAR index_url2
[] =
621 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
623 hres
= CoCreateInstance(&CLSID_FileProtocol
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
624 &IID_IInternetProtocol
, (void**)&protocol
);
625 ok(hres
== S_OK
, "CoCreateInstance failed: %08x\n", hres
);
629 SET_EXPECT(GetBindInfo
);
630 expect_hrResult
= MK_E_SYNTAX
;
631 hres
= IInternetProtocol_Start(protocol
, wszIndexHtml
, &protocol_sink
, &bind_info
, 0, 0);
632 ok(hres
== MK_E_SYNTAX
, "Start failed: %08x, expected MK_E_SYNTAX\n", hres
);
633 CHECK_CALLED(GetBindInfo
);
635 SET_EXPECT(GetBindInfo
);
636 if(!(bindf
& BINDF_FROMURLMON
))
637 SET_EXPECT(ReportProgress_DIRECTBIND
);
638 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
639 SET_EXPECT(ReportResult
);
640 expect_hrResult
= INET_E_RESOURCE_NOT_FOUND
;
641 hres
= IInternetProtocol_Start(protocol
, index_url
, &protocol_sink
, &bind_info
, 0, 0);
642 ok(hres
== INET_E_RESOURCE_NOT_FOUND
,
643 "Start failed: %08x expected INET_E_RESOURCE_NOT_FOUND\n", hres
);
644 CHECK_CALLED(GetBindInfo
);
645 if(!(bindf
& BINDF_FROMURLMON
))
646 CHECK_CALLED(ReportProgress_DIRECTBIND
);
647 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
648 CHECK_CALLED(ReportResult
);
650 IInternetProtocol_Release(protocol
);
652 hres
= CoCreateInstance(&CLSID_FileProtocol
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
653 &IID_IInternetProtocol
, (void**)&protocol
);
654 ok(hres
== S_OK
, "CoCreateInstance failed: %08x\n", hres
);
658 SET_EXPECT(GetBindInfo
);
659 if(!(bindf
& BINDF_FROMURLMON
))
660 SET_EXPECT(ReportProgress_DIRECTBIND
);
661 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
662 SET_EXPECT(ReportResult
);
663 expect_hrResult
= INET_E_RESOURCE_NOT_FOUND
;
665 hres
= IInternetProtocol_Start(protocol
, index_url2
, &protocol_sink
, &bind_info
, 0, 0);
666 ok(hres
== INET_E_RESOURCE_NOT_FOUND
,
667 "Start failed: %08x, expected INET_E_RESOURCE_NOT_FOUND\n", hres
);
668 CHECK_CALLED(GetBindInfo
);
669 if(!(bindf
& BINDF_FROMURLMON
))
670 CHECK_CALLED(ReportProgress_DIRECTBIND
);
671 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
672 CHECK_CALLED(ReportResult
);
674 IInternetProtocol_Release(protocol
);
677 static void test_file_protocol(void) {
683 static const WCHAR wszFile
[] = {'f','i','l','e',':',0};
684 static const WCHAR wszFile2
[] = {'f','i','l','e',':','/','/',0};
685 static const WCHAR wszFile3
[] = {'f','i','l','e',':','/','/','/',0};
686 static const char html_doc
[] = "<HTML></HTML>";
688 tested_protocol
= FILE_TEST
;
690 file
= CreateFileW(wszIndexHtml
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
691 FILE_ATTRIBUTE_NORMAL
, NULL
);
692 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
693 if(file
== INVALID_HANDLE_VALUE
)
695 WriteFile(file
, html_doc
, sizeof(html_doc
)-1, &size
, NULL
);
698 file_name
= wszIndexHtml
;
700 test_file_protocol_url(index_url
);
701 bindf
= BINDF_FROMURLMON
;
702 test_file_protocol_url(index_url
);
704 memcpy(buf
, wszFile
, sizeof(wszFile
));
705 len
= sizeof(wszFile
)/sizeof(WCHAR
)-1;
706 len
+= GetCurrentDirectoryW(sizeof(buf
)/sizeof(WCHAR
)-len
, buf
+len
);
708 memcpy(buf
+len
, wszIndexHtml
, sizeof(wszIndexHtml
));
710 file_name
= buf
+ sizeof(wszFile
)/sizeof(WCHAR
)-1;
712 test_file_protocol_url(buf
);
713 bindf
= BINDF_FROMURLMON
;
714 test_file_protocol_url(buf
);
716 memcpy(buf
, wszFile2
, sizeof(wszFile2
));
717 len
= sizeof(wszFile2
)/sizeof(WCHAR
)-1;
718 len
+= GetCurrentDirectoryW(sizeof(buf
)/sizeof(WCHAR
)-len
, buf
+len
);
720 memcpy(buf
+len
, wszIndexHtml
, sizeof(wszIndexHtml
));
722 file_name
= buf
+ sizeof(wszFile2
)/sizeof(WCHAR
)-1;
724 test_file_protocol_url(buf
);
725 bindf
= BINDF_FROMURLMON
;
726 test_file_protocol_url(buf
);
728 memcpy(buf
, wszFile3
, sizeof(wszFile3
));
729 len
= sizeof(wszFile3
)/sizeof(WCHAR
)-1;
730 len
+= GetCurrentDirectoryW(sizeof(buf
)/sizeof(WCHAR
)-len
, buf
+len
);
732 memcpy(buf
+len
, wszIndexHtml
, sizeof(wszIndexHtml
));
734 file_name
= buf
+ sizeof(wszFile3
)/sizeof(WCHAR
)-1;
736 test_file_protocol_url(buf
);
737 bindf
= BINDF_FROMURLMON
;
738 test_file_protocol_url(buf
);
740 DeleteFileW(wszIndexHtml
);
743 test_file_protocol_fail();
744 bindf
= BINDF_FROMURLMON
;
745 test_file_protocol_fail();
748 static BOOL
http_protocol_start(LPCWSTR url
, BOOL is_first
)
752 first_data_notif
= TRUE
;
754 SET_EXPECT(GetBindInfo
);
755 SET_EXPECT(GetBindString_USER_AGENT
);
756 SET_EXPECT(GetBindString_ACCEPT_MIMES
);
757 SET_EXPECT(QueryService_HttpNegotiate
);
758 SET_EXPECT(BeginningTransaction
);
759 SET_EXPECT(GetRootSecurityId
);
761 hres
= IInternetProtocol_Start(http_protocol
, url
, &protocol_sink
, &bind_info
, 0, 0);
763 ok(hres
== S_OK
, "Start failed: %08x\n", hres
);
768 CHECK_CALLED(GetBindInfo
);
769 CHECK_CALLED(GetBindString_USER_AGENT
);
770 CHECK_CALLED(GetBindString_ACCEPT_MIMES
);
771 CHECK_CALLED(QueryService_HttpNegotiate
);
772 CHECK_CALLED(BeginningTransaction
);
773 CHECK_CALLED(GetRootSecurityId
);
778 static void test_http_protocol_url(LPCWSTR url
)
780 IInternetProtocolInfo
*protocol_info
;
781 IClassFactory
*factory
;
787 hres
= CoGetClassObject(&CLSID_HttpProtocol
, CLSCTX_INPROC_SERVER
, NULL
,
788 &IID_IUnknown
, (void**)&unk
);
789 ok(hres
== S_OK
, "CoGetClassObject failed: %08x\n", hres
);
793 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&protocol_info
);
794 ok(hres
== E_NOINTERFACE
,
795 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
798 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)&factory
);
799 ok(hres
== S_OK
, "Could not get IClassFactory interface\n");
800 IUnknown_Release(unk
);
804 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
,
805 (void**)&http_protocol
);
806 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
807 if(SUCCEEDED(hres
)) {
812 bindf
= BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
| BINDF_PULLDATA
| BINDF_FROMURLMON
;
814 test_priority(http_protocol
);
816 SET_EXPECT(ReportProgress_FINDINGRESOURCE
);
817 SET_EXPECT(ReportProgress_CONNECTING
);
818 SET_EXPECT(ReportProgress_SENDINGREQUEST
);
820 if(!http_protocol_start(url
, TRUE
))
823 hres
= IInternetProtocol_Read(http_protocol
, buf
, 2, &cb
);
824 ok(hres
== E_PENDING
, "Read failed: %08x, expected E_PENDING\n", hres
);
825 ok(!cb
, "cb=%d, expected 0\n", cb
);
828 SET_EXPECT(ReportResult
);
829 expect_hrResult
= S_OK
;
831 GetMessageW(&msg
, NULL
, 0, 0);
833 CHECK_CALLED(Switch
);
834 CHECK_CALLED(ReportResult
);
836 IInternetProtocol_Release(http_protocol
);
839 IClassFactory_Release(factory
);
842 static void test_http_protocol(void)
844 static const WCHAR winehq_url
[] =
845 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
846 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
848 tested_protocol
= HTTP_TEST
;
849 test_http_protocol_url(winehq_url
);
853 static LRESULT WINAPI
wnd_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
860 SET_EXPECT(ReportData
);
862 CHECK_CALLED(ReportProgress_FINDINGRESOURCE
);
863 CHECK_CALLED(ReportProgress_CONNECTING
);
864 CHECK_CALLED(ReportProgress_SENDINGREQUEST
);
866 SET_EXPECT(OnResponse
);
867 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE
);
870 hres
= IInternetProtocol_Continue(http_protocol
, (PROTOCOLDATA
*)lParam
);
871 ok(hres
== S_OK
, "Continue failed: %08x\n", hres
);
873 CHECK_CALLED(ReportData
);
875 CHECK_CALLED(OnResponse
);
876 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE
);
879 do hres
= IInternetProtocol_Read(http_protocol
, buf
, sizeof(buf
), &cb
);
882 ok(hres
== S_FALSE
|| hres
== E_PENDING
, "Read failed: %08x\n", hres
);
885 PostMessageW(protocol_hwnd
, WM_USER
+1, 0, 0);
890 hres
= IInternetProtocol_LockRequest(http_protocol
, 0);
891 ok(hres
== S_OK
, "LockRequest failed: %08x\n", hres
);
893 do hres
= IInternetProtocol_Read(http_protocol
, buf
, sizeof(buf
), &cb
);
895 ok(hres
== S_FALSE
|| hres
== E_PENDING
, "Read failed: %08x\n", hres
);
899 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
902 static HWND
create_protocol_window(void)
904 static const WCHAR wszProtocolWindow
[] =
905 {'P','r','o','t','o','c','o','l','W','i','n','d','o','w',0};
906 static WNDCLASSEXW wndclass
= {
910 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
,
915 RegisterClassExW(&wndclass
);
916 return CreateWindowW(wszProtocolWindow
, wszProtocolWindow
,
917 WS_OVERLAPPEDWINDOW
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
918 CW_USEDEFAULT
, NULL
, NULL
, NULL
, NULL
);
921 static void test_mk_protocol(void)
923 IInternetProtocolInfo
*protocol_info
;
924 IInternetProtocol
*protocol
;
925 IClassFactory
*factory
;
929 hres
= CoGetClassObject(&CLSID_MkProtocol
, CLSCTX_INPROC_SERVER
, NULL
,
930 &IID_IUnknown
, (void**)&unk
);
931 ok(hres
== S_OK
, "CoGetClassObject failed: %08x\n", hres
);
933 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&protocol_info
);
934 ok(hres
== E_NOINTERFACE
,
935 "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n",
938 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)&factory
);
939 ok(hres
== S_OK
, "Could not get IClassFactory interface\n");
940 IUnknown_Release(unk
);
944 hres
= IClassFactory_CreateInstance(factory
, NULL
, &IID_IInternetProtocol
,
946 IClassFactory_Release(factory
);
947 ok(hres
== S_OK
, "Could not get IInternetProtocol: %08x\n", hres
);
949 IInternetProtocol_Release(protocol
);
956 protocol_hwnd
= create_protocol_window();
958 test_file_protocol();
959 test_http_protocol();
962 DestroyWindow(protocol_hwnd
);