1 /* 2 * Internet Security and Zone Manager 3 * 4 * Copyright (c) 2004 Huw D M Davies 5 * Copyright 2004 Jacek Caban 6 * Copyright 2009 Detlef Riekenberg 7 * Copyright 2011 Thomas Mullaly for CodeWeavers 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 */ 23 24 #include <stdio.h> 25 26 #include "urlmon_main.h" 27 #include "winreg.h" 28 #include "wininet.h" 29 30 #define NO_SHLWAPI_REG 31 #include "shlwapi.h" 32 33 #include "wine/debug.h" 34 35 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 36 37 static const WCHAR currentlevelW[] = {'C','u','r','r','e','n','t','L','e','v','e','l',0}; 38 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; 39 static const WCHAR displaynameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; 40 static const WCHAR fileW[] = {'f','i','l','e',0}; 41 static const WCHAR flagsW[] = {'F','l','a','g','s',0}; 42 static const WCHAR iconW[] = {'I','c','o','n',0}; 43 static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0}; 44 static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d', 45 'L','e','v','e','l',0}; 46 static const WCHAR wszZonesKey[] = {'S','o','f','t','w','a','r','e','\\', 47 'M','i','c','r','o','s','o','f','t','\\', 48 'W','i','n','d','o','w','s','\\', 49 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 50 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 51 'Z','o','n','e','s','\\',0}; 52 static const WCHAR zone_map_keyW[] = {'S','o','f','t','w','a','r','e','\\', 53 'M','i','c','r','o','s','o','f','t','\\', 54 'W','i','n','d','o','w','s','\\', 55 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 56 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 57 'Z','o','n','e','M','a','p',0}; 58 static const WCHAR wszZoneMapDomainsKey[] = {'S','o','f','t','w','a','r','e','\\', 59 'M','i','c','r','o','s','o','f','t','\\', 60 'W','i','n','d','o','w','s','\\', 61 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 62 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 63 'Z','o','n','e','M','a','p','\\', 64 'D','o','m','a','i','n','s',0}; 65 66 static inline BOOL is_drive_path(const WCHAR *path) 67 { 68 return isalphaW(*path) && *(path+1) == ':'; 69 } 70 71 /* List of schemes types Windows seems to expect to be hierarchical. */ 72 static inline BOOL is_hierarchical_scheme(URL_SCHEME type) { 73 return(type == URL_SCHEME_HTTP || type == URL_SCHEME_FTP || 74 type == URL_SCHEME_GOPHER || type == URL_SCHEME_NNTP || 75 type == URL_SCHEME_TELNET || type == URL_SCHEME_WAIS || 76 type == URL_SCHEME_FILE || type == URL_SCHEME_HTTPS || 77 type == URL_SCHEME_RES); 78 } 79 80 /******************************************************************** 81 * get_string_from_reg [internal] 82 * 83 * helper to get a string from the reg. 84 * 85 */ 86 static void get_string_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPWSTR out, DWORD maxlen) 87 { 88 DWORD type = REG_SZ; 89 DWORD len = maxlen * sizeof(WCHAR); 90 DWORD res; 91 92 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len); 93 94 if (res && hklm) { 95 len = maxlen * sizeof(WCHAR); 96 type = REG_SZ; 97 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len); 98 } 99 100 if (res) { 101 TRACE("%s failed: %d\n", debugstr_w(name), res); 102 *out = '\0'; 103 } 104 } 105 106 /******************************************************************** 107 * get_dword_from_reg [internal] 108 * 109 * helper to get a dword from the reg. 110 * 111 */ 112 static void get_dword_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPDWORD out) 113 { 114 DWORD type = REG_DWORD; 115 DWORD len = sizeof(DWORD); 116 DWORD res; 117 118 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len); 119 120 if (res && hklm) { 121 len = sizeof(DWORD); 122 type = REG_DWORD; 123 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len); 124 } 125 126 if (res) { 127 TRACE("%s failed: %d\n", debugstr_w(name), res); 128 *out = 0; 129 } 130 } 131 132 static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone) 133 { 134 DWORD res, size; 135 HKEY hkey; 136 137 static const WCHAR wszZoneMapProtocolKey[] = 138 {'S','o','f','t','w','a','r','e','\\', 139 'M','i','c','r','o','s','o','f','t','\\', 140 'W','i','n','d','o','w','s','\\', 141 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 142 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 143 'Z','o','n','e','M','a','p','\\', 144 'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0}; 145 146 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey); 147 if(res != ERROR_SUCCESS) { 148 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey)); 149 return E_UNEXPECTED; 150 } 151 152 size = sizeof(DWORD); 153 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size); 154 RegCloseKey(hkey); 155 if(res == ERROR_SUCCESS) 156 return S_OK; 157 158 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapProtocolKey, &hkey); 159 if(res != ERROR_SUCCESS) { 160 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey)); 161 return E_UNEXPECTED; 162 } 163 164 size = sizeof(DWORD); 165 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size); 166 RegCloseKey(hkey); 167 if(res == ERROR_SUCCESS) 168 return S_OK; 169 170 *zone = 3; 171 return S_OK; 172 } 173 174 /******************************************************************** 175 * matches_domain_pattern [internal] 176 * 177 * Checks if the given string matches the specified domain pattern. 178 * 179 * This function looks for explicit wildcard domain components iff 180 * they appear at the very beginning of the 'pattern' string 181 * 182 * pattern = "*.google.com" 183 */ 184 static BOOL matches_domain_pattern(LPCWSTR pattern, LPCWSTR str, BOOL implicit_wildcard, LPCWSTR *matched) 185 { 186 BOOL matches = FALSE; 187 DWORD pattern_len = strlenW(pattern); 188 DWORD str_len = strlenW(str); 189 190 TRACE("(%d) Checking if %s matches %s\n", implicit_wildcard, debugstr_w(str), debugstr_w(pattern)); 191 192 *matched = NULL; 193 if(str_len >= pattern_len) { 194 /* Check if there's an explicit wildcard in the pattern. */ 195 if(pattern[0] == '*' && pattern[1] == '.') { 196 /* Make sure that 'str' matches the wildcard pattern. 197 * 198 * Example: 199 * pattern = "*.google.com" 200 * 201 * So in this case 'str' would have to end with ".google.com" in order 202 * to map to this pattern. 203 */ 204 if(str_len >= pattern_len+1 && !strcmpiW(str+(str_len-pattern_len+1), pattern+1)) { 205 /* Check if there's another '.' inside of the "unmatched" portion 206 * of 'str'. 207 * 208 * Example: 209 * pattern = "*.google.com" 210 * str = "test.testing.google.com" 211 * 212 * The currently matched portion is ".google.com" in 'str', we need 213 * see if there's a '.' inside of the unmatched portion ("test.testing"), because 214 * if there is and 'implicit_wildcard' isn't set, then this isn't 215 * a match. 216 */ 217 const WCHAR *ptr; 218 if(str_len > pattern_len+1 && (ptr = memrchrW(str, '.', str_len-pattern_len-2))) { 219 if(implicit_wildcard) { 220 matches = TRUE; 221 *matched = ptr+1; 222 } 223 } else { 224 matches = TRUE; 225 *matched = str; 226 } 227 } 228 } else if(implicit_wildcard && str_len > pattern_len) { 229 /* When the pattern has an implicit wildcard component, it means 230 * that anything goes in 'str' as long as it ends with the pattern 231 * and that the beginning of the match has a '.' before it. 232 * 233 * Example: 234 * pattern = "google.com" 235 * str = "www.google.com" 236 * 237 * Implicitly matches the pattern, where as: 238 * 239 * pattern = "google.com" 240 * str = "wwwgoogle.com" 241 * 242 * Doesn't match the pattern. 243 */ 244 if(str[str_len-pattern_len-1] == '.' && !strcmpiW(str+(str_len-pattern_len), pattern)) { 245 matches = TRUE; 246 *matched = str+(str_len-pattern_len); 247 } 248 } else { 249 /* The pattern doesn't have an implicit wildcard, or an explicit wildcard, 250 * so 'str' has to be an exact match to the 'pattern'. 251 */ 252 if(!strcmpiW(str, pattern)) { 253 matches = TRUE; 254 *matched = str; 255 } 256 } 257 } 258 259 if(matches) 260 TRACE("Found a match: matched=%s\n", debugstr_w(*matched)); 261 else 262 TRACE("No match found\n"); 263 264 return matches; 265 } 266 267 static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone) 268 { 269 static const WCHAR wildcardW[] = {'*',0}; 270 271 DWORD res; 272 DWORD size = sizeof(DWORD); 273 DWORD type; 274 275 /* See if the key contains a value for the scheme first. */ 276 res = RegQueryValueExW(key, schema, NULL, &type, (BYTE*)zone, &size); 277 if(res == ERROR_SUCCESS) { 278 if(type == REG_DWORD) 279 return TRUE; 280 WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(schema)); 281 } 282 283 /* Try to get the zone for the wildcard scheme. */ 284 size = sizeof(DWORD); 285 res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size); 286 if(res != ERROR_SUCCESS) 287 return FALSE; 288 289 if(type != REG_DWORD) { 290 WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW)); 291 return FALSE; 292 } 293 294 return TRUE; 295 } 296 297 /******************************************************************** 298 * search_domain_for_zone [internal] 299 * 300 * Searches the specified 'domain' registry key to see if 'host' maps into it, or any 301 * of its subdomain registry keys. 302 * 303 * Returns S_OK if a match is found, S_FALSE if no matches were found, or an error code. 304 */ 305 static HRESULT search_domain_for_zone(HKEY domains, LPCWSTR domain, DWORD domain_len, LPCWSTR schema, 306 LPCWSTR host, DWORD host_len, DWORD *zone) 307 { 308 BOOL found = FALSE; 309 HKEY domain_key; 310 DWORD res; 311 LPCWSTR matched; 312 313 if(host_len >= domain_len && matches_domain_pattern(domain, host, TRUE, &matched)) { 314 res = RegOpenKeyW(domains, domain, &domain_key); 315 if(res != ERROR_SUCCESS) { 316 ERR("Failed to open domain key %s: %d\n", debugstr_w(domain), res); 317 return E_UNEXPECTED; 318 } 319 320 if(matched == host) 321 found = get_zone_for_scheme(domain_key, schema, zone); 322 else { 323 INT domain_offset; 324 DWORD subdomain_count, subdomain_len; 325 BOOL check_domain = TRUE; 326 327 find_domain_name(domain, domain_len, &domain_offset); 328 329 res = RegQueryInfoKeyW(domain_key, NULL, NULL, NULL, &subdomain_count, &subdomain_len, 330 NULL, NULL, NULL, NULL, NULL, NULL); 331 if(res != ERROR_SUCCESS) { 332 ERR("Unable to query info for key %s: %d\n", debugstr_w(domain), res); 333 RegCloseKey(domain_key); 334 return E_UNEXPECTED; 335 } 336 337 if(subdomain_count) { 338 WCHAR *subdomain; 339 WCHAR *component; 340 DWORD i; 341 342 subdomain = heap_alloc((subdomain_len+1)*sizeof(WCHAR)); 343 if(!subdomain) { 344 RegCloseKey(domain_key); 345 return E_OUTOFMEMORY; 346 } 347 348 component = heap_strndupW(host, matched-host-1); 349 if(!component) { 350 heap_free(subdomain); 351 RegCloseKey(domain_key); 352 return E_OUTOFMEMORY; 353 } 354 355 for(i = 0; i < subdomain_count; ++i) { 356 DWORD len = subdomain_len+1; 357 const WCHAR *sub_matched; 358 359 res = RegEnumKeyExW(domain_key, i, subdomain, &len, NULL, NULL, NULL, NULL); 360 if(res != ERROR_SUCCESS) { 361 heap_free(component); 362 heap_free(subdomain); 363 RegCloseKey(domain_key); 364 return E_UNEXPECTED; 365 } 366 367 if(matches_domain_pattern(subdomain, component, FALSE, &sub_matched)) { 368 HKEY subdomain_key; 369 370 res = RegOpenKeyW(domain_key, subdomain, &subdomain_key); 371 if(res != ERROR_SUCCESS) { 372 ERR("Unable to open subdomain key %s of %s: %d\n", debugstr_w(subdomain), 373 debugstr_w(domain), res); 374 heap_free(component); 375 heap_free(subdomain); 376 RegCloseKey(domain_key); 377 return E_UNEXPECTED; 378 } 379 380 found = get_zone_for_scheme(subdomain_key, schema, zone); 381 check_domain = FALSE; 382 RegCloseKey(subdomain_key); 383 break; 384 } 385 } 386 heap_free(subdomain); 387 heap_free(component); 388 } 389 390 /* There's a chance that 'host' implicitly mapped into 'domain', in 391 * which case we check to see if 'domain' contains zone information. 392 * 393 * This can only happen if 'domain' is its own domain name. 394 * Example: 395 * "google.com" (domain name = "google.com") 396 * 397 * So if: 398 * host = "www.google.com" 399 * 400 * Then host would map directly into the "google.com" domain key. 401 * 402 * If 'domain' has more than just its domain name, or it does not 403 * have a domain name, then we don't perform the check. The reason 404 * for this is that these domains don't allow implicit mappings. 405 * Example: 406 * domain = "org" (has no domain name) 407 * host = "www.org" 408 * 409 * The mapping would only happen if the "org" key had an explicit subkey 410 * called "www". 411 */ 412 if(check_domain && !domain_offset && !strchrW(host, matched-host-1)) 413 found = get_zone_for_scheme(domain_key, schema, zone); 414 } 415 RegCloseKey(domain_key); 416 } 417 418 return found ? S_OK : S_FALSE; 419 } 420 421 static HRESULT search_for_domain_mapping(HKEY domains, LPCWSTR schema, LPCWSTR host, DWORD host_len, DWORD *zone) 422 { 423 WCHAR *domain; 424 DWORD domain_count, domain_len, i; 425 DWORD res; 426 HRESULT hres = S_FALSE; 427 428 res = RegQueryInfoKeyW(domains, NULL, NULL, NULL, &domain_count, &domain_len, 429 NULL, NULL, NULL, NULL, NULL, NULL); 430 if(res != ERROR_SUCCESS) { 431 WARN("Failed to retrieve information about key\n"); 432 return E_UNEXPECTED; 433 } 434 435 if(!domain_count) 436 return S_FALSE; 437 438 domain = heap_alloc((domain_len+1)*sizeof(WCHAR)); 439 if(!domain) 440 return E_OUTOFMEMORY; 441 442 for(i = 0; i < domain_count; ++i) { 443 DWORD len = domain_len+1; 444 445 res = RegEnumKeyExW(domains, i, domain, &len, NULL, NULL, NULL, NULL); 446 if(res != ERROR_SUCCESS) { 447 heap_free(domain); 448 return E_UNEXPECTED; 449 } 450 451 hres = search_domain_for_zone(domains, domain, len, schema, host, host_len, zone); 452 if(FAILED(hres) || hres == S_OK) 453 break; 454 } 455 456 heap_free(domain); 457 return hres; 458 } 459 460 static HRESULT get_zone_from_domains(IUri *uri, DWORD *zone) 461 { 462 HRESULT hres; 463 BSTR host, scheme; 464 DWORD res; 465 HKEY domains; 466 DWORD scheme_type; 467 468 hres = IUri_GetScheme(uri, &scheme_type); 469 if(FAILED(hres)) 470 return hres; 471 472 /* Windows doesn't play nice with unknown scheme types when it tries 473 * to check if a host name maps into any domains. 474 */ 475 if(scheme_type == URL_SCHEME_UNKNOWN) 476 return S_FALSE; 477 478 hres = IUri_GetHost(uri, &host); 479 if(FAILED(hres)) 480 return hres; 481 482 /* Known hierarchical scheme types must have a host. If they don't Windows 483 * assigns URLZONE_INVALID to the zone. 484 */ 485 if((scheme_type != URL_SCHEME_UNKNOWN && scheme_type != URL_SCHEME_FILE) 486 && is_hierarchical_scheme(scheme_type) && !*host) { 487 *zone = URLZONE_INVALID; 488 489 SysFreeString(host); 490 491 /* The MapUrlToZone functions return S_OK when this condition occurs. */ 492 return S_OK; 493 } 494 495 hres = IUri_GetSchemeName(uri, &scheme); 496 if(FAILED(hres)) { 497 SysFreeString(host); 498 return hres; 499 } 500 501 /* First try CURRENT_USER. */ 502 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapDomainsKey, &domains); 503 if(res == ERROR_SUCCESS) { 504 hres = search_for_domain_mapping(domains, scheme, host, SysStringLen(host), zone); 505 RegCloseKey(domains); 506 } else 507 WARN("Failed to open HKCU's %s key\n", debugstr_w(wszZoneMapDomainsKey)); 508 509 /* If that doesn't work try LOCAL_MACHINE. */ 510 if(hres == S_FALSE) { 511 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapDomainsKey, &domains); 512 if(res == ERROR_SUCCESS) { 513 hres = search_for_domain_mapping(domains, scheme, host, SysStringLen(host), zone); 514 RegCloseKey(domains); 515 } else 516 WARN("Failed to open HKLM's %s key\n", debugstr_w(wszZoneMapDomainsKey)); 517 } 518 519 SysFreeString(host); 520 SysFreeString(scheme); 521 return hres; 522 } 523 524 static HRESULT map_security_uri_to_zone(IUri *uri, DWORD *zone) 525 { 526 HRESULT hres; 527 BSTR scheme; 528 529 *zone = URLZONE_INVALID; 530 531 hres = IUri_GetSchemeName(uri, &scheme); 532 if(FAILED(hres)) 533 return hres; 534 535 if(!strcmpiW(scheme, fileW)) { 536 BSTR path; 537 WCHAR *ptr, *path_start, root[20]; 538 539 hres = IUri_GetPath(uri, &path); 540 if(FAILED(hres)) { 541 SysFreeString(scheme); 542 return hres; 543 } 544 545 if(*path == '/' && is_drive_path(path+1)) 546 path_start = path+1; 547 else 548 path_start = path; 549 550 if((ptr = strchrW(path_start, ':')) && ptr-path_start+1 < ARRAY_SIZE(root)) { 551 UINT type; 552 553 memcpy(root, path_start, (ptr-path_start+1)*sizeof(WCHAR)); 554 root[ptr-path_start+1] = 0; 555 556 type = GetDriveTypeW(root); 557 558 switch(type) { 559 case DRIVE_UNKNOWN: 560 case DRIVE_NO_ROOT_DIR: 561 break; 562 case DRIVE_REMOVABLE: 563 case DRIVE_FIXED: 564 case DRIVE_CDROM: 565 case DRIVE_RAMDISK: 566 *zone = URLZONE_LOCAL_MACHINE; 567 hres = S_OK; 568 break; 569 case DRIVE_REMOTE: 570 *zone = URLZONE_INTERNET; 571 hres = S_OK; 572 break; 573 default: 574 FIXME("unsupported drive type %d\n", type); 575 } 576 } 577 SysFreeString(path); 578 } 579 580 if(*zone == URLZONE_INVALID) { 581 hres = get_zone_from_domains(uri, zone); 582 if(hres == S_FALSE) 583 hres = get_zone_from_reg(scheme, zone); 584 } 585 586 SysFreeString(scheme); 587 return hres; 588 } 589 590 static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url) 591 { 592 IUri *secur_uri; 593 LPWSTR secur_url; 594 HRESULT hres; 595 596 *zone = URLZONE_INVALID; 597 598 hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0); 599 if(hres != S_OK) { 600 DWORD size = strlenW(url)*sizeof(WCHAR); 601 602 secur_url = CoTaskMemAlloc(size); 603 if(!secur_url) 604 return E_OUTOFMEMORY; 605 606 memcpy(secur_url, url, size); 607 } 608 609 hres = CreateUri(secur_url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &secur_uri); 610 if(FAILED(hres)) { 611 CoTaskMemFree(secur_url); 612 return hres; 613 } 614 615 hres = map_security_uri_to_zone(secur_uri, zone); 616 IUri_Release(secur_uri); 617 618 if(FAILED(hres) || !ret_url) 619 CoTaskMemFree(secur_url); 620 else 621 *ret_url = secur_url; 622 623 return hres; 624 } 625 626 static HRESULT map_uri_to_zone(IUri *uri, DWORD *zone, IUri **ret_uri) 627 { 628 HRESULT hres; 629 IUri *secur_uri; 630 631 hres = CoInternetGetSecurityUrlEx(uri, &secur_uri, PSU_SECURITY_URL_ONLY, 0); 632 if(FAILED(hres)) 633 return hres; 634 635 hres = map_security_uri_to_zone(secur_uri, zone); 636 if(FAILED(hres) || !ret_uri) 637 IUri_Release(secur_uri); 638 else 639 *ret_uri = secur_uri; 640 641 return hres; 642 } 643 644 static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey) 645 { 646 static const WCHAR wszFormat[] = {'%','s','%','u',0}; 647 648 WCHAR key_name[ARRAY_SIZE(wszZonesKey) + 12]; 649 DWORD res; 650 651 wsprintfW(key_name, wszFormat, wszZonesKey, zone); 652 653 res = RegOpenKeyW(parent_key, key_name, hkey); 654 655 if(res != ERROR_SUCCESS) { 656 WARN("RegOpenKey failed\n"); 657 return E_INVALIDARG; 658 } 659 660 return S_OK; 661 } 662 663 static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD size, URLZONEREG zone_reg) 664 { 665 HKEY parent_key; 666 HKEY hkey; 667 LONG res; 668 HRESULT hres; 669 670 switch(action) { 671 case URLACTION_SCRIPT_OVERRIDE_SAFETY: 672 case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY: 673 *(DWORD*)policy = URLPOLICY_DISALLOW; 674 return S_OK; 675 } 676 677 switch(zone_reg) { 678 case URLZONEREG_DEFAULT: 679 case URLZONEREG_HKCU: 680 parent_key = HKEY_CURRENT_USER; 681 break; 682 case URLZONEREG_HKLM: 683 parent_key = HKEY_LOCAL_MACHINE; 684 break; 685 default: 686 WARN("Unknown URLZONEREG: %d\n", zone_reg); 687 return E_FAIL; 688 }; 689 690 hres = open_zone_key(parent_key, zone, &hkey); 691 if(SUCCEEDED(hres)) { 692 WCHAR action_str[16]; 693 DWORD len = size; 694 695 static const WCHAR formatW[] = {'%','X',0}; 696 697 wsprintfW(action_str, formatW, action); 698 699 res = RegQueryValueExW(hkey, action_str, NULL, NULL, policy, &len); 700 if(res == ERROR_MORE_DATA) { 701 hres = E_INVALIDARG; 702 }else if(res == ERROR_FILE_NOT_FOUND) { 703 hres = E_FAIL; 704 }else if(res != ERROR_SUCCESS) { 705 ERR("RegQueryValue failed: %d\n", res); 706 hres = E_UNEXPECTED; 707 } 708 709 RegCloseKey(hkey); 710 } 711 712 if(FAILED(hres) && zone_reg == URLZONEREG_DEFAULT) 713 return get_action_policy(zone, action, policy, size, URLZONEREG_HKLM); 714 715 return hres; 716 } 717 718 static HRESULT generate_security_id(IUri *uri, BYTE *secid, DWORD *secid_len, DWORD zone) 719 { 720 DWORD len; 721 HRESULT hres; 722 DWORD scheme_type; 723 724 if(zone == URLZONE_INVALID) 725 return E_INVALIDARG; 726 727 hres = IUri_GetScheme(uri, &scheme_type); 728 if(FAILED(hres)) 729 return hres; 730 731 /* Windows handles opaque URLs differently then hierarchical ones. */ 732 if(!is_hierarchical_scheme(scheme_type) && scheme_type != URL_SCHEME_WILDCARD) { 733 BSTR display_uri; 734 735 hres = IUri_GetDisplayUri(uri, &display_uri); 736 if(FAILED(hres)) 737 return hres; 738 739 len = WideCharToMultiByte(CP_ACP, 0, display_uri, -1, NULL, 0, NULL, NULL)-1; 740 741 if(len+sizeof(DWORD) > *secid_len) { 742 SysFreeString(display_uri); 743 return E_NOT_SUFFICIENT_BUFFER; 744 } 745 746 WideCharToMultiByte(CP_ACP, 0, display_uri, -1, (LPSTR)secid, len, NULL, NULL); 747 SysFreeString(display_uri); 748 749 *(DWORD*)(secid+len) = zone; 750 } else { 751 BSTR host, scheme; 752 DWORD host_len, scheme_len; 753 BYTE *ptr; 754 755 hres = IUri_GetHost(uri, &host); 756 if(FAILED(hres)) 757 return hres; 758 759 /* The host can't be empty for Wildcard URIs. */ 760 if(scheme_type == URL_SCHEME_WILDCARD && !*host) { 761 SysFreeString(host); 762 return E_INVALIDARG; 763 } 764 765 hres = IUri_GetSchemeName(uri, &scheme); 766 if(FAILED(hres)) { 767 SysFreeString(host); 768 return hres; 769 } 770 771 host_len = WideCharToMultiByte(CP_ACP, 0, host, -1, NULL, 0, NULL, NULL)-1; 772 scheme_len = WideCharToMultiByte(CP_ACP, 0, scheme, -1, NULL, 0, NULL, NULL)-1; 773 774 len = host_len+scheme_len+sizeof(BYTE); 775 776 if(len+sizeof(DWORD) > *secid_len) { 777 SysFreeString(host); 778 SysFreeString(scheme); 779 return E_NOT_SUFFICIENT_BUFFER; 780 } 781 782 WideCharToMultiByte(CP_ACP, 0, scheme, -1, (LPSTR)secid, len, NULL, NULL); 783 SysFreeString(scheme); 784 785 ptr = secid+scheme_len; 786 *ptr++ = ':'; 787 788 WideCharToMultiByte(CP_ACP, 0, host, -1, (LPSTR)ptr, host_len, NULL, NULL); 789 SysFreeString(host); 790 791 ptr += host_len; 792 793 *(DWORD*)ptr = zone; 794 } 795 796 *secid_len = len+sizeof(DWORD); 797 798 return S_OK; 799 } 800 801 static HRESULT get_security_id_for_url(LPCWSTR url, BYTE *secid, DWORD *secid_len) 802 { 803 HRESULT hres; 804 DWORD zone = URLZONE_INVALID; 805 LPWSTR secur_url = NULL; 806 IUri *uri; 807 808 hres = map_url_to_zone(url, &zone, &secur_url); 809 if(FAILED(hres)) 810 return hres == 0x80041001 ? E_INVALIDARG : hres; 811 812 hres = CreateUri(secur_url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &uri); 813 CoTaskMemFree(secur_url); 814 if(FAILED(hres)) 815 return hres; 816 817 hres = generate_security_id(uri, secid, secid_len, zone); 818 IUri_Release(uri); 819 820 return hres; 821 } 822 823 static HRESULT get_security_id_for_uri(IUri *uri, BYTE *secid, DWORD *secid_len) 824 { 825 HRESULT hres; 826 IUri *secur_uri; 827 DWORD zone = URLZONE_INVALID; 828 829 hres = map_uri_to_zone(uri, &zone, &secur_uri); 830 if(FAILED(hres)) 831 return hres; 832 833 hres = generate_security_id(secur_uri, secid, secid_len, zone); 834 IUri_Release(secur_uri); 835 836 return hres; 837 } 838 839 /*********************************************************************** 840 * InternetSecurityManager implementation 841 * 842 */ 843 typedef struct { 844 IInternetSecurityManagerEx2 IInternetSecurityManagerEx2_iface; 845 846 LONG ref; 847 848 IInternetSecurityMgrSite *mgrsite; 849 IInternetSecurityManager *custom_manager; 850 } SecManagerImpl; 851 852 static inline SecManagerImpl *impl_from_IInternetSecurityManagerEx2(IInternetSecurityManagerEx2 *iface) 853 { 854 return CONTAINING_RECORD(iface, SecManagerImpl, IInternetSecurityManagerEx2_iface); 855 } 856 857 static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManagerEx2* iface,REFIID riid,void** ppvObject) 858 { 859 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 860 861 TRACE("(%p)->(%s %p)\n",This,debugstr_guid(riid),ppvObject); 862 863 if(!ppvObject) 864 return E_INVALIDARG; 865 866 if(IsEqualIID(&IID_IUnknown, riid) || 867 IsEqualIID(&IID_IInternetSecurityManager, riid) || 868 IsEqualIID(&IID_IInternetSecurityManagerEx, riid) || 869 IsEqualIID(&IID_IInternetSecurityManagerEx2, riid)) { 870 *ppvObject = iface; 871 } else { 872 WARN("not supported interface %s\n", debugstr_guid(riid)); 873 *ppvObject = NULL; 874 return E_NOINTERFACE; 875 } 876 877 IInternetSecurityManagerEx2_AddRef(iface); 878 return S_OK; 879 } 880 881 static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManagerEx2* iface) 882 { 883 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 884 ULONG refCount = InterlockedIncrement(&This->ref); 885 886 TRACE("(%p) ref=%u\n", This, refCount); 887 888 return refCount; 889 } 890 891 static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManagerEx2* iface) 892 { 893 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 894 ULONG refCount = InterlockedDecrement(&This->ref); 895 896 TRACE("(%p) ref=%u\n", This, refCount); 897 898 /* destroy the object if there are no more references on it */ 899 if (!refCount){ 900 if(This->mgrsite) 901 IInternetSecurityMgrSite_Release(This->mgrsite); 902 if(This->custom_manager) 903 IInternetSecurityManager_Release(This->custom_manager); 904 905 heap_free(This); 906 907 URLMON_UnlockModule(); 908 } 909 910 return refCount; 911 } 912 913 static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManagerEx2 *iface, 914 IInternetSecurityMgrSite *pSite) 915 { 916 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 917 918 TRACE("(%p)->(%p)\n", This, pSite); 919 920 if(This->mgrsite) 921 IInternetSecurityMgrSite_Release(This->mgrsite); 922 923 if(This->custom_manager) { 924 IInternetSecurityManager_Release(This->custom_manager); 925 This->custom_manager = NULL; 926 } 927 928 This->mgrsite = pSite; 929 930 if(pSite) { 931 IServiceProvider *servprov; 932 HRESULT hres; 933 934 IInternetSecurityMgrSite_AddRef(pSite); 935 936 hres = IInternetSecurityMgrSite_QueryInterface(pSite, &IID_IServiceProvider, 937 (void**)&servprov); 938 if(SUCCEEDED(hres)) { 939 IServiceProvider_QueryService(servprov, &SID_SInternetSecurityManager, 940 &IID_IInternetSecurityManager, (void**)&This->custom_manager); 941 IServiceProvider_Release(servprov); 942 } 943 } 944 945 return S_OK; 946 } 947 948 static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManagerEx2 *iface, 949 IInternetSecurityMgrSite **ppSite) 950 { 951 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 952 953 TRACE("(%p)->(%p)\n", This, ppSite); 954 955 if(!ppSite) 956 return E_INVALIDARG; 957 958 if(This->mgrsite) 959 IInternetSecurityMgrSite_AddRef(This->mgrsite); 960 961 *ppSite = This->mgrsite; 962 return S_OK; 963 } 964 965 static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManagerEx2 *iface, 966 LPCWSTR pwszUrl, DWORD *pdwZone, 967 DWORD dwFlags) 968 { 969 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 970 HRESULT hres; 971 972 TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags); 973 974 if(This->custom_manager) { 975 hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager, 976 pwszUrl, pdwZone, dwFlags); 977 if(hres != INET_E_DEFAULT_ACTION) 978 return hres; 979 } 980 981 if(!pwszUrl) { 982 *pdwZone = URLZONE_INVALID; 983 return E_INVALIDARG; 984 } 985 986 if(dwFlags) 987 FIXME("not supported flags: %08x\n", dwFlags); 988 989 return map_url_to_zone(pwszUrl, pdwZone, NULL); 990 } 991 992 static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManagerEx2 *iface, 993 LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) 994 { 995 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 996 997 TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId, 998 pcbSecurityId, dwReserved); 999 1000 if(This->custom_manager) { 1001 HRESULT hres; 1002 1003 hres = IInternetSecurityManager_GetSecurityId(This->custom_manager, 1004 pwszUrl, pbSecurityId, pcbSecurityId, dwReserved); 1005 if(hres != INET_E_DEFAULT_ACTION) 1006 return hres; 1007 } 1008 1009 if(!pwszUrl || !pbSecurityId || !pcbSecurityId) 1010 return E_INVALIDARG; 1011 1012 if(dwReserved) 1013 FIXME("dwReserved is not supported\n"); 1014 1015 return get_security_id_for_url(pwszUrl, pbSecurityId, pcbSecurityId); 1016 } 1017 1018 1019 static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManagerEx2 *iface, 1020 LPCWSTR pwszUrl, DWORD dwAction, 1021 BYTE *pPolicy, DWORD cbPolicy, 1022 BYTE *pContext, DWORD cbContext, 1023 DWORD dwFlags, DWORD dwReserved) 1024 { 1025 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1026 DWORD zone, policy; 1027 HRESULT hres; 1028 1029 TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction, 1030 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); 1031 1032 if(This->custom_manager) { 1033 hres = IInternetSecurityManager_ProcessUrlAction(This->custom_manager, pwszUrl, dwAction, 1034 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); 1035 if(hres != INET_E_DEFAULT_ACTION) 1036 return hres; 1037 } 1038 1039 if(dwFlags || dwReserved) 1040 FIXME("Unsupported arguments\n"); 1041 1042 if(!pwszUrl) 1043 return E_INVALIDARG; 1044 1045 hres = map_url_to_zone(pwszUrl, &zone, NULL); 1046 if(FAILED(hres)) 1047 return hres; 1048 1049 hres = get_action_policy(zone, dwAction, (BYTE*)&policy, sizeof(policy), URLZONEREG_DEFAULT); 1050 if(FAILED(hres)) 1051 return hres; 1052 1053 TRACE("policy %x\n", policy); 1054 if(cbPolicy >= sizeof(DWORD)) 1055 *(DWORD*)pPolicy = policy; 1056 1057 switch(GetUrlPolicyPermissions(policy)) { 1058 case URLPOLICY_ALLOW: 1059 case URLPOLICY_CHANNEL_SOFTDIST_PRECACHE: 1060 return S_OK; 1061 case URLPOLICY_DISALLOW: 1062 return S_FALSE; 1063 case URLPOLICY_QUERY: 1064 FIXME("URLPOLICY_QUERY not implemented\n"); 1065 return E_FAIL; 1066 default: 1067 FIXME("Not implemented policy %x\n", policy); 1068 } 1069 1070 return E_FAIL; 1071 } 1072 1073 1074 static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManagerEx2 *iface, 1075 LPCWSTR pwszUrl, REFGUID guidKey, 1076 BYTE **ppPolicy, DWORD *pcbPolicy, 1077 BYTE *pContext, DWORD cbContext, 1078 DWORD dwReserved) 1079 { 1080 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1081 HRESULT hres; 1082 1083 TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey), 1084 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); 1085 1086 if(This->custom_manager) { 1087 hres = IInternetSecurityManager_QueryCustomPolicy(This->custom_manager, pwszUrl, guidKey, 1088 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); 1089 if(hres != INET_E_DEFAULT_ACTION) 1090 return hres; 1091 } 1092 1093 WARN("Unknown guidKey %s\n", debugstr_guid(guidKey)); 1094 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 1095 } 1096 1097 static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManagerEx2 *iface, 1098 DWORD dwZone, LPCWSTR pwszPattern, DWORD dwFlags) 1099 { 1100 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1101 HRESULT hres; 1102 1103 TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags); 1104 1105 if(This->custom_manager) { 1106 hres = IInternetSecurityManager_SetZoneMapping(This->custom_manager, dwZone, 1107 pwszPattern, dwFlags); 1108 if(hres != INET_E_DEFAULT_ACTION) 1109 return hres; 1110 } 1111 1112 FIXME("Default action is not implemented\n"); 1113 return E_NOTIMPL; 1114 } 1115 1116 static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManagerEx2 *iface, 1117 DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags) 1118 { 1119 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1120 HRESULT hres; 1121 1122 TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags); 1123 1124 if(This->custom_manager) { 1125 hres = IInternetSecurityManager_GetZoneMappings(This->custom_manager, dwZone, 1126 ppenumString, dwFlags); 1127 if(hres != INET_E_DEFAULT_ACTION) 1128 return hres; 1129 } 1130 1131 FIXME("Default action is not implemented\n"); 1132 return E_NOTIMPL; 1133 } 1134 1135 static HRESULT WINAPI SecManagerImpl_ProcessUrlActionEx(IInternetSecurityManagerEx2 *iface, 1136 LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, 1137 DWORD dwFlags, DWORD dwReserved, DWORD *pdwOutFlags) 1138 { 1139 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1140 FIXME("(%p)->(%s %08x %p %d %p %d %08x %08x %p) stub\n", This, debugstr_w(pwszUrl), dwAction, pPolicy, cbPolicy, 1141 pContext, cbContext, dwFlags, dwReserved, pdwOutFlags); 1142 return E_NOTIMPL; 1143 } 1144 1145 static HRESULT WINAPI SecManagerImpl_MapUrlToZoneEx2(IInternetSecurityManagerEx2 *iface, 1146 IUri *pUri, DWORD *pdwZone, DWORD dwFlags, LPWSTR *ppwszMappedUrl, DWORD *pdwOutFlags) 1147 { 1148 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1149 1150 TRACE("(%p)->(%p %p %08x %p %p)\n", This, pUri, pdwZone, dwFlags, ppwszMappedUrl, pdwOutFlags); 1151 1152 if(This->custom_manager) { 1153 HRESULT hres; 1154 IInternetSecurityManagerEx2 *sec_mgr2; 1155 1156 hres = IInternetSecurityManager_QueryInterface(This->custom_manager, &IID_IInternetSecurityManagerEx2, 1157 (void**)&sec_mgr2); 1158 if(SUCCEEDED(hres)) { 1159 hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, pUri, pdwZone, dwFlags, ppwszMappedUrl, pdwOutFlags); 1160 IInternetSecurityManagerEx2_Release(sec_mgr2); 1161 } else { 1162 BSTR url; 1163 1164 hres = IUri_GetDisplayUri(pUri, &url); 1165 if(FAILED(hres)) 1166 return hres; 1167 1168 hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager, url, pdwZone, dwFlags); 1169 SysFreeString(url); 1170 } 1171 1172 if(hres != INET_E_DEFAULT_ACTION) 1173 return hres; 1174 } 1175 1176 if(!pdwZone) 1177 return E_INVALIDARG; 1178 1179 if(!pUri) { 1180 *pdwZone = URLZONE_INVALID; 1181 return E_INVALIDARG; 1182 } 1183 1184 if(dwFlags) 1185 FIXME("Unsupported flags: %08x\n", dwFlags); 1186 1187 return map_uri_to_zone(pUri, pdwZone, NULL); 1188 } 1189 1190 static HRESULT WINAPI SecManagerImpl_ProcessUrlActionEx2(IInternetSecurityManagerEx2 *iface, 1191 IUri *pUri, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, 1192 DWORD dwFlags, DWORD_PTR dwReserved, DWORD *pdwOutFlags) 1193 { 1194 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1195 FIXME("(%p)->(%p %08x %p %d %p %d %08x %08x %p) stub\n", This, pUri, dwAction, pPolicy, 1196 cbPolicy, pContext, cbContext, dwFlags, (DWORD)dwReserved, pdwOutFlags); 1197 return E_NOTIMPL; 1198 } 1199 1200 static HRESULT WINAPI SecManagerImpl_GetSecurityIdEx2(IInternetSecurityManagerEx2 *iface, 1201 IUri *pUri, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) 1202 { 1203 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1204 TRACE("(%p)->(%p %p %p %08x) stub\n", This, pUri, pbSecurityId, pcbSecurityId, (DWORD)dwReserved); 1205 1206 if(dwReserved) 1207 FIXME("dwReserved is not supported yet\n"); 1208 1209 if(!pUri || !pcbSecurityId || !pbSecurityId) 1210 return E_INVALIDARG; 1211 1212 return get_security_id_for_uri(pUri, pbSecurityId, pcbSecurityId); 1213 } 1214 1215 static HRESULT WINAPI SecManagerImpl_QueryCustomPolicyEx2(IInternetSecurityManagerEx2 *iface, 1216 IUri *pUri, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, 1217 DWORD cbContext, DWORD_PTR dwReserved) 1218 { 1219 SecManagerImpl *This = impl_from_IInternetSecurityManagerEx2(iface); 1220 FIXME("(%p)->(%p %s %p %p %p %d %08x) stub\n", This, pUri, debugstr_guid(guidKey), ppPolicy, pcbPolicy, 1221 pContext, cbContext, (DWORD)dwReserved); 1222 return E_NOTIMPL; 1223 } 1224 1225 static const IInternetSecurityManagerEx2Vtbl VT_SecManagerImpl = 1226 { 1227 SecManagerImpl_QueryInterface, 1228 SecManagerImpl_AddRef, 1229 SecManagerImpl_Release, 1230 SecManagerImpl_SetSecuritySite, 1231 SecManagerImpl_GetSecuritySite, 1232 SecManagerImpl_MapUrlToZone, 1233 SecManagerImpl_GetSecurityId, 1234 SecManagerImpl_ProcessUrlAction, 1235 SecManagerImpl_QueryCustomPolicy, 1236 SecManagerImpl_SetZoneMapping, 1237 SecManagerImpl_GetZoneMappings, 1238 SecManagerImpl_ProcessUrlActionEx, 1239 SecManagerImpl_MapUrlToZoneEx2, 1240 SecManagerImpl_ProcessUrlActionEx2, 1241 SecManagerImpl_GetSecurityIdEx2, 1242 SecManagerImpl_QueryCustomPolicyEx2 1243 }; 1244 1245 HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) 1246 { 1247 SecManagerImpl *This; 1248 1249 TRACE("(%p,%p)\n",pUnkOuter,ppobj); 1250 This = heap_alloc(sizeof(*This)); 1251 1252 /* Initialize the virtual function table. */ 1253 This->IInternetSecurityManagerEx2_iface.lpVtbl = &VT_SecManagerImpl; 1254 1255 This->ref = 1; 1256 This->mgrsite = NULL; 1257 This->custom_manager = NULL; 1258 1259 *ppobj = This; 1260 1261 URLMON_LockModule(); 1262 1263 return S_OK; 1264 } 1265 1266 /*********************************************************************** 1267 * InternetZoneManager implementation 1268 * 1269 */ 1270 typedef struct { 1271 IInternetZoneManagerEx2 IInternetZoneManagerEx2_iface; 1272 LONG ref; 1273 LPDWORD *zonemaps; 1274 DWORD zonemap_count; 1275 } ZoneMgrImpl; 1276 1277 static inline ZoneMgrImpl *impl_from_IInternetZoneManagerEx2(IInternetZoneManagerEx2 *iface) 1278 { 1279 return CONTAINING_RECORD(iface, ZoneMgrImpl, IInternetZoneManagerEx2_iface); 1280 } 1281 1282 1283 /*********************************************************************** 1284 * build_zonemap_from_reg [internal] 1285 * 1286 * Enumerate the Zones in the Registry and return the Zones in a DWORD-array 1287 * The number of the Zones is returned in data[0] 1288 */ 1289 static LPDWORD build_zonemap_from_reg(void) 1290 { 1291 WCHAR name[32]; 1292 HKEY hkey; 1293 LPDWORD data = NULL; 1294 DWORD allocated = 6; /* space for the zonecount and Zone "0" up to Zone "4" */ 1295 DWORD used = 0; 1296 DWORD res; 1297 DWORD len; 1298 1299 1300 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey); 1301 if (res) 1302 return NULL; 1303 1304 data = heap_alloc(allocated * sizeof(DWORD)); 1305 if (!data) 1306 goto cleanup; 1307 1308 while (!res) { 1309 name[0] = '\0'; 1310 len = ARRAY_SIZE(name); 1311 res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL); 1312 1313 if (!res) { 1314 used++; 1315 if (used == allocated) { 1316 LPDWORD new_data; 1317 1318 allocated *= 2; 1319 new_data = heap_realloc_zero(data, allocated * sizeof(DWORD)); 1320 if (!new_data) 1321 goto cleanup; 1322 1323 data = new_data; 1324 } 1325 data[used] = atoiW(name); 1326 } 1327 } 1328 if (used) { 1329 RegCloseKey(hkey); 1330 data[0] = used; 1331 return data; 1332 } 1333 1334 cleanup: 1335 /* something failed */ 1336 RegCloseKey(hkey); 1337 heap_free(data); 1338 return NULL; 1339 } 1340 1341 /******************************************************************** 1342 * IInternetZoneManager_QueryInterface 1343 */ 1344 static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManagerEx2* iface, REFIID riid, void** ppvObject) 1345 { 1346 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1347 1348 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject); 1349 1350 if(!This || !ppvObject) 1351 return E_INVALIDARG; 1352 1353 if(IsEqualIID(&IID_IUnknown, riid)) { 1354 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObject); 1355 }else if(IsEqualIID(&IID_IInternetZoneManager, riid)) { 1356 TRACE("(%p)->(IID_InternetZoneManager %p)\n", This, ppvObject); 1357 }else if(IsEqualIID(&IID_IInternetZoneManagerEx, riid)) { 1358 TRACE("(%p)->(IID_InternetZoneManagerEx %p)\n", This, ppvObject); 1359 }else if(IsEqualIID(&IID_IInternetZoneManagerEx2, riid)) { 1360 TRACE("(%p)->(IID_InternetZoneManagerEx2 %p)\n", This, ppvObject); 1361 } 1362 else 1363 { 1364 FIXME("Unknown interface: %s\n", debugstr_guid(riid)); 1365 *ppvObject = NULL; 1366 return E_NOINTERFACE; 1367 } 1368 1369 *ppvObject = iface; 1370 IInternetZoneManagerEx2_AddRef(iface); 1371 return S_OK; 1372 } 1373 1374 /******************************************************************** 1375 * IInternetZoneManager_AddRef 1376 */ 1377 static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManagerEx2* iface) 1378 { 1379 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1380 ULONG refCount = InterlockedIncrement(&This->ref); 1381 1382 TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); 1383 1384 return refCount; 1385 } 1386 1387 /******************************************************************** 1388 * IInternetZoneManager_Release 1389 */ 1390 static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManagerEx2* iface) 1391 { 1392 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1393 ULONG refCount = InterlockedDecrement(&This->ref); 1394 1395 TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); 1396 1397 if(!refCount) { 1398 while (This->zonemap_count) heap_free(This->zonemaps[--This->zonemap_count]); 1399 heap_free(This->zonemaps); 1400 heap_free(This); 1401 URLMON_UnlockModule(); 1402 } 1403 1404 return refCount; 1405 } 1406 1407 /******************************************************************** 1408 * IInternetZoneManager_GetZoneAttributes 1409 */ 1410 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* iface, 1411 DWORD dwZone, 1412 ZONEATTRIBUTES* pZoneAttributes) 1413 { 1414 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1415 HRESULT hr; 1416 HKEY hcu; 1417 HKEY hklm = NULL; 1418 1419 TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes); 1420 1421 if (!pZoneAttributes) 1422 return E_INVALIDARG; 1423 1424 hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu); 1425 if (FAILED(hr)) 1426 return S_OK; /* IE6 and older returned E_FAIL here */ 1427 1428 hr = open_zone_key(HKEY_LOCAL_MACHINE, dwZone, &hklm); 1429 if (FAILED(hr)) 1430 TRACE("Zone %d not in HKLM\n", dwZone); 1431 1432 get_string_from_reg(hcu, hklm, displaynameW, pZoneAttributes->szDisplayName, MAX_ZONE_PATH); 1433 get_string_from_reg(hcu, hklm, descriptionW, pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION); 1434 get_string_from_reg(hcu, hklm, iconW, pZoneAttributes->szIconPath, MAX_ZONE_PATH); 1435 get_dword_from_reg(hcu, hklm, minlevelW, &pZoneAttributes->dwTemplateMinLevel); 1436 get_dword_from_reg(hcu, hklm, currentlevelW, &pZoneAttributes->dwTemplateCurrentLevel); 1437 get_dword_from_reg(hcu, hklm, recommendedlevelW, &pZoneAttributes->dwTemplateRecommended); 1438 get_dword_from_reg(hcu, hklm, flagsW, &pZoneAttributes->dwFlags); 1439 1440 RegCloseKey(hklm); 1441 RegCloseKey(hcu); 1442 return S_OK; 1443 } 1444 1445 /******************************************************************** 1446 * IInternetZoneManager_SetZoneAttributes 1447 */ 1448 static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* iface, 1449 DWORD dwZone, 1450 ZONEATTRIBUTES* pZoneAttributes) 1451 { 1452 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1453 HRESULT hr; 1454 HKEY hcu; 1455 1456 TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes); 1457 1458 if (!pZoneAttributes) 1459 return E_INVALIDARG; 1460 1461 hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu); 1462 if (FAILED(hr)) 1463 return S_OK; /* IE6 returned E_FAIL here */ 1464 1465 /* cbSize is ignored */ 1466 RegSetValueExW(hcu, displaynameW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDisplayName, 1467 (lstrlenW(pZoneAttributes->szDisplayName)+1)* sizeof(WCHAR)); 1468 1469 RegSetValueExW(hcu, descriptionW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDescription, 1470 (lstrlenW(pZoneAttributes->szDescription)+1)* sizeof(WCHAR)); 1471 1472 RegSetValueExW(hcu, iconW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szIconPath, 1473 (lstrlenW(pZoneAttributes->szIconPath)+1)* sizeof(WCHAR)); 1474 1475 RegSetValueExW(hcu, minlevelW, 0, REG_DWORD, 1476 (const BYTE*) &pZoneAttributes->dwTemplateMinLevel, sizeof(DWORD)); 1477 1478 RegSetValueExW(hcu, currentlevelW, 0, REG_DWORD, 1479 (const BYTE*) &pZoneAttributes->dwTemplateCurrentLevel, sizeof(DWORD)); 1480 1481 RegSetValueExW(hcu, recommendedlevelW, 0, REG_DWORD, 1482 (const BYTE*) &pZoneAttributes->dwTemplateRecommended, sizeof(DWORD)); 1483 1484 RegSetValueExW(hcu, flagsW, 0, REG_DWORD, (const BYTE*) &pZoneAttributes->dwFlags, sizeof(DWORD)); 1485 RegCloseKey(hcu); 1486 return S_OK; 1487 1488 } 1489 1490 /******************************************************************** 1491 * IInternetZoneManager_GetZoneCustomPolicy 1492 */ 1493 static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManagerEx2* iface, 1494 DWORD dwZone, 1495 REFGUID guidKey, 1496 BYTE** ppPolicy, 1497 DWORD* pcbPolicy, 1498 URLZONEREG ulrZoneReg) 1499 { 1500 FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey), 1501 ppPolicy, pcbPolicy, ulrZoneReg); 1502 return E_NOTIMPL; 1503 } 1504 1505 /******************************************************************** 1506 * IInternetZoneManager_SetZoneCustomPolicy 1507 */ 1508 static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManagerEx2* iface, 1509 DWORD dwZone, 1510 REFGUID guidKey, 1511 BYTE* ppPolicy, 1512 DWORD cbPolicy, 1513 URLZONEREG ulrZoneReg) 1514 { 1515 FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey), 1516 ppPolicy, cbPolicy, ulrZoneReg); 1517 return E_NOTIMPL; 1518 } 1519 1520 /******************************************************************** 1521 * IInternetZoneManager_GetZoneActionPolicy 1522 */ 1523 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManagerEx2* iface, 1524 DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg) 1525 { 1526 TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy, 1527 cbPolicy, urlZoneReg); 1528 1529 if(!pPolicy) 1530 return E_INVALIDARG; 1531 1532 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg); 1533 } 1534 1535 /******************************************************************** 1536 * IInternetZoneManager_SetZoneActionPolicy 1537 */ 1538 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManagerEx2* iface, 1539 DWORD dwZone, 1540 DWORD dwAction, 1541 BYTE* pPolicy, 1542 DWORD cbPolicy, 1543 URLZONEREG urlZoneReg) 1544 { 1545 FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy, 1546 cbPolicy, urlZoneReg); 1547 return E_NOTIMPL; 1548 } 1549 1550 /******************************************************************** 1551 * IInternetZoneManager_PromptAction 1552 */ 1553 static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManagerEx2* iface, 1554 DWORD dwAction, 1555 HWND hwndParent, 1556 LPCWSTR pwszUrl, 1557 LPCWSTR pwszText, 1558 DWORD dwPromptFlags) 1559 { 1560 FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent, 1561 debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags ); 1562 return E_NOTIMPL; 1563 } 1564 1565 /******************************************************************** 1566 * IInternetZoneManager_LogAction 1567 */ 1568 static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManagerEx2* iface, 1569 DWORD dwAction, 1570 LPCWSTR pwszUrl, 1571 LPCWSTR pwszText, 1572 DWORD dwLogFlags) 1573 { 1574 FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl), 1575 debugstr_w(pwszText), dwLogFlags); 1576 return E_NOTIMPL; 1577 } 1578 1579 /******************************************************************** 1580 * IInternetZoneManager_CreateZoneEnumerator 1581 */ 1582 static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManagerEx2* iface, 1583 DWORD* pdwEnum, 1584 DWORD* pdwCount, 1585 DWORD dwFlags) 1586 { 1587 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1588 LPDWORD * new_maps; 1589 LPDWORD data; 1590 DWORD i; 1591 1592 TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags); 1593 if (!pdwEnum || !pdwCount || (dwFlags != 0)) 1594 return E_INVALIDARG; 1595 1596 data = build_zonemap_from_reg(); 1597 TRACE("found %d zones\n", data ? data[0] : -1); 1598 1599 if (!data) 1600 return E_FAIL; 1601 1602 for (i = 0; i < This->zonemap_count; i++) { 1603 if (This->zonemaps && !This->zonemaps[i]) { 1604 This->zonemaps[i] = data; 1605 *pdwEnum = i; 1606 *pdwCount = data[0]; 1607 return S_OK; 1608 } 1609 } 1610 1611 if (This->zonemaps) { 1612 /* try to double the nr. of pointers in the array */ 1613 new_maps = heap_realloc_zero(This->zonemaps, This->zonemap_count * 2 * sizeof(LPDWORD)); 1614 if (new_maps) 1615 This->zonemap_count *= 2; 1616 } 1617 else 1618 { 1619 This->zonemap_count = 2; 1620 new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD)); 1621 } 1622 1623 if (!new_maps) { 1624 heap_free(data); 1625 return E_FAIL; 1626 } 1627 This->zonemaps = new_maps; 1628 This->zonemaps[i] = data; 1629 *pdwEnum = i; 1630 *pdwCount = data[0]; 1631 return S_OK; 1632 } 1633 1634 /******************************************************************** 1635 * IInternetZoneManager_GetZoneAt 1636 */ 1637 static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManagerEx2* iface, 1638 DWORD dwEnum, 1639 DWORD dwIndex, 1640 DWORD* pdwZone) 1641 { 1642 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1643 LPDWORD data; 1644 1645 TRACE("(%p)->(0x%08x, %d, %p)\n", This, dwEnum, dwIndex, pdwZone); 1646 1647 /* make sure, that dwEnum and dwIndex are in the valid range */ 1648 if (dwEnum < This->zonemap_count) { 1649 if ((data = This->zonemaps[dwEnum])) { 1650 if (dwIndex < data[0]) { 1651 *pdwZone = data[dwIndex + 1]; 1652 return S_OK; 1653 } 1654 } 1655 } 1656 return E_INVALIDARG; 1657 } 1658 1659 /******************************************************************** 1660 * IInternetZoneManager_DestroyZoneEnumerator 1661 */ 1662 static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManagerEx2* iface, 1663 DWORD dwEnum) 1664 { 1665 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 1666 LPDWORD data; 1667 1668 TRACE("(%p)->(0x%08x)\n", This, dwEnum); 1669 /* make sure, that dwEnum is valid */ 1670 if (dwEnum < This->zonemap_count) { 1671 if ((data = This->zonemaps[dwEnum])) { 1672 This->zonemaps[dwEnum] = NULL; 1673 heap_free(data); 1674 return S_OK; 1675 } 1676 } 1677 return E_INVALIDARG; 1678 } 1679 1680 /******************************************************************** 1681 * IInternetZoneManager_CopyTemplatePoliciesToZone 1682 */ 1683 static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManagerEx2* iface, 1684 DWORD dwTemplate, 1685 DWORD dwZone, 1686 DWORD dwReserved) 1687 { 1688 FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved); 1689 return E_NOTIMPL; 1690 } 1691 1692 /******************************************************************** 1693 * IInternetZoneManagerEx_GetZoneActionPolicyEx 1694 */ 1695 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicyEx(IInternetZoneManagerEx2* iface, 1696 DWORD dwZone, 1697 DWORD dwAction, 1698 BYTE* pPolicy, 1699 DWORD cbPolicy, 1700 URLZONEREG urlZoneReg, 1701 DWORD dwFlags) 1702 { 1703 TRACE("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x)\n", iface, dwZone, 1704 dwAction, pPolicy, cbPolicy, urlZoneReg, dwFlags); 1705 1706 if(!pPolicy) 1707 return E_INVALIDARG; 1708 1709 if (dwFlags) 1710 FIXME("dwFlags 0x%x ignored\n", dwFlags); 1711 1712 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg); 1713 } 1714 1715 /******************************************************************** 1716 * IInternetZoneManagerEx_SetZoneActionPolicyEx 1717 */ 1718 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicyEx(IInternetZoneManagerEx2* iface, 1719 DWORD dwZone, 1720 DWORD dwAction, 1721 BYTE* pPolicy, 1722 DWORD cbPolicy, 1723 URLZONEREG urlZoneReg, 1724 DWORD dwFlags) 1725 { 1726 FIXME("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x) stub\n", iface, dwZone, dwAction, pPolicy, 1727 cbPolicy, urlZoneReg, dwFlags); 1728 return E_NOTIMPL; 1729 } 1730 1731 /******************************************************************** 1732 * IInternetZoneManagerEx2_GetZoneAttributesEx 1733 */ 1734 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* iface, 1735 DWORD dwZone, 1736 ZONEATTRIBUTES* pZoneAttributes, 1737 DWORD dwFlags) 1738 { 1739 TRACE("(%p)->(%d, %p, 0x%x)\n", iface, dwZone, pZoneAttributes, dwFlags); 1740 1741 if (dwFlags) 1742 FIXME("dwFlags 0x%x ignored\n", dwFlags); 1743 1744 return IInternetZoneManagerEx2_GetZoneAttributes(iface, dwZone, pZoneAttributes); 1745 } 1746 1747 1748 /******************************************************************** 1749 * IInternetZoneManagerEx2_GetZoneSecurityState 1750 */ 1751 static HRESULT WINAPI ZoneMgrImpl_GetZoneSecurityState(IInternetZoneManagerEx2* iface, 1752 DWORD dwZoneIndex, 1753 BOOL fRespectPolicy, 1754 LPDWORD pdwState, 1755 BOOL *pfPolicyEncountered) 1756 { 1757 FIXME("(%p)->(%d, %d, %p, %p) stub\n", iface, dwZoneIndex, fRespectPolicy, 1758 pdwState, pfPolicyEncountered); 1759 1760 *pdwState = SECURITY_IE_STATE_GREEN; 1761 1762 if (pfPolicyEncountered) 1763 *pfPolicyEncountered = FALSE; 1764 1765 return S_OK; 1766 } 1767 1768 /******************************************************************** 1769 * IInternetZoneManagerEx2_GetIESecurityState 1770 */ 1771 static HRESULT WINAPI ZoneMgrImpl_GetIESecurityState(IInternetZoneManagerEx2* iface, 1772 BOOL fRespectPolicy, 1773 LPDWORD pdwState, 1774 BOOL *pfPolicyEncountered, 1775 BOOL fNoCache) 1776 { 1777 FIXME("(%p)->(%d, %p, %p, %d) stub\n", iface, fRespectPolicy, pdwState, 1778 pfPolicyEncountered, fNoCache); 1779 1780 *pdwState = SECURITY_IE_STATE_GREEN; 1781 1782 if (pfPolicyEncountered) 1783 *pfPolicyEncountered = FALSE; 1784 1785 return S_OK; 1786 } 1787 1788 /******************************************************************** 1789 * IInternetZoneManagerEx2_FixInsecureSettings 1790 */ 1791 static HRESULT WINAPI ZoneMgrImpl_FixInsecureSettings(IInternetZoneManagerEx2* iface) 1792 { 1793 FIXME("(%p) stub\n", iface); 1794 return S_OK; 1795 } 1796 1797 /******************************************************************** 1798 * IInternetZoneManager_Construct 1799 */ 1800 static const IInternetZoneManagerEx2Vtbl ZoneMgrImplVtbl = { 1801 ZoneMgrImpl_QueryInterface, 1802 ZoneMgrImpl_AddRef, 1803 ZoneMgrImpl_Release, 1804 /* IInternetZoneManager */ 1805 ZoneMgrImpl_GetZoneAttributes, 1806 ZoneMgrImpl_SetZoneAttributes, 1807 ZoneMgrImpl_GetZoneCustomPolicy, 1808 ZoneMgrImpl_SetZoneCustomPolicy, 1809 ZoneMgrImpl_GetZoneActionPolicy, 1810 ZoneMgrImpl_SetZoneActionPolicy, 1811 ZoneMgrImpl_PromptAction, 1812 ZoneMgrImpl_LogAction, 1813 ZoneMgrImpl_CreateZoneEnumerator, 1814 ZoneMgrImpl_GetZoneAt, 1815 ZoneMgrImpl_DestroyZoneEnumerator, 1816 ZoneMgrImpl_CopyTemplatePoliciesToZone, 1817 /* IInternetZoneManagerEx */ 1818 ZoneMgrImpl_GetZoneActionPolicyEx, 1819 ZoneMgrImpl_SetZoneActionPolicyEx, 1820 /* IInternetZoneManagerEx2 */ 1821 ZoneMgrImpl_GetZoneAttributesEx, 1822 ZoneMgrImpl_GetZoneSecurityState, 1823 ZoneMgrImpl_GetIESecurityState, 1824 ZoneMgrImpl_FixInsecureSettings, 1825 }; 1826 1827 HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) 1828 { 1829 ZoneMgrImpl* ret = heap_alloc_zero(sizeof(ZoneMgrImpl)); 1830 1831 TRACE("(%p %p)\n", pUnkOuter, ppobj); 1832 ret->IInternetZoneManagerEx2_iface.lpVtbl = &ZoneMgrImplVtbl; 1833 ret->ref = 1; 1834 *ppobj = &ret->IInternetZoneManagerEx2_iface; 1835 1836 URLMON_LockModule(); 1837 1838 return S_OK; 1839 } 1840 1841 /*********************************************************************** 1842 * CoInternetCreateSecurityManager (URLMON.@) 1843 * 1844 */ 1845 HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP, 1846 IInternetSecurityManager **ppSM, DWORD dwReserved ) 1847 { 1848 TRACE("%p %p %d\n", pSP, ppSM, dwReserved ); 1849 1850 if(pSP) 1851 FIXME("pSP not supported\n"); 1852 1853 return SecManagerImpl_Construct(NULL, (void**) ppSM); 1854 } 1855 1856 /******************************************************************** 1857 * CoInternetCreateZoneManager (URLMON.@) 1858 */ 1859 HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneManager** ppZM, DWORD dwReserved) 1860 { 1861 TRACE("(%p %p %x)\n", pSP, ppZM, dwReserved); 1862 return ZoneMgrImpl_Construct(NULL, (void**)ppZM); 1863 } 1864 1865 static HRESULT parse_security_url(const WCHAR *url, PSUACTION action, WCHAR **result) { 1866 IInternetProtocolInfo *protocol_info; 1867 WCHAR *tmp, *new_url = NULL, *alloc_url = NULL; 1868 DWORD size, new_size; 1869 HRESULT hres = S_OK, parse_hres; 1870 1871 while(1) { 1872 TRACE("parsing %s\n", debugstr_w(url)); 1873 1874 protocol_info = get_protocol_info(url); 1875 if(!protocol_info) 1876 break; 1877 1878 size = strlenW(url)+1; 1879 new_url = CoTaskMemAlloc(size*sizeof(WCHAR)); 1880 if(!new_url) { 1881 hres = E_OUTOFMEMORY; 1882 break; 1883 } 1884 1885 new_size = 0; 1886 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, size, &new_size, 0); 1887 if(parse_hres == S_FALSE) { 1888 if(!new_size) { 1889 hres = E_UNEXPECTED; 1890 break; 1891 } 1892 1893 tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR)); 1894 if(!tmp) { 1895 hres = E_OUTOFMEMORY; 1896 break; 1897 } 1898 new_url = tmp; 1899 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, 1900 new_size, &new_size, 0); 1901 if(parse_hres == S_FALSE) { 1902 hres = E_FAIL; 1903 break; 1904 } 1905 } 1906 1907 if(parse_hres != S_OK || !strcmpW(url, new_url)) 1908 break; 1909 1910 CoTaskMemFree(alloc_url); 1911 url = alloc_url = new_url; 1912 new_url = NULL; 1913 } 1914 1915 CoTaskMemFree(new_url); 1916 1917 if(hres != S_OK) { 1918 WARN("failed: %08x\n", hres); 1919 CoTaskMemFree(alloc_url); 1920 return hres; 1921 } 1922 1923 if(action == PSU_DEFAULT && (protocol_info = get_protocol_info(url))) { 1924 size = strlenW(url)+1; 1925 new_url = CoTaskMemAlloc(size * sizeof(WCHAR)); 1926 if(new_url) { 1927 new_size = 0; 1928 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, 1929 new_url, size, &new_size, 0); 1930 if(parse_hres == S_FALSE) { 1931 if(new_size) { 1932 tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR)); 1933 if(tmp) { 1934 new_url = tmp; 1935 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, new_url, 1936 new_size, &new_size, 0); 1937 if(parse_hres == S_FALSE) 1938 hres = E_FAIL; 1939 }else { 1940 hres = E_OUTOFMEMORY; 1941 } 1942 }else { 1943 hres = E_UNEXPECTED; 1944 } 1945 } 1946 1947 if(hres == S_OK && parse_hres == S_OK) { 1948 CoTaskMemFree(alloc_url); 1949 url = alloc_url = new_url; 1950 new_url = NULL; 1951 } 1952 1953 CoTaskMemFree(new_url); 1954 }else { 1955 hres = E_OUTOFMEMORY; 1956 } 1957 IInternetProtocolInfo_Release(protocol_info); 1958 } 1959 1960 if(FAILED(hres)) { 1961 WARN("failed %08x\n", hres); 1962 CoTaskMemFree(alloc_url); 1963 return hres; 1964 } 1965 1966 if(!alloc_url) { 1967 size = strlenW(url)+1; 1968 alloc_url = CoTaskMemAlloc(size * sizeof(WCHAR)); 1969 if(!alloc_url) 1970 return E_OUTOFMEMORY; 1971 memcpy(alloc_url, url, size * sizeof(WCHAR)); 1972 } 1973 1974 *result = alloc_url; 1975 return S_OK; 1976 } 1977 1978 /******************************************************************** 1979 * CoInternetGetSecurityUrl (URLMON.@) 1980 */ 1981 HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved) 1982 { 1983 WCHAR *secure_url; 1984 HRESULT hres; 1985 1986 TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved); 1987 1988 hres = parse_security_url(pwzUrl, psuAction, &secure_url); 1989 if(FAILED(hres)) 1990 return hres; 1991 1992 if(psuAction != PSU_SECURITY_URL_ONLY) { 1993 PARSEDURLW parsed_url = { sizeof(parsed_url) }; 1994 DWORD size; 1995 1996 /* FIXME: Use helpers from uri.c */ 1997 if(SUCCEEDED(ParseURLW(secure_url, &parsed_url))) { 1998 WCHAR *new_url; 1999 2000 switch(parsed_url.nScheme) { 2001 case URL_SCHEME_FTP: 2002 case URL_SCHEME_HTTP: 2003 case URL_SCHEME_HTTPS: 2004 size = strlenW(secure_url)+1; 2005 new_url = CoTaskMemAlloc(size * sizeof(WCHAR)); 2006 if(new_url) 2007 hres = UrlGetPartW(secure_url, new_url, &size, URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME); 2008 else 2009 hres = E_OUTOFMEMORY; 2010 CoTaskMemFree(secure_url); 2011 if(hres != S_OK) { 2012 WARN("UrlGetPart failed: %08x\n", hres); 2013 CoTaskMemFree(new_url); 2014 return FAILED(hres) ? hres : E_FAIL; 2015 } 2016 secure_url = new_url; 2017 } 2018 } 2019 } 2020 2021 *ppwzSecUrl = secure_url; 2022 return S_OK; 2023 } 2024 2025 /******************************************************************** 2026 * CoInternetGetSecurityUrlEx (URLMON.@) 2027 */ 2028 HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION psuAction, DWORD_PTR dwReserved) 2029 { 2030 URL_SCHEME scheme_type; 2031 BSTR secure_uri; 2032 WCHAR *ret_url; 2033 HRESULT hres; 2034 2035 TRACE("(%p,%p,%u,%u)\n", pUri, ppSecUri, psuAction, (DWORD)dwReserved); 2036 2037 if(!pUri || !ppSecUri) 2038 return E_INVALIDARG; 2039 2040 hres = IUri_GetDisplayUri(pUri, &secure_uri); 2041 if(FAILED(hres)) 2042 return hres; 2043 2044 hres = parse_security_url(secure_uri, psuAction, &ret_url); 2045 SysFreeString(secure_uri); 2046 if(FAILED(hres)) 2047 return hres; 2048 2049 /* File URIs have to hierarchical. */ 2050 hres = IUri_GetScheme(pUri, (DWORD*)&scheme_type); 2051 if(SUCCEEDED(hres) && scheme_type == URL_SCHEME_FILE) { 2052 const WCHAR *tmp = ret_url; 2053 2054 /* Check and see if a "//" is after the scheme name. */ 2055 tmp += ARRAY_SIZE(fileW); 2056 if(*tmp != '/' || *(tmp+1) != '/') 2057 hres = E_INVALIDARG; 2058 } 2059 2060 if(SUCCEEDED(hres)) 2061 hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri); 2062 CoTaskMemFree(ret_url); 2063 return hres; 2064 } 2065 2066 /******************************************************************** 2067 * CompareSecurityIds (URLMON.@) 2068 */ 2069 HRESULT WINAPI CompareSecurityIds(BYTE *secid1, DWORD size1, BYTE *secid2, DWORD size2, DWORD reserved) 2070 { 2071 FIXME("(%p %d %p %d %x)\n", secid1, size1, secid2, size2, reserved); 2072 return E_NOTIMPL; 2073 } 2074 2075 /******************************************************************** 2076 * IsInternetESCEnabledLocal (URLMON.108) 2077 * 2078 * Undocumented, returns TRUE if IE is running in Enhanced Security Configuration. 2079 */ 2080 BOOL WINAPI IsInternetESCEnabledLocal(void) 2081 { 2082 static BOOL esc_initialized, esc_enabled; 2083 2084 TRACE("()\n"); 2085 2086 if(!esc_initialized) { 2087 DWORD type, size, val; 2088 HKEY zone_map; 2089 2090 static const WCHAR iehardenW[] = {'I','E','H','a','r','d','e','n',0}; 2091 2092 if(RegOpenKeyExW(HKEY_CURRENT_USER, zone_map_keyW, 0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) { 2093 size = sizeof(DWORD); 2094 if(RegQueryValueExW(zone_map, iehardenW, NULL, &type, (BYTE*)&val, &size) == ERROR_SUCCESS) 2095 esc_enabled = type == REG_DWORD && val != 0; 2096 RegCloseKey(zone_map); 2097 } 2098 esc_initialized = TRUE; 2099 } 2100 2101 return esc_enabled; 2102 } 2103