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