2 * Copyright 2005 Jacek Caban
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <wine/test.h>
31 DEFINE_GUID(CLSID_FileProtocol, 0x79EAC9E7, 0xBAF9, 0x11CE, 0x8C,0x82, 0x00,0xAA,0x00,0x4B,0xA9,0x0B);
33 #define DEFINE_EXPECT(func) \
34 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
36 #define SET_EXPECT(func) \
37 expect_ ## func = TRUE
39 #define CHECK_EXPECT(func) \
40 ok(expect_ ##func, "unexpected call\n"); \
41 expect_ ## func = FALSE; \
42 called_ ## func = TRUE
44 #define CHECK_EXPECT2(func) \
45 ok(expect_ ##func, "unexpected call\n"); \
46 called_ ## func = TRUE
48 #define CHECK_CALLED(func) \
49 ok(called_ ## func, "expected " #func "\n"); \
50 expect_ ## func = called_ ## func = FALSE
52 DEFINE_EXPECT(GetBindInfo);
53 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
54 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
55 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
56 DEFINE_EXPECT(ReportData);
57 DEFINE_EXPECT(ReportResult);
59 static HRESULT expect_hrResult;
60 static LPCWSTR file_name;
62 static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
64 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
71 static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
76 static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
81 static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
83 ok(0, "unexpected call\n");
87 static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode,
90 static const WCHAR text_html[] = {'t','e','x','t','/','h','t','m','l',0};
92 switch(ulStatusCode) {
93 case BINDSTATUS_MIMETYPEAVAILABLE:
94 CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
96 ok(!lstrcmpW(szStatusText, text_html), "szStatusText != text/html\n");
97 case BINDSTATUS_DIRECTBIND:
98 CHECK_EXPECT2(ReportProgress_DIRECTBIND);
100 ok(!lstrcmpW(szStatusText, text_html), "szStatusText != text/html\n");
102 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
103 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
105 ok(!lstrcmpW(szStatusText, file_name), "szStatusText != file_name\n");
112 static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF,
113 ULONG ulProgress, ULONG ulProgressMax)
115 CHECK_EXPECT(ReportData);
117 ok(ulProgress == ulProgressMax, "ulProgress != ulProgressMax\n");
118 ok(ulProgressMax == 13, "ulProgressMax=%ld, expected 13\n", ulProgressMax);
119 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION),
120 "grcf = %08lx\n", grfBSCF);
125 static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult,
126 DWORD dwError, LPCWSTR szResult)
128 CHECK_EXPECT(ReportResult);
130 ok(hrResult == expect_hrResult, "hrResult = %08lx, expected: %08lx\n",
131 hrResult, expect_hrResult);
132 if(SUCCEEDED(hrResult))
133 ok(dwError == ERROR_SUCCESS, "dwError = %ld, expected ERROR_SUCCESS\n", dwError);
135 ok(dwError != ERROR_SUCCESS, "dwError == ERROR_SUCCESS\n");
136 ok(!szResult, "szResult != NULL\n");
141 static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
142 ProtocolSink_QueryInterface,
144 ProtocolSink_Release,
146 ProtocolSink_ReportProgress,
147 ProtocolSink_ReportData,
148 ProtocolSink_ReportResult
151 static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
153 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
155 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
159 return E_NOINTERFACE;
162 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
167 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
172 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
174 CHECK_EXPECT(GetBindInfo);
176 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
178 ok(!*grfBINDF, "*grfBINDF != 0\n");
179 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
180 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %ld\n", pbindinfo->cbSize);
185 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType,
186 LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
188 ok(0, "unexpected call\n");
192 static IInternetBindInfoVtbl bind_info_vtbl = {
193 BindInfo_QueryInterface,
196 BindInfo_GetBindInfo,
197 BindInfo_GetBindString
200 static IInternetBindInfo bind_info = { &bind_info_vtbl };
202 static void file_protocol_start(IInternetProtocol *protocol, LPCWSTR url, BOOL is_first)
206 SET_EXPECT(GetBindInfo);
207 SET_EXPECT(ReportProgress_DIRECTBIND);
209 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
210 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
211 SET_EXPECT(ReportResult);
213 SET_EXPECT(ReportData);
214 expect_hrResult = S_OK;
216 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
217 ok(hres == S_OK, "Start failed: %08lx\n", hres);
219 CHECK_CALLED(GetBindInfo);
220 todo_wine { CHECK_CALLED(ReportProgress_DIRECTBIND); }
222 CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
223 todo_wine { CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); }
224 CHECK_CALLED(ReportResult);
226 CHECK_CALLED(ReportData);
229 static void test_file_protocol_url(LPCWSTR url)
231 IInternetProtocolInfo *protocol_info;
233 IClassFactory *factory;
236 hres = CoGetClassObject(&CLSID_FileProtocol, CLSCTX_INPROC_SERVER, NULL,
237 &IID_IUnknown, (void**)&unk);
238 ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
242 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
243 ok(hres == E_NOINTERFACE,
244 "Could not get IInternetProtocolInfo interface: %08lx, expected E_NOINTERFACE\n", hres);
246 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
247 ok(hres == S_OK, "Could not get IClassFactory interface\n");
248 if(SUCCEEDED(hres)) {
249 IInternetProtocol *protocol;
252 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
253 ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
255 if(SUCCEEDED(hres)) {
256 file_protocol_start(protocol, url, TRUE);
257 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
258 ok(hres == S_OK, "Read failed: %08lx\n", hres);
259 ok(cb == 2, "cb=%lu expected 2\n", cb);
260 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
261 ok(hres == S_FALSE, "Read failed: %08lx\n", hres);
262 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
263 ok(hres == S_FALSE, "Read failed: %08lx expected S_FALSE\n", hres);
264 ok(cb == 0, "cb=%lu expected 0\n", cb);
265 hres = IInternetProtocol_UnlockRequest(protocol);
266 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
268 file_protocol_start(protocol, url, FALSE);
269 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
270 ok(hres == S_FALSE, "Read failed: %08lx\n", hres);
271 hres = IInternetProtocol_LockRequest(protocol, 0);
272 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
273 hres = IInternetProtocol_UnlockRequest(protocol);
274 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
276 IInternetProtocol_Release(protocol);
279 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
280 ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
282 if(SUCCEEDED(hres)) {
283 file_protocol_start(protocol, url, TRUE);
284 hres = IInternetProtocol_LockRequest(protocol, 0);
285 ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
286 hres = IInternetProtocol_Terminate(protocol, 0);
287 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
288 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
289 ok(hres == S_OK, "Read failed: %08lx\n\n", hres);
290 hres = IInternetProtocol_UnlockRequest(protocol);
291 ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
292 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
293 ok(hres == S_OK, "Read failed: %08lx\n", hres);
294 hres = IInternetProtocol_Terminate(protocol, 0);
295 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
297 IInternetProtocol_Release(protocol);
300 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
301 ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
303 if(SUCCEEDED(hres)) {
304 file_protocol_start(protocol, url, TRUE);
305 hres = IInternetProtocol_Terminate(protocol, 0);
306 ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
307 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
308 ok(hres == S_OK, "Read failed: %08lx\n", hres);
309 ok(cb == 2, "cb=%lu expected 2\n", cb);
311 IInternetProtocol_Release(protocol);
314 IClassFactory_Release(factory);
317 IUnknown_Release(unk);
320 static void test_file_protocol(void) {
321 IInternetProtocol *protocol;
327 static const WCHAR index_url[] =
328 {'f','i','l','e',':','i','n','d','e','x','.','h','t','m','l',0};
329 static const WCHAR index_url2[] =
330 {'f','i','l','e',':','/','/','i','n','d','e','x','.','h','t','m','l',0};
331 static const WCHAR wszFile[] = {'f','i','l','e',':',0};
332 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
333 static const char html_doc[] = "<HTML></HTML>";
335 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
336 FILE_ATTRIBUTE_NORMAL, NULL);
337 ok(file != NULL, "CreateFile failed\n");
340 WriteFile(file, html_doc, sizeof(html_doc)-1, NULL, NULL);
343 file_name = wszIndexHtml;
344 test_file_protocol_url(index_url);
346 memcpy(buf, wszFile, sizeof(wszFile));
347 len = sizeof(wszFile)/sizeof(WCHAR)-1;
348 len += GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR)-len, buf+len);
350 memcpy(buf+len, wszIndexHtml, sizeof(wszIndexHtml));
352 file_name = buf + sizeof(wszFile)/sizeof(WCHAR)-1;
353 test_file_protocol_url(buf);
355 DeleteFileW(wszIndexHtml);
357 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
358 &IID_IInternetProtocol, (void**)&protocol);
359 ok(hres == S_OK, "CoCreateInstance failed: %08lx\n", hres);
363 SET_EXPECT(GetBindInfo);
364 expect_hrResult = MK_E_SYNTAX;
365 hres = IInternetProtocol_Start(protocol, wszIndexHtml, &protocol_sink, &bind_info, 0, 0);
366 ok(hres == MK_E_SYNTAX, "Start failed: %08lx, expected MK_E_SYNTAX\n", hres);
367 CHECK_CALLED(GetBindInfo);
369 SET_EXPECT(GetBindInfo);
370 SET_EXPECT(ReportProgress_DIRECTBIND);
371 SET_EXPECT(ReportResult);
372 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
373 hres = IInternetProtocol_Start(protocol, index_url, &protocol_sink, &bind_info, 0, 0);
374 ok(hres == INET_E_RESOURCE_NOT_FOUND,
375 "Start failed: %08lx expected INET_E_RESOURCE_NOT_FOUND\n", hres);
376 CHECK_CALLED(GetBindInfo);
377 todo_wine { CHECK_CALLED(ReportProgress_DIRECTBIND); }
378 CHECK_CALLED(ReportResult);
380 IInternetProtocol_Release(protocol);
382 hres = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
383 &IID_IInternetProtocol, (void**)&protocol);
384 ok(hres == S_OK, "CoCreateInstance failed: %08lx\n", hres);
388 SET_EXPECT(GetBindInfo);
389 SET_EXPECT(ReportProgress_DIRECTBIND);
390 SET_EXPECT(ReportResult);
391 expect_hrResult = INET_E_RESOURCE_NOT_FOUND;
392 hres = IInternetProtocol_Start(protocol, index_url2, &protocol_sink, &bind_info, 0, 0);
393 ok(hres == INET_E_RESOURCE_NOT_FOUND,
394 "Start failed: %08lx, expected INET_E_RESOURCE_NOT_FOUND\n", hres);
395 CHECK_CALLED(GetBindInfo);
396 todo_wine { CHECK_CALLED(ReportProgress_DIRECTBIND); }
397 CHECK_CALLED(ReportResult);
399 IInternetProtocol_Release(protocol);
406 test_file_protocol();