ReactOS 0.4.15-dev-7788-g1ad9096
protocol.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#define COBJMACROS
20#ifdef __REACTOS__
21#define CONST_VTABLE
22#endif
23
24#include <wine/test.h>
25#include <stdarg.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "initguid.h"
30#include "ole2.h"
31#include "urlmon.h"
32#include "shlwapi.h"
33
34#define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
36
37#define SET_EXPECT(func) \
38 expect_ ## func = TRUE
39
40#define CHECK_EXPECT(func) \
41 do { \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 expect_ ## func = FALSE; \
44 called_ ## func = TRUE; \
45 }while(0)
46
47#define SET_CALLED(func) \
48 expect_ ## func = called_ ## func = FALSE
49
50#define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 SET_CALLED(func); \
54 }while(0)
55
56DEFINE_GUID(CLSID_ITSProtocol,0x9d148291,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);
57
58DEFINE_EXPECT(GetBindInfo);
59DEFINE_EXPECT(ReportProgress_BEGINDOWNLOADDATA);
60DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
61DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
62DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
63DEFINE_EXPECT(ReportProgress_DIRECTBIND);
64DEFINE_EXPECT(ReportData);
65DEFINE_EXPECT(ReportResult);
66DEFINE_EXPECT(outer_QI_test);
67
70static DWORD bindf;
71
72static const WCHAR blank_url1[] = {'i','t','s',':',
73 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
74static const WCHAR blank_url2[] = {'m','S','-','i','T','s',':',
75 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
76static const WCHAR blank_url3[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
77 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
78static const WCHAR blank_url4[] = {'i','t','s',':',
79 't','e','s','t','.','c','h','m',':',':','b','l','a','n','k','.','h','t','m','l',0};
80static const WCHAR blank_url5[] = {'i','t','s',':',
81 't','e','s','t','.','c','h','m',':',':','\\','b','l','a','n','k','.','h','t','m','l',0};
82static const WCHAR blank_url6[] = {'i','t','s',':',
83 't','e','s','t','.','c','h','m',':',':','/','%','6','2','l','a','n','k','.','h','t','m','l',0};
84static const WCHAR blank_url7[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
85 't','e','s','t','.','c','h','m',':',':','\\','b','l','a','n','k','.','h','t','m','l',0};
86static const WCHAR blank_url8[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
87 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l','/',0};
88static const WCHAR blank_url9[] = {'i','t','s',':',
89 't','e','s','t','.','c','h','m',':',':','/','d','i','r','/','.','.','/','b','l','a','n','k','.','h','t','m','l',0};
90
91static enum {
95
96static const WCHAR cache_file1[] =
97 {'t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
98static const WCHAR cache_file2[] =
99 {'t','e','s','t','.','c','h','m',':',':','\\','b','l','a','n','k','.','h','t','m','l',0};
100static const WCHAR cache_file3[] =
101 {'t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l','/',0};
103
104static const WCHAR *a2w(const char *str)
105{
106 static WCHAR bufs[8][128];
107 static int i;
108
109 if(!str)
110 return NULL;
111
112 i = (i+1) % 8;
113 MultiByteToWideChar(CP_ACP, 0, str, -1, bufs[i], 128);
114 return bufs[i];
115}
116
117static int strcmp_wa(const WCHAR *str1, const char *str2)
118{
119 return lstrcmpW(str1, a2w(str2));
120}
121
123{
124 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
125 *ppv = iface;
126 return S_OK;
127 }
128 return E_NOINTERFACE;
129}
130
132{
133 return 2;
134}
135
137{
138 return 1;
139}
140
141static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
142{
143 ok(0, "unexpected call\n");
144 return E_NOTIMPL;
145}
146
148 LPCWSTR szStatusText)
149{
150 static const WCHAR blank_html[] = {'b','l','a','n','k','.','h','t','m','l',0};
151 static const WCHAR text_html[] = {'t','e','x','t','/','h','t','m','l',0};
152
153 switch(ulStatusCode) {
154 case BINDSTATUS_BEGINDOWNLOADDATA:
155 CHECK_EXPECT(ReportProgress_BEGINDOWNLOADDATA);
156 ok(!szStatusText, "szStatusText != NULL\n");
157 break;
158 case BINDSTATUS_SENDINGREQUEST:
159 CHECK_EXPECT(ReportProgress_SENDINGREQUEST);
161 ok(!lstrcmpW(szStatusText, blank_html), "unexpected szStatusText\n");
162 else
163 ok(szStatusText == NULL, "szStatusText != NULL\n");
164 break;
165 case BINDSTATUS_MIMETYPEAVAILABLE:
166 CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
167 ok(!lstrcmpW(szStatusText, text_html), "unexpected szStatusText\n");
168 break;
169 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
170 CHECK_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
171 ok(!lstrcmpW(szStatusText, cache_file), "unexpected szStatusText\n");
172 break;
173 case BINDSTATUS_DIRECTBIND:
174 CHECK_EXPECT(ReportProgress_DIRECTBIND);
175 ok(!szStatusText, "szStatusText != NULL\n");
176 break;
177 default:
178 ok(0, "unexpected ulStatusCode %d\n", ulStatusCode);
179 break;
180 }
181
182 return S_OK;
183}
184
186 ULONG ulProgressMax)
187{
188 CHECK_EXPECT(ReportData);
189
190 ok(ulProgress == ulProgressMax, "ulProgress != ulProgressMax\n");
192 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcf = %08x\n", grfBSCF);
193 else
194 ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION), "grcf = %08x\n", grfBSCF);
195
196 if(read_protocol) {
197 BYTE buf[100];
198 DWORD cb = 0xdeadbeef;
200
201 hres = IInternetProtocol_Read(read_protocol, buf, sizeof(buf), &cb);
202 ok(hres == S_OK, "Read failed: %08x\n", hres);
203 ok(cb == 13, "cb=%u expected 13\n", cb);
204 ok(!memcmp(buf, "<html></html>", 13), "unexpected data\n");
205 }
206
207 return S_OK;
208}
209
211 DWORD dwError, LPCWSTR szResult)
212{
213 CHECK_EXPECT(ReportResult);
214
215 ok(hrResult == expect_hrResult, "expected: %08x got: %08x\n", expect_hrResult, hrResult);
216 ok(dwError == 0, "dwError = %d\n", dwError);
217 ok(!szResult, "szResult != NULL\n");
218
219 return S_OK;
220}
221
222static IInternetProtocolSinkVtbl protocol_sink_vtbl = {
230};
231
234};
235
237{
238 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetBindInfo, riid)) {
239 *ppv = iface;
240 return S_OK;
241 }
242 return E_NOINTERFACE;
243}
244
246{
247 return 2;
248}
249
251{
252 return 1;
253}
254
255static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
256{
257 CHECK_EXPECT(GetBindInfo);
258
259 ok(grfBINDF != NULL, "grfBINDF == NULL\n");
260 if(grfBINDF)
261 ok(!*grfBINDF, "*grfBINDF != 0\n");
262 ok(pbindinfo != NULL, "pbindinfo == NULL\n");
263 ok(pbindinfo->cbSize == sizeof(BINDINFO), "wrong size of pbindinfo: %d\n", pbindinfo->cbSize);
264
265 *grfBINDF = bindf;
266 return S_OK;
267}
268
270 ULONG cEl, ULONG *pcElFetched)
271{
272 ok(0, "unexpected call\n");
273 return E_NOTIMPL;
274}
275
276static IInternetBindInfoVtbl bind_info_vtbl = {
282};
283
286};
287
289{
291
292 SET_EXPECT(GetBindInfo);
293 SET_EXPECT(ReportResult);
294
295 expect_hrResult = expected_hres;
296 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
297 ok(hres == expected_hres, "expected: %08x got: %08x\n", expected_hres, hres);
298
299 CHECK_CALLED(GetBindInfo);
300 CHECK_CALLED(ReportResult);
301}
302
303#define protocol_start(p,u,e) _protocol_start(__LINE__,p,u,e)
305{
307
308 SET_EXPECT(GetBindInfo);
310 SET_EXPECT(ReportProgress_DIRECTBIND);
311 SET_EXPECT(ReportProgress_SENDINGREQUEST);
312 if(expect_mime)
313 SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
315 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
316 SET_EXPECT(ReportData);
318 SET_EXPECT(ReportProgress_BEGINDOWNLOADDATA);
319 SET_EXPECT(ReportResult);
321
322 hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0);
323
324 if(FAILED(hres)) {
325 SET_CALLED(GetBindInfo);
327 SET_CALLED(ReportProgress_DIRECTBIND);
328 SET_CALLED(ReportProgress_SENDINGREQUEST);
329 if(expect_mime)
330 SET_CALLED(ReportProgress_MIMETYPEAVAILABLE);
332 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
333 SET_CALLED(ReportData);
335 SET_CALLED(ReportProgress_BEGINDOWNLOADDATA);
336 SET_CALLED(ReportResult);
337 }else {
338 CHECK_CALLED(GetBindInfo);
340 SET_CALLED(ReportProgress_DIRECTBIND);
341 CHECK_CALLED(ReportProgress_SENDINGREQUEST);
342 if(expect_mime)
343 CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE);
345 SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
346 CHECK_CALLED(ReportData);
348 CHECK_CALLED(ReportProgress_BEGINDOWNLOADDATA);
349 CHECK_CALLED(ReportResult);
350 }
351
352 return hres;
353}
354
356{
358 BYTE buf[512];
359 ULONG cb, ref;
361
362 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
363 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
364 if(FAILED(hres))
365 return;
366
367 hres = protocol_start(protocol, url, expect_mime);
368 if(FAILED(hres)) {
369 IInternetProtocol_Release(protocol);
370 return;
371 }
372
373 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
374 ok(hres == S_OK, "Read failed: %08x\n", hres);
375 ok(cb == 13, "cb=%u expected 13\n", cb);
376 ok(!memcmp(buf, "<html></html>", 13), "unexpected data\n");
377 ref = IInternetProtocol_Release(protocol);
378 ok(!ref, "protocol ref=%d\n", ref);
379
380 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
381 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
382 if(FAILED(hres))
383 return;
384
385 cb = 0xdeadbeef;
386 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
387 ok(hres == (test_protocol == ITS_PROTOCOL ? INET_E_DATA_NOT_AVAILABLE : E_FAIL),
388 "Read returned %08x\n", hres);
389 ok(cb == 0xdeadbeef, "cb=%u expected 0xdeadbeef\n", cb);
390
391 protocol_start(protocol, url, expect_mime);
392 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
393 ok(hres == S_OK, "Read failed: %08x\n", hres);
394 ok(cb == 2, "cb=%u expected 2\n", cb);
395 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
396 ok(hres == S_OK, "Read failed: %08x\n", hres);
397 ok(cb == 11, "cb=%u, expected 11\n", cb);
398 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
399 ok(hres == S_FALSE, "Read failed: %08x expected S_FALSE\n", hres);
400 ok(cb == 0, "cb=%u expected 0\n", cb);
401 hres = IInternetProtocol_UnlockRequest(protocol);
402 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
403 ref = IInternetProtocol_Release(protocol);
404 ok(!ref, "protocol ref=%d\n", ref);
405
406 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
407 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
408 if(FAILED(hres))
409 return;
410
411 protocol_start(protocol, url, expect_mime);
412 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
413 ok(hres == S_OK, "Read failed: %08x\n", hres);
414 hres = IInternetProtocol_LockRequest(protocol, 0);
415 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
416 hres = IInternetProtocol_UnlockRequest(protocol);
417 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
418 hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
419 ok(hres == S_OK, "Read failed: %08x\n", hres);
420 ok(cb == 11, "cb=%u, expected 11\n", cb);
421 ref = IInternetProtocol_Release(protocol);
422 ok(!ref, "protocol ref=%d\n", ref);
423
424 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
425 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
426 if(FAILED(hres))
427 return;
428
429 protocol_start(protocol, url, expect_mime);
430 hres = IInternetProtocol_LockRequest(protocol, 0);
431 ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
432 hres = IInternetProtocol_Terminate(protocol, 0);
433 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
434 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
435 ok(hres == S_OK, "Read failed: %08x\n", hres);
436 ok(cb == 2, "cb=%u, expected 2\n", cb);
437 hres = IInternetProtocol_UnlockRequest(protocol);
438 ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
439 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
440 ok(hres == S_OK, "Read failed: %08x\n", hres);
441 ok(cb == 2, "cb=%u, expected 2\n", cb);
442 hres = IInternetProtocol_Terminate(protocol, 0);
443 ok(hres == S_OK, "Terminate failed: %08x\n", hres);
444 hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
445 ok(hres == S_OK, "Read failed: %08x\n", hres);
446 ok(cb == 2, "cb=%u expected 2\n", cb);
447 ref = IInternetProtocol_Release(protocol);
448 ok(!ref, "protocol ref=%d\n", ref);
449
450 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&read_protocol);
451 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
452 if(FAILED(hres))
453 return;
454
455 protocol_start(read_protocol, url, expect_mime);
456 ref = IInternetProtocol_Release(read_protocol);
457 ok(!ref, "protocol ref=%d\n", ref);
459}
460
461static const struct {
462 const char *base_url;
463 const char *rel_url;
466 const char *combined_url;
467} combine_tests[] = {
468 {"its:test.chm::/blank.html", "its:test.chm::/blank.html", 0, STG_E_INVALIDNAME, NULL},
469 {"mS-iTs:test.chm::/blank.html", "mS-iTs:test.chm::/blank.html", 0, STG_E_INVALIDNAME, NULL},
470 {"its:test.chm::/blank.html", "test.html", 0, S_OK, "its:test.chm::/test.html"},
471 {"its:test.chm::/blank.html", "test.chm::/test.html", 0, STG_E_INVALIDNAME, NULL},
472 {"its:test.chm::/blank.html", "/test.html", 0, S_OK, "its:test.chm::/test.html"},
473 {"its:test.chm::/blank.html", "te:t.html", 0, STG_E_INVALIDNAME, NULL},
474 {"its:test.chm::/blank.html", "/test.html", URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, S_OK, "its:test.chm::/test.html"},
475 {"its:test.chm::/blank.html", "dir/test.html", 0, S_OK, "its:test.chm::/dir/test.html"},
476 {"test.html", "test.chm::/test.html", 0, 0x80041001, NULL},
477 {"its:test:.chm::/blank.html", "test.html", 0, S_OK, "its:test:.chm::/test.html"},
478 {"its:test.chm::/dir/blank.html", "test.html", 0, S_OK, "its:test.chm::/dir/test.html"},
479 {"its:test.chm::blank.html", "test.html", 0, S_OK, "its:test.chm::blank.htmltest.html"},
480 {"ms-its:test.chm::/dir/blank.html", "test.html", 0, S_OK, "ms-its:test.chm::/dir/test.html"},
481 {"mk:@MSITStore:test.chm::/dir/blank.html", "test.html", 0, S_OK, "mk:@MSITStore:test.chm::/dir/test.html"},
482 {"xxx:test.chm::/dir/blank.html", "test.html", 0, INET_E_USE_DEFAULT_PROTOCOLHANDLER, NULL},
483 {"its:test.chm::/dir/blank.html", "/test.html", 0, S_OK, "its:test.chm::/test.html"},
484 {"its:test.chm::/blank.html", "#frag", 0, S_OK, "its:test.chm::/blank.html#frag"},
485 {"its:test.chm::/blank.html#hash", "#frag", 0, S_OK, "its:test.chm::/blank.html#hash#frag"},
486 {"its:test.chm::/blank.html", "test.html#frag", 0, S_OK, "its:test.chm::/test.html#frag"},
487 {"its:test.chm::/blank.html", "/test.html#frag", 0, S_OK, "its:test.chm::/test.html#frag"},
488 {"its:test.chm::/blank.html", "?query", 0, S_OK, "its:test.chm::/?query"},
489 {"its:test.chm::/blank.html#frag/blank", "test.html", 0, S_OK, "its:test.chm::/blank.html#frag/test.html"},
491
493{
495 WCHAR buf[1024];
496 DWORD size, i;
498
499 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolInfo, (void**)&info);
500 ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08x\n", hres);
501 if(FAILED(hres))
502 return;
503
504 for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) {
505 if(i != PARSE_CANONICALIZE && i != PARSE_SECURITY_URL) {
506 hres = IInternetProtocolInfo_ParseUrl(info, blank_url1, i, 0, buf,
507 ARRAY_SIZE(buf), &size, 0);
508 ok(hres == INET_E_DEFAULT_ACTION,
509 "[%d] failed: %08x, expected INET_E_DEFAULT_ACTION\n", i, hres);
510 }
511 }
512
513 for(i=0; i < ARRAY_SIZE(combine_tests); i++) {
514 size = 0xdeadbeef;
515 memset(buf, 0xfe, sizeof(buf));
516 hres = IInternetProtocolInfo_CombineUrl(info, a2w(combine_tests[i].base_url),
518 ARRAY_SIZE(buf), &size, 0);
519 ok(hres == combine_tests[i].hres, "[%d] CombineUrl returned %08x, expected %08x\n",
522 : 0xdeadbeef), "[%d] unexpected size=%d\n", i, size);
524 ok(!strcmp_wa(buf, combine_tests[i].combined_url), "[%d] unexpected result: %s\n", i, wine_dbgstr_w(buf));
525 else
526 ok(buf[0] == 0xfefe, "buf changed\n");
527 }
528
529 size = 0xdeadbeef;
530 memset(buf, 0xfe, sizeof(buf));
531 hres = IInternetProtocolInfo_CombineUrl(info, a2w("its:test.chm::/blank.html"), a2w("test.html"), 0, buf,
532 1, &size, 0);
533 ok(hres == E_OUTOFMEMORY, "CombineUrl failed: %08x\n", hres);
534 ok(size == 25, "size=%d\n", size);
535 ok(buf[0] == 0xfefe, "buf changed\n");
536
537 IInternetProtocolInfo_Release(info);
538}
539
540static void test_its_protocol(void)
541{
544 IUnknown *unk;
545 ULONG ref;
547
548 static const WCHAR wrong_url1[] =
549 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','.','h','t','m','l',0};
550 static const WCHAR wrong_url2[] =
551 {'i','t','s',':','t','e','s','.','c','h','m',':',':','b','/','l','a','n','k','.','h','t','m','l',0};
552 static const WCHAR wrong_url3[] =
553 {'i','t','s',':','t','e','s','t','.','c','h','m','/','b','l','a','n','k','.','h','t','m','l',0};
554 static const WCHAR wrong_url4[] = {'m','k',':','@','M','S','I','T','S','t','o','r',':',
555 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
556 static const WCHAR wrong_url5[] = {'f','i','l','e',':',
557 't','e','s','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
558
560
561 hres = CoGetClassObject(&CLSID_ITSProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
562 ok(hres == S_OK ||
563 broken(hres == REGDB_E_CLASSNOTREG), /* Some W95 and NT4 */
564 "CoGetClassObject failed: %08x\n", hres);
565 if(FAILED(hres))
566 return;
567
568 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&info);
569 ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo: %08x\n", hres);
570
571 hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
572 ok(hres == S_OK, "Could not get IClassFactory interface\n");
573 if(SUCCEEDED(hres)) {
575
576 hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
577 ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
578 if(SUCCEEDED(hres)) {
580
584
585 hres = IInternetProtocol_Start(protocol, wrong_url4, &protocol_sink, &bind_info, 0, 0);
586 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER,
587 "Start failed: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres);
588
589 hres = IInternetProtocol_Start(protocol, wrong_url5, &protocol_sink, &bind_info, 0, 0);
590 ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER,
591 "Start failed: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres);
592
593 ref = IInternetProtocol_Release(protocol);
594 ok(!ref, "protocol ref=%d\n", ref);
595
604 bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
606 }
607
608 IClassFactory_Release(factory);
609 }
610
611 IUnknown_Release(unk);
612}
613
614static void test_mk_protocol(void)
615{
618
620
621 hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory,
622 (void**)&cf);
623 ok(hres == S_OK ||
624 broken(hres == REGDB_E_CLASSNOTREG), /* Some W95 and NT4 */
625 "CoGetClassObject failed: %08x\n", hres);
626 if(FAILED(hres))
627 return;
628
635
636 IClassFactory_Release(cf);
637}
638
639static BOOL create_chm(void)
640{
641 HANDLE file;
642 HRSRC src;
643 DWORD size;
644
647 ok(file != INVALID_HANDLE_VALUE, "Could not create test.chm file\n");
649 return FALSE;
650
652
655
656 return TRUE;
657}
658
659static void delete_chm(void)
660{
661 BOOL ret;
662
663 ret = DeleteFileA("test.chm");
664 ok(ret, "DeleteFileA failed: %d\n", GetLastError());
665}
666
667static const IID outer_test_iid = {0xabcabc00,0,0,{0,0,0,0,0,0,0,0x66}};
668
670{
672 CHECK_EXPECT(outer_QI_test);
673 *ppv = (IUnknown*)0xdeadbeef;
674 return S_OK;
675 }
676 ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
677 return E_NOINTERFACE;
678}
679
681{
682 return 2;
683}
684
686{
687 return 1;
688}
689
690static const IUnknownVtbl outer_vtbl = {
694};
695
697{
698 IUnknown outer = { &outer_vtbl };
700 IUnknown *unk, *unk2, *unk3;
702
703 hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&class_factory);
704 ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
705
706 hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IUnknown, (void**)&unk);
707 ok(hres == S_OK, "CreateInstance returned: %08x\n", hres);
708
709 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&unk2);
710 ok(hres == S_OK, "Could not get IInternetProtocol iface: %08x\n", hres);
711
712 SET_EXPECT(outer_QI_test);
713 hres = IUnknown_QueryInterface(unk2, &outer_test_iid, (void**)&unk3);
714 CHECK_CALLED(outer_QI_test);
715 ok(hres == S_OK, "Could not get IInternetProtocol iface: %08x\n", hres);
716 ok(unk3 == (IUnknown*)0xdeadbeef, "unexpected unk2\n");
717
718 IUnknown_Release(unk2);
719 IUnknown_Release(unk);
720
721 unk = (void*)0xdeadbeef;
722 hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IInternetProtocol, (void**)&unk);
723 ok(hres == CLASS_E_NOAGGREGATION, "CreateInstance returned: %08x\n", hres);
724 ok(!unk, "unk = %p\n", unk);
725
726 IClassFactory_Release(class_factory);
727}
728
730{
732
733 if(!create_chm())
734 return;
735
738 test_com_aggregation(&CLSID_ITSProtocol);
739
740 delete_chm();
742}
#define broken(x)
Definition: _sntprintf.h:21
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
const GUID IID_IUnknown
const GUID IID_IClassFactory
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define MultiByteToWideChar
Definition: compat.h:110
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3103
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
const GLenum * bufs
Definition: glext.h:6026
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define CREATE_ALWAYS
Definition: disk.h:72
static const WCHAR url[]
Definition: encode.c:1432
static IInternetProtocolSink protocol_sink
Definition: mimeole.c:1411
static IInternetBindInfo bind_info
Definition: mimeole.c:1273
static HRESULT _protocol_start(unsigned line, IInternetProtocol *protocol, LPCWSTR url, BOOL expect_mime)
Definition: protocol.c:304
#define SET_EXPECT(func)
Definition: protocol.c:37
static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, LPCWSTR szStatusText)
Definition: protocol.c:147
static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
Definition: protocol.c:141
const char * rel_url
Definition: protocol.c:463
static const WCHAR blank_url1[]
Definition: protocol.c:72
static int strcmp_wa(const WCHAR *str1, const char *str2)
Definition: protocol.c:117
static const IUnknownVtbl outer_vtbl
Definition: protocol.c:690
static const WCHAR blank_url3[]
Definition: protocol.c:76
DWORD flags
Definition: protocol.c:464
static enum @1659 test_protocol
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
Definition: protocol.c:250
static IInternetBindInfoVtbl bind_info_vtbl
Definition: protocol.c:276
static IInternetProtocolSinkVtbl protocol_sink_vtbl
Definition: protocol.c:222
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: protocol.c:680
HRESULT hres
Definition: protocol.c:465
static void delete_chm(void)
Definition: protocol.c:659
static const WCHAR blank_url9[]
Definition: protocol.c:88
#define CHECK_EXPECT(func)
Definition: protocol.c:40
static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
Definition: protocol.c:136
static const WCHAR blank_url2[]
Definition: protocol.c:74
static void test_its_protocol_info(IInternetProtocol *protocol)
Definition: protocol.c:492
#define DEFINE_EXPECT(func)
Definition: protocol.c:34
static const IID outer_test_iid
Definition: protocol.c:667
static const WCHAR blank_url7[]
Definition: protocol.c:84
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
Definition: protocol.c:236
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: protocol.c:255
const char * base_url
Definition: protocol.c:462
static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
Definition: protocol.c:122
static void test_mk_protocol(void)
Definition: protocol.c:614
static const WCHAR blank_url8[]
Definition: protocol.c:86
#define protocol_start(p, u, e)
Definition: protocol.c:303
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: protocol.c:669
static const WCHAR blank_url5[]
Definition: protocol.c:80
@ ITS_PROTOCOL
Definition: protocol.c:92
@ MK_PROTOCOL
Definition: protocol.c:93
static HRESULT expect_hrResult
Definition: protocol.c:68
static const WCHAR cache_file1[]
Definition: protocol.c:96
static const WCHAR cache_file3[]
Definition: protocol.c:100
static void test_protocol_url(IClassFactory *factory, LPCWSTR url, BOOL expect_mime)
Definition: protocol.c:355
const char * combined_url
Definition: protocol.c:466
static void test_com_aggregation(const CLSID *clsid)
Definition: protocol.c:696
static void test_protocol_fail(IInternetProtocol *protocol, LPCWSTR url, HRESULT expected_hres)
Definition: protocol.c:288
static BOOL create_chm(void)
Definition: protocol.c:639
#define CHECK_CALLED(func)
Definition: protocol.c:50
static DWORD bindf
Definition: protocol.c:70
static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
Definition: protocol.c:210
static const WCHAR * a2w(const char *str)
Definition: protocol.c:104
static void test_its_protocol(void)
Definition: protocol.c:540
static const struct @1660 combine_tests[]
static const WCHAR cache_file2[]
Definition: protocol.c:98
static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
Definition: protocol.c:185
static const WCHAR * cache_file
Definition: protocol.c:102
static const WCHAR blank_url4[]
Definition: protocol.c:78
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
Definition: protocol.c:269
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
Definition: protocol.c:245
#define SET_CALLED(func)
Definition: protocol.c:47
static const WCHAR blank_url6[]
Definition: protocol.c:82
static IInternetProtocol * read_protocol
Definition: protocol.c:69
static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
Definition: protocol.c:131
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: protocol.c:685
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static LPOLESTR
Definition: stg_prop.c:27
REFCLSID clsid
Definition: msctf.c:82
#define GENERIC_WRITE
Definition: nt_native.h:90
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
const WCHAR * str
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define memset(x, y, z)
Definition: compat.h:39
#define URL_DONT_ESCAPE_EXTRA_INFO
Definition: shlwapi.h:1217
#define URL_ESCAPE_SPACES_ONLY
Definition: shlwapi.h:1216
Definition: main.c:439
Definition: fci.c:127
Definition: parser.c:49
Definition: send.c:48
uint32_t ULONG
Definition: typedefs.h:59
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
#define S_FALSE
Definition: winerror.h:2357
#define STG_E_INVALIDNAME
Definition: winerror.h:2584
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_FILENOTFOUND
Definition: winerror.h:2565
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193