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