ReactOS  0.4.12-dev-918-g6c6e7b8
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 
56 DEFINE_GUID(CLSID_ITSProtocol,0x9d148291,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);
57 
58 DEFINE_EXPECT(GetBindInfo);
59 DEFINE_EXPECT(ReportProgress_BEGINDOWNLOADDATA);
60 DEFINE_EXPECT(ReportProgress_SENDINGREQUEST);
61 DEFINE_EXPECT(ReportProgress_MIMETYPEAVAILABLE);
62 DEFINE_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
63 DEFINE_EXPECT(ReportProgress_DIRECTBIND);
64 DEFINE_EXPECT(ReportData);
65 DEFINE_EXPECT(ReportResult);
66 DEFINE_EXPECT(outer_QI_test);
67 
70 static DWORD bindf;
71 
72 static 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};
74 static 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};
76 static 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};
78 static 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};
80 static 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};
82 static 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};
84 static 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};
86 static 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};
88 static 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 
91 static enum {
95 
96 static const WCHAR cache_file1[] =
97  {'t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
98 static const WCHAR cache_file2[] =
99  {'t','e','s','t','.','c','h','m',':',':','\\','b','l','a','n','k','.','h','t','m','l',0};
100 static const WCHAR cache_file3[] =
101  {'t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l','/',0};
102 static const WCHAR *cache_file = cache_file1;
103 
104 static 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 
117 static 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 
141 static 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;
199  HRESULT hres;
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 
222 static 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 
255 static 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 
269 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr,
270  ULONG cEl, ULONG *pcElFetched)
271 {
272  ok(0, "unexpected call\n");
273  return E_NOTIMPL;
274 }
275 
276 static IInternetBindInfoVtbl bind_info_vtbl = {
282 };
283 
286 };
287 
289 {
290  HRESULT hres;
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 {
306  HRESULT hres;
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;
360  HRESULT hres;
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 
461 static 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"},
490 };
491 
493 {
495  WCHAR buf[1024];
496  DWORD size, i;
497  HRESULT hres;
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",
520  i, hres, combine_tests[i].hres);
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 
540 static void test_its_protocol(void)
541 {
544  IUnknown *unk;
545  ULONG ref;
546  HRESULT hres;
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 
614 static void test_mk_protocol(void)
615 {
616  IClassFactory *cf;
617  HRESULT hres;
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 
639 static BOOL create_chm(void)
640 {
641  HANDLE file;
642  HRSRC src;
643  DWORD size;
644 
645  file = CreateFileA("test.chm", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
647  ok(file != INVALID_HANDLE_VALUE, "Could not create test.chm file\n");
649  return FALSE;
650 
652 
654  CloseHandle(file);
655 
656  return TRUE;
657 }
658 
659 static void delete_chm(void)
660 {
661  BOOL ret;
662 
663  ret = DeleteFileA("test.chm");
664  ok(ret, "DeleteFileA failed: %d\n", GetLastError());
665 }
666 
667 static 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 
690 static const IUnknownVtbl outer_vtbl = {
692  outer_AddRef,
694 };
695 
696 static void test_com_aggregation(const CLSID *clsid)
697 {
698  IUnknown outer = { &outer_vtbl };
699  IClassFactory *class_factory;
700  IUnknown *unk, *unk2, *unk3;
701  HRESULT hres;
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();
741  OleUninitialize();
742 }
static IClassFactory * cf
static void test_mk_protocol(void)
Definition: protocol.c:614
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
Definition: protocol.c:122
static ULONG WINAPI ProtocolSink_AddRef(IInternetProtocolSink *iface)
Definition: protocol.c:131
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
static const WCHAR blank_url5[]
Definition: protocol.c:80
#define STG_E_INVALIDNAME
Definition: winerror.h:2584
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
const char * rel_url
Definition: protocol.c:463
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
Definition: protocol.c:210
static const WCHAR cache_file1[]
Definition: protocol.c:96
const GLenum * bufs
Definition: glext.h:6026
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static ULONG WINAPI ProtocolSink_Release(IInternetProtocolSink *iface)
Definition: protocol.c:136
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
Definition: protocol.c:250
#define CHECK_CALLED(func)
Definition: protocol.c:50
REFIID riid
Definition: precomp.h:44
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
REFIID LPVOID * ppv
Definition: atlbase.h:39
const char * base_url
Definition: protocol.c:462
#define CHECK_EXPECT(func)
Definition: protocol.c:40
const char * wine_dbgstr_guid(const GUID *guid)
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static const IUnknownVtbl outer_vtbl
Definition: protocol.c:690
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
static IInternetProtocol * read_protocol
Definition: protocol.c:69
static LPOLESTR
Definition: stg_prop.c:27
static BOOL create_chm(void)
Definition: protocol.c:639
#define E_FAIL
Definition: ddrawi.h:102
Definition: send.c:47
static void test_its_protocol(void)
Definition: protocol.c:540
static const WCHAR blank_url6[]
Definition: protocol.c:82
static IInternetProtocolSink protocol_sink
Definition: protocol.c:232
struct _test_info info[]
Definition: SetCursorPos.c:19
static void delete_chm(void)
Definition: protocol.c:659
static const WCHAR cache_file2[]
Definition: protocol.c:98
#define SET_EXPECT(func)
Definition: protocol.c:37
DWORD flags
Definition: protocol.c:464
static const WCHAR blank_url9[]
Definition: protocol.c:88
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
static enum @1591 test_protocol
static const WCHAR blank_url2[]
Definition: protocol.c:74
static const WCHAR blank_url3[]
Definition: protocol.c:76
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: main.c:440
#define GENERIC_WRITE
Definition: nt_native.h:90
GLenum GLint ref
Definition: glext.h:6028
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
#define S_FALSE
Definition: winerror.h:2357
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
const WCHAR * str
static const WCHAR * cache_file
Definition: protocol.c:102
#define protocol_start(p, u, e)
Definition: protocol.c:303
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
Definition: protocol.c:185
static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
Definition: protocol.c:269
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
Definition: parser.c:48
START_TEST(protocol)
Definition: protocol.c:729
HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3012
#define ok(value,...)
Definition: CComObject.cpp:34
static IInternetBindInfo bind_info
Definition: protocol.c:284
static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, LPCWSTR szStatusText)
Definition: protocol.c:147
static const WCHAR blank_url1[]
Definition: protocol.c:72
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: protocol.c:255
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR url[]
Definition: encode.c:1432
static HRESULT _protocol_start(unsigned line, IInternetProtocol *protocol, LPCWSTR url, BOOL expect_mime)
Definition: protocol.c:304
static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
Definition: protocol.c:141
const GUID IID_IUnknown
static int strcmp_wa(const WCHAR *str1, const char *str2)
Definition: protocol.c:117
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
static const WCHAR blank_url4[]
Definition: protocol.c:78
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR blank_url7[]
Definition: protocol.c:84
static DWORD cb
Definition: integrity.c:41
GLbitfield flags
Definition: glext.h:7161
int ret
#define STG_E_FILENOTFOUND
Definition: winerror.h:2565
static IInternetBindInfoVtbl bind_info_vtbl
Definition: protocol.c:276
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
REFCLSID clsid
Definition: msctf.c:84
unsigned char BYTE
Definition: mem.h:68
GLenum src
Definition: glext.h:6340
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define SET_CALLED(func)
Definition: protocol.c:47
static const IID outer_test_iid
Definition: protocol.c:667
#define broken(x)
Definition: _sntprintf.h:21
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
Definition: protocol.c:236
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:172
static const WCHAR * a2w(const char *str)
Definition: protocol.c:104
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
#define ARRAY_SIZE(a)
Definition: main.h:24
static HRESULT expect_hrResult
Definition: protocol.c:68
static const WCHAR cache_file3[]
Definition: protocol.c:100
#define E_NOTIMPL
Definition: ddrawi.h:99
DEFINE_GUID(CLSID_ITSProtocol, 0x9d148291, 0xb9c8, 0x11d0, 0xa4, 0xcc, 0x00, 0x00, 0xf8, 0x01, 0x49, 0xf6)
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static void test_protocol_url(IClassFactory *factory, LPCWSTR url, BOOL expect_mime)
Definition: protocol.c:355
const char * combined_url
Definition: protocol.c:466
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
#define MultiByteToWideChar
Definition: compat.h:100
static IInternetProtocolSinkVtbl protocol_sink_vtbl
Definition: protocol.c:222
static void test_com_aggregation(const CLSID *clsid)
Definition: protocol.c:696
static const struct @1592 combine_tests[]
unsigned int ULONG
Definition: retypes.h:1
static ClassFactoryImpl factory
Definition: ole_server.c:234
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: protocol.c:669
static void test_protocol_fail(IInternetProtocol *protocol, LPCWSTR url, HRESULT expected_hres)
Definition: protocol.c:288
static const WCHAR blank_url8[]
Definition: protocol.c:86
#define URL_ESCAPE_SPACES_ONLY
Definition: shlwapi.h:1216
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: protocol.c:685
static void test_its_protocol_info(IInternetProtocol *protocol)
Definition: protocol.c:492
const GUID IID_IClassFactory
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:233
#define memset(x, y, z)
Definition: compat.h:39
static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
Definition: protocol.c:245
#define DEFINE_EXPECT(func)
Definition: protocol.c:34
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: protocol.c:680
#define SUCCEEDED(hr)
Definition: intsafe.h:57
#define URL_DONT_ESCAPE_EXTRA_INFO
Definition: shlwapi.h:1217
Definition: fci.c:126
static DWORD bindf
Definition: protocol.c:70