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