ReactOS  0.4.14-dev-41-g31d7680
misc.c
Go to the documentation of this file.
1 /*
2  * Copyright 2005-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 #define CONST_VTABLE
21 #define NONAMELESSUNION
22 
23 #include <wine/test.h>
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdio.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "ole2.h"
31 #include "urlmon.h"
32 
33 #include "initguid.h"
34 #include "wine/heap.h"
35 
36 DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
37 
38 #define DEFINE_EXPECT(func) \
39  static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
40 
41 #define SET_EXPECT(func) \
42  expect_ ## func = TRUE
43 
44 #define CHECK_EXPECT(func) \
45  do { \
46  ok(expect_ ##func, "unexpected call " #func "\n"); \
47  expect_ ## func = FALSE; \
48  called_ ## func = TRUE; \
49  }while(0)
50 
51 #define CHECK_EXPECT2(func) \
52  do { \
53  ok(expect_ ##func, "unexpected call " #func "\n"); \
54  called_ ## func = TRUE; \
55  }while(0)
56 
57 #define CHECK_CALLED(func) \
58  do { \
59  ok(called_ ## func, "expected " #func "\n"); \
60  expect_ ## func = called_ ## func = FALSE; \
61  }while(0)
62 
63 DEFINE_EXPECT(ParseUrl);
64 DEFINE_EXPECT(QI_IInternetProtocolInfo);
65 DEFINE_EXPECT(CreateInstance);
67 
68 static HRESULT (WINAPI *pCoInternetCompareUrl)(LPCWSTR, LPCWSTR, DWORD);
69 static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD);
70 static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
71 static HRESULT (WINAPI *pCoInternetParseUrl)(LPCWSTR, PARSEACTION, DWORD, LPWSTR, DWORD, DWORD *, DWORD);
72 static HRESULT (WINAPI *pCoInternetQueryInfo)(LPCWSTR, QUERYOPTION, DWORD, LPVOID, DWORD, DWORD *, DWORD);
73 static HRESULT (WINAPI *pCopyStgMedium)(const STGMEDIUM *, STGMEDIUM *);
74 static HRESULT (WINAPI *pCopyBindInfo)(const BINDINFO *, BINDINFO *);
75 static HRESULT (WINAPI *pFindMimeFromData)(LPBC, LPCWSTR, LPVOID, DWORD, LPCWSTR,
76  DWORD, LPWSTR*, DWORD);
77 static HRESULT (WINAPI *pObtainUserAgentString)(DWORD, LPSTR, DWORD*);
78 static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
79 static HRESULT (WINAPI *pUrlMkGetSessionOption)(DWORD, LPVOID, DWORD, DWORD *, DWORD);
80 static HRESULT (WINAPI *pCompareSecurityIds)(BYTE*,DWORD,BYTE*,DWORD,DWORD);
81 static HRESULT (WINAPI *pCoInternetIsFeatureEnabled)(INTERNETFEATURELIST,DWORD);
82 static HRESULT (WINAPI *pCoInternetSetFeatureEnabled)(INTERNETFEATURELIST,DWORD,BOOL);
83 static HRESULT (WINAPI *pIEInstallScope)(DWORD*);
84 
85 static int strcmp_wa(const WCHAR *strw, const char *stra)
86 {
87  WCHAR buf[512];
88  MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
89  return lstrcmpW(strw, buf);
90 }
91 
92 static WCHAR *a2w(const char *str)
93 {
94  WCHAR *ret;
95  int len;
96 
97  if(!str)
98  return NULL;
99 
100  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
101  ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
102  MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
103 
104  return ret;
105 }
106 
107 static WCHAR *a2co(const char *str)
108 {
109  WCHAR *ret;
110  int len;
111 
112  if(!str)
113  return NULL;
114 
115  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
116  ret = CoTaskMemAlloc(len*sizeof(WCHAR));
117  MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
118 
119  return ret;
120 }
121 
122 static void test_CreateFormatEnum(void)
123 {
124  IEnumFORMATETC *fenum = NULL, *fenum2 = NULL;
125  FORMATETC fetc[5];
126  ULONG ul;
127  HRESULT hres;
128 
129  static DVTARGETDEVICE dev = {sizeof(dev),0,0,0,0,{0}};
130  static FORMATETC formatetc[] = {
131  {0,&dev,0,0,0},
132  {0,&dev,0,1,0},
133  {0,NULL,0,2,0},
134  {0,NULL,0,3,0},
135  {0,NULL,0,4,0}
136  };
137 
138  hres = CreateFormatEnumerator(0, formatetc, &fenum);
139  ok(hres == E_FAIL, "CreateFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
140  hres = CreateFormatEnumerator(0, formatetc, NULL);
141  ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
142  hres = CreateFormatEnumerator(5, formatetc, NULL);
143  ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
144 
145 
146  hres = CreateFormatEnumerator(5, formatetc, &fenum);
147  ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
148  if(FAILED(hres))
149  return;
150 
151  hres = IEnumFORMATETC_Next(fenum, 2, NULL, &ul);
152  ok(hres == E_INVALIDARG, "Next failed: %08x, expected E_INVALIDARG\n", hres);
153  ul = 100;
154  hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
155  ok(hres == S_OK, "Next failed: %08x\n", hres);
156  ok(ul == 0, "ul=%d, expected 0\n", ul);
157 
158  hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
159  ok(hres == S_OK, "Next failed: %08x\n", hres);
160  ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
161  ok(fetc[1].lindex == 1, "fetc[1].lindex=%d, expected 1\n", fetc[1].lindex);
162  ok(fetc[0].ptd == &dev, "fetc[0].ptd=%p, expected %p\n", fetc[0].ptd, &dev);
163  ok(ul == 2, "ul=%d, expected 2\n", ul);
164 
165  hres = IEnumFORMATETC_Skip(fenum, 1);
166  ok(hres == S_OK, "Skip failed: %08x\n", hres);
167 
168  hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
169  ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
170  ok(fetc[0].lindex == 3, "fetc[0].lindex=%d, expected 3\n", fetc[0].lindex);
171  ok(fetc[1].lindex == 4, "fetc[1].lindex=%d, expected 4\n", fetc[1].lindex);
172  ok(fetc[0].ptd == NULL, "fetc[0].ptd=%p, expected NULL\n", fetc[0].ptd);
173  ok(ul == 2, "ul=%d, expected 2\n", ul);
174 
175  hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
176  ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
177  ok(ul == 0, "ul=%d, expected 0\n", ul);
178  ul = 100;
179  hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
180  ok(hres == S_OK, "Next failed: %08x\n", hres);
181  ok(ul == 0, "ul=%d, expected 0\n", ul);
182 
183  hres = IEnumFORMATETC_Skip(fenum, 3);
184  ok(hres == S_FALSE, "Skip failed: %08x, expected S_FALSE\n", hres);
185 
186  hres = IEnumFORMATETC_Reset(fenum);
187  ok(hres == S_OK, "Reset failed: %08x\n", hres);
188 
189  hres = IEnumFORMATETC_Next(fenum, 5, fetc, NULL);
190  ok(hres == S_OK, "Next failed: %08x\n", hres);
191  ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
192 
193  hres = IEnumFORMATETC_Reset(fenum);
194  ok(hres == S_OK, "Reset failed: %08x\n", hres);
195 
196  hres = IEnumFORMATETC_Skip(fenum, 2);
197  ok(hres == S_OK, "Skip failed: %08x\n", hres);
198 
199  hres = IEnumFORMATETC_Clone(fenum, NULL);
200  ok(hres == E_INVALIDARG, "Clone failed: %08x, expected E_INVALIDARG\n", hres);
201 
202  hres = IEnumFORMATETC_Clone(fenum, &fenum2);
203  ok(hres == S_OK, "Clone failed: %08x\n", hres);
204 
205  if(SUCCEEDED(hres)) {
206  ok(fenum != fenum2, "fenum == fenum2\n");
207 
208  hres = IEnumFORMATETC_Next(fenum2, 2, fetc, &ul);
209  ok(hres == S_OK, "Next failed: %08x\n", hres);
210  ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
211 
212  IEnumFORMATETC_Release(fenum2);
213  }
214 
215  hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
216  ok(hres == S_OK, "Next failed: %08x\n", hres);
217  ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
218 
219  hres = IEnumFORMATETC_Skip(fenum, 1);
220  ok(hres == S_OK, "Skip failed: %08x\n", hres);
221 
222  IEnumFORMATETC_Release(fenum);
223 }
224 
226 {
227  IBindCtx *bctx = NULL;
228  IEnumFORMATETC *format = NULL, *format2 = NULL;
229  IUnknown *unk = NULL;
230  HRESULT hres;
231 
232  static FORMATETC formatetc = {0,NULL,0,0,0};
233  static WCHAR wszEnumFORMATETC[] =
234  {'_','E','n','u','m','F','O','R','M','A','T','E','T','C','_',0};
235 
236  CreateBindCtx(0, &bctx);
237 
238  hres = CreateFormatEnumerator(1, &formatetc, &format);
239  ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
240  if(FAILED(hres))
241  return;
242 
244  ok(hres == E_INVALIDARG,
245  "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
246  hres = RegisterFormatEnumerator(bctx, NULL, 0);
247  ok(hres == E_INVALIDARG,
248  "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
249 
251  ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
252 
253  hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
254  ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
255  ok(unk == (IUnknown*)format, "unk != format\n");
256 
258  ok(hres == E_INVALIDARG,
259  "RevokeFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
260 
262  ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
263 
265  ok(hres == E_FAIL, "RevokeFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
266 
267  hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
268  ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
269 
271  ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
272 
273  hres = CreateFormatEnumerator(1, &formatetc, &format2);
274  ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
275 
276  if(SUCCEEDED(hres)) {
278  ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
279 
280  IEnumFORMATETC_Release(format2);
281  }
282 
283  hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
284  ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
285 
286  IEnumFORMATETC_Release(format);
287 
289  ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
291  ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
292  hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
293  ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
294 
295  IEnumFORMATETC_Release(format);
296  IBindCtx_Release(bctx);
297 }
298 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
299  '/','b','l','a','n','k','.','h','t','m',0};
300 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
301 static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
302 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
303  '%','2','e','j','p','g',0};
304 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
305  '.','o','r','g',0};
306 static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
307 static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
308  'f','i','l','e','.','t','e','s','t',0};
309 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
310 static const WCHAR url9[] =
311  {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
312  '/','s','i','t','e','/','a','b','o','u','t',0};
313 static const WCHAR url10[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e','.','*','.',
314  'c','o','m',0};
315 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
316  '.','j','p','g',0};
317 
318 static const WCHAR path3[] = {'c',':','\\','I','n','d','e','x','.','h','t','m',0};
319 static const WCHAR path4[] = {'s','o','m','e',' ','f','i','l','e','.','j','p','g',0};
320 
321 static const WCHAR wszRes[] = {'r','e','s',0};
322 static const WCHAR wszFile[] = {'f','i','l','e',0};
323 static const WCHAR wszHttp[] = {'h','t','t','p',0};
324 static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
325 static const WCHAR wszEmpty[] = {0};
326 static const WCHAR wszGoogle[] = {'g','o','o','g','l','e','.','*','.','c','o','m',0};
327 
328 static const WCHAR wszWineHQ[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
329 static const WCHAR wszHttpWineHQ[] = {'h','t','t','p',':','/','/','w','w','w','.',
330  'w','i','n','e','h','q','.','o','r','g',0};
331 static const WCHAR wszHttpGoogle[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e',
332  '.','*','.','c','o','m',0};
333 
334 struct parse_test {
345 };
346 
347 static const struct parse_test parse_tests[] = {
355 };
356 
357 static void test_CoInternetParseUrl(void)
358 {
359  HRESULT hres;
360  DWORD size;
361  int i;
362 
363  static WCHAR buf[4096];
364 
365  memset(buf, 0xf0, sizeof(buf));
366  hres = pCoInternetParseUrl(parse_tests[0].url, PARSE_SCHEMA, 0, buf,
367  3, &size, 0);
368  ok(hres == E_POINTER, "schema failed: %08x, expected E_POINTER\n", hres);
369 
370  for(i = 0; i < ARRAY_SIZE(parse_tests); i++) {
371  memset(buf, 0xf0, sizeof(buf));
372  hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SECURITY_URL, 0, buf,
373  ARRAY_SIZE(buf), &size, 0);
374  ok(hres == parse_tests[i].secur_hres, "[%d] security url failed: %08x, expected %08x\n",
376 
377  memset(buf, 0xf0, sizeof(buf));
378  hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ENCODE, 0, buf,
379  ARRAY_SIZE(buf), &size, 0);
380  ok(hres == S_OK, "[%d] encoding failed: %08x\n", i, hres);
381  ok(size == lstrlenW(parse_tests[i].encoded_url), "[%d] wrong size\n", i);
382  ok(!lstrcmpW(parse_tests[i].encoded_url, buf), "[%d] wrong encoded url\n", i);
383 
384  memset(buf, 0xf0, sizeof(buf));
385  hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_PATH_FROM_URL, 0, buf,
386  ARRAY_SIZE(buf), &size, 0);
387  ok(hres == parse_tests[i].path_hres, "[%d] path failed: %08x, expected %08x\n",
389  if(parse_tests[i].path) {
390  ok(size == lstrlenW(parse_tests[i].path), "[%d] wrong size\n", i);
391  ok(!lstrcmpW(parse_tests[i].path, buf), "[%d] wrong path\n", i);
392  }
393 
394  memset(buf, 0xf0, sizeof(buf));
395  hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SCHEMA, 0, buf,
396  ARRAY_SIZE(buf), &size, 0);
397  ok(hres == S_OK, "[%d] schema failed: %08x\n", i, hres);
398  ok(size == lstrlenW(parse_tests[i].schema), "[%d] wrong size\n", i);
399  ok(!lstrcmpW(parse_tests[i].schema, buf), "[%d] wrong schema\n", i);
400 
401  if(memcmp(parse_tests[i].url, wszRes, 3*sizeof(WCHAR))
402  && memcmp(parse_tests[i].url, wszAbout, 5*sizeof(WCHAR))) {
403  memset(buf, 0xf0, sizeof(buf));
404  hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_DOMAIN, 0, buf,
405  ARRAY_SIZE(buf), &size, 0);
406  ok(hres == parse_tests[i].domain_hres, "[%d] domain failed: %08x\n", i, hres);
407  if(parse_tests[i].domain)
408  ok(!lstrcmpW(parse_tests[i].domain, buf), "[%d] wrong domain, received %s\n", i, wine_dbgstr_w(buf));
409  }
410 
411  memset(buf, 0xf0, sizeof(buf));
412  hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ROOTDOCUMENT, 0, buf,
413  ARRAY_SIZE(buf), &size, 0);
414  ok(hres == parse_tests[i].rootdocument_hres, "[%d] rootdocument failed: %08x\n", i, hres);
416  ok(!lstrcmpW(parse_tests[i].rootdocument, buf), "[%d] wrong rootdocument, received %s\n", i, wine_dbgstr_w(buf));
417  }
418 }
419 
420 static void test_CoInternetCompareUrl(void)
421 {
422  HRESULT hres;
423 
424  hres = pCoInternetCompareUrl(url1, url1, 0);
425  ok(hres == S_OK, "CoInternetCompareUrl failed: %08x\n", hres);
426 
427  hres = pCoInternetCompareUrl(url1, url3, 0);
428  ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
429 
430  hres = pCoInternetCompareUrl(url3, url1, 0);
431  ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
432 }
433 
434 static const struct {
437 } query_info_tests[] = {
438  {url1, 0},
439  {url2, 0},
440  {url3, 0},
441  {url4, 0},
442  {url5, 0},
443  {url6, 0},
444  {url7, 0},
445  {url8, 0}
446 };
447 
448 static void test_CoInternetQueryInfo(void)
449 {
450  BYTE buf[100];
451  DWORD cb, i;
452  HRESULT hres;
453 
454  for(i = 0; i < ARRAY_SIZE(query_info_tests); i++) {
455  cb = 0xdeadbeef;
456  memset(buf, '?', sizeof(buf));
457  hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), &cb, 0);
458  ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
459  ok(cb == sizeof(DWORD), "[%d] cb = %d\n", i, cb);
460  ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
462 
463  hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, 3, &cb, 0);
464  ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
465  hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, NULL, sizeof(buf), &cb, 0);
466  ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
467 
468  memset(buf, '?', sizeof(buf));
469  hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), NULL, 0);
470  ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
471  ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
473  }
474 }
475 
476 static const struct {
477  const char *url;
478  const char *mime;
481  const char *broken_mime;
482 } mime_tests[] = {
483  {"res://mshtml.dll/blank.htm", "text/html", S_OK},
484  {"index.htm", "text/html", S_OK},
485  {"file://c:\\Index.htm", "text/html", S_OK},
486  {"file://c:\\Index.htm?q=test", "text/html", S_OK, TRUE},
487  {"file://c:\\Index.htm#hash_part", "text/html", S_OK, TRUE},
488  {"file://c:\\Index.htm#hash_part.txt", "text/html", S_OK, FALSE, "text/plain"},
489  {"file://some%20file%2ejpg", NULL, E_FAIL},
490  {"http://www.winehq.org", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)},
491  {"about:blank", NULL, E_FAIL},
492  {"ftp://winehq.org/file.test", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)}
493 };
494 
495 static BYTE data1[] = "test data\n";
496 static BYTE data2[] = {31,'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0};
497 static BYTE data3[] = {0,0,0};
498 static BYTE data4[] = {'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0,0};
499 static BYTE data5[] = {0xa,0xa,0xa,'x',32,'x',0};
500 static BYTE data6[] = {0xfa,0xfa,0xfa,0xfa,'\n','\r','\t','x','x','x',1};
501 static BYTE data7[] = "<html>blahblah";
502 static BYTE data8[] = {'t','e','s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
503 static BYTE data9[] = {'t','e',0,'s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
504 static BYTE data10[] = "<HtmL>blahblah";
505 static BYTE data11[] = "blah<HTML>blahblah";
506 static BYTE data12[] = "blah<HTMLblahblah";
507 static BYTE data13[] = "blahHTML>blahblah";
508 static BYTE data14[] = "blah<HTMblahblah";
509 static BYTE data15[] = {0xff,0xd8};
510 static BYTE data16[] = {0xff,0xd8,'h'};
511 static BYTE data17[] = {0,0xff,0xd8};
512 static BYTE data18[] = {0xff,0xd8,'<','h','t','m','l','>'};
513 static BYTE data19[] = {'G','I','F','8','7','a'};
514 static BYTE data20[] = {'G','I','F','8','9','a'};
515 static BYTE data21[] = {'G','I','F','8','7'};
516 static BYTE data22[] = {'G','i','F','8','7','a'};
517 static BYTE data23[] = {'G','i','F','8','8','a'};
518 static BYTE data24[] = {'g','i','f','8','7','a'};
519 static BYTE data25[] = {'G','i','F','8','7','A'};
520 static BYTE data26[] = {'G','i','F','8','7','a','<','h','t','m','l','>'};
521 static BYTE data27[] = {0x30,'G','i','F','8','7','A'};
522 static BYTE data28[] = {0x42,0x4d,0x6e,0x42,0x1c,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00};
523 static BYTE data29[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x','x'};
524 static BYTE data30[] = {0x42,0x4d,'x','x','x','x',0x00,0x01,0x00,0x00,'x','x','x','x'};
525 static BYTE data31[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'<','h','t','m','l','>'};
526 static BYTE data32[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
527 static BYTE data33[] = {0x00,0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
528 static BYTE data34[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
529 static BYTE data35[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x','x','x','x',0};
530 static BYTE data36[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,'x','x'};
531 static BYTE data37[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'<','h','t','m','l','>'};
532 static BYTE data38[] = {0x00,0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
533 static BYTE data39[] = {0x4d,0x4d,0x00,0x2a,0xff};
534 static BYTE data40[] = {0x4d,0x4d,0x00,0x2a,'<','h','t','m','l','>',0};
535 static BYTE data41[] = {0x4d,0x4d,0xff};
536 static BYTE data42[] = {0x4d,0x4d};
537 static BYTE data43[] = {0x00,0x4d,0x4d,0x00};
538 static BYTE data44[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
539 static BYTE data45[] = {'R','I','F','f',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
540 static BYTE data46[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20};
541 static BYTE data47[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x21,0xff};
542 static BYTE data48[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,'<','h','t','m','l','>'};
543 static BYTE data49[] = {'R','I','F','F',0x0f,0x0f,0xf0,0xf0,'A','V','I',0x20,0xf0,0x00};
544 static BYTE data50[] = {0x00,0x00,0x01,0xb3,0xff};
545 static BYTE data51[] = {0x00,0x00,0x01,0xba,0xff};
546 static BYTE data52[] = {0x00,0x00,0x01,0xb8,0xff};
547 static BYTE data53[] = {0x00,0x00,0x01,0xba};
548 static BYTE data54[] = {0x00,0x00,0x01,0xba,'<','h','t','m','l','>'};
549 static BYTE data55[] = {0x1f,0x8b,'x'};
550 static BYTE data56[] = {0x1f};
551 static BYTE data57[] = {0x1f,0x8b,'<','h','t','m','l','>','t','e','s','t',0};
552 static BYTE data58[] = {0x1f,0x8b};
553 static BYTE data59[] = {0x50,0x4b,'x'};
554 static BYTE data60[] = {0x50,0x4b};
555 static BYTE data61[] = {0x50,0x4b,'<','h','t','m','l','>',0};
556 static BYTE data62[] = {0xca,0xfe,0xba,0xbe,'x'};
557 static BYTE data63[] = {0xca,0xfe,0xba,0xbe};
558 static BYTE data64[] = {0xca,0xfe,0xba,0xbe,'<','h','t','m','l','>',0};
559 static BYTE data65[] = {0x25,0x50,0x44,0x46,'x'};
560 static BYTE data66[] = {0x25,0x50,0x44,0x46};
561 static BYTE data67[] = {0x25,0x50,0x44,0x46,'x','<','h','t','m','l','>'};
562 static BYTE data68[] = {'M','Z','x'};
563 static BYTE data69[] = {'M','Z'};
564 static BYTE data70[] = {'M','Z','<','h','t','m','l','>',0xff};
565 static BYTE data71[] = {'{','\\','r','t','f',0};
566 static BYTE data72[] = {'{','\\','r','t','f'};
567 static BYTE data73[] = {' ','{','\\','r','t','f',' '};
568 static BYTE data74[] = {'{','\\','r','t','f','<','h','t','m','l','>',' '};
569 static BYTE data75[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E',0xff};
570 static BYTE data76[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E'};
571 static BYTE data77[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V',0xff,0xff};
572 static BYTE data78[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'<','h','t','m','l','>',0xff};
573 static BYTE data79[] = {'%','!',0xff};
574 static BYTE data80[] = {'%','!'};
575 static BYTE data81[] = {'%','!','P','S','<','h','t','m','l','>'};
576 static BYTE data82[] = {'.','s','n','d',0};
577 static BYTE data83[] = {'.','s','n','d'};
578 static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1};
579 static BYTE data85[] = {'.','S','N','D',0};
580 static BYTE data86[] = {0x49,0x49,0x2a,0xff};
581 static BYTE data87[] = {' ','<','h','e','a','d'};
582 static BYTE data88[] = {' ','<','h','e','a','d','>'};
583 static BYTE data89[] = {'\t','\r','<','h','e','a','d','>'};
584 static BYTE data90[] = {'<','H','e','A','d',' '};
585 static BYTE data91[] = {'<','?','x','m','l',' ',0};
586 static BYTE data92[] = {'a','b','c','<','?','x','m','l',' ',' '};
587 static BYTE data93[] = {'<','?','x','m','l',' ',' ','<','h','t','m','l','>'};
588 static BYTE data94[] = {'<','h','t','m','l','>','<','?','x','m','l',' ',' '};
589 static BYTE data95[] = {'{','\\','r','t','f','<','?','x','m','l',' ',' '};
590 static BYTE data96[] = {'<','?','x','m','l',' '};
591 static BYTE data97[] = "<body";
592 static BYTE data98[] = "blah<BoDyblahblah";
593 
594 static const struct {
597  const char *mime;
598  const char *mime_pjpeg;
599  const char *broken_mime;
600  const char *url;
601  const char *proposed_mime;
602 } mime_tests2[] = {
603  {data1, sizeof(data1), "text/plain"},
604  {data2, sizeof(data2), "application/octet-stream", "image/pjpeg"},
605  {data3, sizeof(data3), "application/octet-stream", "image/pjpeg"},
606  {data4, sizeof(data4), "application/octet-stream", "image/pjpeg"},
607  {data5, sizeof(data5), "text/plain"},
608  {data6, sizeof(data6), "text/plain"},
609  {data7, sizeof(data7), "text/html", "text/plain"},
610  {data8, sizeof(data8), "text/html", "text/plain"},
611  {data9, sizeof(data9), "text/html", "image/pjpeg"},
612  {data10, sizeof(data10), "text/html", "text/plain"},
613  {data11, sizeof(data11), "text/html", "text/plain"},
614  {data12, sizeof(data12), "text/html", "text/plain"},
615  {data13, sizeof(data13), "text/plain"},
616  {data14, sizeof(data14), "text/plain"},
617  {data15, sizeof(data15), "text/plain"},
618  {data16, sizeof(data16), "image/pjpeg"},
619  {data17, sizeof(data17), "application/octet-stream", "image/pjpeg"},
620  {data18, sizeof(data18), "text/html", "image/pjpeg"},
621  {data19, sizeof(data19), "image/gif"},
622  {data20, sizeof(data20), "image/gif"},
623  {data21, sizeof(data21), "text/plain"},
624  {data22, sizeof(data22), "image/gif"},
625  {data23, sizeof(data23), "text/plain"},
626  {data24, sizeof(data24), "image/gif"},
627  {data25, sizeof(data25), "image/gif"},
628  {data26, sizeof(data26), "text/html", "image/gif"},
629  {data27, sizeof(data27), "text/plain"},
630  {data28, sizeof(data28), "image/bmp"},
631  {data29, sizeof(data29), "image/bmp"},
632  {data30, sizeof(data30), "application/octet-stream", "image/pjpeg"},
633  {data31, sizeof(data31), "text/html", "image/bmp"},
634  {data32, sizeof(data32), "application/octet-stream", "image/pjpeg"},
635  {data33, sizeof(data33), "application/octet-stream", "image/pjpeg"},
636  {data34, sizeof(data34), "image/x-png"},
637  {data35, sizeof(data35), "image/x-png"},
638  {data36, sizeof(data36), "application/octet-stream", "image/pjpeg"},
639  {data37, sizeof(data37), "text/html", "image/x-png"},
640  {data38, sizeof(data38), "application/octet-stream", "image/pjpeg"},
641  {data39, sizeof(data39), "image/tiff"},
642  {data40, sizeof(data40), "text/html", "image/tiff"},
643  {data41, sizeof(data41), "text/plain", NULL, "image/tiff"},
644  {data42, sizeof(data42), "text/plain"},
645  {data43, sizeof(data43), "application/octet-stream", "image/pjpeg"},
646  {data44, sizeof(data44), "video/avi"},
647  {data45, sizeof(data45), "text/plain"},
648  {data46, sizeof(data46), "text/plain"},
649  {data47, sizeof(data47), "text/plain"},
650  {data48, sizeof(data48), "text/html", "video/avi"},
651  {data49, sizeof(data49), "video/avi"},
652  {data50, sizeof(data50), "video/mpeg"},
653  {data51, sizeof(data51), "video/mpeg"},
654  {data52, sizeof(data52), "application/octet-stream", "image/pjpeg"},
655  {data53, sizeof(data53), "application/octet-stream", "image/pjpeg", "image/x-icon"},
656  {data54, sizeof(data54), "text/html", "video/mpeg"},
657  {data55, sizeof(data55), "application/x-gzip-compressed"},
658  {data56, sizeof(data56), "text/plain"},
659  {data57, sizeof(data57), "text/html", "application/x-gzip-compressed"},
660  {data58, sizeof(data58), "application/octet-stream", "image/pjpeg"},
661  {data59, sizeof(data59), "application/x-zip-compressed"},
662  {data60, sizeof(data60), "text/plain"},
663  {data61, sizeof(data61), "text/html", "application/x-zip-compressed"},
664  {data62, sizeof(data62), "application/java"},
665  {data63, sizeof(data63), "text/plain"},
666  {data64, sizeof(data64), "text/html", "application/java"},
667  {data65, sizeof(data65), "application/pdf"},
668  {data66, sizeof(data66), "text/plain"},
669  {data67, sizeof(data67), "text/html", "application/pdf"},
670  {data68, sizeof(data68), "application/x-msdownload"},
671  {data69, sizeof(data69), "text/plain"},
672  {data70, sizeof(data70), "text/html", "application/x-msdownload"},
673  {data71, sizeof(data71), "text/richtext"},
674  {data72, sizeof(data72), "text/plain"},
675  {data73, sizeof(data73), "text/plain"},
676  {data74, sizeof(data74), "text/html", "text/richtext"},
677  {data75, sizeof(data75), "audio/wav"},
678  {data76, sizeof(data76), "text/plain"},
679  {data77, sizeof(data77), "text/plain"},
680  {data78, sizeof(data78), "text/html", "text/plain"},
681  {data79, sizeof(data79), "application/postscript"},
682  {data80, sizeof(data80), "text/plain"},
683  {data81, sizeof(data81), "text/html", "application/postscript"},
684  {data82, sizeof(data82), "audio/basic"},
685  {data83, sizeof(data83), "text/plain"},
686  {data84, sizeof(data84), "text/html", "audio/basic"},
687  {data85, sizeof(data85), "text/plain"},
688  {data86, sizeof(data86), "image/tiff", NULL, "text/plain"},
689  {data87, sizeof(data87), "text/plain"},
690  {data88, sizeof(data88), "text/html", "text/plain"},
691  {data89, sizeof(data89), "text/html", "text/plain"},
692  {data90, sizeof(data90), "text/html", "text/plain"},
693  {data91, sizeof(data91), "text/xml", "text/plain"},
694  {data92, sizeof(data92), "text/xml", "text/plain"},
695  {data93, sizeof(data93), "text/xml", "text/plain"},
696  {data94, sizeof(data94), "text/html", "text/plain"},
697  {data95, sizeof(data95), "text/xml", "text/richtext"},
698  {data96, sizeof(data96), "text/plain"},
699  {data97, sizeof(data97), "text/html", "text/plain"},
700  {data98, sizeof(data98), "text/html", "text/plain"},
701  {data1, sizeof(data1), "text/plain", NULL, NULL, "res://mshtml.dll/blank.htm"},
702  {NULL, 0, "text/html", NULL, NULL, "res://mshtml.dll/blank.htm"},
703  {data1, sizeof(data1), "text/plain", NULL, NULL, "res://mshtml.dll/blank.htm", "application/octet-stream"},
704  {data1, sizeof(data1), "text/plain", NULL, NULL, "file:some%20file%2ejpg", "application/octet-stream"},
705  {NULL, sizeof(data1), "text/html", NULL, NULL, "res://mshtml.dll/blank.htm"},
706  {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css"},
707  {data2, sizeof(data2), "text/css", NULL, NULL, "http://www.winehq.org/test.css"},
708  {data10, sizeof(data10), "text/html", NULL, NULL, "http://www.winehq.org/test.css"},
709  {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css", "text/plain"},
710  {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css", "application/octet-stream"},
711  {data1, sizeof(data1), "text/test", NULL, NULL, "http://www.winehq.org/test.css", "text/test"}
712 };
713 
714 static void test_FindMimeFromData(void)
715 {
717  HRESULT hres;
718  BYTE b;
719  int i;
720 
721  static const WCHAR app_octet_streamW[] =
722  {'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m',0};
723  static const WCHAR image_pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
724  static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
725  static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n',0};
726 
727  for(i = 0; i < ARRAY_SIZE(mime_tests); i++) {
728  mime = (LPWSTR)0xf0f0f0f0;
729  url = a2w(mime_tests[i].url);
730  hres = pFindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
731  if(mime_tests[i].mime) {
732  ok(hres == S_OK || broken(mime_tests[i].broken_failure), "[%d] FindMimeFromData failed: %08x\n", i, hres);
733  if(hres == S_OK) {
736  "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
738  }
739  }else {
740  ok(hres == E_FAIL || hres == mime_tests[i].hres,
741  "[%d] FindMimeFromData failed: %08x, expected %08x\n",
742  i, hres, mime_tests[i].hres);
743  ok(mime == (LPWSTR)0xf0f0f0f0, "[%d] mime != 0xf0f0f0f0\n", i);
744  }
745 
746  mime = (LPWSTR)0xf0f0f0f0;
747  hres = pFindMimeFromData(NULL, url, NULL, 0, text_plainW, 0, &mime, 0);
748  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
749  ok(!strcmp_wa(mime, "text/plain"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
751 
752  mime = (LPWSTR)0xf0f0f0f0;
753  hres = pFindMimeFromData(NULL, url, NULL, 0, app_octet_streamW, 0, &mime, 0);
754  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
755  ok(!strcmp_wa(mime, "application/octet-stream"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
757  heap_free(url);
758  }
759 
760  for(i = 0; i < ARRAY_SIZE(mime_tests2); i++) {
761  url = a2w(mime_tests2[i].url);
763  hres = pFindMimeFromData(NULL, url, mime_tests2[i].data, mime_tests2[i].size,
764  proposed_mime, 0, &mime, 0);
765  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
768  "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
770  heap_free(url);
772  if(!b || url || proposed_mime)
773  continue;
774 
775  hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
776  app_octet_streamW, 0, &mime, 0);
777  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
780  "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
782 
783  hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
784  text_plainW, 0, &mime, 0);
785  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
788  "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
790 
791  hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
792  text_htmlW, 0, &mime, 0);
793  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
794  if(!strcmp("application/octet-stream", mime_tests2[i].mime)
795  || !strcmp("text/plain", mime_tests2[i].mime) || i==92)
796  ok(!strcmp_wa(mime, "text/html"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
797  else
798  ok(!strcmp_wa(mime, mime_tests2[i].mime), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
800 
801  hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
802  image_pjpegW, 0, &mime, 0);
803  ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
806  "[%d] wrong mime, got %s\n", i, wine_dbgstr_w(mime));
808  }
809 
810  hres = pFindMimeFromData(NULL, NULL, NULL, 0, NULL, 0, &mime, 0);
811  ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
812 
813  hres = pFindMimeFromData(NULL, NULL, NULL, 0, text_plainW, 0, &mime, 0);
814  ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
815 
816  hres = pFindMimeFromData(NULL, NULL, data1, 0, NULL, 0, &mime, 0);
817  ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
818 
819  hres = pFindMimeFromData(NULL, url1, data1, 0, NULL, 0, &mime, 0);
820  ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
821 
822  hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, &mime, 0);
823  ok(hres == S_OK, "FindMimeFromData failed: %08x\n", hres);
824  ok(!strcmp_wa(mime, "text/plain"), "wrong mime: %s\n", wine_dbgstr_w(mime));
826 
827  hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, NULL, 0);
828  ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
829 }
830 
831 static void register_protocols(void)
832 {
833  IInternetSession *session;
835  HRESULT hres;
836 
837  static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
838 
839  hres = pCoInternetGetSession(0, &session, 0);
840  ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
841  if(FAILED(hres))
842  return;
843 
844  hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL,
845  &IID_IClassFactory, (void**)&factory);
846  ok(hres == S_OK, "Could not get AboutProtocol factory: %08x\n", hres);
847  if(FAILED(hres))
848  return;
849 
850  IInternetSession_RegisterNameSpace(session, factory, &CLSID_AboutProtocol,
851  wszAbout, 0, NULL, 0);
852  IClassFactory_Release(factory);
853 
854  IInternetSession_Release(session);
855 }
856 
858  REFIID riid, void **ppv)
859 {
860  ok(0, "unexpected call\n");
861  return E_NOINTERFACE;
862 }
863 
865 {
866  return 2;
867 }
868 
870 {
871  return 1;
872 }
873 
875  PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
876  DWORD *pcchResult, DWORD dwReserved)
877 {
878  CHECK_EXPECT2(ParseUrl);
879 
880  if(ParseAction == PARSE_SECURITY_URL) {
881  if(pcchResult)
882  *pcchResult = ARRAY_SIZE(url1);
883 
884  if(cchResult < ARRAY_SIZE(url1))
885  return S_FALSE;
886 
887  memcpy(pwzResult, url1, sizeof(url1));
888  return S_OK;
889  }
890 
891  return E_NOTIMPL;
892 }
893 
895  LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
896  LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
897 {
898  ok(0, "unexpected call\n");
899  return E_NOTIMPL;
900 }
901 
903  LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
904 {
905  ok(0, "unexpected call\n");
906  return E_NOTIMPL;
907 }
908 
910  LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
911  DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
912 {
913  ok(0, "unexpected call\n");
914  return E_NOTIMPL;
915 }
916 
917 static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
925 };
926 
928 
929 static HRESULT qiret;
931 
933 {
934  if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
935  CHECK_EXPECT2(QI_IInternetProtocolInfo);
936  ok(iface == expect_cf, "unexpected iface\n");
937  *ppv = &protocol_info;
938  return qiret;
939  }
940 
941  ok(0, "unexpected call\n");
942  return E_NOINTERFACE;
943 }
944 
946 {
947  return 2;
948 }
949 
951 {
952  return 1;
953 }
954 
956  REFIID riid, void **ppv)
957 {
958  ok(0, "unexpected call\n");
959  return E_NOTIMPL;
960 }
961 
963  REFIID riid, void **ppv)
964 {
965  CHECK_EXPECT(CreateInstance);
966 
967  ok(iface == expect_cf, "unexpected iface\n");
968  ok(pOuter == NULL, "pOuter = %p\n", pOuter);
969  ok(IsEqualGUID(&IID_IInternetProtocolInfo, riid), "unexpected riid\n");
970  ok(ppv != NULL, "ppv == NULL\n");
971 
972  *ppv = &protocol_info;
973  return S_OK;
974 }
975 
977 {
978  ok(0, "unexpected call\n");
979  return S_OK;
980 }
981 
982 static const IClassFactoryVtbl ClassFactoryVtbl = {
988 };
989 
990 static const IClassFactoryVtbl ProtocolCFVtbl = {
996 };
997 
1001 
1002 static void test_NameSpace(void)
1003 {
1004  IInternetSession *session;
1005  WCHAR buf[200];
1006  LPWSTR sec_url;
1007  DWORD size;
1008  HRESULT hres;
1009 
1010  static const WCHAR wszTest[] = {'t','e','s','t',0};
1011 
1012  hres = pCoInternetGetSession(0, &session, 0);
1013  ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1014  if(FAILED(hres))
1015  return;
1016 
1017  hres = IInternetSession_RegisterNameSpace(session, NULL, &IID_NULL,
1018  wszTest, 0, NULL, 0);
1019  ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1020 
1021  hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1022  NULL, 0, NULL, 0);
1023  ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1024 
1025  hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1026  wszTest, 0, NULL, 0);
1027  ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1028 
1029  qiret = E_NOINTERFACE;
1031  SET_EXPECT(QI_IInternetProtocolInfo);
1032  SET_EXPECT(CreateInstance);
1033  SET_EXPECT(ParseUrl);
1034 
1035  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1036  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1037 
1038  CHECK_CALLED(QI_IInternetProtocolInfo);
1039  CHECK_CALLED(CreateInstance);
1040  CHECK_CALLED(ParseUrl);
1041 
1042  qiret = S_OK;
1043  SET_EXPECT(QI_IInternetProtocolInfo);
1044  SET_EXPECT(ParseUrl);
1045 
1046  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1047  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1048 
1049  CHECK_CALLED(QI_IInternetProtocolInfo);
1050  CHECK_CALLED(ParseUrl);
1051 
1052  SET_EXPECT(QI_IInternetProtocolInfo);
1053  SET_EXPECT(ParseUrl);
1054 
1055  hres = pCoInternetParseUrl(url8, PARSE_SECURITY_URL, 0, buf, ARRAY_SIZE(buf), &size, 0);
1056  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1057  ok(size == ARRAY_SIZE(url1), "Size = %d\n", size);
1058  if(size == ARRAY_SIZE(url1))
1059  ok(!memcmp(buf, url1, sizeof(url1)), "Encoded url = %s\n", wine_dbgstr_w(buf));
1060 
1061  CHECK_CALLED(QI_IInternetProtocolInfo);
1062  CHECK_CALLED(ParseUrl);
1063 
1064  SET_EXPECT(QI_IInternetProtocolInfo);
1065  SET_EXPECT(ParseUrl);
1066 
1067  if (pCoInternetGetSecurityUrl) {
1068  hres = pCoInternetGetSecurityUrl(url8, &sec_url, PSU_SECURITY_URL_ONLY, 0);
1069  ok(hres == S_OK, "CoInternetGetSecurityUrl failed: %08x\n", hres);
1070  if(hres == S_OK) {
1071  ok(lstrlenW(sec_url) > ARRAY_SIZE(wszFile) &&
1072  !memcmp(sec_url, wszFile, sizeof(wszFile)-sizeof(WCHAR)),
1073  "Encoded url = %s\n", wine_dbgstr_w(sec_url));
1074  CoTaskMemFree(sec_url);
1075  }
1076 
1077  CHECK_CALLED(QI_IInternetProtocolInfo);
1078  CHECK_CALLED(ParseUrl);
1079  }
1080 
1081  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1082  ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1083 
1084  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1085  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1086 
1087  hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf2, &IID_NULL,
1088  wszTest, 0, NULL, 0);
1089  ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1090 
1091  hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1092  wszTest, 0, NULL, 0);
1093  ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1094 
1095  hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1096  wszTest, 0, NULL, 0);
1097  ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1098 
1099  SET_EXPECT(QI_IInternetProtocolInfo);
1100  SET_EXPECT(ParseUrl);
1101 
1102  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1103  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1104 
1105  CHECK_CALLED(QI_IInternetProtocolInfo);
1106  CHECK_CALLED(ParseUrl);
1107 
1108  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1109  ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1110 
1111  SET_EXPECT(QI_IInternetProtocolInfo);
1112  SET_EXPECT(ParseUrl);
1113 
1114  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1115  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1116 
1117  CHECK_CALLED(QI_IInternetProtocolInfo);
1118  CHECK_CALLED(ParseUrl);
1119 
1120  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1121  ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1122 
1124  SET_EXPECT(QI_IInternetProtocolInfo);
1125  SET_EXPECT(ParseUrl);
1126 
1127  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1128  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1129 
1130  CHECK_CALLED(QI_IInternetProtocolInfo);
1131  CHECK_CALLED(ParseUrl);
1132 
1133  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1134  ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1135  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1136  ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1137  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, NULL);
1138  ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1139  hres = IInternetSession_UnregisterNameSpace(session, NULL, wszTest);
1140  ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1141 
1142  hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf2, wszTest);
1143  ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1144 
1145  hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1146  ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1147 
1148  IInternetSession_Release(session);
1149 }
1150 
1151 static void test_MimeFilter(void)
1152 {
1153  IInternetSession *session;
1154  HRESULT hres;
1155 
1156  static const WCHAR mimeW[] = {'t','e','s','t','/','m','i','m','e',0};
1157 
1158  hres = pCoInternetGetSession(0, &session, 0);
1159  ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1160  if(FAILED(hres))
1161  return;
1162 
1163  hres = IInternetSession_RegisterMimeFilter(session, &test_cf, &IID_NULL, mimeW);
1164  ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
1165 
1166  hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1167  ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1168 
1169  hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1170  ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1171 
1172  hres = IInternetSession_UnregisterMimeFilter(session, (void*)0xdeadbeef, mimeW);
1173  ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1174 
1175  IInternetSession_Release(session);
1176 }
1177 
1179 {
1181  return 0;
1182 }
1183 
1184 static const IUnknownVtbl unk_vtbl = {
1185  (void*)0xdeadbeef,
1186  (void*)0xdeadbeef,
1187  unk_Release
1188 };
1189 
1190 static void test_ReleaseBindInfo(void)
1191 {
1192  BINDINFO bi;
1193  IUnknown unk = { &unk_vtbl };
1194 
1195  pReleaseBindInfo(NULL); /* shouldn't crash */
1196 
1197  memset(&bi, 0, sizeof(bi));
1198  bi.cbSize = sizeof(BINDINFO);
1199  bi.pUnk = &unk;
1201  pReleaseBindInfo(&bi);
1202  ok(bi.cbSize == sizeof(BINDINFO), "bi.cbSize=%d\n", bi.cbSize);
1203  ok(bi.pUnk == NULL, "bi.pUnk=%p, expected NULL\n", bi.pUnk);
1205 
1206  memset(&bi, 0, sizeof(bi));
1207  bi.cbSize = offsetof(BINDINFO, pUnk);
1208  bi.pUnk = &unk;
1209  pReleaseBindInfo(&bi);
1210  ok(bi.cbSize == offsetof(BINDINFO, pUnk), "bi.cbSize=%d\n", bi.cbSize);
1211  ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1212 
1213  memset(&bi, 0, sizeof(bi));
1214  bi.pUnk = &unk;
1215  pReleaseBindInfo(&bi);
1216  ok(!bi.cbSize, "bi.cbSize=%d, expected 0\n", bi.cbSize);
1217  ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1218 }
1219 
1220 static void test_CopyStgMedium(void)
1221 {
1222  STGMEDIUM src, dst;
1223  HGLOBAL empty, hg;
1224  char *ptr1, *ptr2;
1225  HRESULT hres;
1226  int size;
1227 
1228  static WCHAR fileW[] = {'f','i','l','e',0};
1229 
1230  memset(&src, 0xf0, sizeof(src));
1231  memset(&dst, 0xe0, sizeof(dst));
1232  memset(&empty, 0xf0, sizeof(empty));
1233  src.tymed = TYMED_NULL;
1234  src.pUnkForRelease = NULL;
1235  hres = pCopyStgMedium(&src, &dst);
1236  ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1237  ok(dst.tymed == TYMED_NULL, "tymed=%d\n", dst.tymed);
1238  ok(dst.u.hGlobal == empty, "u=%p\n", dst.u.hGlobal);
1239  ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1240 
1241  memset(&dst, 0xe0, sizeof(dst));
1242  src.tymed = TYMED_ISTREAM;
1243  src.u.pstm = NULL;
1244  src.pUnkForRelease = NULL;
1245  hres = pCopyStgMedium(&src, &dst);
1246  ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1247  ok(dst.tymed == TYMED_ISTREAM, "tymed=%d\n", dst.tymed);
1248  ok(!dst.u.pstm, "pstm=%p\n", dst.u.pstm);
1249  ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1250 
1251  memset(&dst, 0xe0, sizeof(dst));
1252  src.tymed = TYMED_FILE;
1253  src.u.lpszFileName = fileW;
1254  src.pUnkForRelease = NULL;
1255  hres = pCopyStgMedium(&src, &dst);
1256  ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1257  ok(dst.tymed == TYMED_FILE, "tymed=%d\n", dst.tymed);
1258  ok(dst.u.lpszFileName && dst.u.lpszFileName != fileW, "lpszFileName=%p\n", dst.u.lpszFileName);
1259  ok(!lstrcmpW(dst.u.lpszFileName, fileW), "wrong file name\n");
1260  ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1262 
1263  /* TYMED_HGLOBAL */
1264  hg = GlobalAlloc(GMEM_MOVEABLE, 10);
1265  ptr1 = GlobalLock(hg);
1266  memset(ptr1, 0xfa, 10);
1267  memset(&dst, 0xe0, sizeof(dst));
1268  src.tymed = TYMED_HGLOBAL;
1269  src.u.hGlobal = hg;
1270  hres = pCopyStgMedium(&src, &dst);
1271  ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1272  ok(dst.tymed == TYMED_HGLOBAL, "tymed=%d\n", dst.tymed);
1273  ok(dst.u.hGlobal != hg, "got %p, %p\n", dst.u.hGlobal, hg);
1274  size = GlobalSize(dst.u.hGlobal);
1275  ok(size == 10, "got size %d\n", size);
1276  /* compare contents */
1277  ptr2 = GlobalLock(dst.u.hGlobal);
1278  ok(!memcmp(ptr1, ptr2, 10), "got wrong data\n");
1279  GlobalUnlock(ptr2);
1280  GlobalUnlock(ptr1);
1281  ok(GlobalFlags(dst.u.hGlobal) == 0, "got 0x%08x\n", GlobalFlags(dst.u.hGlobal));
1282  GlobalFree(hg);
1284 
1285  memset(&dst, 0xe0, sizeof(dst));
1286  src.tymed = TYMED_HGLOBAL;
1287  src.u.hGlobal = NULL;
1288  hres = pCopyStgMedium(&src, &dst);
1289  ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1290  ok(dst.u.hGlobal == NULL, "got %p\n", dst.u.hGlobal);
1291 
1292  hres = pCopyStgMedium(&src, NULL);
1293  ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1294  hres = pCopyStgMedium(NULL, &dst);
1295  ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1296 }
1297 
1298 static void test_CopyBindInfo(void)
1299 {
1300  BINDINFO src[2], dest[2];
1301  SECURITY_DESCRIPTOR sec_desc;
1302  HRESULT hres;
1303  int i;
1304 
1305  hres = pCopyBindInfo(NULL, NULL);
1306  ok(hres == E_POINTER, "CopyBindInfo returned %08x, expected E_POINTER\n", hres);
1307 
1308  memset(src, 0, sizeof(BINDINFO[2]));
1309  memset(dest, 0xde, sizeof(BINDINFO[2]));
1310  hres = pCopyBindInfo(src, dest);
1311  ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1312 
1313  memset(src, 0, sizeof(BINDINFO[2]));
1314  memset(dest, 0xde, sizeof(BINDINFO[2]));
1315  src[0].cbSize = sizeof(BINDINFO);
1316  dest[0].cbSize = 0;
1317  hres = pCopyBindInfo(src, dest);
1318  ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1319 
1320  memset(src, 0, sizeof(BINDINFO[2]));
1321  memset(dest, 0xde, sizeof(BINDINFO[2]));
1322  src[0].cbSize = 1;
1323  dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1324  hres = pCopyBindInfo(src, dest);
1325  ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1326  ok(dest[0].cbSize == sizeof(BINDINFO)+sizeof(DWORD), "incorrect cbSize: %d\n", dest[0].cbSize);
1327  for(i=1; i<dest[0].cbSize/sizeof(int); i++)
1328  ok(((int*)dest)[i] == 0, "unset values should be set to 0, got %d on %d\n", ((int*)dest)[i], i);
1329 
1330  memset(src, 0, sizeof(BINDINFO[2]));
1331  memset(dest, 0xde, sizeof(BINDINFO[2]));
1332  src[0].cbSize = sizeof(BINDINFO)+2*sizeof(DWORD);
1333  dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1334  hres = pCopyBindInfo(src, dest);
1335  ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1336  ok(dest[1].cbSize == src[1].cbSize, "additional data should be copied\n");
1337  ok(dest[1].szExtraInfo != src[1].szExtraInfo,
1338  "data not fitting in destination buffer should not be copied\n");
1339 
1340  memset(src, 0xf0, sizeof(BINDINFO[2]));
1341  memset(dest, 0xde, sizeof(BINDINFO[2]));
1342  src[0].cbSize = sizeof(BINDINFO);
1343  src[0].szExtraInfo = CoTaskMemAlloc(sizeof(WCHAR));
1344  src[0].szExtraInfo[0] = 0;
1345  src[0].szCustomVerb = NULL;
1346  src[0].pUnk = NULL;
1347  src[0].stgmedData.tymed = TYMED_NULL;
1348  src[0].stgmedData.pUnkForRelease = NULL;
1349  dest[0].cbSize = sizeof(BINDINFO);
1350  hres = pCopyBindInfo(src, dest);
1351  ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1352 
1353  ok(dest[0].cbSize == sizeof(BINDINFO), "incorrect cbSize: %d\n", dest[0].cbSize);
1354  ok(dest[0].szExtraInfo && !dest[0].szExtraInfo[0] && dest[0].szExtraInfo!=src[0].szExtraInfo,
1355  "incorrect szExtraInfo: (%p!=%p) %d\n", dest[0].szExtraInfo,
1356  src[0].szExtraInfo, dest[0].szExtraInfo[0]);
1357  ok(!memcmp(&dest[0].stgmedData, &src[0].stgmedData, sizeof(STGMEDIUM)),
1358  "incorrect stgmedData value\n");
1359  ok(src[0].grfBindInfoF == dest[0].grfBindInfoF, "grfBindInfoF = %x, expected %x\n",
1360  dest[0].grfBindInfoF, src[0].grfBindInfoF);
1361  ok(src[0].dwBindVerb == dest[0].dwBindVerb, "dwBindVerb = %x, expected %x\n",
1362  dest[0].dwBindVerb, src[0].dwBindVerb);
1363  ok(!dest[0].szCustomVerb, "szCustmoVerb != NULL\n");
1364  ok(src[0].cbstgmedData == dest[0].cbstgmedData, "cbstgmedData = %x, expected %x\n",
1365  dest[0].cbstgmedData, src[0].cbstgmedData);
1366  ok(src[0].dwOptions == dest[0].dwOptions, "dwOptions = %x, expected %x\n",
1367  dest[0].dwOptions, src[0].dwOptions);
1368  ok(src[0].dwOptionsFlags == dest[0].dwOptionsFlags, "dwOptionsFlags = %x, expected %x\n",
1369  dest[0].dwOptionsFlags, src[0].dwOptionsFlags);
1370  ok(src[0].dwCodePage == dest[0].dwCodePage, "dwCodePage = %x, expected %x\n",
1371  dest[0].dwCodePage, src[0].dwCodePage);
1372  ok(!dest[0].securityAttributes.nLength,
1373  "unexpected securityAttributes.nLength value: %d\n",
1374  dest[0].securityAttributes.nLength);
1375  ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1376  "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1377  dest[0].securityAttributes.lpSecurityDescriptor);
1378  ok(!dest[0].securityAttributes.bInheritHandle,
1379  "unexpected securityAttributes.bInheritHandle value: %d\n",
1380  dest[0].securityAttributes.bInheritHandle);
1381  ok(!memcmp(&dest[0].iid, &src[0].iid, sizeof(IID)),
1382  "incorrect iid value\n");
1383  ok(!dest[0].pUnk, "pUnk != NULL\n");
1384  ok(src[0].dwReserved == dest[0].dwReserved, "dwReserved = %x, expected %x\n",
1385  dest[0].dwReserved, src[0].dwReserved);
1386 
1387  CoTaskMemFree(src[0].szExtraInfo);
1388  CoTaskMemFree(dest[0].szExtraInfo);
1389 
1390  src[0].szExtraInfo = NULL;
1391  src[0].securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
1393  "InitializeSecurityDescriptor failed\n");
1394  src[0].securityAttributes.lpSecurityDescriptor = (void*)&sec_desc;
1395  src[0].securityAttributes.bInheritHandle = TRUE;
1396  hres = pCopyBindInfo(src, dest);
1397  ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1398  ok(!dest[0].securityAttributes.nLength,
1399  "unexpected securityAttributes.nLength value: %d\n",
1400  dest[0].securityAttributes.nLength);
1401  ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1402  "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1403  dest[0].securityAttributes.lpSecurityDescriptor);
1404  ok(!dest[0].securityAttributes.bInheritHandle,
1405  "unexpected securityAttributes.bInheritHandle value: %d\n",
1406  dest[0].securityAttributes.bInheritHandle);
1407 }
1408 
1410 {
1411  DWORD encoding, size;
1412  HRESULT hres;
1413 
1414  size = encoding = 0xdeadbeef;
1415  hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1416  sizeof(encoding), &size, 0);
1417  ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1418  ok(encoding != 0xdeadbeef, "encoding not changed\n");
1419  ok(size == sizeof(encoding), "size=%d\n", size);
1420 
1421  size = encoding = 0xdeadbeef;
1422  hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1423  sizeof(encoding)+1, &size, 0);
1424  ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1425  ok(encoding != 0xdeadbeef, "encoding not changed\n");
1426  ok(size == sizeof(encoding), "size=%d\n", size);
1427 
1428  size = encoding = 0xdeadbeef;
1429  hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1430  sizeof(encoding)-1, &size, 0);
1431  ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1432  ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1433  ok(size == 0xdeadbeef, "size=%d\n", size);
1434 
1435  size = encoding = 0xdeadbeef;
1436  hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, NULL,
1437  sizeof(encoding)-1, &size, 0);
1438  ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1439  ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1440  ok(size == 0xdeadbeef, "size=%d\n", size);
1441 
1442  encoding = 0xdeadbeef;
1443  hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1444  sizeof(encoding)-1, NULL, 0);
1445  ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1446  ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1447 }
1448 
1449 static void test_user_agent(void)
1450 {
1451  static const CHAR expected[] = "Mozilla/4.0 (compatible; MSIE ";
1452  static char test_str[] = "test";
1453  static char test2_str[] = "test\0test";
1454  static CHAR str[3];
1455  LPSTR str2 = NULL;
1456  HRESULT hres;
1457  DWORD size, saved;
1458 
1459  hres = pObtainUserAgentString(0, NULL, NULL);
1460  ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1461 
1462  size = 100;
1463  hres = pObtainUserAgentString(0, NULL, &size);
1464  ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1465  ok(size == 100, "size=%d, expected %d\n", size, 100);
1466 
1467  size = 0;
1468  hres = pObtainUserAgentString(0, str, &size);
1469  ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1470  ok(size > 0, "size=%d, expected non-zero\n", size);
1471 
1472  size = 2;
1473  str[0] = 'a';
1474  hres = pObtainUserAgentString(0, str, &size);
1475  ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1476  ok(size > 0, "size=%d, expected non-zero\n", size);
1477  ok(str[0] == 'a', "str[0]=%c, expected 'a'\n", str[0]);
1478 
1479  size = 0;
1480  hres = pObtainUserAgentString(1, str, &size);
1481  ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1482  ok(size > 0, "size=%d, expected non-zero\n", size);
1483 
1484  str2 = HeapAlloc(GetProcessHeap(), 0, (size+20)*sizeof(CHAR));
1485  saved = size;
1486  hres = pObtainUserAgentString(0, str2, &size);
1487  ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1488  ok(size == saved, "size=%d, expected %d\n", size, saved);
1489  ok(strlen(expected) <= strlen(str2) &&
1490  !memcmp(expected, str2, strlen(expected)*sizeof(CHAR)),
1491  "user agent was \"%s\", expected to start with \"%s\"\n",
1492  str2, expected);
1493 
1494  size = saved+10;
1495  hres = pObtainUserAgentString(0, str2, &size);
1496  ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1497  ok(size == saved, "size=%d, expected %d\n", size, saved);
1498 
1499  size = 0;
1500  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, &size, 0);
1501  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1502  ok(size, "size == 0\n");
1503 
1504  size = 0xdeadbeef;
1505  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 1000, &size, 0);
1506  ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1507  ok(size, "size == 0\n");
1508 
1509  saved = size;
1510  size = 0;
1511  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved+10, &size, 0);
1512  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1513  ok(size == saved, "size = %d, expected %d\n", size, saved);
1514  ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1515  "user agent was \"%s\", expected to start with \"%s\"\n",
1516  str2, expected);
1517 
1518  size = 0;
1519  str2[0] = 0;
1520  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1521  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1522  ok(size == saved, "size = %d, expected %d\n", size, saved);
1523  ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1524  "user agent was \"%s\", expected to start with \"%s\"\n",
1525  str2, expected);
1526 
1527  size = saved;
1528  str2[0] = 0;
1529  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved-1, &size, 0);
1530  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1531  ok(size == saved, "size = %d, expected %d\n", size, saved);
1532  ok(!str2[0], "buf changed\n");
1533 
1534  size = saved;
1535  str2[0] = 0;
1536  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, NULL, 0);
1537  ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1538  ok(!str2[0], "buf changed\n");
1539 
1540  hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, sizeof(test_str), 0);
1541  ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1542 
1543  size = 0;
1544  str2[0] = 0;
1545  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1546  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1547  ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1548 
1549  hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test2_str, sizeof(test2_str), 0);
1550  ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1551 
1552  size = 0;
1553  str2[0] = 0;
1554  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1555  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1556  ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1557 
1558  hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 2, 0);
1559  ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1560 
1561  size = 0;
1562  str2[0] = 0;
1563  hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1564  ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1565  ok(size == 3 && !strcmp(str2, "te"), "wrong user agent\n");
1566 
1567  hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 0, 0);
1568  ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1569 
1570  hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, sizeof(test_str), 0);
1571  ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1572 
1573  hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, 0);
1574  ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1575 
1576  HeapFree(GetProcessHeap(), 0, str2);
1577 }
1578 
1579 static void test_MkParseDisplayNameEx(void)
1580 {
1581  IMoniker *mon = NULL;
1582  LPWSTR name;
1583  DWORD issys;
1584  ULONG eaten = 0;
1585  IBindCtx *bctx;
1586  HRESULT hres;
1587 
1588  static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
1589  '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
1590  '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
1591 
1592  const struct
1593  {
1594  LPBC *ppbc;
1595  LPCWSTR szDisplayName;
1596  ULONG *pchEaten;
1597  LPMONIKER *ppmk;
1598  } invalid_parameters[] =
1599  {
1600  {NULL, NULL, NULL, NULL},
1601  {NULL, NULL, NULL, &mon},
1602  {NULL, NULL, &eaten, NULL},
1603  {NULL, NULL, &eaten, &mon},
1604  {NULL, wszEmpty, NULL, NULL},
1605  {NULL, wszEmpty, NULL, &mon},
1606  {NULL, wszEmpty, &eaten, NULL},
1607  {NULL, wszEmpty, &eaten, &mon},
1608  {&bctx, NULL, NULL, NULL},
1609  {&bctx, NULL, NULL, &mon},
1610  {&bctx, NULL, &eaten, NULL},
1611  {&bctx, NULL, &eaten, &mon},
1612  {&bctx, wszEmpty, NULL, NULL},
1613  {&bctx, wszEmpty, NULL, &mon},
1614  {&bctx, wszEmpty, &eaten, NULL},
1615  {&bctx, wszEmpty, &eaten, &mon},
1616  };
1617 
1618  int i;
1619 
1620  CreateBindCtx(0, &bctx);
1621 
1622  for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
1623  {
1624  eaten = 0xdeadbeef;
1625  mon = (IMoniker *)0xdeadbeef;
1626  hres = MkParseDisplayNameEx(invalid_parameters[i].ppbc ? *invalid_parameters[i].ppbc : NULL,
1627  invalid_parameters[i].szDisplayName,
1628  invalid_parameters[i].pchEaten,
1629  invalid_parameters[i].ppmk);
1630  ok(hres == E_INVALIDARG,
1631  "[%d] Expected MkParseDisplayNameEx to return E_INVALIDARG, got %08x\n", i, hres);
1632  ok(eaten == 0xdeadbeef, "[%d] Expected eaten to be 0xdeadbeef, got %u\n", i, eaten);
1633  ok(mon == (IMoniker *)0xdeadbeef, "[%d] Expected mon to be 0xdeadbeef, got %p\n", i, mon);
1634  }
1635 
1636  hres = MkParseDisplayNameEx(bctx, url9, &eaten, &mon);
1637  ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
1638  ok(eaten == ARRAY_SIZE(url9)-1, "eaten=%d\n", eaten);
1639  ok(mon != NULL, "mon == NULL\n");
1640 
1641  hres = IMoniker_GetDisplayName(mon, NULL, 0, &name);
1642  ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1643  ok(!lstrcmpW(name, url9), "wrong display name %s\n", wine_dbgstr_w(name));
1645 
1646  hres = IMoniker_IsSystemMoniker(mon, &issys);
1647  ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1648  ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
1649 
1650  IMoniker_Release(mon);
1651 
1652  hres = MkParseDisplayNameEx(bctx, clsid_nameW, &eaten, &mon);
1653  ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
1654  ok(eaten == ARRAY_SIZE(clsid_nameW)-1, "eaten=%d\n", eaten);
1655  ok(mon != NULL, "mon == NULL\n");
1656 
1657  hres = IMoniker_IsSystemMoniker(mon, &issys);
1658  ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1659  ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
1660 
1661  IMoniker_Release(mon);
1662 
1663  hres = MkParseDisplayNameEx(bctx, url8, &eaten, &mon);
1664  ok(FAILED(hres), "MkParseDisplayNameEx succeeded: %08x\n", hres);
1665 
1666  IBindCtx_Release(bctx);
1667 }
1668 
1669 static void test_IsValidURL(void)
1670 {
1671  HRESULT hr;
1672  IBindCtx *bctx = NULL;
1673 
1674  hr = IsValidURL(NULL, 0, 0);
1675  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1676 
1678  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1679 
1680  CreateBindCtx(0, &bctx);
1681 
1682  hr = IsValidURL(bctx, wszHttpWineHQ, 0);
1683  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1684 
1685  IBindCtx_Release(bctx);
1686 }
1687 
1688 static const struct {
1693 } default_feature_tests[] = {
1694  {FEATURE_OBJECT_CACHING,GET_FEATURE_FROM_PROCESS,S_OK},
1695  {FEATURE_ZONE_ELEVATION,GET_FEATURE_FROM_PROCESS,S_FALSE},
1696  {FEATURE_MIME_HANDLING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1697  {FEATURE_MIME_SNIFFING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1698  {FEATURE_WINDOW_RESTRICTIONS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1699  {FEATURE_WEBOC_POPUPMANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1700  {FEATURE_BEHAVIORS,GET_FEATURE_FROM_PROCESS,S_OK},
1701  {FEATURE_DISABLE_MK_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_OK},
1702  {FEATURE_LOCALMACHINE_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1703  {FEATURE_SECURITYBAND,GET_FEATURE_FROM_PROCESS,S_FALSE},
1704  {FEATURE_RESTRICT_ACTIVEXINSTALL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1705  {FEATURE_VALIDATE_NAVIGATE_URL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1706  {FEATURE_RESTRICT_FILEDOWNLOAD,GET_FEATURE_FROM_PROCESS,S_FALSE},
1707  {FEATURE_ADDON_MANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1708  {FEATURE_PROTOCOL_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1709  {FEATURE_HTTP_USERNAME_PASSWORD_DISABLE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1710  {FEATURE_SAFE_BINDTOOBJECT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1711  {FEATURE_UNC_SAVEDFILECHECK,GET_FEATURE_FROM_PROCESS,S_FALSE},
1712  {FEATURE_GET_URL_DOM_FILEPATH_UNENCODED,GET_FEATURE_FROM_PROCESS,S_OK},
1713  {FEATURE_TABBED_BROWSING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1714  {FEATURE_SSLUX,GET_FEATURE_FROM_PROCESS,S_FALSE},
1715  {FEATURE_DISABLE_NAVIGATION_SOUNDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1716  {FEATURE_DISABLE_LEGACY_COMPRESSION,GET_FEATURE_FROM_PROCESS,S_OK},
1717  {FEATURE_FORCE_ADDR_AND_STATUS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1718  {FEATURE_XMLHTTP,GET_FEATURE_FROM_PROCESS,S_OK},
1719  {FEATURE_DISABLE_TELNET_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1720  {FEATURE_FEEDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1721  {FEATURE_BLOCK_INPUT_PROMPTS,GET_FEATURE_FROM_PROCESS,S_FALSE}
1722 };
1723 
1725  HRESULT hres;
1726  DWORD i;
1727 
1728  for(i = 0; i < ARRAY_SIZE(default_feature_tests); ++i) {
1729  hres = pCoInternetIsFeatureEnabled(default_feature_tests[i].feature, default_feature_tests[i].get_flags);
1731  ok(hres == default_feature_tests[i].expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1733  }
1734 }
1735 
1736 /* With older versions of IE (IE 7 and earlier), urlmon caches
1737  * the FeatureControl values from the registry when it's loaded
1738  * into memory. Newer versions of IE conditionally cache the
1739  * the FeatureControl registry values (i.e. When a call to
1740  * CoInternetIsFeatureEnabled and a corresponding CoInternetSetFeatureEnabled
1741  * call hasn't already been made for the specified Feature). Because of
1742  * this we skip these tests on IE 7 and earlier.
1743  */
1744 static const char* szFeatureControlKey = "Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl";
1745 
1747  HRESULT hres;
1748  DWORD res;
1749  char module[MAX_PATH];
1750  char *name;
1752  HKEY feature;
1753  DWORD value;
1754  BOOL skip_zone;
1755  BOOL delete_feature_key = TRUE;
1756 
1757  static const char* szFeatureBehaviorsKey = "FEATURE_BEHAVIORS";
1758  static const char* szFeatureZoneElevationKey = "FEATURE_ZONE_ELEVATION";
1759 
1760  if(!pIEInstallScope) {
1761  win_skip("Skipping internet feature registry tests, IE is too old...\n");
1762  return;
1763  }
1764 
1765  res = GetModuleFileNameA(NULL, module, sizeof(module));
1766  ok(res, "GetModuleFileName failed: %d\n", GetLastError());
1767 
1768  name = strrchr(module, '\\')+1;
1769 
1770  /* Some Windows machines don't have a FeatureControl key in HKCU. */
1772  ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1773 
1774  res = RegOpenKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1775  if(res == ERROR_SUCCESS) {
1776  /* FEATURE_BEHAVIORS already existed, so don't delete it when we're done. */
1777  delete_feature_key = FALSE;
1778  }else {
1779  res = RegCreateKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1780  ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1781  }
1782 
1783  value = 0;
1784  res = RegSetValueExA(feature, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1785  ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1786 
1787  hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1788  ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1789 
1790  if(delete_feature_key) {
1792  RegDeleteKeyA(feature_control, szFeatureBehaviorsKey);
1793  } else {
1796  }
1797 
1798  /* IE's feature control cached the value it got from the registry earlier. */
1799  hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1800  ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1801 
1802  /* Restore this feature back to its default value. */
1803  hres = pCoInternetSetFeatureEnabled(FEATURE_BEHAVIORS, SET_FEATURE_ON_PROCESS, TRUE);
1804  ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1805 
1807 
1809  ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1810 
1811  res = RegOpenKeyA(feature_control, szFeatureZoneElevationKey, &feature);
1812  ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1813 
1814  value = 1;
1815  res = RegSetValueExA(feature, "*", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1816  if (res == ERROR_ACCESS_DENIED)
1817  {
1818  skip("Not allowed to modify zone elevation\n");
1819  skip_zone = TRUE;
1820  }
1821  else
1822  {
1823  skip_zone = FALSE;
1824  ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1825 
1826  hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1827  ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1828  }
1829  RegDeleteValueA(feature, "*");
1832 
1833  /* Value is still cached from last time. */
1834  if (!skip_zone)
1835  {
1836  hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1837  ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1838 
1839  hres = pCoInternetSetFeatureEnabled(FEATURE_ZONE_ELEVATION, SET_FEATURE_ON_PROCESS, FALSE);
1840  ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1841  }
1842 
1844 }
1845 
1847  HRESULT hres;
1848 
1849  hres = pCoInternetIsFeatureEnabled(FEATURE_ENTRY_COUNT, GET_FEATURE_FROM_PROCESS);
1850  ok(hres == E_FAIL, "CoInternetIsFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1851 }
1852 
1853 static const struct {
1859  DWORD get_flags;
1862 } internet_feature_tests[] = {
1863  {FEATURE_OBJECT_CACHING,SET_FEATURE_ON_PROCESS,FALSE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1864  {FEATURE_WEBOC_POPUPMANAGEMENT,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK},
1865  {FEATURE_LOCALMACHINE_LOCKDOWN,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK}
1866 };
1867 
1869  HRESULT hres;
1870  DWORD i;
1871 
1872  hres = pCoInternetSetFeatureEnabled(FEATURE_ENTRY_COUNT,SET_FEATURE_ON_PROCESS,TRUE);
1873  ok(hres == E_FAIL, "CoInternetSetFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1874 
1875  for(i = 0; i < ARRAY_SIZE(internet_feature_tests); ++i) {
1876  hres = pCoInternetSetFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags,
1879  ok(hres == internet_feature_tests[i].set_expected, "CoInternetSetFeatureEnabled returned %08x, expected %08x on test %d\n",
1881 
1882  hres = pCoInternetIsFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags);
1884  ok(hres == internet_feature_tests[i].get_expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1886 
1887  }
1888 }
1889 
1890 static void test_internet_features(void) {
1891  HKEY key;
1892  DWORD res;
1893 
1894  if(!pCoInternetIsFeatureEnabled || !pCoInternetSetFeatureEnabled) {
1895  win_skip("Skipping internet feature tests, IE is too old\n");
1896  return;
1897  }
1898 
1899  /* IE10 takes FeatureControl key into account only if it's available upon process start. */
1901  if(res != ERROR_SUCCESS) {
1903  STARTUPINFOA si = { 0 };
1904  char cmdline[MAX_PATH];
1905  char **argv;
1906  BOOL ret;
1907 
1909  ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1910 
1911  trace("Running features tests in a separated process.\n");
1912 
1914  sprintf(cmdline, "\"%s\" %s internet_features", argv[0], argv[1]);
1915  ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
1916  ok(ret, "Could not create process: %u\n", GetLastError());
1917  winetest_wait_child_process( pi.hProcess );
1918  CloseHandle(pi.hThread);
1919  CloseHandle(pi.hProcess);
1920 
1922  return;
1923  }
1924 
1928 }
1929 
1930 static BINDINFO rem_bindinfo = { sizeof(rem_bindinfo) }, in_bindinfo;
1932 
1934 {
1935  if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)
1936  || IsEqualGUID(&IID_IBindStatusCallback, riid)
1937  || IsEqualGUID(&IID_IUnknown, riid)) {
1938  *ppv = iface;
1939  return S_OK;
1940  }
1941 
1942  *ppv = NULL;
1943  return E_NOINTERFACE;
1944 }
1945 
1947 {
1948  return 2;
1949 }
1950 
1952 {
1953  return 1;
1954 }
1955 
1957  DWORD dwReserved, IBinding *pib)
1958 {
1959  ok(0, "unexpected call\n");
1960  return S_OK;
1961 }
1962 
1964 {
1965  ok(0, "unexpected call\n");
1966  return E_NOTIMPL;
1967 }
1968 
1970 {
1971  ok(0, "unexpected call\n");
1972  return E_NOTIMPL;
1973 }
1974 
1976  ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
1977 {
1978  ok(0, "unexpected call\n");
1979  return S_OK;
1980 }
1981 
1983 {
1984  ok(0, "unexpected call\n");
1985  return S_OK;
1986 }
1987 
1988 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1989 {
1990  in_bindinfo = *pbindinfo;
1991  *grfBINDF = rem_bindf;
1992  *pbindinfo = rem_bindinfo;
1993  return S_OK;
1994 }
1995 
1996 static STGMEDIUM in_stgmed, rem_stgmed;
1997 
1999  DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
2000 {
2001  in_stgmed = *pstgmed;
2002  *pstgmed = rem_stgmed;
2003  return S_OK;
2004 }
2005 
2007 {
2008  ok(0, "unexpected call\n");
2009  return S_OK;
2010 }
2011 
2013  BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
2014 {
2015  in_bindinfo = *pbindinfo;
2016  *grfBINDF = rem_bindf;
2017  *pbindinfo = rem_bindinfo;
2018  *grfBINDF2 = 11;
2019  *pdwReserved = 12;
2020  return S_OK;
2021 }
2022 
2023 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
2036 };
2037 
2039 
2040 typedef struct {
2043 } RefUnk;
2044 
2045 static inline RefUnk *impl_from_IUnknown(IUnknown *iface)
2046 {
2047  return CONTAINING_RECORD(iface, RefUnk, IUnknown_iface);
2048 }
2049 
2051 {
2052  if(!IsEqualGUID(&IID_IUnknown, riid)) {
2053  *ppv = NULL;
2054  return E_NOINTERFACE;
2055  }
2056 
2057  IUnknown_AddRef(iface);
2058  *ppv = iface;
2059  return S_OK;
2060 }
2061 
2063 {
2064  RefUnk *This = impl_from_IUnknown(iface);
2065  return InterlockedIncrement(&This->ref);
2066 }
2067 
2069 {
2070  RefUnk *This = impl_from_IUnknown(iface);
2071  return InterlockedDecrement(&This->ref);
2072 }
2073 
2074 static const IUnknownVtbl RefUnkVtbl = {
2076  RefUnk_AddRef,
2078 };
2079 
2081 
2083 
2085 {
2086  IStream *stream = arg;
2088  MSG msg;
2089  HRESULT hres;
2090 
2091  CoInitialize(NULL);
2092 
2093  hres = CoMarshalInterface(stream, &IID_IBindStatusCallback, (IUnknown*)&BindStatusCallback,
2094  MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2095  ok(hres == S_OK, "CoMarshalInterface failed: %08x\n", hres);
2096 
2097  zero.QuadPart = 0;
2098  hres = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
2099  ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2100 
2102 
2103  while(GetMessageW(&msg, NULL, 0, 0)) {
2106  }
2107 
2108  CoUninitialize();
2109  return 0;
2110 }
2111 
2112 static void test_bsc_marshaling(void)
2113 {
2114  FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM};
2115  IBindStatusCallbackEx *callbackex;
2117  BINDINFO bindinfo;
2118  IStream *stream, *binding_stream;
2119  HANDLE thread;
2120  WCHAR *extra_info_out;
2121  WCHAR *verb_out;
2123  STGMEDIUM stgmed;
2124  void *buf;
2125  DWORD bindf;
2126  HRESULT hres;
2127 
2129  ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
2130 
2134 
2135  hres = CoUnmarshalInterface(stream, &IID_IBindStatusCallback, (void**)&bsc);
2136  ok(hres == S_OK, "CoUnmarshalInterface failed: %08x\n", hres);
2137 
2138  hres = CreateStreamOnHGlobal(NULL, TRUE, &binding_stream);
2139  ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
2140  hres = IStream_Write(binding_stream, "xxx", 3, NULL);
2141  ok(hres == S_OK, "Write failed: %08x\n", hres);
2142 
2143  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2144  bindf = 0xdeadbeef;
2145 
2146  memset(&bindinfo, 0, sizeof(bindinfo));
2147  bindinfo.cbSize = sizeof(bindinfo);
2148  bindinfo.grfBindInfoF = 12;
2149  bindinfo.dwBindVerb = 13;
2150  bindinfo.cbstgmedData = 19;
2151  bindinfo.dwOptions = 14;
2152  bindinfo.dwOptionsFlags = 15;
2153  bindinfo.dwCodePage = 16;
2154  bindinfo.securityAttributes.nLength = 30;
2155  bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0001;
2156  bindinfo.securityAttributes.bInheritHandle = 31;
2157  bindinfo.iid.Data1 = 17;
2158  bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2159  bindinfo.dwReserved = 18;
2160  bindinfo.stgmedData.pUnkForRelease = &unk_in.IUnknown_iface;
2161  unk_in.ref = 1;
2162 
2163  memset(&rem_bindinfo, 0, sizeof(bindinfo));
2164  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2165  rem_bindinfo.szExtraInfo = extra_info_out = a2co("extra info out");
2166  rem_bindinfo.grfBindInfoF = 22;
2167  rem_bindinfo.dwBindVerb = 23;
2168  rem_bindinfo.szCustomVerb = verb_out = a2co("custom verb out");
2169  rem_bindinfo.cbstgmedData = 29;
2170  rem_bindinfo.dwOptions = 24;
2171  rem_bindinfo.dwOptionsFlags = 25;
2172  rem_bindinfo.dwCodePage = 16;
2173  rem_bindinfo.securityAttributes.nLength = 40;
2174  rem_bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0002;
2175  rem_bindinfo.securityAttributes.bInheritHandle = 41;
2176  rem_bindinfo.iid.Data1 = 27;
2177  rem_bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2178  rem_bindinfo.dwReserved = 18;
2179  rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2180  unk_out.ref = 1;
2181 
2182  hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2183  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2184  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2185 
2186  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2187  ok(!in_bindinfo.szExtraInfo, "szExtraInfo = %s\n", wine_dbgstr_w(in_bindinfo.szExtraInfo));
2188  ok(in_bindinfo.grfBindInfoF == 12, "cbSize = %u\n", in_bindinfo.grfBindInfoF);
2189  ok(in_bindinfo.dwBindVerb == 13, "dwBindVerb = %u\n", in_bindinfo.dwBindVerb);
2190  ok(!in_bindinfo.szCustomVerb, "szCustomVerb = %s\n", wine_dbgstr_w(in_bindinfo.szCustomVerb));
2191  ok(in_bindinfo.cbstgmedData == 19, "cbstgmedData = %u\n", in_bindinfo.cbstgmedData);
2192  ok(!in_bindinfo.dwOptions, "dwOptions = %u\n", in_bindinfo.dwOptions);
2193  ok(!in_bindinfo.dwOptionsFlags, "dwOptionsFlags = %u\n", in_bindinfo.dwOptionsFlags);
2194  ok(!in_bindinfo.dwCodePage, "dwCodePage = %u\n", in_bindinfo.dwCodePage);
2195  ok(!in_bindinfo.iid.Data1, "iid.Data1 = %u\n", in_bindinfo.iid.Data1);
2196  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2197  ok(!in_bindinfo.dwReserved, "dwReserved = %u\n", in_bindinfo.dwReserved);
2198  ok(!in_bindinfo.securityAttributes.nLength, "securityAttributes.nLength = %u\n",
2199  in_bindinfo.securityAttributes.nLength);
2200  ok(!in_bindinfo.securityAttributes.lpSecurityDescriptor,
2201  "securityAttributes.lpSecurityDescriptor = %p\n",
2202  in_bindinfo.securityAttributes.lpSecurityDescriptor);
2203  ok(!in_bindinfo.securityAttributes.bInheritHandle, "securityAttributes.bInheritHandle = %u\n",
2204  in_bindinfo.securityAttributes.bInheritHandle);
2205  ok(!in_bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2206  in_bindinfo.stgmedData.pUnkForRelease);
2207 
2208  ok(bindinfo.cbSize == sizeof(rem_bindinfo), "cbSize = %u\n", rem_bindinfo.cbSize);
2209  ok(!strcmp_wa(bindinfo.szExtraInfo, "extra info out"),
2210  "szExtraInfo = %s\n", wine_dbgstr_w(bindinfo.szExtraInfo));
2211  ok(bindinfo.grfBindInfoF == 22, "grfBindInfoF = %u\n", rem_bindinfo.grfBindInfoF);
2212  ok(bindinfo.dwBindVerb == 23, "dwBindVerb = %u\n", bindinfo.dwBindVerb);
2213  ok(bindinfo.szCustomVerb != verb_out, "szCustomVerb == inbuf\n");
2214  ok(!strcmp_wa(bindinfo.szCustomVerb, "custom verb out"), "szCustomVerb = %s\n",
2215  wine_dbgstr_w(bindinfo.szCustomVerb));
2216  ok(bindinfo.cbstgmedData == 29, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2217  ok(bindinfo.dwOptions == 24, "dwOptions = %u\n", bindinfo.dwOptions);
2218  ok(bindinfo.dwOptionsFlags == 25, "dwOptionsFlags = %u\n", bindinfo.dwOptionsFlags);
2219  ok(bindinfo.dwCodePage, "dwCodePage = %u\n", bindinfo.dwCodePage);
2220  ok(!bindinfo.iid.Data1, "iid.Data1 = %u\n", bindinfo.iid.Data1);
2221  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2222  ok(bindinfo.dwReserved == 18, "dwReserved = %u\n", bindinfo.dwReserved);
2223  ok(bindinfo.securityAttributes.nLength == 30, "securityAttributes.nLength = %u\n",
2224  bindinfo.securityAttributes.nLength);
2225  ok(bindinfo.securityAttributes.lpSecurityDescriptor == (void*)0xdead0001,
2226  "securityAttributes.lpSecurityDescriptor = %p\n",
2227  bindinfo.securityAttributes.lpSecurityDescriptor);
2228  ok(bindinfo.securityAttributes.bInheritHandle == 31, "securityAttributes.bInheritHandle = %u\n",
2229  bindinfo.securityAttributes.bInheritHandle);
2230  ok(bindinfo.stgmedData.pUnkForRelease == &unk_in.IUnknown_iface, "pUnkForRelease = %p\n",
2231  bindinfo.stgmedData.pUnkForRelease);
2232  ok(unk_out.ref == 1, "unk_out.ref = %u\n", unk_out.ref);
2233 
2234  bindinfo.stgmedData.pUnkForRelease = NULL;
2235  ReleaseBindInfo(&bindinfo);
2236 
2237  zero.QuadPart = 0;
2238  hres = IStream_Seek(binding_stream, zero, STREAM_SEEK_SET, NULL);
2239  ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2240 
2241  /* Return IStream stgmed from GetBindInfo, it's not marshaled back */
2242  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2243  bindf = 0xdeadbeef;
2244 
2245  memset(&bindinfo, 0, sizeof(bindinfo));
2246  bindinfo.cbSize = sizeof(bindinfo);
2247 
2248  memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2249  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2250 
2251  rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2252  rem_bindinfo.stgmedData.u.pstm = binding_stream;
2253  rem_bindinfo.cbstgmedData = 3;
2254  IStream_AddRef(binding_stream);
2255 
2256  hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2257  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2258  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2259 
2260  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2261  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2262  ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2263  in_bindinfo.stgmedData.tymed);
2264 
2265  ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2266  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2267  ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2268  bindinfo.stgmedData.tymed);
2269  ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2270  bindinfo.stgmedData.u.pstm);
2271  ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2272  bindinfo.stgmedData.pUnkForRelease);
2273  ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2274 
2275  ReleaseBindInfo(&bindinfo);
2276 
2277  /* Same, but with pUnkForRelease, it's not marshaled back */
2278  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2279  bindf = 0xdeadbeef;
2280 
2281  memset(&bindinfo, 0, sizeof(bindinfo));
2282  bindinfo.cbSize = sizeof(bindinfo);
2283 
2284  memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2285  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2286 
2287  rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2288  rem_bindinfo.stgmedData.u.pstm = binding_stream;
2289  rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2290  unk_out.ref = 1;
2291  rem_bindinfo.cbstgmedData = 3;
2292  IStream_AddRef(binding_stream);
2293 
2294  hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2295  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2296  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2297 
2298  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2299  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2300  ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2301  in_bindinfo.stgmedData.tymed);
2302 
2303  ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2304  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2305  ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2306  bindinfo.stgmedData.tymed);
2307  ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2308  bindinfo.stgmedData.u.pstm);
2309  ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2310  bindinfo.stgmedData.pUnkForRelease);
2311  ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2312 
2313  ReleaseBindInfo(&bindinfo);
2314 
2315  /* Return HGLOBAL stgmed from GetBindInfo, it's not marshaled back */
2316  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2317  bindf = 0xdeadbeef;
2318 
2319  memset(&bindinfo, 0, sizeof(bindinfo));
2320  bindinfo.cbSize = sizeof(bindinfo);
2321 
2322  memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2323  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2324 
2325  rem_bindinfo.stgmedData.tymed = TYMED_HGLOBAL;
2326 
2327  buf = GlobalAlloc(0, 5);
2328  strcpy(buf, "test");
2329  rem_bindinfo.stgmedData.u.hGlobal = buf;
2330  rem_bindinfo.cbstgmedData = 5;
2331 
2332  hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2333  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2334  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2335 
2336  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2337  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2338  ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2339  in_bindinfo.stgmedData.tymed);
2340 
2341  ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2342  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2343  ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2344  bindinfo.stgmedData.tymed);
2345  ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2346  bindinfo.stgmedData.u.pstm);
2347  ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2348  bindinfo.stgmedData.pUnkForRelease);
2349  ok(bindinfo.cbstgmedData == 5, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2350 
2351  ReleaseBindInfo(&bindinfo);
2352 
2353  /* Same with GetBindInfoEx */
2354  hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackEx, (void**)&callbackex);
2355  if(SUCCEEDED(hres)) {
2356  DWORD bindf2, reserved;
2357 
2358  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2359  bindf = bindf2 = reserved = 0xdeadbeef;
2360 
2361  memset(&bindinfo, 0, sizeof(bindinfo));
2362  bindinfo.cbSize = sizeof(bindinfo);
2363  bindinfo.grfBindInfoF = 12;
2364  bindinfo.dwBindVerb = 13;
2365  bindinfo.cbstgmedData = 19;
2366  bindinfo.dwOptions = 14;
2367  bindinfo.dwOptionsFlags = 15;
2368  bindinfo.dwCodePage = 16;
2369  bindinfo.securityAttributes.nLength = 30;
2370  bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0001;
2371  bindinfo.securityAttributes.bInheritHandle = 31;
2372  bindinfo.iid.Data1 = 17;
2373  bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2374  bindinfo.dwReserved = 18;
2375  bindinfo.stgmedData.pUnkForRelease = &unk_in.IUnknown_iface;
2376  unk_in.ref = 1;
2377 
2378  memset(&rem_bindinfo, 0, sizeof(bindinfo));
2379  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2380  rem_bindinfo.szExtraInfo = extra_info_out = a2co("extra info out");
2381  rem_bindinfo.grfBindInfoF = 22;
2382  rem_bindinfo.dwBindVerb = 23;
2383  rem_bindinfo.szCustomVerb = verb_out = a2co("custom verb out");
2384  rem_bindinfo.cbstgmedData = 29;
2385  rem_bindinfo.dwOptions = 24;
2386  rem_bindinfo.dwOptionsFlags = 25;
2387  rem_bindinfo.dwCodePage = 16;
2388  rem_bindinfo.securityAttributes.nLength = 40;
2389  rem_bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0002;
2390  rem_bindinfo.securityAttributes.bInheritHandle = 41;
2391  rem_bindinfo.iid.Data1 = 27;
2392  rem_bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2393  rem_bindinfo.dwReserved = 18;
2394  rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2395  unk_out.ref = 1;
2396 
2397  hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2398  ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2399  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2400  ok(bindf2 == 11, "bindf2 = %x\n", bindf);
2401  ok(reserved == 12, "reserved = %x\n", reserved);
2402 
2403  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2404  ok(!in_bindinfo.szExtraInfo, "szExtraInfo = %s\n", wine_dbgstr_w(in_bindinfo.szExtraInfo));
2405  ok(in_bindinfo.grfBindInfoF == 12, "cbSize = %u\n", in_bindinfo.grfBindInfoF);
2406  ok(in_bindinfo.dwBindVerb == 13, "dwBindVerb = %u\n", in_bindinfo.dwBindVerb);
2407  ok(!in_bindinfo.szCustomVerb, "szCustomVerb = %s\n", wine_dbgstr_w(in_bindinfo.szCustomVerb));
2408  ok(in_bindinfo.cbstgmedData == 19, "cbstgmedData = %u\n", in_bindinfo.cbstgmedData);
2409  ok(!in_bindinfo.dwOptions, "dwOptions = %u\n", in_bindinfo.dwOptions);
2410  ok(!in_bindinfo.dwOptionsFlags, "dwOptionsFlags = %u\n", in_bindinfo.dwOptionsFlags);
2411  ok(!in_bindinfo.dwCodePage, "dwCodePage = %u\n", in_bindinfo.dwCodePage);
2412  ok(!in_bindinfo.iid.Data1, "iid.Data1 = %u\n", in_bindinfo.iid.Data1);
2413  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2414  ok(!in_bindinfo.dwReserved, "dwReserved = %u\n", in_bindinfo.dwReserved);
2415  ok(!in_bindinfo.securityAttributes.nLength, "securityAttributes.nLength = %u\n",
2416  in_bindinfo.securityAttributes.nLength);
2417  ok(!in_bindinfo.securityAttributes.lpSecurityDescriptor,
2418  "securityAttributes.lpSecurityDescriptor = %p\n",
2419  in_bindinfo.securityAttributes.lpSecurityDescriptor);
2420  ok(!in_bindinfo.securityAttributes.bInheritHandle, "securityAttributes.bInheritHandle = %u\n",
2421  in_bindinfo.securityAttributes.bInheritHandle);
2422  ok(!in_bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2423  in_bindinfo.stgmedData.pUnkForRelease);
2424 
2425  ok(bindinfo.cbSize == sizeof(rem_bindinfo), "cbSize = %u\n", rem_bindinfo.cbSize);
2426  ok(!strcmp_wa(bindinfo.szExtraInfo, "extra info out"),
2427  "szExtraInfo = %s\n", wine_dbgstr_w(bindinfo.szExtraInfo));
2428  ok(bindinfo.grfBindInfoF == 22, "grfBindInfoF = %u\n", rem_bindinfo.grfBindInfoF);
2429  ok(bindinfo.dwBindVerb == 23, "dwBindVerb = %u\n", bindinfo.dwBindVerb);
2430  ok(bindinfo.szCustomVerb != verb_out, "szCustomVerb == inbuf\n");
2431  ok(!strcmp_wa(bindinfo.szCustomVerb, "custom verb out"), "szCustomVerb = %s\n",
2432  wine_dbgstr_w(bindinfo.szCustomVerb));
2433  ok(bindinfo.cbstgmedData == 29, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2434  ok(bindinfo.dwOptions == 24, "dwOptions = %u\n", bindinfo.dwOptions);
2435  ok(bindinfo.dwOptionsFlags == 25, "dwOptionsFlags = %u\n", bindinfo.dwOptionsFlags);
2436  ok(bindinfo.dwCodePage, "dwCodePage = %u\n", bindinfo.dwCodePage);
2437  ok(!bindinfo.iid.Data1, "iid.Data1 = %u\n", bindinfo.iid.Data1);
2438  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2439  ok(bindinfo.dwReserved == 18, "dwReserved = %u\n", bindinfo.dwReserved);
2440  ok(bindinfo.securityAttributes.nLength == 30, "securityAttributes.nLength = %u\n",
2441  bindinfo.securityAttributes.nLength);
2442  ok(bindinfo.securityAttributes.lpSecurityDescriptor == (void*)0xdead0001,
2443  "securityAttributes.lpSecurityDescriptor = %p\n",
2444  bindinfo.securityAttributes.lpSecurityDescriptor);
2445  ok(bindinfo.securityAttributes.bInheritHandle == 31, "securityAttributes.bInheritHandle = %u\n",
2446  bindinfo.securityAttributes.bInheritHandle);
2447  ok(bindinfo.stgmedData.pUnkForRelease == &unk_in.IUnknown_iface, "pUnkForRelease = %p\n",
2448  bindinfo.stgmedData.pUnkForRelease);
2449  ok(unk_out.ref == 1, "unk_out.ref = %u\n", unk_out.ref);
2450 
2451  bindinfo.stgmedData.pUnkForRelease = NULL;
2452  ReleaseBindInfo(&bindinfo);
2453 
2454  zero.QuadPart = 0;
2455  hres = IStream_Seek(binding_stream, zero, STREAM_SEEK_SET, NULL);
2456  ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2457 
2458  /* Return IStream stgmed from GetBindInfoEx, it's not marshaled back */
2459  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2460  bindf = bindf2 = reserved = 0xdeadbeef;
2461 
2462  memset(&bindinfo, 0, sizeof(bindinfo));
2463  bindinfo.cbSize = sizeof(bindinfo);
2464 
2465  memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2466  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2467 
2468  rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2469  rem_bindinfo.stgmedData.u.pstm = binding_stream;
2470  rem_bindinfo.cbstgmedData = 3;
2471  IStream_AddRef(binding_stream);
2472 
2473  hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2474  ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2475  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2476 
2477  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2478  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2479  ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2480  in_bindinfo.stgmedData.tymed);
2481 
2482  ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2483  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2484  ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2485  bindinfo.stgmedData.tymed);
2486  ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2487  bindinfo.stgmedData.u.pstm);
2488  ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2489  bindinfo.stgmedData.pUnkForRelease);
2490  ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2491 
2492  ReleaseBindInfo(&bindinfo);
2493 
2494  /* Same, but with pUnkForRelease, it's not marshaled back */
2495  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2496  bindf = bindf2 = reserved = 0xdeadbeef;
2497 
2498  memset(&bindinfo, 0, sizeof(bindinfo));
2499  bindinfo.cbSize = sizeof(bindinfo);
2500 
2501  memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2502  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2503 
2504  rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2505  rem_bindinfo.stgmedData.u.pstm = binding_stream;
2506  rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2507  unk_out.ref = 1;
2508  rem_bindinfo.cbstgmedData = 3;
2509  IStream_AddRef(binding_stream);
2510 
2511  hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2512  ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2513  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2514 
2515  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2516  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2517  ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2518  in_bindinfo.stgmedData.tymed);
2519 
2520  ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2521  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2522  ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2523  bindinfo.stgmedData.tymed);
2524  ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2525  bindinfo.stgmedData.u.pstm);
2526  ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2527  bindinfo.stgmedData.pUnkForRelease);
2528  ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2529 
2530  ReleaseBindInfo(&bindinfo);
2531 
2532  /* Return HGLOBAL stgmed from GetBindInfoEx, it's not marshaled back */
2533  rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2534  bindf = bindf2 = reserved = 0xdeadbeef;
2535 
2536  memset(&bindinfo, 0, sizeof(bindinfo));
2537  bindinfo.cbSize = sizeof(bindinfo);
2538 
2539  memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2540  rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2541 
2542  rem_bindinfo.stgmedData.tymed = TYMED_HGLOBAL;
2543 
2544  buf = GlobalAlloc(0, 5);
2545  strcpy(buf, "test");
2546  rem_bindinfo.stgmedData.u.hGlobal = buf;
2547  rem_bindinfo.cbstgmedData = 5;
2548 
2549  hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2550  ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2551  ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2552 
2553  ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2554  ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2555  ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2556  in_bindinfo.stgmedData.tymed);
2557 
2558  ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2559  ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2560  ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2561  bindinfo.stgmedData.tymed);
2562  ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2563  bindinfo.stgmedData.u.pstm);
2564  ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2565  bindinfo.stgmedData.pUnkForRelease);
2566  ok(bindinfo.cbstgmedData == 5, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2567 
2568  ReleaseBindInfo(&bindinfo);
2569 
2570  IBindStatusCallbackEx_Release(callbackex);
2571  }else {
2572  win_skip("IBindStatusCallbackEx not supported\n");
2573  }
2574 
2575  /* Test marshaling stgmed from OnDataAvailable */
2576  memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2577  stgmed.tymed = TYMED_ISTREAM;
2578  stgmed.u.pstm = binding_stream;
2579  stgmed.pUnkForRelease = NULL;
2580 
2581  hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2582  ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2583 
2584  ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2585  ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2586  ok(!in_stgmed.pUnkForRelease, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2587 
2588  /* OnDataAvailable with both IStream and pUnkForRelease */
2589  memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2590  stgmed.tymed = TYMED_ISTREAM;
2591  stgmed.u.pstm = binding_stream;
2592  stgmed.pUnkForRelease = &unk_in.IUnknown_iface;
2593  unk_in.ref = 1;
2594 
2595  hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2596  ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2597 
2598  ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2599  ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2600  ok(in_stgmed.pUnkForRelease != NULL, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2601  ok(unk_in.ref > 1, "ref = %u\n", unk_in.ref);
2602 
2603  /* OnDataAvailable with TYMED_ISTREAM, but NULL stream */
2604  memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2605  stgmed.tymed = TYMED_ISTREAM;
2606  stgmed.u.pstm = binding_stream;
2607  stgmed.pUnkForRelease = NULL;
2608 
2609  hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2610  ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2611 
2612  ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2613  ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2614  ok(!in_stgmed.pUnkForRelease, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2615 
2616  /* OnDataAvailable with TYMED_NULL and pUnkForRelease */
2617  memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2618  stgmed.tymed = TYMED_NULL;
2619  stgmed.u.pstm = binding_stream;
2620  stgmed.pUnkForRelease = &unk_in.IUnknown_iface;
2621  unk_in.ref = 1;
2622 
2623  hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2624  ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2625 
2626  ok(in_stgmed.tymed == TYMED_NULL, "tymed = %u\n", in_stgmed.tymed);
2627  ok(!in_stgmed.u.pstm, "pstm != NULL\n");
2628  ok(in_stgmed.pUnkForRelease != NULL, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2629  ok(unk_in.ref == 1, "ref = %u\n", unk_in.ref);
2630 
2631  IStream_Release(binding_stream);
2632  IBindStatusCallback_Release(bsc);
2633 
2634  TerminateThread(thread, 0);
2635 }
2636 
2638 {
2639  HMODULE hurlmon;
2640  int argc;
2641  char **argv;
2642 
2644 
2645  hurlmon = GetModuleHandleA("urlmon.dll");
2646  pCoInternetCompareUrl = (void *) GetProcAddress(hurlmon, "CoInternetCompareUrl");
2647  pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
2648  pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
2649  pCoInternetParseUrl = (void*) GetProcAddress(hurlmon, "CoInternetParseUrl");
2650  pCoInternetQueryInfo = (void*) GetProcAddress(hurlmon, "CoInternetQueryInfo");
2651  pCopyStgMedium = (void*) GetProcAddress(hurlmon, "CopyStgMedium");
2652  pCopyBindInfo = (void*) GetProcAddress(hurlmon, "CopyBindInfo");
2653  pFindMimeFromData = (void*) GetProcAddress(hurlmon, "FindMimeFromData");
2654  pObtainUserAgentString = (void*) GetProcAddress(hurlmon, "ObtainUserAgentString");
2655  pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
2656  pUrlMkGetSessionOption = (void*) GetProcAddress(hurlmon, "UrlMkGetSessionOption");
2657  pCompareSecurityIds = (void*) GetProcAddress(hurlmon, "CompareSecurityIds");
2658  pCoInternetIsFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabled");
2659  pCoInternetSetFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetSetFeatureEnabled");
2660  pIEInstallScope = (void*) GetProcAddress(hurlmon, "IEInstallScope");
2661 
2662  if (!pCoInternetCompareUrl || !pCoInternetGetSecurityUrl ||
2663  !pCoInternetGetSession || !pCoInternetParseUrl || !pCompareSecurityIds) {
2664  win_skip("Various needed functions not present, too old IE\n");
2665  return;
2666  }
2667 
2669 
2670  if(argc <= 2 || strcmp(argv[2], "internet_features")) {
2672 
2679  test_NameSpace();
2680  test_MimeFilter();
2685  test_user_agent();
2687  test_IsValidURL();
2689  }
2690 
2692 
2693  OleUninitialize();
2694 }
static PARSEACTION
Definition: misc.c:71
#define DEFINE_EXPECT(func)
Definition: misc.c:38
static ULONG WINAPI RefUnk_Release(IUnknown *iface)
Definition: misc.c:2068
HRESULT secur_hres
Definition: misc.c:336
static void test_FindMimeFromData(void)
Definition: misc.c:714
static const WCHAR image_pjpegW[]
Definition: mimefilter.c:491
enum FEATURE_SAFE_BINDTOOBJECT
LPCWSTR path
Definition: misc.c:339
DWORD dwOptions
Definition: solitaire.cpp:23
INTERNETFEATURELIST feature
Definition: misc.c:1689
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3257
static int argc
Definition: ServiceArgs.c:12
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1982
enum FEATURE_FORCE_ADDR_AND_STATUS
static BYTE data66[]
Definition: misc.c:560
BYTE * data
Definition: misc.c:595
BOOL WINAPI TranslateMessage(_In_ const MSG *)
static void test_CoInternetCompareUrl(void)
Definition: misc.c:420
static void test_MkParseDisplayNameEx(void)
Definition: misc.c:1579
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv)
Definition: misc.c:955
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
static BYTE data83[]
Definition: misc.c:577
enum FEATURE_FEEDS
static const struct @1647 default_feature_tests[]
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
CLSID CLSID_AboutProtocol
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:586
#define CHECK_CALLED(func)
Definition: misc.c:57
HRESULT hr
Definition: shlfolder.c:183
static const WCHAR wszHttpWineHQ[]
Definition: misc.c:329
BOOL todo
Definition: misc.c:1692
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
interface IBindCtx * LPBC
Definition: objfwd.h:18
static BYTE data51[]
Definition: misc.c:545
static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface, DWORD dwReserved, IBinding *pib)
Definition: misc.c:1956
static IInternetProtocolInfo protocol_info
Definition: misc.c:927
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2036
static BYTE data78[]
Definition: misc.c:572
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static BYTE data79[]
Definition: misc.c:573
const char * broken_mime
Definition: misc.c:481
static DWORD WINAPI bsc_thread(void *arg)
Definition: misc.c:2084
HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength, DWORD Reserved)
Definition: session.c:680
static BYTE data1[]
Definition: misc.c:495
static BYTE data35[]
Definition: misc.c:529
static BYTE data33[]
Definition: misc.c:527
static const char * szFeatureControlKey
Definition: misc.c:1744
REFIID riid
Definition: precomp.h:44
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
void WINAPI ReleaseBindInfo(BINDINFO *pbindinfo)
Definition: urlmon_main.c:572
static BOOL
Definition: misc.c:82
static const WCHAR empty[]
Definition: main.c:49
#define CP_ACP
Definition: compat.h:99
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:808
static BYTE data17[]
Definition: misc.c:511
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
enum FEATURE_ZONE_ELEVATION
static HANDLE thread_ready
Definition: misc.c:2082
static HRESULT(WINAPI *pCoInternetCompareUrl)(LPCWSTR
#define HKEY_CURRENT_USER
Definition: winreg.h:11
UINT NTAPI GlobalFlags(HGLOBAL hMem)
Definition: heapmem.c:520
static BYTE data43[]
Definition: misc.c:537
char CHAR
Definition: xmlstorage.h:175
static IClassFactory test_cf
Definition: misc.c:1000
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
HRESULT expected
Definition: misc.c:1691
static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface, REFIID riid, IUnknown *punk)
Definition: misc.c:2006
static BYTE data85[]
Definition: misc.c:579
DWORD uses_net
Definition: misc.c:436
HRESULT domain_hres
Definition: misc.c:342
static BYTE data4[]
Definition: misc.c:498
static const WCHAR url4e[]
Definition: misc.c:315
static void test_CoInternetParseUrl(void)
Definition: misc.c:357
LPCWSTR schema
Definition: misc.c:340
BOOL set_todo
Definition: misc.c:1858
REFIID LPVOID * ppv
Definition: atlbase.h:39
DWORD get_flags
Definition: misc.c:1690
static BYTE data45[]
Definition: misc.c:539
HRESULT WINAPI RevokeFormatEnumerator(LPBC pbc, IEnumFORMATETC *pEFetc)
Definition: format.c:210
static BYTE data53[]
Definition: misc.c:547
enum FEATURE_SECURITYBAND
static BYTE data26[]
Definition: misc.c:520
static const struct parse_test parse_tests[]
Definition: misc.c:347
const char * mime_pjpeg
Definition: misc.c:598
static BYTE data3[]
Definition: misc.c:497
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
enum FEATURE_DISABLE_TELNET_PROTOCOL
Definition: misc.c:2040
static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl
Definition: misc.c:917
Definition: tftpd.h:125
static BYTE data10[]
Definition: misc.c:504
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
static const WCHAR path3[]
Definition: misc.c:318
HRESULT set_expected
Definition: misc.c:1857
void * arg
Definition: msvc.h:12
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: tftpd.h:79
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
Definition: misc.c:976
static LPSTR
Definition: misc.c:33
static BYTE data93[]
Definition: misc.c:587
HRESULT rootdocument_hres
Definition: misc.c:344
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
static const WCHAR wszHttp[]
Definition: misc.c:323
static BYTE data44[]
Definition: misc.c:538
LPCWSTR rootdocument
Definition: misc.c:343
HRESULT get_expected
Definition: misc.c:1860
#define lstrlenW
Definition: compat.h:407
static BYTE data97[]
Definition: misc.c:591
#define E_FAIL
Definition: ddrawi.h:102
static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
Definition: misc.c:864
static const WCHAR wszWineHQ[]
Definition: misc.c:328
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:548
enum FEATURE_BLOCK_INPUT_PROMPTS
static const WCHAR url2[]
Definition: misc.c:300
enum FEATURE_MIME_HANDLING
static BYTE data27[]
Definition: misc.c:521
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static int dev
Definition: mkdosfs.c:536
static void test_NameSpace(void)
Definition: misc.c:1002
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
static BINDINFO in_bindinfo
Definition: misc.c:1930
static void test_internet_features_registry(void)
Definition: misc.c:1746
static LPVOID
Definition: misc.c:72
static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface, REFIID riid, void **ppv)
Definition: misc.c:1933
static int
Definition: misc.c:55
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static void register_protocols(void)
Definition: misc.c:831
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
BOOL get_todo
Definition: misc.c:1861
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static void test_internet_feature_defaults(void)
Definition: misc.c:1724
static BYTE data75[]
Definition: misc.c:569
static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
Definition: misc.c:909
enum FEATURE_XMLHTTP
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 BYTE data82[]
Definition: misc.c:576
static BYTE data98[]
Definition: misc.c:592
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
Definition: misc.c:945
static const IClassFactoryVtbl ClassFactoryVtbl
Definition: misc.c:982
static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl
Definition: misc.c:2023
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define CHECK_EXPECT2(func)
Definition: misc.c:51
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
enum FEATURE_BEHAVIORS
static BYTE data41[]
Definition: misc.c:535
static const WCHAR url5[]
Definition: misc.c:304
static BYTE data68[]
Definition: misc.c:562
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
Definition: main.c:440
IUnknown IUnknown_iface
Definition: misc.c:2041
static BYTE data6[]
Definition: misc.c:500
static HRESULT WINAPI BindStatusCallbackEx_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
Definition: misc.c:2012
static BYTE data14[]
Definition: misc.c:508
static BYTE data50[]
Definition: misc.c:544
static BYTE data15[]
Definition: misc.c:509
r reserved
Definition: btrfs.c:2893
#define S_FALSE
Definition: winerror.h:2357
static IBindStatusCallbackEx bsc
Definition: url.c:2149
static const struct @1645 mime_tests[]
static IClassFactory test_protocol_cf
Definition: misc.c:998
static STGMEDIUM in_stgmed
Definition: misc.c:1996
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
static void test_user_agent(void)
Definition: misc.c:1449
#define __HRESULT_FROM_WIN32(x)
Definition: winerror.h:85
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
static void test_CopyStgMedium(void)
Definition: misc.c:1220
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
static RefUnk unk_in
Definition: misc.c:2080
#define offsetof(TYPE, MEMBER)
static BYTE data87[]
Definition: misc.c:581