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