Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensec_mgr.c
Go to the documentation of this file.
00001 /* 00002 * Internet Security and Zone Manager 00003 * 00004 * Copyright (c) 2004 Huw D M Davies 00005 * Copyright 2004 Jacek Caban 00006 * Copyright 2009 Detlef Riekenberg 00007 * Copyright 2011 Thomas Mullaly for CodeWeavers 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include <stdio.h> 00025 00026 #include "urlmon_main.h" 00027 #include "winreg.h" 00028 #include "wininet.h" 00029 00030 #define NO_SHLWAPI_REG 00031 #include "shlwapi.h" 00032 00033 #include "wine/debug.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 00036 00037 static const WCHAR currentlevelW[] = {'C','u','r','r','e','n','t','L','e','v','e','l',0}; 00038 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; 00039 static const WCHAR displaynameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; 00040 static const WCHAR fileW[] = {'f','i','l','e',0}; 00041 static const WCHAR flagsW[] = {'F','l','a','g','s',0}; 00042 static const WCHAR iconW[] = {'I','c','o','n',0}; 00043 static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0}; 00044 static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d', 00045 'L','e','v','e','l',0}; 00046 static const WCHAR wszZonesKey[] = {'S','o','f','t','w','a','r','e','\\', 00047 'M','i','c','r','o','s','o','f','t','\\', 00048 'W','i','n','d','o','w','s','\\', 00049 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00050 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 00051 'Z','o','n','e','s','\\',0}; 00052 static const WCHAR wszZoneMapDomainsKey[] = {'S','o','f','t','w','a','r','e','\\', 00053 'M','i','c','r','o','s','o','f','t','\\', 00054 'W','i','n','d','o','w','s','\\', 00055 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00056 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 00057 'Z','o','n','e','M','a','p','\\', 00058 'D','o','m','a','i','n','s',0}; 00059 00060 /******************************************************************** 00061 * get_string_from_reg [internal] 00062 * 00063 * helper to get a string from the reg. 00064 * 00065 */ 00066 static void get_string_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPWSTR out, DWORD maxlen) 00067 { 00068 DWORD type = REG_SZ; 00069 DWORD len = maxlen * sizeof(WCHAR); 00070 DWORD res; 00071 00072 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len); 00073 00074 if (res && hklm) { 00075 len = maxlen * sizeof(WCHAR); 00076 type = REG_SZ; 00077 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len); 00078 } 00079 00080 if (res) { 00081 TRACE("%s failed: %d\n", debugstr_w(name), res); 00082 *out = '\0'; 00083 } 00084 } 00085 00086 /******************************************************************** 00087 * get_dword_from_reg [internal] 00088 * 00089 * helper to get a dword from the reg. 00090 * 00091 */ 00092 static void get_dword_from_reg(HKEY hcu, HKEY hklm, LPCWSTR name, LPDWORD out) 00093 { 00094 DWORD type = REG_DWORD; 00095 DWORD len = sizeof(DWORD); 00096 DWORD res; 00097 00098 res = RegQueryValueExW(hcu, name, NULL, &type, (LPBYTE) out, &len); 00099 00100 if (res && hklm) { 00101 len = sizeof(DWORD); 00102 type = REG_DWORD; 00103 res = RegQueryValueExW(hklm, name, NULL, &type, (LPBYTE) out, &len); 00104 } 00105 00106 if (res) { 00107 TRACE("%s failed: %d\n", debugstr_w(name), res); 00108 *out = 0; 00109 } 00110 } 00111 00112 static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone) 00113 { 00114 DWORD res, size; 00115 HKEY hkey; 00116 00117 static const WCHAR wszZoneMapProtocolKey[] = 00118 {'S','o','f','t','w','a','r','e','\\', 00119 'M','i','c','r','o','s','o','f','t','\\', 00120 'W','i','n','d','o','w','s','\\', 00121 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00122 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 00123 'Z','o','n','e','M','a','p','\\', 00124 'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0}; 00125 00126 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey); 00127 if(res != ERROR_SUCCESS) { 00128 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey)); 00129 return E_UNEXPECTED; 00130 } 00131 00132 size = sizeof(DWORD); 00133 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size); 00134 RegCloseKey(hkey); 00135 if(res == ERROR_SUCCESS) 00136 return S_OK; 00137 00138 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapProtocolKey, &hkey); 00139 if(res != ERROR_SUCCESS) { 00140 ERR("Could not open key %s\n", debugstr_w(wszZoneMapProtocolKey)); 00141 return E_UNEXPECTED; 00142 } 00143 00144 size = sizeof(DWORD); 00145 res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size); 00146 RegCloseKey(hkey); 00147 if(res == ERROR_SUCCESS) 00148 return S_OK; 00149 00150 *zone = 3; 00151 return S_OK; 00152 } 00153 00154 /******************************************************************** 00155 * matches_domain_pattern [internal] 00156 * 00157 * Checks if the given string matches the specified domain pattern. 00158 * 00159 * This function looks for explicit wildcard domain components iff 00160 * they appear at the very beginning of the 'pattern' string 00161 * 00162 * pattern = "*.google.com" 00163 */ 00164 static BOOL matches_domain_pattern(LPCWSTR pattern, LPCWSTR str, BOOL implicit_wildcard, LPCWSTR *matched) 00165 { 00166 BOOL matches = FALSE; 00167 DWORD pattern_len = strlenW(pattern); 00168 DWORD str_len = strlenW(str); 00169 00170 TRACE("(%d) Checking if %s matches %s\n", implicit_wildcard, debugstr_w(str), debugstr_w(pattern)); 00171 00172 *matched = NULL; 00173 if(str_len >= pattern_len) { 00174 /* Check if there's an explicit wildcard in the pattern. */ 00175 if(pattern[0] == '*' && pattern[1] == '.') { 00176 /* Make sure that 'str' matches the wildcard pattern. 00177 * 00178 * Example: 00179 * pattern = "*.google.com" 00180 * 00181 * So in this case 'str' would have to end with ".google.com" in order 00182 * to map to this pattern. 00183 */ 00184 if(str_len >= pattern_len+1 && !strcmpiW(str+(str_len-pattern_len+1), pattern+1)) { 00185 /* Check if there's another '.' inside of the "unmatched" portion 00186 * of 'str'. 00187 * 00188 * Example: 00189 * pattern = "*.google.com" 00190 * str = "test.testing.google.com" 00191 * 00192 * The currently matched portion is ".google.com" in 'str', we need 00193 * see if there's a '.' inside of the unmatched portion ("test.testing"), because 00194 * if there is and 'implicit_wildcard' isn't set, then this isn't 00195 * a match. 00196 */ 00197 const WCHAR *ptr; 00198 if(str_len > pattern_len+1 && (ptr = memrchrW(str, '.', str_len-pattern_len-2))) { 00199 if(implicit_wildcard) { 00200 matches = TRUE; 00201 *matched = ptr+1; 00202 } 00203 } else { 00204 matches = TRUE; 00205 *matched = str; 00206 } 00207 } 00208 } else if(implicit_wildcard && str_len > pattern_len) { 00209 /* When the pattern has an implicit wildcard component, it means 00210 * that anything goes in 'str' as long as it ends with the pattern 00211 * and that the beginning of the match has a '.' before it. 00212 * 00213 * Example: 00214 * pattern = "google.com" 00215 * str = "www.google.com" 00216 * 00217 * Implicitly matches the pattern, where as: 00218 * 00219 * pattern = "google.com" 00220 * str = "wwwgoogle.com" 00221 * 00222 * Doesn't match the pattern. 00223 */ 00224 if(str_len > pattern_len) { 00225 if(str[str_len-pattern_len-1] == '.' && !strcmpiW(str+(str_len-pattern_len), pattern)) { 00226 matches = TRUE; 00227 *matched = str+(str_len-pattern_len); 00228 } 00229 } 00230 } else { 00231 /* The pattern doesn't have an implicit wildcard, or an explicit wildcard, 00232 * so 'str' has to be an exact match to the 'pattern'. 00233 */ 00234 if(!strcmpiW(str, pattern)) { 00235 matches = TRUE; 00236 *matched = str; 00237 } 00238 } 00239 } 00240 00241 if(matches) 00242 TRACE("Found a match: matched=%s\n", debugstr_w(*matched)); 00243 else 00244 TRACE("No match found\n"); 00245 00246 return matches; 00247 } 00248 00249 static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone) 00250 { 00251 static const WCHAR wildcardW[] = {'*',0}; 00252 00253 DWORD res; 00254 DWORD size = sizeof(DWORD); 00255 DWORD type; 00256 00257 /* See if the key contains a value for the scheme first. */ 00258 res = RegQueryValueExW(key, schema, NULL, &type, (BYTE*)zone, &size); 00259 if(type != REG_DWORD) 00260 WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(schema)); 00261 00262 if(res != ERROR_SUCCESS || type != REG_DWORD) { 00263 /* Try to get the zone for the wildcard scheme. */ 00264 size = sizeof(DWORD); 00265 res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size); 00266 if(type != REG_DWORD) 00267 WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW)); 00268 } 00269 00270 return res == ERROR_SUCCESS && type == REG_DWORD; 00271 } 00272 00273 /******************************************************************** 00274 * search_domain_for_zone [internal] 00275 * 00276 * Searches the specified 'domain' registry key to see if 'host' maps into it, or any 00277 * of it's subdomain registry keys. 00278 * 00279 * Returns S_OK if a match is found, S_FALSE if no matches were found, or an error code. 00280 */ 00281 static HRESULT search_domain_for_zone(HKEY domains, LPCWSTR domain, DWORD domain_len, LPCWSTR schema, 00282 LPCWSTR host, DWORD host_len, DWORD *zone) 00283 { 00284 BOOL found = FALSE; 00285 HKEY domain_key; 00286 DWORD res; 00287 LPCWSTR matched; 00288 00289 if(host_len >= domain_len && matches_domain_pattern(domain, host, TRUE, &matched)) { 00290 res = RegOpenKeyW(domains, domain, &domain_key); 00291 if(res != ERROR_SUCCESS) { 00292 ERR("Failed to open domain key %s: %d\n", debugstr_w(domain), res); 00293 return E_UNEXPECTED; 00294 } 00295 00296 if(matched == host) 00297 found = get_zone_for_scheme(domain_key, schema, zone); 00298 else { 00299 INT domain_offset; 00300 DWORD subdomain_count, subdomain_len; 00301 BOOL check_domain = TRUE; 00302 00303 find_domain_name(domain, domain_len, &domain_offset); 00304 00305 res = RegQueryInfoKeyW(domain_key, NULL, NULL, NULL, &subdomain_count, &subdomain_len, 00306 NULL, NULL, NULL, NULL, NULL, NULL); 00307 if(res != ERROR_SUCCESS) { 00308 ERR("Unable to query info for key %s: %d\n", debugstr_w(domain), res); 00309 RegCloseKey(domain_key); 00310 return E_UNEXPECTED; 00311 } 00312 00313 if(subdomain_count) { 00314 WCHAR *subdomain; 00315 WCHAR *component; 00316 DWORD i; 00317 00318 subdomain = heap_alloc((subdomain_len+1)*sizeof(WCHAR)); 00319 if(!subdomain) { 00320 RegCloseKey(domain_key); 00321 return E_OUTOFMEMORY; 00322 } 00323 00324 component = heap_strndupW(host, matched-host-1); 00325 if(!component) { 00326 heap_free(subdomain); 00327 RegCloseKey(domain_key); 00328 return E_OUTOFMEMORY; 00329 } 00330 00331 for(i = 0; i < subdomain_count; ++i) { 00332 DWORD len = subdomain_len+1; 00333 const WCHAR *sub_matched; 00334 00335 res = RegEnumKeyExW(domain_key, i, subdomain, &len, NULL, NULL, NULL, NULL); 00336 if(res != ERROR_SUCCESS) { 00337 heap_free(component); 00338 heap_free(subdomain); 00339 RegCloseKey(domain_key); 00340 return E_UNEXPECTED; 00341 } 00342 00343 if(matches_domain_pattern(subdomain, component, FALSE, &sub_matched)) { 00344 HKEY subdomain_key; 00345 00346 res = RegOpenKeyW(domain_key, subdomain, &subdomain_key); 00347 if(res != ERROR_SUCCESS) { 00348 ERR("Unable to open subdomain key %s of %s: %d\n", debugstr_w(subdomain), 00349 debugstr_w(domain), res); 00350 heap_free(component); 00351 heap_free(subdomain); 00352 RegCloseKey(domain_key); 00353 return E_UNEXPECTED; 00354 } 00355 00356 found = get_zone_for_scheme(subdomain_key, schema, zone); 00357 check_domain = FALSE; 00358 RegCloseKey(subdomain_key); 00359 break; 00360 } 00361 } 00362 heap_free(subdomain); 00363 heap_free(component); 00364 } 00365 00366 /* There's a chance that 'host' implicitly mapped into 'domain', in 00367 * which case we check to see if 'domain' contains zone information. 00368 * 00369 * This can only happen if 'domain' is it's own domain name. 00370 * Example: 00371 * "google.com" (domain name = "google.com") 00372 * 00373 * So if: 00374 * host = "www.google.com" 00375 * 00376 * Then host would map directly into the "google.com" domain key. 00377 * 00378 * If 'domain' has more than just it's domain name, or it does not 00379 * have a domain name, then we don't perform the check. The reason 00380 * for this is that these domains don't allow implicit mappings. 00381 * Example: 00382 * domain = "org" (has no domain name) 00383 * host = "www.org" 00384 * 00385 * The mapping would only happen if the "org" key had an explicit subkey 00386 * called "www". 00387 */ 00388 if(check_domain && !domain_offset && !strchrW(host, matched-host-1)) 00389 found = get_zone_for_scheme(domain_key, schema, zone); 00390 } 00391 RegCloseKey(domain_key); 00392 } 00393 00394 return found ? S_OK : S_FALSE; 00395 } 00396 00397 static HRESULT search_for_domain_mapping(HKEY domains, LPCWSTR schema, LPCWSTR host, DWORD host_len, DWORD *zone) 00398 { 00399 WCHAR *domain; 00400 DWORD domain_count, domain_len, i; 00401 DWORD res; 00402 HRESULT hres = S_FALSE; 00403 00404 res = RegQueryInfoKeyW(domains, NULL, NULL, NULL, &domain_count, &domain_len, 00405 NULL, NULL, NULL, NULL, NULL, NULL); 00406 if(res != ERROR_SUCCESS) { 00407 WARN("Failed to retrieve information about key\n"); 00408 return E_UNEXPECTED; 00409 } 00410 00411 if(!domain_count) 00412 return S_FALSE; 00413 00414 domain = heap_alloc((domain_len+1)*sizeof(WCHAR)); 00415 if(!domain) 00416 return E_OUTOFMEMORY; 00417 00418 for(i = 0; i < domain_count; ++i) { 00419 DWORD len = domain_len+1; 00420 00421 res = RegEnumKeyExW(domains, i, domain, &len, NULL, NULL, NULL, NULL); 00422 if(res != ERROR_SUCCESS) { 00423 heap_free(domain); 00424 return E_UNEXPECTED; 00425 } 00426 00427 hres = search_domain_for_zone(domains, domain, len, schema, host, host_len, zone); 00428 if(FAILED(hres) || hres == S_OK) 00429 break; 00430 } 00431 00432 heap_free(domain); 00433 return hres; 00434 } 00435 00436 static HRESULT get_zone_from_domains(LPCWSTR url, LPCWSTR schema, DWORD *zone) 00437 { 00438 HRESULT hres; 00439 WCHAR *host_name; 00440 DWORD host_len = lstrlenW(url)+1; 00441 DWORD res; 00442 HKEY domains; 00443 00444 host_name = heap_alloc(host_len*sizeof(WCHAR)); 00445 if(!host_name) 00446 return E_OUTOFMEMORY; 00447 00448 hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, host_name, host_len, &host_len, 0); 00449 if(hres == S_FALSE) { 00450 WCHAR *tmp = heap_realloc(host_name, (host_len+1)*sizeof(WCHAR)); 00451 if(!tmp) { 00452 heap_free(host_name); 00453 return E_OUTOFMEMORY; 00454 } 00455 00456 host_name = tmp; 00457 hres = CoInternetParseUrl(url, PARSE_DOMAIN, 0, host_name, host_len+1, &host_len, 0); 00458 } 00459 00460 /* Windows doesn't play nice with unknown scheme types when it tries 00461 * to check if a host name maps into any domains. 00462 * 00463 * The reason is with how CoInternetParseUrl handles unknown scheme types 00464 * when it's parsing the domain of a URL (IE it always returns E_FAIL). 00465 * 00466 * Windows doesn't compenstate for this and simply doesn't check if 00467 * the URL maps into any domains. 00468 */ 00469 if(hres != S_OK) { 00470 heap_free(host_name); 00471 if(hres == E_FAIL) 00472 return S_FALSE; 00473 return hres; 00474 } 00475 00476 /* First try CURRENT_USER. */ 00477 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapDomainsKey, &domains); 00478 if(res == ERROR_SUCCESS) { 00479 hres = search_for_domain_mapping(domains, schema, host_name, host_len, zone); 00480 RegCloseKey(domains); 00481 } else 00482 WARN("Failed to open HKCU's %s key\n", debugstr_w(wszZoneMapDomainsKey)); 00483 00484 /* If that doesn't work try LOCAL_MACHINE. */ 00485 if(hres == S_FALSE) { 00486 res = RegOpenKeyW(HKEY_LOCAL_MACHINE, wszZoneMapDomainsKey, &domains); 00487 if(res == ERROR_SUCCESS) { 00488 hres = search_for_domain_mapping(domains, schema, host_name, host_len, zone); 00489 RegCloseKey(domains); 00490 } else 00491 WARN("Failed to open HKLM's %s key\n", debugstr_w(wszZoneMapDomainsKey)); 00492 } 00493 00494 heap_free(host_name); 00495 return hres; 00496 } 00497 00498 static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url) 00499 { 00500 LPWSTR secur_url; 00501 WCHAR schema[64]; 00502 DWORD size=0; 00503 HRESULT hres; 00504 00505 *zone = URLZONE_INVALID; 00506 00507 hres = CoInternetGetSecurityUrl(url, &secur_url, PSU_SECURITY_URL_ONLY, 0); 00508 if(hres != S_OK) { 00509 size = strlenW(url)*sizeof(WCHAR); 00510 00511 secur_url = heap_alloc(size); 00512 if(!secur_url) 00513 return E_OUTOFMEMORY; 00514 00515 memcpy(secur_url, url, size); 00516 } 00517 00518 hres = CoInternetParseUrl(secur_url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0); 00519 if(FAILED(hres) || !*schema) { 00520 heap_free(secur_url); 00521 return E_INVALIDARG; 00522 } 00523 00524 /* file protocol is a special case */ 00525 if(!strcmpW(schema, fileW)) { 00526 WCHAR path[MAX_PATH], root[20]; 00527 WCHAR *ptr; 00528 00529 hres = CoInternetParseUrl(secur_url, PARSE_PATH_FROM_URL, 0, path, 00530 sizeof(path)/sizeof(WCHAR), &size, 0); 00531 00532 if(SUCCEEDED(hres) && (ptr = strchrW(path, '\\')) && ptr-path < sizeof(root)/sizeof(WCHAR)) { 00533 UINT type; 00534 00535 memcpy(root, path, (ptr-path)*sizeof(WCHAR)); 00536 root[ptr-path] = 0; 00537 00538 type = GetDriveTypeW(root); 00539 00540 switch(type) { 00541 case DRIVE_UNKNOWN: 00542 case DRIVE_NO_ROOT_DIR: 00543 break; 00544 case DRIVE_REMOVABLE: 00545 case DRIVE_FIXED: 00546 case DRIVE_CDROM: 00547 case DRIVE_RAMDISK: 00548 *zone = URLZONE_LOCAL_MACHINE; 00549 hres = S_OK; 00550 break; 00551 case DRIVE_REMOTE: 00552 *zone = URLZONE_INTERNET; 00553 hres = S_OK; 00554 break; 00555 default: 00556 FIXME("unsupported drive type %d\n", type); 00557 } 00558 } 00559 } 00560 00561 if(*zone == URLZONE_INVALID) { 00562 hres = get_zone_from_domains(secur_url, schema, zone); 00563 if(hres == S_FALSE) 00564 hres = get_zone_from_reg(schema, zone); 00565 } 00566 00567 if(FAILED(hres) || !ret_url) 00568 heap_free(secur_url); 00569 else 00570 *ret_url = secur_url; 00571 00572 return hres; 00573 } 00574 00575 static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey) 00576 { 00577 static const WCHAR wszFormat[] = {'%','s','%','u',0}; 00578 00579 WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+12]; 00580 DWORD res; 00581 00582 wsprintfW(key_name, wszFormat, wszZonesKey, zone); 00583 00584 res = RegOpenKeyW(parent_key, key_name, hkey); 00585 00586 if(res != ERROR_SUCCESS) { 00587 WARN("RegOpenKey failed\n"); 00588 return E_INVALIDARG; 00589 } 00590 00591 return S_OK; 00592 } 00593 00594 static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD size, URLZONEREG zone_reg) 00595 { 00596 HKEY parent_key; 00597 HKEY hkey; 00598 LONG res; 00599 HRESULT hres; 00600 00601 switch(action) { 00602 case URLACTION_SCRIPT_OVERRIDE_SAFETY: 00603 case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY: 00604 *(DWORD*)policy = URLPOLICY_DISALLOW; 00605 return S_OK; 00606 } 00607 00608 switch(zone_reg) { 00609 case URLZONEREG_DEFAULT: 00610 case URLZONEREG_HKCU: 00611 parent_key = HKEY_CURRENT_USER; 00612 break; 00613 case URLZONEREG_HKLM: 00614 parent_key = HKEY_LOCAL_MACHINE; 00615 break; 00616 default: 00617 WARN("Unknown URLZONEREG: %d\n", zone_reg); 00618 return E_FAIL; 00619 }; 00620 00621 hres = open_zone_key(parent_key, zone, &hkey); 00622 if(SUCCEEDED(hres)) { 00623 WCHAR action_str[16]; 00624 DWORD len = size; 00625 00626 static const WCHAR formatW[] = {'%','X',0}; 00627 00628 wsprintfW(action_str, formatW, action); 00629 00630 res = RegQueryValueExW(hkey, action_str, NULL, NULL, policy, &len); 00631 if(res == ERROR_MORE_DATA) { 00632 hres = E_INVALIDARG; 00633 }else if(res == ERROR_FILE_NOT_FOUND) { 00634 hres = E_FAIL; 00635 }else if(res != ERROR_SUCCESS) { 00636 ERR("RegQueryValue failed: %d\n", res); 00637 hres = E_UNEXPECTED; 00638 } 00639 00640 RegCloseKey(hkey); 00641 } 00642 00643 if(FAILED(hres) && zone_reg == URLZONEREG_DEFAULT) 00644 return get_action_policy(zone, action, policy, size, URLZONEREG_HKLM); 00645 00646 return hres; 00647 } 00648 00649 /*********************************************************************** 00650 * InternetSecurityManager implementation 00651 * 00652 */ 00653 typedef struct { 00654 IInternetSecurityManager IInternetSecurityManager_iface; 00655 00656 LONG ref; 00657 00658 IInternetSecurityMgrSite *mgrsite; 00659 IInternetSecurityManager *custom_manager; 00660 } SecManagerImpl; 00661 00662 static inline SecManagerImpl *impl_from_IInternetSecurityManager(IInternetSecurityManager *iface) 00663 { 00664 return CONTAINING_RECORD(iface, SecManagerImpl, IInternetSecurityManager_iface); 00665 } 00666 00667 static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManager* iface,REFIID riid,void** ppvObject) 00668 { 00669 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00670 00671 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject); 00672 00673 /* Perform a sanity check on the parameters.*/ 00674 if ( (This==0) || (ppvObject==0) ) 00675 return E_INVALIDARG; 00676 00677 /* Initialize the return parameter */ 00678 *ppvObject = 0; 00679 00680 /* Compare the riid with the interface IDs implemented by this object.*/ 00681 if (IsEqualIID(&IID_IUnknown, riid) || 00682 IsEqualIID(&IID_IInternetSecurityManager, riid)) 00683 *ppvObject = iface; 00684 00685 /* Check that we obtained an interface.*/ 00686 if (!*ppvObject) { 00687 WARN("not supported interface %s\n", debugstr_guid(riid)); 00688 return E_NOINTERFACE; 00689 } 00690 00691 /* Query Interface always increases the reference count by one when it is successful */ 00692 IInternetSecurityManager_AddRef(iface); 00693 00694 return S_OK; 00695 } 00696 00697 static ULONG WINAPI SecManagerImpl_AddRef(IInternetSecurityManager* iface) 00698 { 00699 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00700 ULONG refCount = InterlockedIncrement(&This->ref); 00701 00702 TRACE("(%p) ref=%u\n", This, refCount); 00703 00704 return refCount; 00705 } 00706 00707 static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface) 00708 { 00709 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00710 ULONG refCount = InterlockedDecrement(&This->ref); 00711 00712 TRACE("(%p) ref=%u\n", This, refCount); 00713 00714 /* destroy the object if there's no more reference on it */ 00715 if (!refCount){ 00716 if(This->mgrsite) 00717 IInternetSecurityMgrSite_Release(This->mgrsite); 00718 if(This->custom_manager) 00719 IInternetSecurityManager_Release(This->custom_manager); 00720 00721 heap_free(This); 00722 00723 URLMON_UnlockModule(); 00724 } 00725 00726 return refCount; 00727 } 00728 00729 static HRESULT WINAPI SecManagerImpl_SetSecuritySite(IInternetSecurityManager *iface, 00730 IInternetSecurityMgrSite *pSite) 00731 { 00732 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00733 00734 TRACE("(%p)->(%p)\n", This, pSite); 00735 00736 if(This->mgrsite) 00737 IInternetSecurityMgrSite_Release(This->mgrsite); 00738 00739 if(This->custom_manager) { 00740 IInternetSecurityManager_Release(This->custom_manager); 00741 This->custom_manager = NULL; 00742 } 00743 00744 This->mgrsite = pSite; 00745 00746 if(pSite) { 00747 IServiceProvider *servprov; 00748 HRESULT hres; 00749 00750 IInternetSecurityMgrSite_AddRef(pSite); 00751 00752 hres = IInternetSecurityMgrSite_QueryInterface(pSite, &IID_IServiceProvider, 00753 (void**)&servprov); 00754 if(SUCCEEDED(hres)) { 00755 IServiceProvider_QueryService(servprov, &SID_SInternetSecurityManager, 00756 &IID_IInternetSecurityManager, (void**)&This->custom_manager); 00757 IServiceProvider_Release(servprov); 00758 } 00759 } 00760 00761 return S_OK; 00762 } 00763 00764 static HRESULT WINAPI SecManagerImpl_GetSecuritySite(IInternetSecurityManager *iface, 00765 IInternetSecurityMgrSite **ppSite) 00766 { 00767 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00768 00769 TRACE("(%p)->(%p)\n", This, ppSite); 00770 00771 if(!ppSite) 00772 return E_INVALIDARG; 00773 00774 if(This->mgrsite) 00775 IInternetSecurityMgrSite_AddRef(This->mgrsite); 00776 00777 *ppSite = This->mgrsite; 00778 return S_OK; 00779 } 00780 00781 static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *iface, 00782 LPCWSTR pwszUrl, DWORD *pdwZone, 00783 DWORD dwFlags) 00784 { 00785 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00786 HRESULT hres; 00787 00788 TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags); 00789 00790 if(This->custom_manager) { 00791 hres = IInternetSecurityManager_MapUrlToZone(This->custom_manager, 00792 pwszUrl, pdwZone, dwFlags); 00793 if(hres != INET_E_DEFAULT_ACTION) 00794 return hres; 00795 } 00796 00797 if(!pwszUrl) { 00798 *pdwZone = URLZONE_INVALID; 00799 return E_INVALIDARG; 00800 } 00801 00802 if(dwFlags) 00803 FIXME("not supported flags: %08x\n", dwFlags); 00804 00805 return map_url_to_zone(pwszUrl, pdwZone, NULL); 00806 } 00807 00808 static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface, 00809 LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) 00810 { 00811 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00812 LPWSTR url, ptr, ptr2; 00813 DWORD zone, len; 00814 HRESULT hres; 00815 00816 static const WCHAR wszFile[] = {'f','i','l','e',':'}; 00817 00818 TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId, 00819 pcbSecurityId, dwReserved); 00820 00821 if(This->custom_manager) { 00822 hres = IInternetSecurityManager_GetSecurityId(This->custom_manager, 00823 pwszUrl, pbSecurityId, pcbSecurityId, dwReserved); 00824 if(hres != INET_E_DEFAULT_ACTION) 00825 return hres; 00826 } 00827 00828 if(!pwszUrl || !pbSecurityId || !pcbSecurityId) 00829 return E_INVALIDARG; 00830 00831 if(dwReserved) 00832 FIXME("dwReserved is not supported\n"); 00833 00834 hres = map_url_to_zone(pwszUrl, &zone, &url); 00835 if(FAILED(hres)) 00836 return hres == 0x80041001 ? E_INVALIDARG : hres; 00837 00838 /* file protocol is a special case */ 00839 if(strlenW(url) >= sizeof(wszFile)/sizeof(WCHAR) 00840 && !memcmp(url, wszFile, sizeof(wszFile)) && strchrW(url, '\\')) { 00841 00842 static const BYTE secidFile[] = {'f','i','l','e',':'}; 00843 00844 heap_free(url); 00845 00846 if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone)) 00847 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00848 00849 memcpy(pbSecurityId, secidFile, sizeof(secidFile)); 00850 *(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone; 00851 00852 *pcbSecurityId = sizeof(secidFile)+sizeof(zone); 00853 return S_OK; 00854 } 00855 00856 ptr = strchrW(url, ':'); 00857 ptr2 = ++ptr; 00858 while(*ptr2 == '/') 00859 ptr2++; 00860 if(ptr2 != ptr) 00861 memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR)); 00862 00863 ptr = strchrW(ptr, '/'); 00864 if(ptr) 00865 *ptr = 0; 00866 00867 len = WideCharToMultiByte(CP_ACP, 0, url, -1, NULL, 0, NULL, NULL)-1; 00868 00869 if(len+sizeof(DWORD) > *pcbSecurityId) { 00870 heap_free(url); 00871 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00872 } 00873 00874 WideCharToMultiByte(CP_ACP, 0, url, -1, (LPSTR)pbSecurityId, len, NULL, NULL); 00875 heap_free(url); 00876 00877 *(DWORD*)(pbSecurityId+len) = zone; 00878 00879 *pcbSecurityId = len+sizeof(DWORD); 00880 00881 return S_OK; 00882 } 00883 00884 00885 static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager *iface, 00886 LPCWSTR pwszUrl, DWORD dwAction, 00887 BYTE *pPolicy, DWORD cbPolicy, 00888 BYTE *pContext, DWORD cbContext, 00889 DWORD dwFlags, DWORD dwReserved) 00890 { 00891 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00892 DWORD zone, policy; 00893 HRESULT hres; 00894 00895 TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction, 00896 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); 00897 00898 if(This->custom_manager) { 00899 hres = IInternetSecurityManager_ProcessUrlAction(This->custom_manager, pwszUrl, dwAction, 00900 pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); 00901 if(hres != INET_E_DEFAULT_ACTION) 00902 return hres; 00903 } 00904 00905 if(dwFlags || dwReserved) 00906 FIXME("Unsupported arguments\n"); 00907 00908 if(!pwszUrl) 00909 return E_INVALIDARG; 00910 00911 hres = map_url_to_zone(pwszUrl, &zone, NULL); 00912 if(FAILED(hres)) 00913 return hres; 00914 00915 hres = get_action_policy(zone, dwAction, (BYTE*)&policy, sizeof(policy), URLZONEREG_DEFAULT); 00916 if(FAILED(hres)) 00917 return hres; 00918 00919 TRACE("policy %x\n", policy); 00920 if(cbPolicy >= sizeof(DWORD)) 00921 *(DWORD*)pPolicy = policy; 00922 00923 switch(GetUrlPolicyPermissions(policy)) { 00924 case URLPOLICY_ALLOW: 00925 case URLPOLICY_CHANNEL_SOFTDIST_PRECACHE: 00926 return S_OK; 00927 case URLPOLICY_DISALLOW: 00928 return S_FALSE; 00929 case URLPOLICY_QUERY: 00930 FIXME("URLPOLICY_QUERY not implemented\n"); 00931 return E_FAIL; 00932 default: 00933 FIXME("Not implemented policy %x\n", policy); 00934 } 00935 00936 return E_FAIL; 00937 } 00938 00939 00940 static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager *iface, 00941 LPCWSTR pwszUrl, REFGUID guidKey, 00942 BYTE **ppPolicy, DWORD *pcbPolicy, 00943 BYTE *pContext, DWORD cbContext, 00944 DWORD dwReserved) 00945 { 00946 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00947 HRESULT hres; 00948 00949 TRACE("(%p)->(%s %s %p %p %p %08x %08x )\n", iface, debugstr_w(pwszUrl), debugstr_guid(guidKey), 00950 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); 00951 00952 if(This->custom_manager) { 00953 hres = IInternetSecurityManager_QueryCustomPolicy(This->custom_manager, pwszUrl, guidKey, 00954 ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); 00955 if(hres != INET_E_DEFAULT_ACTION) 00956 return hres; 00957 } 00958 00959 WARN("Unknown guidKey %s\n", debugstr_guid(guidKey)); 00960 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 00961 } 00962 00963 static HRESULT WINAPI SecManagerImpl_SetZoneMapping(IInternetSecurityManager *iface, 00964 DWORD dwZone, LPCWSTR pwszPattern, DWORD dwFlags) 00965 { 00966 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00967 HRESULT hres; 00968 00969 TRACE("(%p)->(%08x %s %08x)\n", iface, dwZone, debugstr_w(pwszPattern),dwFlags); 00970 00971 if(This->custom_manager) { 00972 hres = IInternetSecurityManager_SetZoneMapping(This->custom_manager, dwZone, 00973 pwszPattern, dwFlags); 00974 if(hres != INET_E_DEFAULT_ACTION) 00975 return hres; 00976 } 00977 00978 FIXME("Default action is not implemented\n"); 00979 return E_NOTIMPL; 00980 } 00981 00982 static HRESULT WINAPI SecManagerImpl_GetZoneMappings(IInternetSecurityManager *iface, 00983 DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags) 00984 { 00985 SecManagerImpl *This = impl_from_IInternetSecurityManager(iface); 00986 HRESULT hres; 00987 00988 TRACE("(%p)->(%08x %p %08x)\n", iface, dwZone, ppenumString,dwFlags); 00989 00990 if(This->custom_manager) { 00991 hres = IInternetSecurityManager_GetZoneMappings(This->custom_manager, dwZone, 00992 ppenumString, dwFlags); 00993 if(hres != INET_E_DEFAULT_ACTION) 00994 return hres; 00995 } 00996 00997 FIXME("Default action is not implemented\n"); 00998 return E_NOTIMPL; 00999 } 01000 01001 static const IInternetSecurityManagerVtbl VT_SecManagerImpl = 01002 { 01003 SecManagerImpl_QueryInterface, 01004 SecManagerImpl_AddRef, 01005 SecManagerImpl_Release, 01006 SecManagerImpl_SetSecuritySite, 01007 SecManagerImpl_GetSecuritySite, 01008 SecManagerImpl_MapUrlToZone, 01009 SecManagerImpl_GetSecurityId, 01010 SecManagerImpl_ProcessUrlAction, 01011 SecManagerImpl_QueryCustomPolicy, 01012 SecManagerImpl_SetZoneMapping, 01013 SecManagerImpl_GetZoneMappings 01014 }; 01015 01016 HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) 01017 { 01018 SecManagerImpl *This; 01019 01020 TRACE("(%p,%p)\n",pUnkOuter,ppobj); 01021 This = heap_alloc(sizeof(*This)); 01022 01023 /* Initialize the virtual function table. */ 01024 This->IInternetSecurityManager_iface.lpVtbl = &VT_SecManagerImpl; 01025 01026 This->ref = 1; 01027 This->mgrsite = NULL; 01028 This->custom_manager = NULL; 01029 01030 *ppobj = This; 01031 01032 URLMON_LockModule(); 01033 01034 return S_OK; 01035 } 01036 01037 /*********************************************************************** 01038 * InternetZoneManager implementation 01039 * 01040 */ 01041 typedef struct { 01042 IInternetZoneManagerEx2 IInternetZoneManagerEx2_iface; 01043 LONG ref; 01044 LPDWORD *zonemaps; 01045 DWORD zonemap_count; 01046 } ZoneMgrImpl; 01047 01048 static inline ZoneMgrImpl *impl_from_IInternetZoneManagerEx2(IInternetZoneManagerEx2 *iface) 01049 { 01050 return CONTAINING_RECORD(iface, ZoneMgrImpl, IInternetZoneManagerEx2_iface); 01051 } 01052 01053 01054 /*********************************************************************** 01055 * build_zonemap_from_reg [internal] 01056 * 01057 * Enumerate the Zones in the Registry and return the Zones in a DWORD-array 01058 * The number of the Zones is returned in data[0] 01059 */ 01060 static LPDWORD build_zonemap_from_reg(void) 01061 { 01062 WCHAR name[32]; 01063 HKEY hkey; 01064 LPDWORD data = NULL; 01065 DWORD allocated = 6; /* space for the zonecount and Zone "0" up to Zone "4" */ 01066 DWORD used = 0; 01067 DWORD res; 01068 DWORD len; 01069 01070 01071 res = RegOpenKeyW(HKEY_CURRENT_USER, wszZonesKey, &hkey); 01072 if (res) 01073 return NULL; 01074 01075 data = heap_alloc(allocated * sizeof(DWORD)); 01076 if (!data) 01077 goto cleanup; 01078 01079 while (!res) { 01080 name[0] = '\0'; 01081 len = sizeof(name) / sizeof(name[0]); 01082 res = RegEnumKeyExW(hkey, used, name, &len, NULL, NULL, NULL, NULL); 01083 01084 if (!res) { 01085 used++; 01086 if (used == allocated) { 01087 LPDWORD new_data; 01088 01089 allocated *= 2; 01090 new_data = heap_realloc_zero(data, allocated * sizeof(DWORD)); 01091 if (!new_data) 01092 goto cleanup; 01093 01094 data = new_data; 01095 } 01096 data[used] = atoiW(name); 01097 } 01098 } 01099 if (used) { 01100 RegCloseKey(hkey); 01101 data[0] = used; 01102 return data; 01103 } 01104 01105 cleanup: 01106 /* something failed */ 01107 RegCloseKey(hkey); 01108 heap_free(data); 01109 return NULL; 01110 } 01111 01112 /******************************************************************** 01113 * IInternetZoneManager_QueryInterface 01114 */ 01115 static HRESULT WINAPI ZoneMgrImpl_QueryInterface(IInternetZoneManagerEx2* iface, REFIID riid, void** ppvObject) 01116 { 01117 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01118 01119 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject); 01120 01121 if(!This || !ppvObject) 01122 return E_INVALIDARG; 01123 01124 if(IsEqualIID(&IID_IUnknown, riid)) { 01125 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObject); 01126 }else if(IsEqualIID(&IID_IInternetZoneManager, riid)) { 01127 TRACE("(%p)->(IID_InternetZoneManager %p)\n", This, ppvObject); 01128 }else if(IsEqualIID(&IID_IInternetZoneManagerEx, riid)) { 01129 TRACE("(%p)->(IID_InternetZoneManagerEx %p)\n", This, ppvObject); 01130 }else if(IsEqualIID(&IID_IInternetZoneManagerEx2, riid)) { 01131 TRACE("(%p)->(IID_InternetZoneManagerEx2 %p)\n", This, ppvObject); 01132 } 01133 else 01134 { 01135 FIXME("Unknown interface: %s\n", debugstr_guid(riid)); 01136 *ppvObject = NULL; 01137 return E_NOINTERFACE; 01138 } 01139 01140 *ppvObject = iface; 01141 IInternetZoneManager_AddRef(iface); 01142 return S_OK; 01143 } 01144 01145 /******************************************************************** 01146 * IInternetZoneManager_AddRef 01147 */ 01148 static ULONG WINAPI ZoneMgrImpl_AddRef(IInternetZoneManagerEx2* iface) 01149 { 01150 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01151 ULONG refCount = InterlockedIncrement(&This->ref); 01152 01153 TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); 01154 01155 return refCount; 01156 } 01157 01158 /******************************************************************** 01159 * IInternetZoneManager_Release 01160 */ 01161 static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManagerEx2* iface) 01162 { 01163 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01164 ULONG refCount = InterlockedDecrement(&This->ref); 01165 01166 TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); 01167 01168 if(!refCount) { 01169 while (This->zonemap_count) heap_free(This->zonemaps[--This->zonemap_count]); 01170 heap_free(This->zonemaps); 01171 heap_free(This); 01172 URLMON_UnlockModule(); 01173 } 01174 01175 return refCount; 01176 } 01177 01178 /******************************************************************** 01179 * IInternetZoneManager_GetZoneAttributes 01180 */ 01181 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* iface, 01182 DWORD dwZone, 01183 ZONEATTRIBUTES* pZoneAttributes) 01184 { 01185 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01186 HRESULT hr; 01187 HKEY hcu; 01188 HKEY hklm = NULL; 01189 01190 TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes); 01191 01192 if (!pZoneAttributes) 01193 return E_INVALIDARG; 01194 01195 hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu); 01196 if (FAILED(hr)) 01197 return S_OK; /* IE6 and older returned E_FAIL here */ 01198 01199 hr = open_zone_key(HKEY_LOCAL_MACHINE, dwZone, &hklm); 01200 if (FAILED(hr)) 01201 TRACE("Zone %d not in HKLM\n", dwZone); 01202 01203 get_string_from_reg(hcu, hklm, displaynameW, pZoneAttributes->szDisplayName, MAX_ZONE_PATH); 01204 get_string_from_reg(hcu, hklm, descriptionW, pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION); 01205 get_string_from_reg(hcu, hklm, iconW, pZoneAttributes->szIconPath, MAX_ZONE_PATH); 01206 get_dword_from_reg(hcu, hklm, minlevelW, &pZoneAttributes->dwTemplateMinLevel); 01207 get_dword_from_reg(hcu, hklm, currentlevelW, &pZoneAttributes->dwTemplateCurrentLevel); 01208 get_dword_from_reg(hcu, hklm, recommendedlevelW, &pZoneAttributes->dwTemplateRecommended); 01209 get_dword_from_reg(hcu, hklm, flagsW, &pZoneAttributes->dwFlags); 01210 01211 RegCloseKey(hklm); 01212 RegCloseKey(hcu); 01213 return S_OK; 01214 } 01215 01216 /******************************************************************** 01217 * IInternetZoneManager_SetZoneAttributes 01218 */ 01219 static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* iface, 01220 DWORD dwZone, 01221 ZONEATTRIBUTES* pZoneAttributes) 01222 { 01223 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01224 HRESULT hr; 01225 HKEY hcu; 01226 01227 TRACE("(%p)->(%d %p)\n", This, dwZone, pZoneAttributes); 01228 01229 if (!pZoneAttributes) 01230 return E_INVALIDARG; 01231 01232 hr = open_zone_key(HKEY_CURRENT_USER, dwZone, &hcu); 01233 if (FAILED(hr)) 01234 return S_OK; /* IE6 returned E_FAIL here */ 01235 01236 /* cbSize is ignored */ 01237 RegSetValueExW(hcu, displaynameW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDisplayName, 01238 (lstrlenW(pZoneAttributes->szDisplayName)+1)* sizeof(WCHAR)); 01239 01240 RegSetValueExW(hcu, descriptionW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDescription, 01241 (lstrlenW(pZoneAttributes->szDescription)+1)* sizeof(WCHAR)); 01242 01243 RegSetValueExW(hcu, iconW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szIconPath, 01244 (lstrlenW(pZoneAttributes->szIconPath)+1)* sizeof(WCHAR)); 01245 01246 RegSetValueExW(hcu, minlevelW, 0, REG_DWORD, 01247 (const BYTE*) &pZoneAttributes->dwTemplateMinLevel, sizeof(DWORD)); 01248 01249 RegSetValueExW(hcu, currentlevelW, 0, REG_DWORD, 01250 (const BYTE*) &pZoneAttributes->dwTemplateCurrentLevel, sizeof(DWORD)); 01251 01252 RegSetValueExW(hcu, recommendedlevelW, 0, REG_DWORD, 01253 (const BYTE*) &pZoneAttributes->dwTemplateRecommended, sizeof(DWORD)); 01254 01255 RegSetValueExW(hcu, flagsW, 0, REG_DWORD, (const BYTE*) &pZoneAttributes->dwFlags, sizeof(DWORD)); 01256 RegCloseKey(hcu); 01257 return S_OK; 01258 01259 } 01260 01261 /******************************************************************** 01262 * IInternetZoneManager_GetZoneCustomPolicy 01263 */ 01264 static HRESULT WINAPI ZoneMgrImpl_GetZoneCustomPolicy(IInternetZoneManagerEx2* iface, 01265 DWORD dwZone, 01266 REFGUID guidKey, 01267 BYTE** ppPolicy, 01268 DWORD* pcbPolicy, 01269 URLZONEREG ulrZoneReg) 01270 { 01271 FIXME("(%p)->(%08x %s %p %p %08x) stub\n", iface, dwZone, debugstr_guid(guidKey), 01272 ppPolicy, pcbPolicy, ulrZoneReg); 01273 return E_NOTIMPL; 01274 } 01275 01276 /******************************************************************** 01277 * IInternetZoneManager_SetZoneCustomPolicy 01278 */ 01279 static HRESULT WINAPI ZoneMgrImpl_SetZoneCustomPolicy(IInternetZoneManagerEx2* iface, 01280 DWORD dwZone, 01281 REFGUID guidKey, 01282 BYTE* ppPolicy, 01283 DWORD cbPolicy, 01284 URLZONEREG ulrZoneReg) 01285 { 01286 FIXME("(%p)->(%08x %s %p %08x %08x) stub\n", iface, dwZone, debugstr_guid(guidKey), 01287 ppPolicy, cbPolicy, ulrZoneReg); 01288 return E_NOTIMPL; 01289 } 01290 01291 /******************************************************************** 01292 * IInternetZoneManager_GetZoneActionPolicy 01293 */ 01294 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManagerEx2* iface, 01295 DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg) 01296 { 01297 TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy, 01298 cbPolicy, urlZoneReg); 01299 01300 if(!pPolicy) 01301 return E_INVALIDARG; 01302 01303 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg); 01304 } 01305 01306 /******************************************************************** 01307 * IInternetZoneManager_SetZoneActionPolicy 01308 */ 01309 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManagerEx2* iface, 01310 DWORD dwZone, 01311 DWORD dwAction, 01312 BYTE* pPolicy, 01313 DWORD cbPolicy, 01314 URLZONEREG urlZoneReg) 01315 { 01316 FIXME("(%p)->(%08x %08x %p %08x %08x) stub\n", iface, dwZone, dwAction, pPolicy, 01317 cbPolicy, urlZoneReg); 01318 return E_NOTIMPL; 01319 } 01320 01321 /******************************************************************** 01322 * IInternetZoneManager_PromptAction 01323 */ 01324 static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManagerEx2* iface, 01325 DWORD dwAction, 01326 HWND hwndParent, 01327 LPCWSTR pwszUrl, 01328 LPCWSTR pwszText, 01329 DWORD dwPromptFlags) 01330 { 01331 FIXME("%p %08x %p %s %s %08x\n", iface, dwAction, hwndParent, 01332 debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags ); 01333 return E_NOTIMPL; 01334 } 01335 01336 /******************************************************************** 01337 * IInternetZoneManager_LogAction 01338 */ 01339 static HRESULT WINAPI ZoneMgrImpl_LogAction(IInternetZoneManagerEx2* iface, 01340 DWORD dwAction, 01341 LPCWSTR pwszUrl, 01342 LPCWSTR pwszText, 01343 DWORD dwLogFlags) 01344 { 01345 FIXME("(%p)->(%08x %s %s %08x) stub\n", iface, dwAction, debugstr_w(pwszUrl), 01346 debugstr_w(pwszText), dwLogFlags); 01347 return E_NOTIMPL; 01348 } 01349 01350 /******************************************************************** 01351 * IInternetZoneManager_CreateZoneEnumerator 01352 */ 01353 static HRESULT WINAPI ZoneMgrImpl_CreateZoneEnumerator(IInternetZoneManagerEx2* iface, 01354 DWORD* pdwEnum, 01355 DWORD* pdwCount, 01356 DWORD dwFlags) 01357 { 01358 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01359 LPDWORD * new_maps; 01360 LPDWORD data; 01361 DWORD i; 01362 01363 TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pdwEnum, pdwCount, dwFlags); 01364 if (!pdwEnum || !pdwCount || (dwFlags != 0)) 01365 return E_INVALIDARG; 01366 01367 data = build_zonemap_from_reg(); 01368 TRACE("found %d zones\n", data ? data[0] : -1); 01369 01370 if (!data) 01371 return E_FAIL; 01372 01373 for (i = 0; i < This->zonemap_count; i++) { 01374 if (This->zonemaps && !This->zonemaps[i]) { 01375 This->zonemaps[i] = data; 01376 *pdwEnum = i; 01377 *pdwCount = data[0]; 01378 return S_OK; 01379 } 01380 } 01381 01382 if (This->zonemaps) { 01383 /* try to double the nr. of pointers in the array */ 01384 new_maps = heap_realloc_zero(This->zonemaps, This->zonemap_count * 2 * sizeof(LPDWORD)); 01385 if (new_maps) 01386 This->zonemap_count *= 2; 01387 } 01388 else 01389 { 01390 This->zonemap_count = 2; 01391 new_maps = heap_alloc_zero(This->zonemap_count * sizeof(LPDWORD)); 01392 } 01393 01394 if (!new_maps) { 01395 heap_free(data); 01396 return E_FAIL; 01397 } 01398 This->zonemaps = new_maps; 01399 This->zonemaps[i] = data; 01400 *pdwEnum = i; 01401 *pdwCount = data[0]; 01402 return S_OK; 01403 } 01404 01405 /******************************************************************** 01406 * IInternetZoneManager_GetZoneAt 01407 */ 01408 static HRESULT WINAPI ZoneMgrImpl_GetZoneAt(IInternetZoneManagerEx2* iface, 01409 DWORD dwEnum, 01410 DWORD dwIndex, 01411 DWORD* pdwZone) 01412 { 01413 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01414 LPDWORD data; 01415 01416 TRACE("(%p)->(0x%08x, %d, %p)\n", This, dwEnum, dwIndex, pdwZone); 01417 01418 /* make sure, that dwEnum and dwIndex are in the valid range */ 01419 if (dwEnum < This->zonemap_count) { 01420 if ((data = This->zonemaps[dwEnum])) { 01421 if (dwIndex < data[0]) { 01422 *pdwZone = data[dwIndex + 1]; 01423 return S_OK; 01424 } 01425 } 01426 } 01427 return E_INVALIDARG; 01428 } 01429 01430 /******************************************************************** 01431 * IInternetZoneManager_DestroyZoneEnumerator 01432 */ 01433 static HRESULT WINAPI ZoneMgrImpl_DestroyZoneEnumerator(IInternetZoneManagerEx2* iface, 01434 DWORD dwEnum) 01435 { 01436 ZoneMgrImpl* This = impl_from_IInternetZoneManagerEx2(iface); 01437 LPDWORD data; 01438 01439 TRACE("(%p)->(0x%08x)\n", This, dwEnum); 01440 /* make sure, that dwEnum is valid */ 01441 if (dwEnum < This->zonemap_count) { 01442 if ((data = This->zonemaps[dwEnum])) { 01443 This->zonemaps[dwEnum] = NULL; 01444 heap_free(data); 01445 return S_OK; 01446 } 01447 } 01448 return E_INVALIDARG; 01449 } 01450 01451 /******************************************************************** 01452 * IInternetZoneManager_CopyTemplatePoliciesToZone 01453 */ 01454 static HRESULT WINAPI ZoneMgrImpl_CopyTemplatePoliciesToZone(IInternetZoneManagerEx2* iface, 01455 DWORD dwTemplate, 01456 DWORD dwZone, 01457 DWORD dwReserved) 01458 { 01459 FIXME("(%p)->(%08x %08x %08x) stub\n", iface, dwTemplate, dwZone, dwReserved); 01460 return E_NOTIMPL; 01461 } 01462 01463 /******************************************************************** 01464 * IInternetZoneManagerEx_GetZoneActionPolicyEx 01465 */ 01466 static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicyEx(IInternetZoneManagerEx2* iface, 01467 DWORD dwZone, 01468 DWORD dwAction, 01469 BYTE* pPolicy, 01470 DWORD cbPolicy, 01471 URLZONEREG urlZoneReg, 01472 DWORD dwFlags) 01473 { 01474 TRACE("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x)\n", iface, dwZone, 01475 dwAction, pPolicy, cbPolicy, urlZoneReg, dwFlags); 01476 01477 if(!pPolicy) 01478 return E_INVALIDARG; 01479 01480 if (dwFlags) 01481 FIXME("dwFlags 0x%x ignored\n", dwFlags); 01482 01483 return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg); 01484 } 01485 01486 /******************************************************************** 01487 * IInternetZoneManagerEx_SetZoneActionPolicyEx 01488 */ 01489 static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicyEx(IInternetZoneManagerEx2* iface, 01490 DWORD dwZone, 01491 DWORD dwAction, 01492 BYTE* pPolicy, 01493 DWORD cbPolicy, 01494 URLZONEREG urlZoneReg, 01495 DWORD dwFlags) 01496 { 01497 FIXME("(%p)->(%d, 0x%x, %p, %d, %d, 0x%x) stub\n", iface, dwZone, dwAction, pPolicy, 01498 cbPolicy, urlZoneReg, dwFlags); 01499 return E_NOTIMPL; 01500 } 01501 01502 /******************************************************************** 01503 * IInternetZoneManagerEx2_GetZoneAttributesEx 01504 */ 01505 static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributesEx(IInternetZoneManagerEx2* iface, 01506 DWORD dwZone, 01507 ZONEATTRIBUTES* pZoneAttributes, 01508 DWORD dwFlags) 01509 { 01510 TRACE("(%p)->(%d, %p, 0x%x)\n", iface, dwZone, pZoneAttributes, dwFlags); 01511 01512 if (dwFlags) 01513 FIXME("dwFlags 0x%x ignored\n", dwFlags); 01514 01515 return IInternetZoneManager_GetZoneAttributes(iface, dwZone, pZoneAttributes); 01516 } 01517 01518 01519 /******************************************************************** 01520 * IInternetZoneManagerEx2_GetZoneSecurityState 01521 */ 01522 static HRESULT WINAPI ZoneMgrImpl_GetZoneSecurityState(IInternetZoneManagerEx2* iface, 01523 DWORD dwZoneIndex, 01524 BOOL fRespectPolicy, 01525 LPDWORD pdwState, 01526 BOOL *pfPolicyEncountered) 01527 { 01528 FIXME("(%p)->(%d, %d, %p, %p) stub\n", iface, dwZoneIndex, fRespectPolicy, 01529 pdwState, pfPolicyEncountered); 01530 01531 *pdwState = SECURITY_IE_STATE_GREEN; 01532 01533 if (pfPolicyEncountered) 01534 *pfPolicyEncountered = FALSE; 01535 01536 return S_OK; 01537 } 01538 01539 /******************************************************************** 01540 * IInternetZoneManagerEx2_GetIESecurityState 01541 */ 01542 static HRESULT WINAPI ZoneMgrImpl_GetIESecurityState(IInternetZoneManagerEx2* iface, 01543 BOOL fRespectPolicy, 01544 LPDWORD pdwState, 01545 BOOL *pfPolicyEncountered, 01546 BOOL fNoCache) 01547 { 01548 FIXME("(%p)->(%d, %p, %p, %d) stub\n", iface, fRespectPolicy, pdwState, 01549 pfPolicyEncountered, fNoCache); 01550 01551 *pdwState = SECURITY_IE_STATE_GREEN; 01552 01553 if (pfPolicyEncountered) 01554 *pfPolicyEncountered = FALSE; 01555 01556 return S_OK; 01557 } 01558 01559 /******************************************************************** 01560 * IInternetZoneManagerEx2_FixInsecureSettings 01561 */ 01562 static HRESULT WINAPI ZoneMgrImpl_FixInsecureSettings(IInternetZoneManagerEx2* iface) 01563 { 01564 FIXME("(%p) stub\n", iface); 01565 return S_OK; 01566 } 01567 01568 /******************************************************************** 01569 * IInternetZoneManager_Construct 01570 */ 01571 static const IInternetZoneManagerEx2Vtbl ZoneMgrImplVtbl = { 01572 ZoneMgrImpl_QueryInterface, 01573 ZoneMgrImpl_AddRef, 01574 ZoneMgrImpl_Release, 01575 /* IInternetZoneManager */ 01576 ZoneMgrImpl_GetZoneAttributes, 01577 ZoneMgrImpl_SetZoneAttributes, 01578 ZoneMgrImpl_GetZoneCustomPolicy, 01579 ZoneMgrImpl_SetZoneCustomPolicy, 01580 ZoneMgrImpl_GetZoneActionPolicy, 01581 ZoneMgrImpl_SetZoneActionPolicy, 01582 ZoneMgrImpl_PromptAction, 01583 ZoneMgrImpl_LogAction, 01584 ZoneMgrImpl_CreateZoneEnumerator, 01585 ZoneMgrImpl_GetZoneAt, 01586 ZoneMgrImpl_DestroyZoneEnumerator, 01587 ZoneMgrImpl_CopyTemplatePoliciesToZone, 01588 /* IInternetZoneManagerEx */ 01589 ZoneMgrImpl_GetZoneActionPolicyEx, 01590 ZoneMgrImpl_SetZoneActionPolicyEx, 01591 /* IInternetZoneManagerEx2 */ 01592 ZoneMgrImpl_GetZoneAttributesEx, 01593 ZoneMgrImpl_GetZoneSecurityState, 01594 ZoneMgrImpl_GetIESecurityState, 01595 ZoneMgrImpl_FixInsecureSettings, 01596 }; 01597 01598 HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) 01599 { 01600 ZoneMgrImpl* ret = heap_alloc_zero(sizeof(ZoneMgrImpl)); 01601 01602 TRACE("(%p %p)\n", pUnkOuter, ppobj); 01603 ret->IInternetZoneManagerEx2_iface.lpVtbl = &ZoneMgrImplVtbl; 01604 ret->ref = 1; 01605 *ppobj = (IInternetZoneManagerEx*)ret; 01606 01607 URLMON_LockModule(); 01608 01609 return S_OK; 01610 } 01611 01612 /*********************************************************************** 01613 * CoInternetCreateSecurityManager (URLMON.@) 01614 * 01615 */ 01616 HRESULT WINAPI CoInternetCreateSecurityManager( IServiceProvider *pSP, 01617 IInternetSecurityManager **ppSM, DWORD dwReserved ) 01618 { 01619 TRACE("%p %p %d\n", pSP, ppSM, dwReserved ); 01620 01621 if(pSP) 01622 FIXME("pSP not supported\n"); 01623 01624 return SecManagerImpl_Construct(NULL, (void**) ppSM); 01625 } 01626 01627 /******************************************************************** 01628 * CoInternetCreateZoneManager (URLMON.@) 01629 */ 01630 HRESULT WINAPI CoInternetCreateZoneManager(IServiceProvider* pSP, IInternetZoneManager** ppZM, DWORD dwReserved) 01631 { 01632 TRACE("(%p %p %x)\n", pSP, ppZM, dwReserved); 01633 return ZoneMgrImpl_Construct(NULL, (void**)ppZM); 01634 } 01635 01636 static HRESULT parse_security_url(const WCHAR *url, PSUACTION action, WCHAR **result) { 01637 IInternetProtocolInfo *protocol_info; 01638 WCHAR *tmp, *new_url = NULL, *alloc_url = NULL; 01639 DWORD size, new_size; 01640 HRESULT hres = S_OK, parse_hres; 01641 01642 while(1) { 01643 TRACE("parsing %s\n", debugstr_w(url)); 01644 01645 protocol_info = get_protocol_info(url); 01646 if(!protocol_info) 01647 break; 01648 01649 size = strlenW(url)+1; 01650 new_url = CoTaskMemAlloc(size*sizeof(WCHAR)); 01651 if(!new_url) { 01652 hres = E_OUTOFMEMORY; 01653 break; 01654 } 01655 01656 new_size = 0; 01657 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, size, &new_size, 0); 01658 if(parse_hres == S_FALSE) { 01659 if(!new_size) { 01660 hres = E_UNEXPECTED; 01661 break; 01662 } 01663 01664 tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR)); 01665 if(!tmp) { 01666 hres = E_OUTOFMEMORY; 01667 break; 01668 } 01669 new_url = tmp; 01670 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL, 0, new_url, 01671 new_size, &new_size, 0); 01672 if(parse_hres == S_FALSE) { 01673 hres = E_FAIL; 01674 break; 01675 } 01676 } 01677 01678 if(parse_hres != S_OK || !strcmpW(url, new_url)) 01679 break; 01680 01681 CoTaskMemFree(alloc_url); 01682 url = alloc_url = new_url; 01683 new_url = NULL; 01684 } 01685 01686 CoTaskMemFree(new_url); 01687 01688 if(hres != S_OK) { 01689 WARN("failed: %08x\n", hres); 01690 CoTaskMemFree(alloc_url); 01691 return hres; 01692 } 01693 01694 if(action == PSU_DEFAULT && (protocol_info = get_protocol_info(url))) { 01695 size = strlenW(url)+1; 01696 new_url = CoTaskMemAlloc(size * sizeof(WCHAR)); 01697 if(new_url) { 01698 new_size = 0; 01699 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, 01700 new_url, size, &new_size, 0); 01701 if(parse_hres == S_FALSE) { 01702 if(new_size) { 01703 tmp = CoTaskMemRealloc(new_url, new_size*sizeof(WCHAR)); 01704 if(tmp) { 01705 new_url = tmp; 01706 parse_hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN, 0, new_url, 01707 new_size, &new_size, 0); 01708 if(parse_hres == S_FALSE) 01709 hres = E_FAIL; 01710 }else { 01711 hres = E_OUTOFMEMORY; 01712 } 01713 }else { 01714 hres = E_UNEXPECTED; 01715 } 01716 } 01717 01718 if(hres == S_OK && parse_hres == S_OK) { 01719 CoTaskMemFree(alloc_url); 01720 url = alloc_url = new_url; 01721 new_url = NULL; 01722 } 01723 01724 CoTaskMemFree(new_url); 01725 }else { 01726 hres = E_OUTOFMEMORY; 01727 } 01728 IInternetProtocolInfo_Release(protocol_info); 01729 } 01730 01731 if(FAILED(hres)) { 01732 WARN("failed %08x\n", hres); 01733 CoTaskMemFree(alloc_url); 01734 return hres; 01735 } 01736 01737 if(!alloc_url) { 01738 size = strlenW(url)+1; 01739 alloc_url = CoTaskMemAlloc(size * sizeof(WCHAR)); 01740 if(!alloc_url) 01741 return E_OUTOFMEMORY; 01742 memcpy(alloc_url, url, size * sizeof(WCHAR)); 01743 } 01744 01745 *result = alloc_url; 01746 return S_OK; 01747 } 01748 01749 /******************************************************************** 01750 * CoInternetGetSecurityUrl (URLMON.@) 01751 */ 01752 HRESULT WINAPI CoInternetGetSecurityUrl(LPCWSTR pwzUrl, LPWSTR *ppwzSecUrl, PSUACTION psuAction, DWORD dwReserved) 01753 { 01754 WCHAR *secure_url; 01755 HRESULT hres; 01756 01757 TRACE("(%p,%p,%u,%u)\n", pwzUrl, ppwzSecUrl, psuAction, dwReserved); 01758 01759 hres = parse_security_url(pwzUrl, psuAction, &secure_url); 01760 if(FAILED(hres)) 01761 return hres; 01762 01763 if(psuAction != PSU_SECURITY_URL_ONLY) { 01764 PARSEDURLW parsed_url = { sizeof(parsed_url) }; 01765 DWORD size; 01766 01767 /* FIXME: Use helpers from uri.c */ 01768 if(SUCCEEDED(ParseURLW(secure_url, &parsed_url))) { 01769 WCHAR *new_url; 01770 01771 switch(parsed_url.nScheme) { 01772 case URL_SCHEME_FTP: 01773 case URL_SCHEME_HTTP: 01774 case URL_SCHEME_HTTPS: 01775 size = strlenW(secure_url)+1; 01776 new_url = CoTaskMemAlloc(size * sizeof(WCHAR)); 01777 if(new_url) 01778 hres = UrlGetPartW(secure_url, new_url, &size, URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME); 01779 else 01780 hres = E_OUTOFMEMORY; 01781 CoTaskMemFree(secure_url); 01782 if(hres != S_OK) { 01783 WARN("UrlGetPart failed: %08x\n", hres); 01784 CoTaskMemFree(new_url); 01785 return FAILED(hres) ? hres : E_FAIL; 01786 } 01787 secure_url = new_url; 01788 } 01789 } 01790 } 01791 01792 *ppwzSecUrl = secure_url; 01793 return S_OK; 01794 } 01795 01796 /******************************************************************** 01797 * CoInternetGetSecurityUrlEx (URLMON.@) 01798 */ 01799 HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION psuAction, DWORD_PTR dwReserved) 01800 { 01801 URL_SCHEME scheme_type; 01802 BSTR secure_uri; 01803 WCHAR *ret_url; 01804 HRESULT hres; 01805 01806 TRACE("(%p,%p,%u,%u)\n", pUri, ppSecUri, psuAction, (DWORD)dwReserved); 01807 01808 if(!pUri || !ppSecUri) 01809 return E_INVALIDARG; 01810 01811 hres = IUri_GetDisplayUri(pUri, &secure_uri); 01812 if(FAILED(hres)) 01813 return hres; 01814 01815 hres = parse_security_url(secure_uri, psuAction, &ret_url); 01816 SysFreeString(secure_uri); 01817 if(FAILED(hres)) 01818 return hres; 01819 01820 hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri); 01821 if(FAILED(hres)) { 01822 CoTaskMemFree(ret_url); 01823 return hres; 01824 } 01825 01826 /* File URIs have to hierarchical. */ 01827 hres = IUri_GetScheme(pUri, (DWORD*)&scheme_type); 01828 if(SUCCEEDED(hres) && scheme_type == URL_SCHEME_FILE) { 01829 const WCHAR *tmp = ret_url; 01830 01831 /* Check and see if a "//" is after the scheme name. */ 01832 tmp += sizeof(fileW)/sizeof(WCHAR); 01833 if(*tmp != '/' || *(tmp+1) != '/') 01834 hres = E_INVALIDARG; 01835 } 01836 01837 if(SUCCEEDED(hres)) 01838 hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri); 01839 CoTaskMemFree(ret_url); 01840 return hres; 01841 } Generated on Sun May 27 2012 04:26:40 for ReactOS by
1.7.6.1
|