wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / urlmon / tests / misc.c
blob2b3df65d5fcdb989e785abe4739a97c08196963a
1 /*
2 * Copyright 2005-2006 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #define CONST_VTABLE
21 #define NONAMELESSUNION
23 #include <wine/test.h>
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdio.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "ole2.h"
31 #include "urlmon.h"
33 #include "initguid.h"
34 #include "wine/heap.h"
36 DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
38 #define DEFINE_EXPECT(func) \
39 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
41 #define SET_EXPECT(func) \
42 expect_ ## func = TRUE
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)
51 #define CHECK_EXPECT2(func) \
52 do { \
53 ok(expect_ ##func, "unexpected call " #func "\n"); \
54 called_ ## func = TRUE; \
55 }while(0)
57 #define CHECK_CALLED(func) \
58 do { \
59 ok(called_ ## func, "expected " #func "\n"); \
60 expect_ ## func = called_ ## func = FALSE; \
61 }while(0)
63 DEFINE_EXPECT(ParseUrl);
64 DEFINE_EXPECT(ParseUrl_ENCODE);
65 DEFINE_EXPECT(ParseUrl_UNESCAPE);
66 DEFINE_EXPECT(QI_IInternetProtocolInfo);
67 DEFINE_EXPECT(CreateInstance);
68 DEFINE_EXPECT(unk_Release);
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*);
87 static WCHAR *a2co(const char *str)
89 WCHAR *ret;
90 int len;
92 if(!str)
93 return NULL;
95 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
96 ret = CoTaskMemAlloc(len*sizeof(WCHAR));
97 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
99 return ret;
102 static void test_CreateFormatEnum(void)
104 IEnumFORMATETC *fenum = NULL, *fenum2 = NULL;
105 FORMATETC fetc[5];
106 ULONG ul;
107 HRESULT hres;
109 static DVTARGETDEVICE dev = {sizeof(dev),0,0,0,0,{0}};
110 static FORMATETC formatetc[] = {
111 {0,&dev,0,0,0},
112 {0,&dev,0,1,0},
113 {0,NULL,0,2,0},
114 {0,NULL,0,3,0},
115 {0,NULL,0,4,0}
118 hres = CreateFormatEnumerator(0, formatetc, &fenum);
119 ok(hres == E_FAIL, "CreateFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
120 hres = CreateFormatEnumerator(0, formatetc, NULL);
121 ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
122 hres = CreateFormatEnumerator(5, formatetc, NULL);
123 ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
126 hres = CreateFormatEnumerator(5, formatetc, &fenum);
127 ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
128 if(FAILED(hres))
129 return;
131 hres = IEnumFORMATETC_Next(fenum, 2, NULL, &ul);
132 ok(hres == E_INVALIDARG, "Next failed: %08x, expected E_INVALIDARG\n", hres);
133 ul = 100;
134 hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
135 ok(hres == S_OK, "Next failed: %08x\n", hres);
136 ok(ul == 0, "ul=%d, expected 0\n", ul);
138 hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
139 ok(hres == S_OK, "Next failed: %08x\n", hres);
140 ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
141 ok(fetc[1].lindex == 1, "fetc[1].lindex=%d, expected 1\n", fetc[1].lindex);
142 ok(fetc[0].ptd == &dev, "fetc[0].ptd=%p, expected %p\n", fetc[0].ptd, &dev);
143 ok(ul == 2, "ul=%d, expected 2\n", ul);
145 hres = IEnumFORMATETC_Skip(fenum, 1);
146 ok(hres == S_OK, "Skip failed: %08x\n", hres);
148 hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
149 ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
150 ok(fetc[0].lindex == 3, "fetc[0].lindex=%d, expected 3\n", fetc[0].lindex);
151 ok(fetc[1].lindex == 4, "fetc[1].lindex=%d, expected 4\n", fetc[1].lindex);
152 ok(fetc[0].ptd == NULL, "fetc[0].ptd=%p, expected NULL\n", fetc[0].ptd);
153 ok(ul == 2, "ul=%d, expected 2\n", ul);
155 hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
156 ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
157 ok(ul == 0, "ul=%d, expected 0\n", ul);
158 ul = 100;
159 hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
160 ok(hres == S_OK, "Next failed: %08x\n", hres);
161 ok(ul == 0, "ul=%d, expected 0\n", ul);
163 hres = IEnumFORMATETC_Skip(fenum, 3);
164 ok(hres == S_FALSE, "Skip failed: %08x, expected S_FALSE\n", hres);
166 hres = IEnumFORMATETC_Reset(fenum);
167 ok(hres == S_OK, "Reset failed: %08x\n", hres);
169 hres = IEnumFORMATETC_Next(fenum, 5, fetc, NULL);
170 ok(hres == S_OK, "Next failed: %08x\n", hres);
171 ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
173 hres = IEnumFORMATETC_Reset(fenum);
174 ok(hres == S_OK, "Reset failed: %08x\n", hres);
176 hres = IEnumFORMATETC_Skip(fenum, 2);
177 ok(hres == S_OK, "Skip failed: %08x\n", hres);
179 hres = IEnumFORMATETC_Clone(fenum, NULL);
180 ok(hres == E_INVALIDARG, "Clone failed: %08x, expected E_INVALIDARG\n", hres);
182 hres = IEnumFORMATETC_Clone(fenum, &fenum2);
183 ok(hres == S_OK, "Clone failed: %08x\n", hres);
185 if(SUCCEEDED(hres)) {
186 ok(fenum != fenum2, "fenum == fenum2\n");
188 hres = IEnumFORMATETC_Next(fenum2, 2, fetc, &ul);
189 ok(hres == S_OK, "Next failed: %08x\n", hres);
190 ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
192 IEnumFORMATETC_Release(fenum2);
195 hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
196 ok(hres == S_OK, "Next failed: %08x\n", hres);
197 ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
199 hres = IEnumFORMATETC_Skip(fenum, 1);
200 ok(hres == S_OK, "Skip failed: %08x\n", hres);
202 IEnumFORMATETC_Release(fenum);
205 static void test_RegisterFormatEnumerator(void)
207 IBindCtx *bctx = NULL;
208 IEnumFORMATETC *format = NULL, *format2 = NULL;
209 IUnknown *unk = NULL;
210 HRESULT hres;
212 static FORMATETC formatetc = {0,NULL,0,0,0};
213 static WCHAR wszEnumFORMATETC[] =
214 {'_','E','n','u','m','F','O','R','M','A','T','E','T','C','_',0};
216 CreateBindCtx(0, &bctx);
218 hres = CreateFormatEnumerator(1, &formatetc, &format);
219 ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
220 if(FAILED(hres))
221 return;
223 hres = RegisterFormatEnumerator(NULL, format, 0);
224 ok(hres == E_INVALIDARG,
225 "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
226 hres = RegisterFormatEnumerator(bctx, NULL, 0);
227 ok(hres == E_INVALIDARG,
228 "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
230 hres = RegisterFormatEnumerator(bctx, format, 0);
231 ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
233 hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
234 ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
235 ok(unk == (IUnknown*)format, "unk != format\n");
237 hres = RevokeFormatEnumerator(NULL, format);
238 ok(hres == E_INVALIDARG,
239 "RevokeFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
241 hres = RevokeFormatEnumerator(bctx, format);
242 ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
244 hres = RevokeFormatEnumerator(bctx, format);
245 ok(hres == E_FAIL, "RevokeFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
247 hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
248 ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
250 hres = RegisterFormatEnumerator(bctx, format, 0);
251 ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
253 hres = CreateFormatEnumerator(1, &formatetc, &format2);
254 ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
256 if(SUCCEEDED(hres)) {
257 hres = RevokeFormatEnumerator(bctx, format);
258 ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
260 IEnumFORMATETC_Release(format2);
263 hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
264 ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
266 IEnumFORMATETC_Release(format);
268 hres = RegisterFormatEnumerator(bctx, format, 0);
269 ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
270 hres = RevokeFormatEnumerator(bctx, NULL);
271 ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
272 hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
273 ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
275 IEnumFORMATETC_Release(format);
276 IBindCtx_Release(bctx);
278 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
279 '/','b','l','a','n','k','.','h','t','m',0};
280 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
281 static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
282 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
283 '%','2','e','j','p','g',0};
284 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
285 '.','o','r','g',0};
286 static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
287 static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
288 'f','i','l','e','.','t','e','s','t',0};
289 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
290 static const WCHAR url9[] =
291 {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
292 '/','s','i','t','e','/','a','b','o','u','t',0};
293 static const WCHAR url10[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e','.','*','.',
294 'c','o','m',0};
295 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
296 '.','j','p','g',0};
298 static const WCHAR path3[] = {'c',':','\\','I','n','d','e','x','.','h','t','m',0};
299 static const WCHAR path4[] = {'s','o','m','e',' ','f','i','l','e','.','j','p','g',0};
301 static const WCHAR wszRes[] = {'r','e','s',0};
302 static const WCHAR wszFile[] = {'f','i','l','e',0};
303 static const WCHAR wszHttp[] = {'h','t','t','p',0};
304 static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
305 static const WCHAR wszEmpty[] = {0};
306 static const WCHAR wszGoogle[] = {'g','o','o','g','l','e','.','*','.','c','o','m',0};
308 static const WCHAR wszWineHQ[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
309 static const WCHAR wszHttpWineHQ[] = {'h','t','t','p',':','/','/','w','w','w','.',
310 'w','i','n','e','h','q','.','o','r','g',0};
311 static const WCHAR wszHttpGoogle[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e',
312 '.','*','.','c','o','m',0};
314 struct parse_test {
315 LPCWSTR url;
316 HRESULT secur_hres;
317 LPCWSTR encoded_url;
318 HRESULT path_hres;
319 LPCWSTR path;
320 LPCWSTR schema;
321 LPCWSTR domain;
322 HRESULT domain_hres;
323 LPCWSTR rootdocument;
324 HRESULT rootdocument_hres;
327 static const struct parse_test parse_tests[] = {
328 {url1, S_OK, url1, E_INVALIDARG, NULL, wszRes, NULL, E_FAIL, NULL, E_FAIL},
329 {url2, E_FAIL, url2, E_INVALIDARG, NULL, wszEmpty, NULL, E_FAIL, NULL, E_FAIL},
330 {url3, E_FAIL, url3, S_OK, path3, wszFile, wszEmpty, S_OK, NULL, E_FAIL},
331 {url4, E_FAIL, url4e, S_OK, path4, wszFile, wszEmpty, S_OK, NULL, E_FAIL},
332 {url5, E_FAIL, url5, E_INVALIDARG, NULL, wszHttp, wszWineHQ, S_OK, wszHttpWineHQ, S_OK},
333 {url6, S_OK, url6, E_INVALIDARG, NULL, wszAbout, NULL, E_FAIL, NULL, E_FAIL},
334 {url10, E_FAIL, url10, E_INVALIDARG,NULL, wszHttp, wszGoogle, S_OK, wszHttpGoogle, S_OK}
337 static void test_CoInternetParseUrl(void)
339 HRESULT hres;
340 DWORD size;
341 int i;
343 static WCHAR buf[4096];
345 memset(buf, 0xf0, sizeof(buf));
346 hres = pCoInternetParseUrl(parse_tests[0].url, PARSE_SCHEMA, 0, buf,
347 3, &size, 0);
348 ok(hres == E_POINTER, "schema failed: %08x, expected E_POINTER\n", hres);
350 for(i = 0; i < ARRAY_SIZE(parse_tests); i++) {
351 memset(buf, 0xf0, sizeof(buf));
352 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SECURITY_URL, 0, buf,
353 ARRAY_SIZE(buf), &size, 0);
354 ok(hres == parse_tests[i].secur_hres, "[%d] security url failed: %08x, expected %08x\n",
355 i, hres, parse_tests[i].secur_hres);
357 memset(buf, 0xf0, sizeof(buf));
358 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ENCODE, 0, buf,
359 ARRAY_SIZE(buf), &size, 0);
360 ok(hres == S_OK, "[%d] encoding failed: %08x\n", i, hres);
361 ok(size == lstrlenW(parse_tests[i].encoded_url), "[%d] wrong size\n", i);
362 ok(!lstrcmpW(parse_tests[i].encoded_url, buf), "[%d] wrong encoded url\n", i);
364 memset(buf, 0xf0, sizeof(buf));
365 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_UNESCAPE, 0, buf,
366 ARRAY_SIZE(buf), &size, 0);
367 ok(hres == S_OK, "[%d] encoding failed: %08x\n", i, hres);
368 ok(size == lstrlenW(parse_tests[i].encoded_url), "[%d] wrong size\n", i);
369 ok(!lstrcmpW(parse_tests[i].encoded_url, buf), "[%d] wrong encoded url\n", i);
371 memset(buf, 0xf0, sizeof(buf));
372 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_PATH_FROM_URL, 0, buf,
373 ARRAY_SIZE(buf), &size, 0);
374 ok(hres == parse_tests[i].path_hres, "[%d] path failed: %08x, expected %08x\n",
375 i, hres, parse_tests[i].path_hres);
376 if(parse_tests[i].path) {
377 ok(size == lstrlenW(parse_tests[i].path), "[%d] wrong size\n", i);
378 ok(!lstrcmpW(parse_tests[i].path, buf), "[%d] wrong path\n", i);
381 memset(buf, 0xf0, sizeof(buf));
382 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SCHEMA, 0, buf,
383 ARRAY_SIZE(buf), &size, 0);
384 ok(hres == S_OK, "[%d] schema failed: %08x\n", i, hres);
385 ok(size == lstrlenW(parse_tests[i].schema), "[%d] wrong size\n", i);
386 ok(!lstrcmpW(parse_tests[i].schema, buf), "[%d] wrong schema\n", i);
388 if(memcmp(parse_tests[i].url, wszRes, 3*sizeof(WCHAR))
389 && memcmp(parse_tests[i].url, wszAbout, 5*sizeof(WCHAR))) {
390 memset(buf, 0xf0, sizeof(buf));
391 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_DOMAIN, 0, buf,
392 ARRAY_SIZE(buf), &size, 0);
393 ok(hres == parse_tests[i].domain_hres, "[%d] domain failed: %08x\n", i, hres);
394 if(parse_tests[i].domain)
395 ok(!lstrcmpW(parse_tests[i].domain, buf), "[%d] wrong domain, received %s\n", i, wine_dbgstr_w(buf));
398 memset(buf, 0xf0, sizeof(buf));
399 hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ROOTDOCUMENT, 0, buf,
400 ARRAY_SIZE(buf), &size, 0);
401 ok(hres == parse_tests[i].rootdocument_hres, "[%d] rootdocument failed: %08x\n", i, hres);
402 if(parse_tests[i].rootdocument)
403 ok(!lstrcmpW(parse_tests[i].rootdocument, buf), "[%d] wrong rootdocument, received %s\n", i, wine_dbgstr_w(buf));
407 static void test_CoInternetCompareUrl(void)
409 HRESULT hres;
411 hres = pCoInternetCompareUrl(url1, url1, 0);
412 ok(hres == S_OK, "CoInternetCompareUrl failed: %08x\n", hres);
414 hres = pCoInternetCompareUrl(url1, url3, 0);
415 ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
417 hres = pCoInternetCompareUrl(url3, url1, 0);
418 ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
421 static const struct {
422 LPCWSTR url;
423 DWORD uses_net;
424 } query_info_tests[] = {
425 {url1, 0},
426 {url2, 0},
427 {url3, 0},
428 {url4, 0},
429 {url5, 0},
430 {url6, 0},
431 {url7, 0},
432 {url8, 0}
435 static void test_CoInternetQueryInfo(void)
437 BYTE buf[100];
438 DWORD cb, i;
439 HRESULT hres;
441 for(i = 0; i < ARRAY_SIZE(query_info_tests); i++) {
442 cb = 0xdeadbeef;
443 memset(buf, '?', sizeof(buf));
444 hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), &cb, 0);
445 ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
446 ok(cb == sizeof(DWORD), "[%d] cb = %d\n", i, cb);
447 ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
448 i, *(DWORD*)buf, query_info_tests[i].uses_net);
450 hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, 3, &cb, 0);
451 ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
452 hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, NULL, sizeof(buf), &cb, 0);
453 ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
455 memset(buf, '?', sizeof(buf));
456 hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), NULL, 0);
457 ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
458 ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
459 i, *(DWORD*)buf, query_info_tests[i].uses_net);
463 static const struct {
464 const WCHAR *url;
465 const WCHAR *mime;
466 HRESULT hres;
467 BOOL broken_failure;
468 const WCHAR *broken_mime;
469 } mime_tests[] = {
470 {L"res://mshtml.dll/blank.htm", L"text/html", S_OK},
471 {L"index.htm", L"text/html", S_OK},
472 {L"file://c:\\Index.htm", L"text/html", S_OK},
473 {L"file://c:\\Index.htm?q=test", L"text/html", S_OK, TRUE},
474 {L"file://c:\\Index.htm#hash_part", L"text/html", S_OK, TRUE},
475 {L"file://c:\\Index.htm#hash_part.txt", L"text/html", S_OK, FALSE, L"text/plain"},
476 {L"file://some%20file%2ejpg", NULL, E_FAIL},
477 {L"http://www.winehq.org", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)},
478 {L"about:blank", NULL, E_FAIL},
479 {L"ftp://winehq.org/file.test", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)}
482 static BYTE data1[] = "test data\n";
483 static BYTE data2[] = {31,'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0};
484 static BYTE data3[] = {0,0,0};
485 static BYTE data4[] = {'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0,0};
486 static BYTE data5[] = {0xa,0xa,0xa,'x',32,'x',0};
487 static BYTE data6[] = {0xfa,0xfa,0xfa,0xfa,'\n','\r','\t','x','x','x',1};
488 static BYTE data7[] = "<html>blahblah";
489 static BYTE data8[] = {'t','e','s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
490 static BYTE data9[] = {'t','e',0,'s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
491 static BYTE data10[] = "<HtmL>blahblah";
492 static BYTE data11[] = "blah<HTML>blahblah";
493 static BYTE data12[] = "blah<HTMLblahblah";
494 static BYTE data13[] = "blahHTML>blahblah";
495 static BYTE data14[] = "blah<HTMblahblah";
496 static BYTE data15[] = {0xff,0xd8};
497 static BYTE data16[] = {0xff,0xd8,'h'};
498 static BYTE data17[] = {0,0xff,0xd8};
499 static BYTE data18[] = {0xff,0xd8,'<','h','t','m','l','>'};
500 static BYTE data19[] = {'G','I','F','8','7','a'};
501 static BYTE data20[] = {'G','I','F','8','9','a'};
502 static BYTE data21[] = {'G','I','F','8','7'};
503 static BYTE data22[] = {'G','i','F','8','7','a'};
504 static BYTE data23[] = {'G','i','F','8','8','a'};
505 static BYTE data24[] = {'g','i','f','8','7','a'};
506 static BYTE data25[] = {'G','i','F','8','7','A'};
507 static BYTE data26[] = {'G','i','F','8','7','a','<','h','t','m','l','>'};
508 static BYTE data27[] = {0x30,'G','i','F','8','7','A'};
509 static BYTE data28[] = {0x42,0x4d,0x6e,0x42,0x1c,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00};
510 static BYTE data29[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x','x'};
511 static BYTE data30[] = {0x42,0x4d,'x','x','x','x',0x00,0x01,0x00,0x00,'x','x','x','x'};
512 static BYTE data31[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'<','h','t','m','l','>'};
513 static BYTE data32[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
514 static BYTE data33[] = {0x00,0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
515 static BYTE data34[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
516 static BYTE data35[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x','x','x','x',0};
517 static BYTE data36[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,'x','x'};
518 static BYTE data37[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'<','h','t','m','l','>'};
519 static BYTE data38[] = {0x00,0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
520 static BYTE data39[] = {0x4d,0x4d,0x00,0x2a,0xff};
521 static BYTE data40[] = {0x4d,0x4d,0x00,0x2a,'<','h','t','m','l','>',0};
522 static BYTE data41[] = {0x4d,0x4d,0xff};
523 static BYTE data42[] = {0x4d,0x4d};
524 static BYTE data43[] = {0x00,0x4d,0x4d,0x00};
525 static BYTE data44[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
526 static BYTE data45[] = {'R','I','F','f',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
527 static BYTE data46[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20};
528 static BYTE data47[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x21,0xff};
529 static BYTE data48[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,'<','h','t','m','l','>'};
530 static BYTE data49[] = {'R','I','F','F',0x0f,0x0f,0xf0,0xf0,'A','V','I',0x20,0xf0,0x00};
531 static BYTE data50[] = {0x00,0x00,0x01,0xb3,0xff};
532 static BYTE data51[] = {0x00,0x00,0x01,0xba,0xff};
533 static BYTE data52[] = {0x00,0x00,0x01,0xb8,0xff};
534 static BYTE data53[] = {0x00,0x00,0x01,0xba};
535 static BYTE data54[] = {0x00,0x00,0x01,0xba,'<','h','t','m','l','>'};
536 static BYTE data55[] = {0x1f,0x8b,'x'};
537 static BYTE data56[] = {0x1f};
538 static BYTE data57[] = {0x1f,0x8b,'<','h','t','m','l','>','t','e','s','t',0};
539 static BYTE data58[] = {0x1f,0x8b};
540 static BYTE data59[] = {0x50,0x4b,'x'};
541 static BYTE data60[] = {0x50,0x4b};
542 static BYTE data61[] = {0x50,0x4b,'<','h','t','m','l','>',0};
543 static BYTE data62[] = {0xca,0xfe,0xba,0xbe,'x'};
544 static BYTE data63[] = {0xca,0xfe,0xba,0xbe};
545 static BYTE data64[] = {0xca,0xfe,0xba,0xbe,'<','h','t','m','l','>',0};
546 static BYTE data65[] = {0x25,0x50,0x44,0x46,'x'};
547 static BYTE data66[] = {0x25,0x50,0x44,0x46};
548 static BYTE data67[] = {0x25,0x50,0x44,0x46,'x','<','h','t','m','l','>'};
549 static BYTE data68[] = {'M','Z','x'};
550 static BYTE data69[] = {'M','Z'};
551 static BYTE data70[] = {'M','Z','<','h','t','m','l','>',0xff};
552 static BYTE data71[] = {'{','\\','r','t','f',0};
553 static BYTE data72[] = {'{','\\','r','t','f'};
554 static BYTE data73[] = {' ','{','\\','r','t','f',' '};
555 static BYTE data74[] = {'{','\\','r','t','f','<','h','t','m','l','>',' '};
556 static BYTE data75[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E',0xff};
557 static BYTE data76[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E'};
558 static BYTE data77[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V',0xff,0xff};
559 static BYTE data78[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'<','h','t','m','l','>',0xff};
560 static BYTE data79[] = {'%','!',0xff};
561 static BYTE data80[] = {'%','!'};
562 static BYTE data81[] = {'%','!','P','S','<','h','t','m','l','>'};
563 static BYTE data82[] = {'.','s','n','d',0};
564 static BYTE data83[] = {'.','s','n','d'};
565 static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1};
566 static BYTE data85[] = {'.','S','N','D',0};
567 static BYTE data86[] = {0x49,0x49,0x2a,0xff};
568 static BYTE data87[] = {' ','<','h','e','a','d'};
569 static BYTE data88[] = {' ','<','h','e','a','d','>'};
570 static BYTE data89[] = {'\t','\r','<','h','e','a','d','>'};
571 static BYTE data90[] = {'<','H','e','A','d',' '};
572 static BYTE data91[] = {'<','?','x','m','l',' ',0};
573 static BYTE data92[] = {'a','b','c','<','?','x','m','l',' ',' '};
574 static BYTE data93[] = {'<','?','x','m','l',' ',' ','<','h','t','m','l','>'};
575 static BYTE data94[] = {'<','h','t','m','l','>','<','?','x','m','l',' ',' '};
576 static BYTE data95[] = {'{','\\','r','t','f','<','?','x','m','l',' ',' '};
577 static BYTE data96[] = {'<','?','x','m','l',' '};
578 static BYTE data97[] = "<body";
579 static BYTE data98[] = "blah<BoDyblahblah";
581 static const struct {
582 BYTE *data;
583 DWORD size;
584 const WCHAR *mime;
585 const WCHAR *mime_pjpeg;
586 const WCHAR *broken_mime;
587 const WCHAR *url;
588 const WCHAR *proposed_mime;
589 } mime_tests2[] = {
590 {data1, sizeof(data1), L"text/plain"},
591 {data2, sizeof(data2), L"application/octet-stream", L"image/pjpeg"},
592 {data3, sizeof(data3), L"application/octet-stream", L"image/pjpeg"},
593 {data4, sizeof(data4), L"application/octet-stream", L"image/pjpeg"},
594 {data5, sizeof(data5), L"text/plain"},
595 {data6, sizeof(data6), L"text/plain"},
596 {data7, sizeof(data7), L"text/html", L"text/plain"},
597 {data8, sizeof(data8), L"text/html", L"text/plain"},
598 {data9, sizeof(data9), L"text/html", L"image/pjpeg"},
599 {data10, sizeof(data10), L"text/html", L"text/plain"},
600 {data11, sizeof(data11), L"text/html", L"text/plain"},
601 {data12, sizeof(data12), L"text/html", L"text/plain"},
602 {data13, sizeof(data13), L"text/plain"},
603 {data14, sizeof(data14), L"text/plain"},
604 {data15, sizeof(data15), L"text/plain"},
605 {data16, sizeof(data16), L"image/pjpeg"},
606 {data17, sizeof(data17), L"application/octet-stream", L"image/pjpeg"},
607 {data18, sizeof(data18), L"text/html", L"image/pjpeg"},
608 {data19, sizeof(data19), L"image/gif"},
609 {data20, sizeof(data20), L"image/gif"},
610 {data21, sizeof(data21), L"text/plain"},
611 {data22, sizeof(data22), L"image/gif"},
612 {data23, sizeof(data23), L"text/plain"},
613 {data24, sizeof(data24), L"image/gif"},
614 {data25, sizeof(data25), L"image/gif"},
615 {data26, sizeof(data26), L"text/html", L"image/gif"},
616 {data27, sizeof(data27), L"text/plain"},
617 {data28, sizeof(data28), L"image/bmp"},
618 {data29, sizeof(data29), L"image/bmp"},
619 {data30, sizeof(data30), L"application/octet-stream", L"image/pjpeg"},
620 {data31, sizeof(data31), L"text/html", L"image/bmp"},
621 {data32, sizeof(data32), L"application/octet-stream", L"image/pjpeg"},
622 {data33, sizeof(data33), L"application/octet-stream", L"image/pjpeg"},
623 {data34, sizeof(data34), L"image/x-png"},
624 {data35, sizeof(data35), L"image/x-png"},
625 {data36, sizeof(data36), L"application/octet-stream", L"image/pjpeg"},
626 {data37, sizeof(data37), L"text/html", L"image/x-png"},
627 {data38, sizeof(data38), L"application/octet-stream", L"image/pjpeg"},
628 {data39, sizeof(data39), L"image/tiff"},
629 {data40, sizeof(data40), L"text/html", L"image/tiff"},
630 {data41, sizeof(data41), L"text/plain", NULL, L"image/tiff"},
631 {data42, sizeof(data42), L"text/plain"},
632 {data43, sizeof(data43), L"application/octet-stream", L"image/pjpeg"},
633 {data44, sizeof(data44), L"video/avi"},
634 {data45, sizeof(data45), L"text/plain"},
635 {data46, sizeof(data46), L"text/plain"},
636 {data47, sizeof(data47), L"text/plain"},
637 {data48, sizeof(data48), L"text/html", L"video/avi"},
638 {data49, sizeof(data49), L"video/avi"},
639 {data50, sizeof(data50), L"video/mpeg"},
640 {data51, sizeof(data51), L"video/mpeg"},
641 {data52, sizeof(data52), L"application/octet-stream", L"image/pjpeg"},
642 {data53, sizeof(data53), L"application/octet-stream", L"image/pjpeg", L"image/x-icon"},
643 {data54, sizeof(data54), L"text/html", L"video/mpeg"},
644 {data55, sizeof(data55), L"application/x-gzip-compressed"},
645 {data56, sizeof(data56), L"text/plain"},
646 {data57, sizeof(data57), L"text/html", L"application/x-gzip-compressed"},
647 {data58, sizeof(data58), L"application/octet-stream", L"image/pjpeg"},
648 {data59, sizeof(data59), L"application/x-zip-compressed"},
649 {data60, sizeof(data60), L"text/plain"},
650 {data61, sizeof(data61), L"text/html", L"application/x-zip-compressed"},
651 {data62, sizeof(data62), L"application/java"},
652 {data63, sizeof(data63), L"text/plain"},
653 {data64, sizeof(data64), L"text/html", L"application/java"},
654 {data65, sizeof(data65), L"application/pdf"},
655 {data66, sizeof(data66), L"text/plain"},
656 {data67, sizeof(data67), L"text/html", L"application/pdf"},
657 {data68, sizeof(data68), L"application/x-msdownload"},
658 {data69, sizeof(data69), L"text/plain"},
659 {data70, sizeof(data70), L"text/html", L"application/x-msdownload"},
660 {data71, sizeof(data71), L"text/richtext"},
661 {data72, sizeof(data72), L"text/plain"},
662 {data73, sizeof(data73), L"text/plain"},
663 {data74, sizeof(data74), L"text/html", L"text/richtext"},
664 {data75, sizeof(data75), L"audio/wav"},
665 {data76, sizeof(data76), L"text/plain"},
666 {data77, sizeof(data77), L"text/plain"},
667 {data78, sizeof(data78), L"text/html", L"text/plain"},
668 {data79, sizeof(data79), L"application/postscript"},
669 {data80, sizeof(data80), L"text/plain"},
670 {data81, sizeof(data81), L"text/html", L"application/postscript"},
671 {data82, sizeof(data82), L"audio/basic"},
672 {data83, sizeof(data83), L"text/plain"},
673 {data84, sizeof(data84), L"text/html", L"audio/basic"},
674 {data85, sizeof(data85), L"text/plain"},
675 {data86, sizeof(data86), L"image/tiff", NULL, L"text/plain"},
676 {data87, sizeof(data87), L"text/plain"},
677 {data88, sizeof(data88), L"text/html", L"text/plain"},
678 {data89, sizeof(data89), L"text/html", L"text/plain"},
679 {data90, sizeof(data90), L"text/html", L"text/plain"},
680 {data91, sizeof(data91), L"text/xml", L"text/plain"},
681 {data92, sizeof(data92), L"text/xml", L"text/plain"},
682 {data93, sizeof(data93), L"text/xml", L"text/plain"},
683 {data94, sizeof(data94), L"text/html", L"text/plain"},
684 {data95, sizeof(data95), L"text/xml", L"text/richtext"},
685 {data96, sizeof(data96), L"text/plain"},
686 {data97, sizeof(data97), L"text/html", L"text/plain"},
687 {data98, sizeof(data98), L"text/html", L"text/plain"},
688 {data1, sizeof(data1), L"text/plain", NULL, NULL, L"res://mshtml.dll/blank.htm"},
689 {NULL, 0, L"text/html", NULL, NULL, L"res://mshtml.dll/blank.htm"},
690 {data1, sizeof(data1), L"text/plain", NULL, NULL, L"res://mshtml.dll/blank.htm", L"application/octet-stream"},
691 {data1, sizeof(data1), L"text/plain", NULL, NULL, L"file:some%20file%2ejpg", L"application/octet-stream"},
692 {NULL, sizeof(data1), L"text/html", NULL, NULL, L"res://mshtml.dll/blank.htm"},
693 {data1, sizeof(data1), L"text/css", NULL, NULL, L"http://www.winehq.org/test.css"},
694 {data2, sizeof(data2), L"text/css", NULL, NULL, L"http://www.winehq.org/test.css"},
695 {data10, sizeof(data10), L"text/html", NULL, NULL, L"http://www.winehq.org/test.css"},
696 {data1, sizeof(data1), L"text/css", NULL, NULL, L"http://www.winehq.org/test.css", L"text/plain"},
697 {data1, sizeof(data1), L"text/css", NULL, NULL, L"http://www.winehq.org/test.css", L"application/octet-stream"},
698 {data1, sizeof(data1), L"text/test", NULL, NULL, L"http://www.winehq.org/test.css", L"text/test"}
701 static void test_FindMimeFromData(void)
703 WCHAR *mime;
704 HRESULT hres;
705 BYTE b;
706 int i;
708 static const WCHAR app_octet_streamW[] =
709 {'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m',0};
710 static const WCHAR image_pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
711 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
712 static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n',0};
714 for(i = 0; i < ARRAY_SIZE(mime_tests); i++) {
715 mime = (LPWSTR)0xf0f0f0f0;
716 hres = pFindMimeFromData(NULL, mime_tests[i].url, NULL, 0, NULL, 0, &mime, 0);
717 if(mime_tests[i].mime) {
718 ok(hres == S_OK || broken(mime_tests[i].broken_failure), "[%d] FindMimeFromData failed: %08x\n", i, hres);
719 if(hres == S_OK) {
720 ok(!lstrcmpW(mime, mime_tests[i].mime)
721 || broken(mime_tests[i].broken_mime && !lstrcmpW(mime, mime_tests[i].broken_mime)),
722 "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
723 CoTaskMemFree(mime);
725 }else {
726 ok(hres == E_FAIL || hres == mime_tests[i].hres,
727 "[%d] FindMimeFromData failed: %08x, expected %08x\n",
728 i, hres, mime_tests[i].hres);
729 ok(mime == (LPWSTR)0xf0f0f0f0, "[%d] mime != 0xf0f0f0f0\n", i);
732 mime = (LPWSTR)0xf0f0f0f0;
733 hres = pFindMimeFromData(NULL, mime_tests[i].url, NULL, 0, text_plainW, 0, &mime, 0);
734 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
735 ok(!lstrcmpW(mime, L"text/plain"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
736 CoTaskMemFree(mime);
738 mime = (LPWSTR)0xf0f0f0f0;
739 hres = pFindMimeFromData(NULL, mime_tests[i].url, NULL, 0, app_octet_streamW, 0, &mime, 0);
740 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
741 ok(!lstrcmpW(mime, L"application/octet-stream"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
742 CoTaskMemFree(mime);
745 for(i = 0; i < ARRAY_SIZE(mime_tests2); i++) {
746 hres = pFindMimeFromData(NULL, mime_tests2[i].url, mime_tests2[i].data, mime_tests2[i].size,
747 mime_tests2[i].proposed_mime, 0, &mime, 0);
748 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
749 b = !lstrcmpW(mime, mime_tests2[i].mime);
750 ok(b || broken(mime_tests2[i].broken_mime && !lstrcmpW(mime, mime_tests2[i].broken_mime)),
751 "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
752 CoTaskMemFree(mime);
753 if(!b || mime_tests2[i].url || mime_tests2[i].proposed_mime)
754 continue;
756 hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
757 app_octet_streamW, 0, &mime, 0);
758 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
759 ok(!lstrcmpW(mime, mime_tests2[i].mime) || broken(mime_tests2[i].broken_mime
760 && !lstrcmpW(mime, mime_tests2[i].broken_mime)),
761 "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
762 CoTaskMemFree(mime);
764 hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
765 text_plainW, 0, &mime, 0);
766 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
767 ok(!lstrcmpW(mime, mime_tests2[i].mime) || broken(mime_tests2[i].broken_mime
768 && !lstrcmpW(mime, mime_tests2[i].broken_mime)),
769 "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
770 CoTaskMemFree(mime);
772 hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
773 text_htmlW, 0, &mime, 0);
774 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
775 if(!lstrcmpW(L"application/octet-stream", mime_tests2[i].mime)
776 || !lstrcmpW(L"text/plain", mime_tests2[i].mime) || i==92)
777 ok(!lstrcmpW(mime, L"text/html"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
778 else
779 ok(!lstrcmpW(mime, mime_tests2[i].mime), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
780 CoTaskMemFree(mime);
782 hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
783 image_pjpegW, 0, &mime, 0);
784 ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
785 ok(!lstrcmpW(mime, mime_tests2[i].mime_pjpeg ? mime_tests2[i].mime_pjpeg : mime_tests2[i].mime)
786 || broken(!lstrcmpW(mime, mime_tests2[i].mime)),
787 "[%d] wrong mime, got %s\n", i, wine_dbgstr_w(mime));
788 CoTaskMemFree(mime);
791 hres = pFindMimeFromData(NULL, NULL, NULL, 0, NULL, 0, &mime, 0);
792 ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
794 hres = pFindMimeFromData(NULL, NULL, NULL, 0, text_plainW, 0, &mime, 0);
795 ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
797 hres = pFindMimeFromData(NULL, NULL, data1, 0, NULL, 0, &mime, 0);
798 ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
800 hres = pFindMimeFromData(NULL, url1, data1, 0, NULL, 0, &mime, 0);
801 ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
803 hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, &mime, 0);
804 ok(hres == S_OK, "FindMimeFromData failed: %08x\n", hres);
805 ok(!lstrcmpW(mime, L"text/plain"), "wrong mime: %s\n", wine_dbgstr_w(mime));
806 CoTaskMemFree(mime);
808 hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, NULL, 0);
809 ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
812 static void register_protocols(void)
814 IInternetSession *session;
815 IClassFactory *factory;
816 HRESULT hres;
818 static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
820 hres = pCoInternetGetSession(0, &session, 0);
821 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
822 if(FAILED(hres))
823 return;
825 hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL,
826 &IID_IClassFactory, (void**)&factory);
827 ok(hres == S_OK, "Could not get AboutProtocol factory: %08x\n", hres);
828 if(FAILED(hres))
829 return;
831 IInternetSession_RegisterNameSpace(session, factory, &CLSID_AboutProtocol,
832 wszAbout, 0, NULL, 0);
833 IClassFactory_Release(factory);
835 IInternetSession_Release(session);
838 static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
839 REFIID riid, void **ppv)
841 ok(0, "unexpected call\n");
842 return E_NOINTERFACE;
845 static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
847 return 2;
850 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
852 return 1;
855 static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
856 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
857 DWORD *pcchResult, DWORD dwReserved)
859 switch(ParseAction) {
860 case PARSE_SECURITY_URL:
861 CHECK_EXPECT2(ParseUrl);
862 if(pcchResult)
863 *pcchResult = ARRAY_SIZE(url1);
865 if(cchResult < ARRAY_SIZE(url1))
866 return S_FALSE;
868 memcpy(pwzResult, url1, sizeof(url1));
869 return S_OK;
870 case PARSE_ENCODE:
871 CHECK_EXPECT2(ParseUrl_ENCODE);
872 break;
874 case PARSE_UNESCAPE:
875 CHECK_EXPECT2(ParseUrl_UNESCAPE);
876 break;
878 default:
879 CHECK_EXPECT2(ParseUrl);
880 break;
883 return E_NOTIMPL;
886 static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
887 LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
888 LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
890 ok(0, "unexpected call\n");
891 return E_NOTIMPL;
894 static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface,
895 LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
897 ok(0, "unexpected call\n");
898 return E_NOTIMPL;
901 static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface,
902 LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
903 DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
905 ok(0, "unexpected call\n");
906 return E_NOTIMPL;
909 static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
910 InternetProtocolInfo_QueryInterface,
911 InternetProtocolInfo_AddRef,
912 InternetProtocolInfo_Release,
913 InternetProtocolInfo_ParseUrl,
914 InternetProtocolInfo_CombineUrl,
915 InternetProtocolInfo_CompareUrl,
916 InternetProtocolInfo_QueryInfo
919 static IInternetProtocolInfo protocol_info = { &InternetProtocolInfoVtbl };
921 static HRESULT qiret;
922 static IClassFactory *expect_cf;
924 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
926 if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
927 CHECK_EXPECT2(QI_IInternetProtocolInfo);
928 ok(iface == expect_cf, "unexpected iface\n");
929 *ppv = &protocol_info;
930 return qiret;
933 ok(0, "unexpected call\n");
934 return E_NOINTERFACE;
937 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
939 return 2;
942 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
944 return 1;
947 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
948 REFIID riid, void **ppv)
950 ok(0, "unexpected call\n");
951 return E_NOTIMPL;
954 static HRESULT WINAPI ProtocolCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
955 REFIID riid, void **ppv)
957 CHECK_EXPECT(CreateInstance);
959 ok(iface == expect_cf, "unexpected iface\n");
960 ok(pOuter == NULL, "pOuter = %p\n", pOuter);
961 ok(IsEqualGUID(&IID_IInternetProtocolInfo, riid), "unexpected riid\n");
962 ok(ppv != NULL, "ppv == NULL\n");
964 *ppv = &protocol_info;
965 return S_OK;
968 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
970 ok(0, "unexpected call\n");
971 return S_OK;
974 static const IClassFactoryVtbl ClassFactoryVtbl = {
975 ClassFactory_QueryInterface,
976 ClassFactory_AddRef,
977 ClassFactory_Release,
978 ClassFactory_CreateInstance,
979 ClassFactory_LockServer
982 static const IClassFactoryVtbl ProtocolCFVtbl = {
983 ClassFactory_QueryInterface,
984 ClassFactory_AddRef,
985 ClassFactory_Release,
986 ProtocolCF_CreateInstance,
987 ClassFactory_LockServer
990 static IClassFactory test_protocol_cf = { &ProtocolCFVtbl };
991 static IClassFactory test_protocol_cf2 = { &ProtocolCFVtbl };
992 static IClassFactory test_cf = { &ClassFactoryVtbl };
994 static void test_NameSpace(void)
996 IInternetSession *session;
997 WCHAR buf[200];
998 LPWSTR sec_url;
999 DWORD size;
1000 HRESULT hres;
1002 static const WCHAR wszTest[] = {'t','e','s','t',0};
1004 hres = pCoInternetGetSession(0, &session, 0);
1005 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1006 if(FAILED(hres))
1007 return;
1009 hres = IInternetSession_RegisterNameSpace(session, NULL, &IID_NULL,
1010 wszTest, 0, NULL, 0);
1011 ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1013 hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1014 NULL, 0, NULL, 0);
1015 ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1017 hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1018 wszTest, 0, NULL, 0);
1019 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1021 qiret = E_NOINTERFACE;
1022 expect_cf = &test_protocol_cf;
1023 SET_EXPECT(QI_IInternetProtocolInfo);
1024 SET_EXPECT(CreateInstance);
1025 SET_EXPECT(ParseUrl_ENCODE);
1027 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1028 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1030 CHECK_CALLED(QI_IInternetProtocolInfo);
1031 CHECK_CALLED(CreateInstance);
1032 CHECK_CALLED(ParseUrl_ENCODE);
1034 qiret = S_OK;
1035 SET_EXPECT(QI_IInternetProtocolInfo);
1036 SET_EXPECT(ParseUrl_ENCODE);
1038 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1039 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1041 CHECK_CALLED(QI_IInternetProtocolInfo);
1042 CHECK_CALLED(ParseUrl_ENCODE);
1044 qiret = S_OK;
1045 SET_EXPECT(QI_IInternetProtocolInfo);
1046 SET_EXPECT(ParseUrl_UNESCAPE);
1048 hres = pCoInternetParseUrl(url8, PARSE_UNESCAPE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1049 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1051 CHECK_CALLED(QI_IInternetProtocolInfo);
1052 CHECK_CALLED(ParseUrl_UNESCAPE);
1054 SET_EXPECT(QI_IInternetProtocolInfo);
1055 SET_EXPECT(ParseUrl);
1057 hres = pCoInternetParseUrl(url8, PARSE_SECURITY_URL, 0, buf, ARRAY_SIZE(buf), &size, 0);
1058 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1059 ok(size == ARRAY_SIZE(url1), "Size = %d\n", size);
1060 if(size == ARRAY_SIZE(url1))
1061 ok(!memcmp(buf, url1, sizeof(url1)), "Encoded url = %s\n", wine_dbgstr_w(buf));
1063 CHECK_CALLED(QI_IInternetProtocolInfo);
1064 CHECK_CALLED(ParseUrl);
1066 SET_EXPECT(QI_IInternetProtocolInfo);
1067 SET_EXPECT(ParseUrl);
1069 if (pCoInternetGetSecurityUrl) {
1070 hres = pCoInternetGetSecurityUrl(url8, &sec_url, PSU_SECURITY_URL_ONLY, 0);
1071 ok(hres == S_OK, "CoInternetGetSecurityUrl failed: %08x\n", hres);
1072 if(hres == S_OK) {
1073 ok(lstrlenW(sec_url) > ARRAY_SIZE(wszFile) &&
1074 !memcmp(sec_url, wszFile, sizeof(wszFile)-sizeof(WCHAR)),
1075 "Encoded url = %s\n", wine_dbgstr_w(sec_url));
1076 CoTaskMemFree(sec_url);
1079 CHECK_CALLED(QI_IInternetProtocolInfo);
1080 CHECK_CALLED(ParseUrl);
1083 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1084 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1086 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1087 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1089 hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf2, &IID_NULL,
1090 wszTest, 0, NULL, 0);
1091 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1093 hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1094 wszTest, 0, NULL, 0);
1095 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1097 hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1098 wszTest, 0, NULL, 0);
1099 ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1101 SET_EXPECT(QI_IInternetProtocolInfo);
1102 SET_EXPECT(ParseUrl_ENCODE);
1104 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1105 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1107 CHECK_CALLED(QI_IInternetProtocolInfo);
1108 CHECK_CALLED(ParseUrl_ENCODE);
1110 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1111 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1113 SET_EXPECT(QI_IInternetProtocolInfo);
1114 SET_EXPECT(ParseUrl_ENCODE);
1116 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1117 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1119 CHECK_CALLED(QI_IInternetProtocolInfo);
1120 CHECK_CALLED(ParseUrl_ENCODE);
1122 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1123 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1125 expect_cf = &test_protocol_cf2;
1126 SET_EXPECT(QI_IInternetProtocolInfo);
1127 SET_EXPECT(ParseUrl_ENCODE);
1129 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1130 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1132 CHECK_CALLED(QI_IInternetProtocolInfo);
1133 CHECK_CALLED(ParseUrl_ENCODE);
1135 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1136 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1137 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1138 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1139 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, NULL);
1140 ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1141 hres = IInternetSession_UnregisterNameSpace(session, NULL, wszTest);
1142 ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1144 hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf2, wszTest);
1145 ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1147 hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1148 ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1150 IInternetSession_Release(session);
1153 static void test_MimeFilter(void)
1155 IInternetSession *session;
1156 HRESULT hres;
1158 static const WCHAR mimeW[] = {'t','e','s','t','/','m','i','m','e',0};
1160 hres = pCoInternetGetSession(0, &session, 0);
1161 ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1162 if(FAILED(hres))
1163 return;
1165 hres = IInternetSession_RegisterMimeFilter(session, &test_cf, &IID_NULL, mimeW);
1166 ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
1168 hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1169 ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1171 hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1172 ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1174 hres = IInternetSession_UnregisterMimeFilter(session, (void*)0xdeadbeef, mimeW);
1175 ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1177 IInternetSession_Release(session);
1180 static ULONG WINAPI unk_Release(IUnknown *iface)
1182 CHECK_EXPECT(unk_Release);
1183 return 0;
1186 static const IUnknownVtbl unk_vtbl = {
1187 (void*)0xdeadbeef,
1188 (void*)0xdeadbeef,
1189 unk_Release
1192 static void test_ReleaseBindInfo(void)
1194 BINDINFO bi;
1195 IUnknown unk = { &unk_vtbl };
1197 pReleaseBindInfo(NULL); /* shouldn't crash */
1199 memset(&bi, 0, sizeof(bi));
1200 bi.cbSize = sizeof(BINDINFO);
1201 bi.pUnk = &unk;
1202 SET_EXPECT(unk_Release);
1203 pReleaseBindInfo(&bi);
1204 ok(bi.cbSize == sizeof(BINDINFO), "bi.cbSize=%d\n", bi.cbSize);
1205 ok(bi.pUnk == NULL, "bi.pUnk=%p, expected NULL\n", bi.pUnk);
1206 CHECK_CALLED(unk_Release);
1208 memset(&bi, 0, sizeof(bi));
1209 bi.cbSize = offsetof(BINDINFO, pUnk);
1210 bi.pUnk = &unk;
1211 pReleaseBindInfo(&bi);
1212 ok(bi.cbSize == offsetof(BINDINFO, pUnk), "bi.cbSize=%d\n", bi.cbSize);
1213 ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1215 memset(&bi, 0, sizeof(bi));
1216 bi.pUnk = &unk;
1217 pReleaseBindInfo(&bi);
1218 ok(!bi.cbSize, "bi.cbSize=%d, expected 0\n", bi.cbSize);
1219 ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1222 static void test_CopyStgMedium(void)
1224 STGMEDIUM src, dst;
1225 HGLOBAL empty, hg;
1226 char *ptr1, *ptr2;
1227 HRESULT hres;
1228 int size;
1230 static WCHAR fileW[] = {'f','i','l','e',0};
1232 memset(&src, 0xf0, sizeof(src));
1233 memset(&dst, 0xe0, sizeof(dst));
1234 memset(&empty, 0xf0, sizeof(empty));
1235 src.tymed = TYMED_NULL;
1236 src.pUnkForRelease = NULL;
1237 hres = pCopyStgMedium(&src, &dst);
1238 ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1239 ok(dst.tymed == TYMED_NULL, "tymed=%d\n", dst.tymed);
1240 ok(dst.u.hGlobal == empty, "u=%p\n", dst.u.hGlobal);
1241 ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1243 memset(&dst, 0xe0, sizeof(dst));
1244 src.tymed = TYMED_ISTREAM;
1245 src.u.pstm = NULL;
1246 src.pUnkForRelease = NULL;
1247 hres = pCopyStgMedium(&src, &dst);
1248 ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1249 ok(dst.tymed == TYMED_ISTREAM, "tymed=%d\n", dst.tymed);
1250 ok(!dst.u.pstm, "pstm=%p\n", dst.u.pstm);
1251 ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1253 memset(&dst, 0xe0, sizeof(dst));
1254 src.tymed = TYMED_FILE;
1255 src.u.lpszFileName = fileW;
1256 src.pUnkForRelease = NULL;
1257 hres = pCopyStgMedium(&src, &dst);
1258 ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1259 ok(dst.tymed == TYMED_FILE, "tymed=%d\n", dst.tymed);
1260 ok(dst.u.lpszFileName && dst.u.lpszFileName != fileW, "lpszFileName=%p\n", dst.u.lpszFileName);
1261 ok(!lstrcmpW(dst.u.lpszFileName, fileW), "wrong file name\n");
1262 ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1263 ReleaseStgMedium(&dst);
1265 /* TYMED_HGLOBAL */
1266 hg = GlobalAlloc(GMEM_MOVEABLE, 10);
1267 ptr1 = GlobalLock(hg);
1268 memset(ptr1, 0xfa, 10);
1269 memset(&dst, 0xe0, sizeof(dst));
1270 src.tymed = TYMED_HGLOBAL;
1271 src.u.hGlobal = hg;
1272 hres = pCopyStgMedium(&src, &dst);
1273 ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1274 ok(dst.tymed == TYMED_HGLOBAL, "tymed=%d\n", dst.tymed);
1275 ok(dst.u.hGlobal != hg, "got %p, %p\n", dst.u.hGlobal, hg);
1276 size = GlobalSize(dst.u.hGlobal);
1277 ok(size == 10, "got size %d\n", size);
1278 /* compare contents */
1279 ptr2 = GlobalLock(dst.u.hGlobal);
1280 ok(!memcmp(ptr1, ptr2, 10), "got wrong data\n");
1281 GlobalUnlock(ptr2);
1282 GlobalUnlock(ptr1);
1283 ok(GlobalFlags(dst.u.hGlobal) == 0, "got 0x%08x\n", GlobalFlags(dst.u.hGlobal));
1284 GlobalFree(hg);
1285 ReleaseStgMedium(&dst);
1287 memset(&dst, 0xe0, sizeof(dst));
1288 src.tymed = TYMED_HGLOBAL;
1289 src.u.hGlobal = NULL;
1290 hres = pCopyStgMedium(&src, &dst);
1291 ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1292 ok(dst.u.hGlobal == NULL, "got %p\n", dst.u.hGlobal);
1294 hres = pCopyStgMedium(&src, NULL);
1295 ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1296 hres = pCopyStgMedium(NULL, &dst);
1297 ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1300 static void test_CopyBindInfo(void)
1302 BINDINFO src[2], dest[2];
1303 SECURITY_DESCRIPTOR sec_desc;
1304 HRESULT hres;
1305 int i;
1307 hres = pCopyBindInfo(NULL, NULL);
1308 ok(hres == E_POINTER, "CopyBindInfo returned %08x, expected E_POINTER\n", hres);
1310 memset(src, 0, sizeof(BINDINFO[2]));
1311 memset(dest, 0xde, sizeof(BINDINFO[2]));
1312 hres = pCopyBindInfo(src, dest);
1313 ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1315 memset(src, 0, sizeof(BINDINFO[2]));
1316 memset(dest, 0xde, sizeof(BINDINFO[2]));
1317 src[0].cbSize = sizeof(BINDINFO);
1318 dest[0].cbSize = 0;
1319 hres = pCopyBindInfo(src, dest);
1320 ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1322 memset(src, 0, sizeof(BINDINFO[2]));
1323 memset(dest, 0xde, sizeof(BINDINFO[2]));
1324 src[0].cbSize = 1;
1325 dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1326 hres = pCopyBindInfo(src, dest);
1327 ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1328 ok(dest[0].cbSize == sizeof(BINDINFO)+sizeof(DWORD), "incorrect cbSize: %d\n", dest[0].cbSize);
1329 for(i=1; i<dest[0].cbSize/sizeof(int); i++)
1330 ok(((int*)dest)[i] == 0, "unset values should be set to 0, got %d on %d\n", ((int*)dest)[i], i);
1332 memset(src, 0, sizeof(BINDINFO[2]));
1333 memset(dest, 0xde, sizeof(BINDINFO[2]));
1334 src[0].cbSize = sizeof(BINDINFO)+2*sizeof(DWORD);
1335 dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1336 hres = pCopyBindInfo(src, dest);
1337 ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1338 ok(dest[1].cbSize == src[1].cbSize, "additional data should be copied\n");
1339 ok(dest[1].szExtraInfo != src[1].szExtraInfo,
1340 "data not fitting in destination buffer should not be copied\n");
1342 memset(src, 0xf0, sizeof(BINDINFO[2]));
1343 memset(dest, 0xde, sizeof(BINDINFO[2]));
1344 src[0].cbSize = sizeof(BINDINFO);
1345 src[0].szExtraInfo = CoTaskMemAlloc(sizeof(WCHAR));
1346 src[0].szExtraInfo[0] = 0;
1347 src[0].szCustomVerb = NULL;
1348 src[0].pUnk = NULL;
1349 src[0].stgmedData.tymed = TYMED_NULL;
1350 src[0].stgmedData.pUnkForRelease = NULL;
1351 dest[0].cbSize = sizeof(BINDINFO);
1352 hres = pCopyBindInfo(src, dest);
1353 ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1355 ok(dest[0].cbSize == sizeof(BINDINFO), "incorrect cbSize: %d\n", dest[0].cbSize);
1356 ok(dest[0].szExtraInfo && !dest[0].szExtraInfo[0] && dest[0].szExtraInfo!=src[0].szExtraInfo,
1357 "incorrect szExtraInfo: (%p!=%p) %d\n", dest[0].szExtraInfo,
1358 src[0].szExtraInfo, dest[0].szExtraInfo[0]);
1359 ok(!memcmp(&dest[0].stgmedData, &src[0].stgmedData, sizeof(STGMEDIUM)),
1360 "incorrect stgmedData value\n");
1361 ok(src[0].grfBindInfoF == dest[0].grfBindInfoF, "grfBindInfoF = %x, expected %x\n",
1362 dest[0].grfBindInfoF, src[0].grfBindInfoF);
1363 ok(src[0].dwBindVerb == dest[0].dwBindVerb, "dwBindVerb = %x, expected %x\n",
1364 dest[0].dwBindVerb, src[0].dwBindVerb);
1365 ok(!dest[0].szCustomVerb, "szCustmoVerb != NULL\n");
1366 ok(src[0].cbstgmedData == dest[0].cbstgmedData, "cbstgmedData = %x, expected %x\n",
1367 dest[0].cbstgmedData, src[0].cbstgmedData);
1368 ok(src[0].dwOptions == dest[0].dwOptions, "dwOptions = %x, expected %x\n",
1369 dest[0].dwOptions, src[0].dwOptions);
1370 ok(src[0].dwOptionsFlags == dest[0].dwOptionsFlags, "dwOptionsFlags = %x, expected %x\n",
1371 dest[0].dwOptionsFlags, src[0].dwOptionsFlags);
1372 ok(src[0].dwCodePage == dest[0].dwCodePage, "dwCodePage = %x, expected %x\n",
1373 dest[0].dwCodePage, src[0].dwCodePage);
1374 ok(!dest[0].securityAttributes.nLength,
1375 "unexpected securityAttributes.nLength value: %d\n",
1376 dest[0].securityAttributes.nLength);
1377 ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1378 "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1379 dest[0].securityAttributes.lpSecurityDescriptor);
1380 ok(!dest[0].securityAttributes.bInheritHandle,
1381 "unexpected securityAttributes.bInheritHandle value: %d\n",
1382 dest[0].securityAttributes.bInheritHandle);
1383 ok(!memcmp(&dest[0].iid, &src[0].iid, sizeof(IID)),
1384 "incorrect iid value\n");
1385 ok(!dest[0].pUnk, "pUnk != NULL\n");
1386 ok(src[0].dwReserved == dest[0].dwReserved, "dwReserved = %x, expected %x\n",
1387 dest[0].dwReserved, src[0].dwReserved);
1389 CoTaskMemFree(src[0].szExtraInfo);
1390 CoTaskMemFree(dest[0].szExtraInfo);
1392 src[0].szExtraInfo = NULL;
1393 src[0].securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
1394 ok(InitializeSecurityDescriptor(&sec_desc, SECURITY_DESCRIPTOR_REVISION),
1395 "InitializeSecurityDescriptor failed\n");
1396 src[0].securityAttributes.lpSecurityDescriptor = (void*)&sec_desc;
1397 src[0].securityAttributes.bInheritHandle = TRUE;
1398 hres = pCopyBindInfo(src, dest);
1399 ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1400 ok(!dest[0].securityAttributes.nLength,
1401 "unexpected securityAttributes.nLength value: %d\n",
1402 dest[0].securityAttributes.nLength);
1403 ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1404 "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1405 dest[0].securityAttributes.lpSecurityDescriptor);
1406 ok(!dest[0].securityAttributes.bInheritHandle,
1407 "unexpected securityAttributes.bInheritHandle value: %d\n",
1408 dest[0].securityAttributes.bInheritHandle);
1411 static void test_UrlMkGetSessionOption(void)
1413 DWORD encoding, size;
1414 HRESULT hres;
1416 size = encoding = 0xdeadbeef;
1417 hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1418 sizeof(encoding), &size, 0);
1419 ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1420 ok(encoding != 0xdeadbeef, "encoding not changed\n");
1421 ok(size == sizeof(encoding), "size=%d\n", size);
1423 size = encoding = 0xdeadbeef;
1424 hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1425 sizeof(encoding)+1, &size, 0);
1426 ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1427 ok(encoding != 0xdeadbeef, "encoding not changed\n");
1428 ok(size == sizeof(encoding), "size=%d\n", size);
1430 size = encoding = 0xdeadbeef;
1431 hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1432 sizeof(encoding)-1, &size, 0);
1433 ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1434 ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1435 ok(size == 0xdeadbeef, "size=%d\n", size);
1437 size = encoding = 0xdeadbeef;
1438 hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, NULL,
1439 sizeof(encoding)-1, &size, 0);
1440 ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1441 ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1442 ok(size == 0xdeadbeef, "size=%d\n", size);
1444 encoding = 0xdeadbeef;
1445 hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1446 sizeof(encoding)-1, NULL, 0);
1447 ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1448 ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1451 static size_t check_prefix(const char *str, const char *prefix)
1453 size_t len = strlen(prefix);
1454 if(memcmp(str, prefix, len)) {
1455 ok(0, "no %s prefix in %s\n", wine_dbgstr_a(prefix), wine_dbgstr_a(str));
1456 return 0;
1458 return len;
1461 static void test_user_agent(void)
1463 static const CHAR expected[] = "Mozilla/4.0 (compatible; MSIE ";
1464 static char test_str[] = "test";
1465 static char test2_str[] = "test\0test";
1466 static CHAR str[3];
1467 OSVERSIONINFOW os_info = {sizeof(os_info)};
1468 char ua[1024], buf[64];
1469 unsigned int i;
1470 LPSTR str2 = NULL;
1471 BOOL is_wow = FALSE;
1472 HRESULT hres;
1473 DWORD size, saved;
1475 hres = pObtainUserAgentString(0, NULL, NULL);
1476 ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1478 size = 100;
1479 hres = pObtainUserAgentString(0, NULL, &size);
1480 ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1481 ok(size == 100, "size=%d, expected %d\n", size, 100);
1483 size = 0;
1484 hres = pObtainUserAgentString(0, str, &size);
1485 ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1486 ok(size > 0, "size=%d, expected non-zero\n", size);
1488 size = 2;
1489 str[0] = 'a';
1490 hres = pObtainUserAgentString(0, str, &size);
1491 ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1492 ok(size > 0, "size=%d, expected non-zero\n", size);
1493 ok(str[0] == 'a', "str[0]=%c, expected 'a'\n", str[0]);
1495 size = 0;
1496 hres = pObtainUserAgentString(1, str, &size);
1497 ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1498 ok(size > 0, "size=%d, expected non-zero\n", size);
1500 str2 = HeapAlloc(GetProcessHeap(), 0, (size+20)*sizeof(CHAR));
1501 saved = size;
1502 hres = pObtainUserAgentString(0, str2, &size);
1503 ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1504 ok(size == saved, "size=%d, expected %d\n", size, saved);
1505 ok(strlen(expected) <= strlen(str2) &&
1506 !memcmp(expected, str2, strlen(expected)*sizeof(CHAR)),
1507 "user agent was \"%s\", expected to start with \"%s\"\n",
1508 str2, expected);
1510 GetVersionExW(&os_info);
1511 if (sizeof(void*) == 4) IsWow64Process(GetCurrentProcess(), &is_wow);
1513 for(i = 1; i < 12; i++) {
1514 const char *p = ua;
1516 if (i != 7) {
1517 size = sizeof(ua);
1518 hres = pObtainUserAgentString(i | UAS_EXACTLEGACY, ua, &size);
1519 ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1520 ok(size == strlen(ua) + 1, "unexpected size %u, expected %u\n", size, strlen(ua) + 1);
1521 ok(!strcmp(ua, str2), "unexpected UA for version %u %s, expected %s\n",
1522 i, wine_dbgstr_a(ua), wine_dbgstr_a(str2));
1525 size = sizeof(ua);
1526 hres = pObtainUserAgentString(i != 1 ? i : UAS_EXACTLEGACY | 7, ua, &size);
1527 ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1528 ok(size == strlen(ua) + 1, "unexpected size %u, expected %u\n", size, strlen(ua) + 1);
1529 if(i < 8 && i != 1)
1530 ok(!strcmp(ua, str2), "unexpected UA for version %u %s, expected %s\n",
1531 i, wine_dbgstr_a(ua), wine_dbgstr_a(str2));
1533 p += check_prefix(p, "Mozilla/");
1534 p += check_prefix(p, i < 9 ? "4.0 (" : "5.0 (");
1535 if(i < 11) {
1536 p += check_prefix(p, "compatible; ");
1537 sprintf(buf, "MSIE %u.0; ", max(i, 7));
1538 p += check_prefix(p, buf);
1540 sprintf(buf, "Windows NT %u.%u; ", os_info.dwMajorVersion, os_info.dwMinorVersion);
1541 p += check_prefix(p, buf);
1542 if(is_wow) {
1543 p += check_prefix(p, "WOW64; ");
1544 }else if(sizeof(void*) == 8) {
1545 p += check_prefix(p, "Win64; ");
1546 #ifdef __x86_64__
1547 p += check_prefix(p, "x64; ");
1548 #endif
1550 if(i != 1) {
1551 p += check_prefix(p, "Trident/");
1552 ok('5' <= *p && *p <= '8', "unexpected version '%c'\n", *p);
1553 if(*p < '7') {
1554 win_skip("skipping UA tests, too old IE\n");
1555 break;
1557 p++; /* skip version number */
1558 p += check_prefix(p, ".0");
1560 if(i == 11) {
1561 p += check_prefix(p, "; rv:11.0) like Gecko");
1562 }else {
1563 if(i != 1)
1564 ok(*p == ';' || *p == ')', "unexpected suffix %s for version %u\n",
1565 wine_dbgstr_a(p), i);
1566 if(i < 9)
1567 p = strchr(p, ')');
1568 p += check_prefix(p, ")");
1571 ok(!*p, "unexpected suffix %s for version %u\n", wine_dbgstr_a(p), i);
1574 size = saved+10;
1575 hres = pObtainUserAgentString(0, str2, &size);
1576 ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1577 ok(size == saved, "size=%d, expected %d\n", size, saved);
1579 size = 0;
1580 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, &size, 0);
1581 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1582 ok(size, "size == 0\n");
1584 size = 0xdeadbeef;
1585 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 1000, &size, 0);
1586 ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1587 ok(size, "size == 0\n");
1589 saved = size;
1590 size = 0;
1591 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved+10, &size, 0);
1592 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1593 ok(size == saved, "size = %d, expected %d\n", size, saved);
1594 ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1595 "user agent was \"%s\", expected to start with \"%s\"\n",
1596 str2, expected);
1598 size = 0;
1599 str2[0] = 0;
1600 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1601 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1602 ok(size == saved, "size = %d, expected %d\n", size, saved);
1603 ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1604 "user agent was \"%s\", expected to start with \"%s\"\n",
1605 str2, expected);
1607 size = saved;
1608 str2[0] = 0;
1609 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved-1, &size, 0);
1610 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1611 ok(size == saved, "size = %d, expected %d\n", size, saved);
1612 ok(!str2[0], "buf changed\n");
1614 size = saved;
1615 str2[0] = 0;
1616 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, NULL, 0);
1617 ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1618 ok(!str2[0], "buf changed\n");
1620 hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, sizeof(test_str), 0);
1621 ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1623 size = 0;
1624 str2[0] = 0;
1625 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1626 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1627 ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1629 hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test2_str, sizeof(test2_str), 0);
1630 ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1632 size = 0;
1633 str2[0] = 0;
1634 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1635 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1636 ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1638 hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 2, 0);
1639 ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1641 size = 0;
1642 str2[0] = 0;
1643 hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1644 ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1645 ok(size == 3 && !strcmp(str2, "te"), "wrong user agent\n");
1647 hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 0, 0);
1648 ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1650 hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, sizeof(test_str), 0);
1651 ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1653 hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, 0);
1654 ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1656 HeapFree(GetProcessHeap(), 0, str2);
1659 static void test_MkParseDisplayNameEx(void)
1661 IMoniker *mon = NULL;
1662 LPWSTR name;
1663 DWORD issys;
1664 ULONG eaten = 0;
1665 IBindCtx *bctx;
1666 HRESULT hres;
1668 static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
1669 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
1670 '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
1672 const struct
1674 LPBC *ppbc;
1675 LPCWSTR szDisplayName;
1676 ULONG *pchEaten;
1677 LPMONIKER *ppmk;
1678 } invalid_parameters[] =
1680 {NULL, NULL, NULL, NULL},
1681 {NULL, NULL, NULL, &mon},
1682 {NULL, NULL, &eaten, NULL},
1683 {NULL, NULL, &eaten, &mon},
1684 {NULL, wszEmpty, NULL, NULL},
1685 {NULL, wszEmpty, NULL, &mon},
1686 {NULL, wszEmpty, &eaten, NULL},
1687 {NULL, wszEmpty, &eaten, &mon},
1688 {&bctx, NULL, NULL, NULL},
1689 {&bctx, NULL, NULL, &mon},
1690 {&bctx, NULL, &eaten, NULL},
1691 {&bctx, NULL, &eaten, &mon},
1692 {&bctx, wszEmpty, NULL, NULL},
1693 {&bctx, wszEmpty, NULL, &mon},
1694 {&bctx, wszEmpty, &eaten, NULL},
1695 {&bctx, wszEmpty, &eaten, &mon},
1698 int i;
1700 CreateBindCtx(0, &bctx);
1702 for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
1704 eaten = 0xdeadbeef;
1705 mon = (IMoniker *)0xdeadbeef;
1706 hres = MkParseDisplayNameEx(invalid_parameters[i].ppbc ? *invalid_parameters[i].ppbc : NULL,
1707 invalid_parameters[i].szDisplayName,
1708 invalid_parameters[i].pchEaten,
1709 invalid_parameters[i].ppmk);
1710 ok(hres == E_INVALIDARG,
1711 "[%d] Expected MkParseDisplayNameEx to return E_INVALIDARG, got %08x\n", i, hres);
1712 ok(eaten == 0xdeadbeef, "[%d] Expected eaten to be 0xdeadbeef, got %u\n", i, eaten);
1713 ok(mon == (IMoniker *)0xdeadbeef, "[%d] Expected mon to be 0xdeadbeef, got %p\n", i, mon);
1716 hres = MkParseDisplayNameEx(bctx, url9, &eaten, &mon);
1717 ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
1718 ok(eaten == ARRAY_SIZE(url9)-1, "eaten=%d\n", eaten);
1719 ok(mon != NULL, "mon == NULL\n");
1721 hres = IMoniker_GetDisplayName(mon, NULL, 0, &name);
1722 ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1723 ok(!lstrcmpW(name, url9), "wrong display name %s\n", wine_dbgstr_w(name));
1724 CoTaskMemFree(name);
1726 hres = IMoniker_IsSystemMoniker(mon, &issys);
1727 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1728 ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
1730 IMoniker_Release(mon);
1732 hres = MkParseDisplayNameEx(bctx, clsid_nameW, &eaten, &mon);
1733 ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
1734 ok(eaten == ARRAY_SIZE(clsid_nameW)-1, "eaten=%d\n", eaten);
1735 ok(mon != NULL, "mon == NULL\n");
1737 hres = IMoniker_IsSystemMoniker(mon, &issys);
1738 ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1739 ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
1741 IMoniker_Release(mon);
1743 hres = MkParseDisplayNameEx(bctx, url8, &eaten, &mon);
1744 ok(FAILED(hres), "MkParseDisplayNameEx succeeded: %08x\n", hres);
1746 IBindCtx_Release(bctx);
1749 static void test_IsValidURL(void)
1751 HRESULT hr;
1752 IBindCtx *bctx = NULL;
1754 hr = IsValidURL(NULL, 0, 0);
1755 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1757 hr = IsValidURL(NULL, wszHttpWineHQ, 0);
1758 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1760 CreateBindCtx(0, &bctx);
1762 hr = IsValidURL(bctx, wszHttpWineHQ, 0);
1763 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1765 IBindCtx_Release(bctx);
1768 static const struct {
1769 INTERNETFEATURELIST feature;
1770 DWORD get_flags;
1771 HRESULT expected;
1772 BOOL todo;
1773 } default_feature_tests[] = {
1774 {FEATURE_OBJECT_CACHING,GET_FEATURE_FROM_PROCESS,S_OK},
1775 {FEATURE_ZONE_ELEVATION,GET_FEATURE_FROM_PROCESS,S_FALSE},
1776 {FEATURE_MIME_HANDLING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1777 {FEATURE_MIME_SNIFFING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1778 {FEATURE_WINDOW_RESTRICTIONS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1779 {FEATURE_WEBOC_POPUPMANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1780 {FEATURE_BEHAVIORS,GET_FEATURE_FROM_PROCESS,S_OK},
1781 {FEATURE_DISABLE_MK_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_OK},
1782 {FEATURE_LOCALMACHINE_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1783 {FEATURE_SECURITYBAND,GET_FEATURE_FROM_PROCESS,S_FALSE},
1784 {FEATURE_RESTRICT_ACTIVEXINSTALL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1785 {FEATURE_VALIDATE_NAVIGATE_URL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1786 {FEATURE_RESTRICT_FILEDOWNLOAD,GET_FEATURE_FROM_PROCESS,S_FALSE},
1787 {FEATURE_ADDON_MANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1788 {FEATURE_PROTOCOL_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1789 {FEATURE_HTTP_USERNAME_PASSWORD_DISABLE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1790 {FEATURE_SAFE_BINDTOOBJECT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1791 {FEATURE_UNC_SAVEDFILECHECK,GET_FEATURE_FROM_PROCESS,S_FALSE},
1792 {FEATURE_GET_URL_DOM_FILEPATH_UNENCODED,GET_FEATURE_FROM_PROCESS,S_OK},
1793 {FEATURE_TABBED_BROWSING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1794 {FEATURE_SSLUX,GET_FEATURE_FROM_PROCESS,S_FALSE},
1795 {FEATURE_DISABLE_NAVIGATION_SOUNDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1796 {FEATURE_DISABLE_LEGACY_COMPRESSION,GET_FEATURE_FROM_PROCESS,S_OK},
1797 {FEATURE_FORCE_ADDR_AND_STATUS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1798 {FEATURE_XMLHTTP,GET_FEATURE_FROM_PROCESS,S_OK},
1799 {FEATURE_DISABLE_TELNET_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1800 {FEATURE_FEEDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1801 {FEATURE_BLOCK_INPUT_PROMPTS,GET_FEATURE_FROM_PROCESS,S_FALSE}
1804 static void test_internet_feature_defaults(void) {
1805 HRESULT hres;
1806 DWORD i;
1808 for(i = 0; i < ARRAY_SIZE(default_feature_tests); ++i) {
1809 hres = pCoInternetIsFeatureEnabled(default_feature_tests[i].feature, default_feature_tests[i].get_flags);
1810 todo_wine_if (default_feature_tests[i].todo)
1811 ok(hres == default_feature_tests[i].expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1812 hres, default_feature_tests[i].expected, i);
1816 /* With older versions of IE (IE 7 and earlier), urlmon caches
1817 * the FeatureControl values from the registry when it's loaded
1818 * into memory. Newer versions of IE conditionally cache the
1819 * the FeatureControl registry values (i.e. When a call to
1820 * CoInternetIsFeatureEnabled and a corresponding CoInternetSetFeatureEnabled
1821 * call hasn't already been made for the specified Feature). Because of
1822 * this we skip these tests on IE 7 and earlier.
1824 static const char* szFeatureControlKey = "Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl";
1826 static void test_internet_features_registry(void) {
1827 HRESULT hres;
1828 DWORD res;
1829 char module[MAX_PATH];
1830 char *name;
1831 HKEY feature_control;
1832 HKEY feature;
1833 DWORD value;
1834 BOOL skip_zone;
1835 BOOL delete_feature_key = TRUE;
1837 static const char* szFeatureBehaviorsKey = "FEATURE_BEHAVIORS";
1838 static const char* szFeatureZoneElevationKey = "FEATURE_ZONE_ELEVATION";
1840 if(!pIEInstallScope) {
1841 win_skip("Skipping internet feature registry tests, IE is too old...\n");
1842 return;
1845 res = GetModuleFileNameA(NULL, module, sizeof(module));
1846 ok(res, "GetModuleFileName failed: %d\n", GetLastError());
1848 name = strrchr(module, '\\')+1;
1850 /* Some Windows machines don't have a FeatureControl key in HKCU. */
1851 res = RegOpenKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &feature_control);
1852 ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1854 res = RegOpenKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1855 if(res == ERROR_SUCCESS) {
1856 /* FEATURE_BEHAVIORS already existed, so don't delete it when we're done. */
1857 delete_feature_key = FALSE;
1858 }else {
1859 res = RegCreateKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1860 ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1863 value = 0;
1864 res = RegSetValueExA(feature, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1865 ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1867 hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1868 ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1870 if(delete_feature_key) {
1871 RegCloseKey(feature);
1872 RegDeleteKeyA(feature_control, szFeatureBehaviorsKey);
1873 } else {
1874 RegDeleteValueA(feature, name);
1875 RegCloseKey(feature);
1878 /* IE's feature control cached the value it got from the registry earlier. */
1879 hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1880 ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1882 /* Restore this feature back to its default value. */
1883 hres = pCoInternetSetFeatureEnabled(FEATURE_BEHAVIORS, SET_FEATURE_ON_PROCESS, TRUE);
1884 ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1886 RegCloseKey(feature_control);
1888 res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szFeatureControlKey, &feature_control);
1889 ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1891 res = RegOpenKeyA(feature_control, szFeatureZoneElevationKey, &feature);
1892 ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1894 value = 1;
1895 res = RegSetValueExA(feature, "*", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1896 if (res == ERROR_ACCESS_DENIED)
1898 skip("Not allowed to modify zone elevation\n");
1899 skip_zone = TRUE;
1901 else
1903 skip_zone = FALSE;
1904 ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1906 hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1907 ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1909 RegDeleteValueA(feature, "*");
1910 RegCloseKey(feature);
1911 RegCloseKey(feature_control);
1913 /* Value is still cached from last time. */
1914 if (!skip_zone)
1916 hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1917 ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1919 hres = pCoInternetSetFeatureEnabled(FEATURE_ZONE_ELEVATION, SET_FEATURE_ON_PROCESS, FALSE);
1920 ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1923 test_internet_feature_defaults();
1926 static void test_CoInternetIsFeatureEnabled(void) {
1927 HRESULT hres;
1929 hres = pCoInternetIsFeatureEnabled(FEATURE_ENTRY_COUNT, GET_FEATURE_FROM_PROCESS);
1930 ok(hres == E_FAIL, "CoInternetIsFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1933 static const struct {
1934 INTERNETFEATURELIST feature;
1935 DWORD set_flags;
1936 BOOL enable;
1937 HRESULT set_expected;
1938 BOOL set_todo;
1939 DWORD get_flags;
1940 HRESULT get_expected;
1941 BOOL get_todo;
1942 } internet_feature_tests[] = {
1943 {FEATURE_OBJECT_CACHING,SET_FEATURE_ON_PROCESS,FALSE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1944 {FEATURE_WEBOC_POPUPMANAGEMENT,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK},
1945 {FEATURE_LOCALMACHINE_LOCKDOWN,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK}
1948 static void test_CoInternetSetFeatureEnabled(void) {
1949 HRESULT hres;
1950 DWORD i;
1952 hres = pCoInternetSetFeatureEnabled(FEATURE_ENTRY_COUNT,SET_FEATURE_ON_PROCESS,TRUE);
1953 ok(hres == E_FAIL, "CoInternetSetFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1955 for(i = 0; i < ARRAY_SIZE(internet_feature_tests); ++i) {
1956 hres = pCoInternetSetFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags,
1957 internet_feature_tests[i].enable);
1958 todo_wine_if (internet_feature_tests[i].set_todo)
1959 ok(hres == internet_feature_tests[i].set_expected, "CoInternetSetFeatureEnabled returned %08x, expected %08x on test %d\n",
1960 hres, internet_feature_tests[i].set_expected, i);
1962 hres = pCoInternetIsFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags);
1963 todo_wine_if (internet_feature_tests[i].get_todo)
1964 ok(hres == internet_feature_tests[i].get_expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1965 hres, internet_feature_tests[i].get_expected, i);
1970 static void test_internet_features(void) {
1971 HKEY key;
1972 DWORD res;
1974 if(!pCoInternetIsFeatureEnabled || !pCoInternetSetFeatureEnabled) {
1975 win_skip("Skipping internet feature tests, IE is too old\n");
1976 return;
1979 /* IE10 takes FeatureControl key into account only if it's available upon process start. */
1980 res = RegOpenKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &key);
1981 if(res != ERROR_SUCCESS) {
1982 PROCESS_INFORMATION pi;
1983 STARTUPINFOA si = { 0 };
1984 char cmdline[MAX_PATH];
1985 char **argv;
1986 BOOL ret;
1988 res = RegCreateKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &key);
1989 ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1991 trace("Running features tests in a separated process.\n");
1993 winetest_get_mainargs( &argv );
1994 sprintf(cmdline, "\"%s\" %s internet_features", argv[0], argv[1]);
1995 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
1996 ok(ret, "Could not create process: %u\n", GetLastError());
1997 wait_child_process( pi.hProcess );
1998 CloseHandle(pi.hThread);
1999 CloseHandle(pi.hProcess);
2001 RegDeleteKeyA(HKEY_CURRENT_USER, szFeatureControlKey);
2002 return;
2005 test_internet_features_registry();
2006 test_CoInternetIsFeatureEnabled();
2007 test_CoInternetSetFeatureEnabled();
2010 static BINDINFO rem_bindinfo = { sizeof(rem_bindinfo) }, in_bindinfo;
2011 static DWORD rem_bindf;
2013 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface, REFIID riid, void **ppv)
2015 if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)
2016 || IsEqualGUID(&IID_IBindStatusCallback, riid)
2017 || IsEqualGUID(&IID_IUnknown, riid)) {
2018 *ppv = iface;
2019 return S_OK;
2022 *ppv = NULL;
2023 return E_NOINTERFACE;
2026 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
2028 return 2;
2031 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
2033 return 1;
2036 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
2037 DWORD dwReserved, IBinding *pib)
2039 ok(0, "unexpected call\n");
2040 return S_OK;
2043 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
2045 ok(0, "unexpected call\n");
2046 return E_NOTIMPL;
2049 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
2051 ok(0, "unexpected call\n");
2052 return E_NOTIMPL;
2055 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
2056 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
2058 ok(0, "unexpected call\n");
2059 return S_OK;
2062 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface, HRESULT hresult, LPCWSTR szError)
2064 ok(0, "unexpected call\n");
2065 return S_OK;
2068 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
2070 in_bindinfo = *pbindinfo;
2071 *grfBINDF = rem_bindf;
2072 *pbindinfo = rem_bindinfo;
2073 return S_OK;
2076 static STGMEDIUM in_stgmed, rem_stgmed;
2078 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface, DWORD grfBSCF,
2079 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
2081 in_stgmed = *pstgmed;
2082 *pstgmed = rem_stgmed;
2083 return S_OK;
2086 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface, REFIID riid, IUnknown *punk)
2088 ok(0, "unexpected call\n");
2089 return S_OK;
2092 static HRESULT WINAPI BindStatusCallbackEx_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
2093 BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
2095 in_bindinfo = *pbindinfo;
2096 *grfBINDF = rem_bindf;
2097 *pbindinfo = rem_bindinfo;
2098 *grfBINDF2 = 11;
2099 *pdwReserved = 12;
2100 return S_OK;
2103 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
2104 BindStatusCallback_QueryInterface,
2105 BindStatusCallback_AddRef,
2106 BindStatusCallback_Release,
2107 BindStatusCallback_OnStartBinding,
2108 BindStatusCallback_GetPriority,
2109 BindStatusCallback_OnLowResource,
2110 BindStatusCallback_OnProgress,
2111 BindStatusCallback_OnStopBinding,
2112 BindStatusCallback_GetBindInfo,
2113 BindStatusCallback_OnDataAvailable,
2114 BindStatusCallback_OnObjectAvailable,
2115 BindStatusCallbackEx_GetBindInfoEx
2118 static IBindStatusCallbackEx BindStatusCallback = { &BindStatusCallbackExVtbl };
2120 typedef struct {
2121 IUnknown IUnknown_iface;
2122 LONG ref;
2123 } RefUnk;
2125 static inline RefUnk *impl_from_IUnknown(IUnknown *iface)
2127 return CONTAINING_RECORD(iface, RefUnk, IUnknown_iface);
2130 static HRESULT WINAPI RefUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
2132 if(!IsEqualGUID(&IID_IUnknown, riid)) {
2133 *ppv = NULL;
2134 return E_NOINTERFACE;
2137 IUnknown_AddRef(iface);
2138 *ppv = iface;
2139 return S_OK;
2142 static ULONG WINAPI RefUnk_AddRef(IUnknown *iface)
2144 RefUnk *This = impl_from_IUnknown(iface);
2145 return InterlockedIncrement(&This->ref);
2148 static ULONG WINAPI RefUnk_Release(IUnknown *iface)
2150 RefUnk *This = impl_from_IUnknown(iface);
2151 return InterlockedDecrement(&This->ref);
2154 static const IUnknownVtbl RefUnkVtbl = {
2155 RefUnk_QueryInterface,
2156 RefUnk_AddRef,
2157 RefUnk_Release
2160 static RefUnk unk_in = {{&RefUnkVtbl}}, unk_out = {{&RefUnkVtbl}};
2162 static HANDLE thread_ready;
2164 static DWORD WINAPI bsc_thread(void *arg)
2166 IStream *stream = arg;
2167 LARGE_INTEGER zero;
2168 MSG msg;
2169 HRESULT hres;
2171 CoInitialize(NULL);
2173 hres = CoMarshalInterface(stream, &IID_IBindStatusCallback, (IUnknown*)&BindStatusCallback,
2174 MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2175 ok(hres == S_OK, "CoMarshalInterface failed: %08x\n", hres);
2177 zero.QuadPart = 0;
2178 hres = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
2179 ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2181 SetEvent(thread_ready);
2183 while(GetMessageW(&msg, NULL, 0, 0)) {
2184 TranslateMessage(&msg);
2185 DispatchMessageW(&msg);
2188 CoUninitialize();
2189 return 0;
2192 static void test_bsc_marshaling(void)
2194 FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM};
2195 IBindStatusCallbackEx *callbackex;
2196 IBindStatusCallback *bsc;
2197 BINDINFO bindinfo;
2198 IStream *stream, *binding_stream;
2199 HANDLE thread;
2200 WCHAR *extra_info_out;
2201 WCHAR *verb_out;
2202 LARGE_INTEGER zero;
2203 STGMEDIUM stgmed;
2204 void *buf;
2205 DWORD bindf;
2206 HRESULT hres;
2208 hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2209 ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
2211 thread_ready = CreateEventW(NULL, TRUE, FALSE, NULL);
2212 thread = CreateThread(NULL, 0, bsc_thread, stream, 0, NULL);
2213 WaitForSingleObject(thread_ready, INFINITE);
2215 hres = CoUnmarshalInterface(stream, &IID_IBindStatusCallback, (void**)&bsc);
2216 ok(hres == S_OK, "CoUnmarshalInterface failed: %08x\n", hres);
2218 hres = CreateStreamOnHGlobal(NULL, TRUE, &binding_stream);
2219 ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
2220 hres = IStream_Write(binding_stream, "xxx", 3, NULL);
2221 ok(hres == S_OK, "Write failed: %08x\n", hres);
2223 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2224 bindf = 0xdeadbeef;
2226 memset(&bindinfo, 0, sizeof(bindinfo));
2227 bindinfo.cbSize = sizeof(bindinfo);
2228 bindinfo.grfBindInfoF = 12;
2229 bindinfo.dwBindVerb = 13;
2230 bindinfo.cbstgmedData = 19;
2231 bindinfo.dwOptions = 14;
2232 bindinfo.dwOptionsFlags = 15;
2233 bindinfo.dwCodePage = 16;
2234 bindinfo.securityAttributes.nLength = 30;
2235 bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0001;
2236 bindinfo.securityAttributes.bInheritHandle = 31;
2237 bindinfo.iid.Data1 = 17;
2238 bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2239 bindinfo.dwReserved = 18;
2240 bindinfo.stgmedData.pUnkForRelease = &unk_in.IUnknown_iface;
2241 unk_in.ref = 1;
2243 memset(&rem_bindinfo, 0, sizeof(bindinfo));
2244 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2245 rem_bindinfo.szExtraInfo = extra_info_out = a2co("extra info out");
2246 rem_bindinfo.grfBindInfoF = 22;
2247 rem_bindinfo.dwBindVerb = 23;
2248 rem_bindinfo.szCustomVerb = verb_out = a2co("custom verb out");
2249 rem_bindinfo.cbstgmedData = 29;
2250 rem_bindinfo.dwOptions = 24;
2251 rem_bindinfo.dwOptionsFlags = 25;
2252 rem_bindinfo.dwCodePage = 16;
2253 rem_bindinfo.securityAttributes.nLength = 40;
2254 rem_bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0002;
2255 rem_bindinfo.securityAttributes.bInheritHandle = 41;
2256 rem_bindinfo.iid.Data1 = 27;
2257 rem_bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2258 rem_bindinfo.dwReserved = 18;
2259 rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2260 unk_out.ref = 1;
2262 hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2263 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2264 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2266 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2267 ok(!in_bindinfo.szExtraInfo, "szExtraInfo = %s\n", wine_dbgstr_w(in_bindinfo.szExtraInfo));
2268 ok(in_bindinfo.grfBindInfoF == 12, "cbSize = %u\n", in_bindinfo.grfBindInfoF);
2269 ok(in_bindinfo.dwBindVerb == 13, "dwBindVerb = %u\n", in_bindinfo.dwBindVerb);
2270 ok(!in_bindinfo.szCustomVerb, "szCustomVerb = %s\n", wine_dbgstr_w(in_bindinfo.szCustomVerb));
2271 ok(in_bindinfo.cbstgmedData == 19, "cbstgmedData = %u\n", in_bindinfo.cbstgmedData);
2272 ok(!in_bindinfo.dwOptions, "dwOptions = %u\n", in_bindinfo.dwOptions);
2273 ok(!in_bindinfo.dwOptionsFlags, "dwOptionsFlags = %u\n", in_bindinfo.dwOptionsFlags);
2274 ok(!in_bindinfo.dwCodePage, "dwCodePage = %u\n", in_bindinfo.dwCodePage);
2275 ok(!in_bindinfo.iid.Data1, "iid.Data1 = %u\n", in_bindinfo.iid.Data1);
2276 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2277 ok(!in_bindinfo.dwReserved, "dwReserved = %u\n", in_bindinfo.dwReserved);
2278 ok(!in_bindinfo.securityAttributes.nLength, "securityAttributes.nLength = %u\n",
2279 in_bindinfo.securityAttributes.nLength);
2280 ok(!in_bindinfo.securityAttributes.lpSecurityDescriptor,
2281 "securityAttributes.lpSecurityDescriptor = %p\n",
2282 in_bindinfo.securityAttributes.lpSecurityDescriptor);
2283 ok(!in_bindinfo.securityAttributes.bInheritHandle, "securityAttributes.bInheritHandle = %u\n",
2284 in_bindinfo.securityAttributes.bInheritHandle);
2285 ok(!in_bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2286 in_bindinfo.stgmedData.pUnkForRelease);
2288 ok(bindinfo.cbSize == sizeof(rem_bindinfo), "cbSize = %u\n", rem_bindinfo.cbSize);
2289 ok(!lstrcmpW(bindinfo.szExtraInfo, L"extra info out"),
2290 "szExtraInfo = %s\n", wine_dbgstr_w(bindinfo.szExtraInfo));
2291 ok(bindinfo.grfBindInfoF == 22, "grfBindInfoF = %u\n", rem_bindinfo.grfBindInfoF);
2292 ok(bindinfo.dwBindVerb == 23, "dwBindVerb = %u\n", bindinfo.dwBindVerb);
2293 ok(bindinfo.szCustomVerb != verb_out, "szCustomVerb == inbuf\n");
2294 ok(!lstrcmpW(bindinfo.szCustomVerb, L"custom verb out"), "szCustomVerb = %s\n",
2295 wine_dbgstr_w(bindinfo.szCustomVerb));
2296 ok(bindinfo.cbstgmedData == 29, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2297 ok(bindinfo.dwOptions == 24, "dwOptions = %u\n", bindinfo.dwOptions);
2298 ok(bindinfo.dwOptionsFlags == 25, "dwOptionsFlags = %u\n", bindinfo.dwOptionsFlags);
2299 ok(bindinfo.dwCodePage, "dwCodePage = %u\n", bindinfo.dwCodePage);
2300 ok(!bindinfo.iid.Data1, "iid.Data1 = %u\n", bindinfo.iid.Data1);
2301 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2302 ok(bindinfo.dwReserved == 18, "dwReserved = %u\n", bindinfo.dwReserved);
2303 ok(bindinfo.securityAttributes.nLength == 30, "securityAttributes.nLength = %u\n",
2304 bindinfo.securityAttributes.nLength);
2305 ok(bindinfo.securityAttributes.lpSecurityDescriptor == (void*)0xdead0001,
2306 "securityAttributes.lpSecurityDescriptor = %p\n",
2307 bindinfo.securityAttributes.lpSecurityDescriptor);
2308 ok(bindinfo.securityAttributes.bInheritHandle == 31, "securityAttributes.bInheritHandle = %u\n",
2309 bindinfo.securityAttributes.bInheritHandle);
2310 ok(bindinfo.stgmedData.pUnkForRelease == &unk_in.IUnknown_iface, "pUnkForRelease = %p\n",
2311 bindinfo.stgmedData.pUnkForRelease);
2312 ok(unk_out.ref == 1, "unk_out.ref = %u\n", unk_out.ref);
2314 bindinfo.stgmedData.pUnkForRelease = NULL;
2315 ReleaseBindInfo(&bindinfo);
2317 zero.QuadPart = 0;
2318 hres = IStream_Seek(binding_stream, zero, STREAM_SEEK_SET, NULL);
2319 ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2321 /* Return IStream stgmed from GetBindInfo, it's not marshaled back */
2322 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2323 bindf = 0xdeadbeef;
2325 memset(&bindinfo, 0, sizeof(bindinfo));
2326 bindinfo.cbSize = sizeof(bindinfo);
2328 memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2329 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2331 rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2332 rem_bindinfo.stgmedData.u.pstm = binding_stream;
2333 rem_bindinfo.cbstgmedData = 3;
2334 IStream_AddRef(binding_stream);
2336 hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2337 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2338 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2340 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2341 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2342 ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2343 in_bindinfo.stgmedData.tymed);
2345 ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2346 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2347 ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2348 bindinfo.stgmedData.tymed);
2349 ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2350 bindinfo.stgmedData.u.pstm);
2351 ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2352 bindinfo.stgmedData.pUnkForRelease);
2353 ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2355 ReleaseBindInfo(&bindinfo);
2357 /* Same, but with pUnkForRelease, it's not marshaled back */
2358 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2359 bindf = 0xdeadbeef;
2361 memset(&bindinfo, 0, sizeof(bindinfo));
2362 bindinfo.cbSize = sizeof(bindinfo);
2364 memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2365 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2367 rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2368 rem_bindinfo.stgmedData.u.pstm = binding_stream;
2369 rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2370 unk_out.ref = 1;
2371 rem_bindinfo.cbstgmedData = 3;
2372 IStream_AddRef(binding_stream);
2374 hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2375 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2376 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2378 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2379 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2380 ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2381 in_bindinfo.stgmedData.tymed);
2383 ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2384 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2385 ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2386 bindinfo.stgmedData.tymed);
2387 ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2388 bindinfo.stgmedData.u.pstm);
2389 ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2390 bindinfo.stgmedData.pUnkForRelease);
2391 ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2393 ReleaseBindInfo(&bindinfo);
2395 /* Return HGLOBAL stgmed from GetBindInfo, it's not marshaled back */
2396 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2397 bindf = 0xdeadbeef;
2399 memset(&bindinfo, 0, sizeof(bindinfo));
2400 bindinfo.cbSize = sizeof(bindinfo);
2402 memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2403 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2405 rem_bindinfo.stgmedData.tymed = TYMED_HGLOBAL;
2407 buf = GlobalAlloc(0, 5);
2408 strcpy(buf, "test");
2409 rem_bindinfo.stgmedData.u.hGlobal = buf;
2410 rem_bindinfo.cbstgmedData = 5;
2412 hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2413 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2414 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2416 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2417 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2418 ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2419 in_bindinfo.stgmedData.tymed);
2421 ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2422 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2423 ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2424 bindinfo.stgmedData.tymed);
2425 ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2426 bindinfo.stgmedData.u.pstm);
2427 ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2428 bindinfo.stgmedData.pUnkForRelease);
2429 ok(bindinfo.cbstgmedData == 5, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2431 ReleaseBindInfo(&bindinfo);
2433 /* Same with GetBindInfoEx */
2434 hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackEx, (void**)&callbackex);
2435 if(SUCCEEDED(hres)) {
2436 DWORD bindf2, reserved;
2438 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2439 bindf = bindf2 = reserved = 0xdeadbeef;
2441 memset(&bindinfo, 0, sizeof(bindinfo));
2442 bindinfo.cbSize = sizeof(bindinfo);
2443 bindinfo.grfBindInfoF = 12;
2444 bindinfo.dwBindVerb = 13;
2445 bindinfo.cbstgmedData = 19;
2446 bindinfo.dwOptions = 14;
2447 bindinfo.dwOptionsFlags = 15;
2448 bindinfo.dwCodePage = 16;
2449 bindinfo.securityAttributes.nLength = 30;
2450 bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0001;
2451 bindinfo.securityAttributes.bInheritHandle = 31;
2452 bindinfo.iid.Data1 = 17;
2453 bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2454 bindinfo.dwReserved = 18;
2455 bindinfo.stgmedData.pUnkForRelease = &unk_in.IUnknown_iface;
2456 unk_in.ref = 1;
2458 memset(&rem_bindinfo, 0, sizeof(bindinfo));
2459 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2460 rem_bindinfo.szExtraInfo = extra_info_out = a2co("extra info out");
2461 rem_bindinfo.grfBindInfoF = 22;
2462 rem_bindinfo.dwBindVerb = 23;
2463 rem_bindinfo.szCustomVerb = verb_out = a2co("custom verb out");
2464 rem_bindinfo.cbstgmedData = 29;
2465 rem_bindinfo.dwOptions = 24;
2466 rem_bindinfo.dwOptionsFlags = 25;
2467 rem_bindinfo.dwCodePage = 16;
2468 rem_bindinfo.securityAttributes.nLength = 40;
2469 rem_bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0002;
2470 rem_bindinfo.securityAttributes.bInheritHandle = 41;
2471 rem_bindinfo.iid.Data1 = 27;
2472 rem_bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2473 rem_bindinfo.dwReserved = 18;
2474 rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2475 unk_out.ref = 1;
2477 hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2478 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2479 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2480 ok(bindf2 == 11, "bindf2 = %x\n", bindf);
2481 ok(reserved == 12, "reserved = %x\n", reserved);
2483 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2484 ok(!in_bindinfo.szExtraInfo, "szExtraInfo = %s\n", wine_dbgstr_w(in_bindinfo.szExtraInfo));
2485 ok(in_bindinfo.grfBindInfoF == 12, "cbSize = %u\n", in_bindinfo.grfBindInfoF);
2486 ok(in_bindinfo.dwBindVerb == 13, "dwBindVerb = %u\n", in_bindinfo.dwBindVerb);
2487 ok(!in_bindinfo.szCustomVerb, "szCustomVerb = %s\n", wine_dbgstr_w(in_bindinfo.szCustomVerb));
2488 ok(in_bindinfo.cbstgmedData == 19, "cbstgmedData = %u\n", in_bindinfo.cbstgmedData);
2489 ok(!in_bindinfo.dwOptions, "dwOptions = %u\n", in_bindinfo.dwOptions);
2490 ok(!in_bindinfo.dwOptionsFlags, "dwOptionsFlags = %u\n", in_bindinfo.dwOptionsFlags);
2491 ok(!in_bindinfo.dwCodePage, "dwCodePage = %u\n", in_bindinfo.dwCodePage);
2492 ok(!in_bindinfo.iid.Data1, "iid.Data1 = %u\n", in_bindinfo.iid.Data1);
2493 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2494 ok(!in_bindinfo.dwReserved, "dwReserved = %u\n", in_bindinfo.dwReserved);
2495 ok(!in_bindinfo.securityAttributes.nLength, "securityAttributes.nLength = %u\n",
2496 in_bindinfo.securityAttributes.nLength);
2497 ok(!in_bindinfo.securityAttributes.lpSecurityDescriptor,
2498 "securityAttributes.lpSecurityDescriptor = %p\n",
2499 in_bindinfo.securityAttributes.lpSecurityDescriptor);
2500 ok(!in_bindinfo.securityAttributes.bInheritHandle, "securityAttributes.bInheritHandle = %u\n",
2501 in_bindinfo.securityAttributes.bInheritHandle);
2502 ok(!in_bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2503 in_bindinfo.stgmedData.pUnkForRelease);
2505 ok(bindinfo.cbSize == sizeof(rem_bindinfo), "cbSize = %u\n", rem_bindinfo.cbSize);
2506 ok(!lstrcmpW(bindinfo.szExtraInfo, L"extra info out"),
2507 "szExtraInfo = %s\n", wine_dbgstr_w(bindinfo.szExtraInfo));
2508 ok(bindinfo.grfBindInfoF == 22, "grfBindInfoF = %u\n", rem_bindinfo.grfBindInfoF);
2509 ok(bindinfo.dwBindVerb == 23, "dwBindVerb = %u\n", bindinfo.dwBindVerb);
2510 ok(bindinfo.szCustomVerb != verb_out, "szCustomVerb == inbuf\n");
2511 ok(!lstrcmpW(bindinfo.szCustomVerb, L"custom verb out"), "szCustomVerb = %s\n",
2512 wine_dbgstr_w(bindinfo.szCustomVerb));
2513 ok(bindinfo.cbstgmedData == 29, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2514 ok(bindinfo.dwOptions == 24, "dwOptions = %u\n", bindinfo.dwOptions);
2515 ok(bindinfo.dwOptionsFlags == 25, "dwOptionsFlags = %u\n", bindinfo.dwOptionsFlags);
2516 ok(bindinfo.dwCodePage, "dwCodePage = %u\n", bindinfo.dwCodePage);
2517 ok(!bindinfo.iid.Data1, "iid.Data1 = %u\n", bindinfo.iid.Data1);
2518 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2519 ok(bindinfo.dwReserved == 18, "dwReserved = %u\n", bindinfo.dwReserved);
2520 ok(bindinfo.securityAttributes.nLength == 30, "securityAttributes.nLength = %u\n",
2521 bindinfo.securityAttributes.nLength);
2522 ok(bindinfo.securityAttributes.lpSecurityDescriptor == (void*)0xdead0001,
2523 "securityAttributes.lpSecurityDescriptor = %p\n",
2524 bindinfo.securityAttributes.lpSecurityDescriptor);
2525 ok(bindinfo.securityAttributes.bInheritHandle == 31, "securityAttributes.bInheritHandle = %u\n",
2526 bindinfo.securityAttributes.bInheritHandle);
2527 ok(bindinfo.stgmedData.pUnkForRelease == &unk_in.IUnknown_iface, "pUnkForRelease = %p\n",
2528 bindinfo.stgmedData.pUnkForRelease);
2529 ok(unk_out.ref == 1, "unk_out.ref = %u\n", unk_out.ref);
2531 bindinfo.stgmedData.pUnkForRelease = NULL;
2532 ReleaseBindInfo(&bindinfo);
2534 zero.QuadPart = 0;
2535 hres = IStream_Seek(binding_stream, zero, STREAM_SEEK_SET, NULL);
2536 ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2538 /* Return IStream stgmed from GetBindInfoEx, it's not marshaled back */
2539 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2540 bindf = bindf2 = reserved = 0xdeadbeef;
2542 memset(&bindinfo, 0, sizeof(bindinfo));
2543 bindinfo.cbSize = sizeof(bindinfo);
2545 memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2546 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2548 rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2549 rem_bindinfo.stgmedData.u.pstm = binding_stream;
2550 rem_bindinfo.cbstgmedData = 3;
2551 IStream_AddRef(binding_stream);
2553 hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2554 ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2555 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2557 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2558 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2559 ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2560 in_bindinfo.stgmedData.tymed);
2562 ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2563 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2564 ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2565 bindinfo.stgmedData.tymed);
2566 ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2567 bindinfo.stgmedData.u.pstm);
2568 ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2569 bindinfo.stgmedData.pUnkForRelease);
2570 ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2572 ReleaseBindInfo(&bindinfo);
2574 /* Same, but with pUnkForRelease, it's not marshaled back */
2575 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2576 bindf = bindf2 = reserved = 0xdeadbeef;
2578 memset(&bindinfo, 0, sizeof(bindinfo));
2579 bindinfo.cbSize = sizeof(bindinfo);
2581 memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2582 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2584 rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2585 rem_bindinfo.stgmedData.u.pstm = binding_stream;
2586 rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2587 unk_out.ref = 1;
2588 rem_bindinfo.cbstgmedData = 3;
2589 IStream_AddRef(binding_stream);
2591 hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2592 ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2593 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2595 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2596 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2597 ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2598 in_bindinfo.stgmedData.tymed);
2600 ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2601 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2602 ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2603 bindinfo.stgmedData.tymed);
2604 ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2605 bindinfo.stgmedData.u.pstm);
2606 ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2607 bindinfo.stgmedData.pUnkForRelease);
2608 ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2610 ReleaseBindInfo(&bindinfo);
2612 /* Return HGLOBAL stgmed from GetBindInfoEx, it's not marshaled back */
2613 rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2614 bindf = bindf2 = reserved = 0xdeadbeef;
2616 memset(&bindinfo, 0, sizeof(bindinfo));
2617 bindinfo.cbSize = sizeof(bindinfo);
2619 memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2620 rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2622 rem_bindinfo.stgmedData.tymed = TYMED_HGLOBAL;
2624 buf = GlobalAlloc(0, 5);
2625 strcpy(buf, "test");
2626 rem_bindinfo.stgmedData.u.hGlobal = buf;
2627 rem_bindinfo.cbstgmedData = 5;
2629 hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2630 ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2631 ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2633 ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2634 ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2635 ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2636 in_bindinfo.stgmedData.tymed);
2638 ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2639 ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2640 ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2641 bindinfo.stgmedData.tymed);
2642 ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2643 bindinfo.stgmedData.u.pstm);
2644 ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2645 bindinfo.stgmedData.pUnkForRelease);
2646 ok(bindinfo.cbstgmedData == 5, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2648 ReleaseBindInfo(&bindinfo);
2650 IBindStatusCallbackEx_Release(callbackex);
2651 }else {
2652 win_skip("IBindStatusCallbackEx not supported\n");
2655 /* Test marshaling stgmed from OnDataAvailable */
2656 memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2657 stgmed.tymed = TYMED_ISTREAM;
2658 stgmed.u.pstm = binding_stream;
2659 stgmed.pUnkForRelease = NULL;
2661 hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2662 ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2664 ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2665 ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2666 ok(!in_stgmed.pUnkForRelease, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2668 /* OnDataAvailable with both IStream and pUnkForRelease */
2669 memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2670 stgmed.tymed = TYMED_ISTREAM;
2671 stgmed.u.pstm = binding_stream;
2672 stgmed.pUnkForRelease = &unk_in.IUnknown_iface;
2673 unk_in.ref = 1;
2675 hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2676 ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2678 ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2679 ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2680 ok(in_stgmed.pUnkForRelease != NULL, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2681 ok(unk_in.ref > 1, "ref = %u\n", unk_in.ref);
2683 /* OnDataAvailable with TYMED_ISTREAM, but NULL stream */
2684 memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2685 stgmed.tymed = TYMED_ISTREAM;
2686 stgmed.u.pstm = binding_stream;
2687 stgmed.pUnkForRelease = NULL;
2689 hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2690 ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2692 ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2693 ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2694 ok(!in_stgmed.pUnkForRelease, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2696 /* OnDataAvailable with TYMED_NULL and pUnkForRelease */
2697 memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2698 stgmed.tymed = TYMED_NULL;
2699 stgmed.u.pstm = binding_stream;
2700 stgmed.pUnkForRelease = &unk_in.IUnknown_iface;
2701 unk_in.ref = 1;
2703 hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2704 ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2706 ok(in_stgmed.tymed == TYMED_NULL, "tymed = %u\n", in_stgmed.tymed);
2707 ok(!in_stgmed.u.pstm, "pstm != NULL\n");
2708 ok(in_stgmed.pUnkForRelease != NULL, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2709 ok(unk_in.ref == 1, "ref = %u\n", unk_in.ref);
2711 IStream_Release(binding_stream);
2712 IBindStatusCallback_Release(bsc);
2714 TerminateThread(thread, 0);
2717 START_TEST(misc)
2719 HMODULE hurlmon;
2720 int argc;
2721 char **argv;
2723 argc = winetest_get_mainargs(&argv);
2725 hurlmon = GetModuleHandleA("urlmon.dll");
2726 pCoInternetCompareUrl = (void *) GetProcAddress(hurlmon, "CoInternetCompareUrl");
2727 pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
2728 pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
2729 pCoInternetParseUrl = (void*) GetProcAddress(hurlmon, "CoInternetParseUrl");
2730 pCoInternetQueryInfo = (void*) GetProcAddress(hurlmon, "CoInternetQueryInfo");
2731 pCopyStgMedium = (void*) GetProcAddress(hurlmon, "CopyStgMedium");
2732 pCopyBindInfo = (void*) GetProcAddress(hurlmon, "CopyBindInfo");
2733 pFindMimeFromData = (void*) GetProcAddress(hurlmon, "FindMimeFromData");
2734 pObtainUserAgentString = (void*) GetProcAddress(hurlmon, "ObtainUserAgentString");
2735 pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
2736 pUrlMkGetSessionOption = (void*) GetProcAddress(hurlmon, "UrlMkGetSessionOption");
2737 pCompareSecurityIds = (void*) GetProcAddress(hurlmon, "CompareSecurityIds");
2738 pCoInternetIsFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabled");
2739 pCoInternetSetFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetSetFeatureEnabled");
2740 pIEInstallScope = (void*) GetProcAddress(hurlmon, "IEInstallScope");
2742 if (!pCoInternetCompareUrl || !pCoInternetGetSecurityUrl ||
2743 !pCoInternetGetSession || !pCoInternetParseUrl || !pCompareSecurityIds) {
2744 win_skip("Various needed functions not present, too old IE\n");
2745 return;
2748 OleInitialize(NULL);
2750 if(argc <= 2 || strcmp(argv[2], "internet_features")) {
2751 register_protocols();
2753 test_CreateFormatEnum();
2754 test_RegisterFormatEnumerator();
2755 test_CoInternetParseUrl();
2756 test_CoInternetCompareUrl();
2757 test_CoInternetQueryInfo();
2758 test_FindMimeFromData();
2759 test_NameSpace();
2760 test_MimeFilter();
2761 test_ReleaseBindInfo();
2762 test_CopyStgMedium();
2763 test_CopyBindInfo();
2764 test_UrlMkGetSessionOption();
2765 test_user_agent();
2766 test_MkParseDisplayNameEx();
2767 test_IsValidURL();
2768 test_bsc_marshaling();
2771 test_internet_features();
2773 OleUninitialize();