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