ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

internet.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2005 Jacek Caban
00003  * Copyright 2011 Thomas Mullaly for CodeWeavers
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00018  */
00019 
00020 #include "urlmon_main.h"
00021 #include "winreg.h"
00022 #include "shlwapi.h"
00023 
00024 #include "wine/debug.h"
00025 
00026 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
00027 
00028 static const WCHAR feature_control_keyW[] =
00029     {'S','o','f','t','w','a','r','e','\\',
00030      'M','i','c','r','o','s','o','f','t','\\',
00031      'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
00032      'M','a','i','n','\\',
00033      'F','e','a','t','u','r','e','C','o','n','t','r','o','l',0};
00034 
00035 static const WCHAR feature_object_cachingW[] =
00036     {'F','E','A','T','U','R','E','_','O','B','J','E','C','T','_','C','A','C','H','I','N','G',0};
00037 static const WCHAR feature_zone_elevationW[] =
00038     {'F','E','A','T','U','R','E','_','Z','O','N','E','_','E','L','E','V','A','T','I','O','N',0};
00039 static const WCHAR feature_mime_handlingW[] =
00040     {'F','E','A','T','U','R','E','_','M','I','M','E','_','H','A','N','D','L','I','N','G',0};
00041 static const WCHAR feature_mime_sniffingW[] =
00042     {'F','E','A','T','U','R','E','_','M','I','M','E','_','S','N','I','F','F','I','N','G',0};
00043 static const WCHAR feature_window_restrictionsW[] =
00044     {'F','E','A','T','U','R','E','_','W','I','N','D','O','W','_','R','E','S','T','R','I','C','T','I','O','N','S',0};
00045 static const WCHAR feature_weboc_popupmanagementW[] =
00046     {'F','E','A','T','U','R','E','_','W','E','B','O','C','_','P','O','P','U','P','M','A','N','A','G','E','M','E','N','T',0};
00047 static const WCHAR feature_behaviorsW[] =
00048     {'F','E','A','T','U','R','E','_','B','E','H','A','V','I','O','R','S',0};
00049 static const WCHAR feature_disable_mk_protocolW[] =
00050     {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','M','K','_','P','R','O','T','O','C','O','L',0};
00051 static const WCHAR feature_localmachine_lockdownW[] =
00052     {'F','E','A','T','U','R','E','_','L','O','C','A','L','M','A','C','H','I','N','E','_','L','O','C','K','D','O','W','N',0};
00053 static const WCHAR feature_securitybandW[] =
00054     {'F','E','A','T','U','R','E','_','S','E','C','U','R','I','T','Y','B','A','N','D',0};
00055 static const WCHAR feature_restrict_activexinstallW[] =
00056     {'F','E','A','T','U','R','E','_','R','E','S','T','R','I','C','T','_','A','C','T','I','V','E','X','I','N','S','T','A','L','L',0};
00057 static const WCHAR feature_validate_navigate_urlW[] =
00058     {'F','E','A','T','U','R','E','_','V','A','L','I','D','A','T','E','_','N','A','V','I','G','A','T','E','_','U','R','L',0};
00059 static const WCHAR feature_restrict_filedownloadW[] =
00060     {'F','E','A','T','U','R','E','_','R','E','S','T','R','I','C','T','_','F','I','L','E','D','O','W','N','L','O','A','D',0};
00061 static const WCHAR feature_addon_managementW[] =
00062     {'F','E','A','T','U','R','E','_','A','D','D','O','N','_','M','A','N','A','G','E','M','E','N','T',0};
00063 static const WCHAR feature_protocol_lockdownW[] =
00064     {'F','E','A','T','U','R','E','_','P','R','O','T','O','C','O','L','_','L','O','C','K','D','O','W','N',0};
00065 static const WCHAR feature_http_username_password_disableW[] =
00066     {'F','E','A','T','U','R','E','_','H','T','T','P','_','U','S','E','R','N','A','M','E','_',
00067      'P','A','S','S','W','O','R','D','_','D','I','S','A','B','L','E',0};
00068 static const WCHAR feature_safe_bindtoobjectW[] =
00069     {'F','E','A','T','U','R','E','_','S','A','F','E','_','B','I','N','D','T','O','O','B','J','E','C','T',0};
00070 static const WCHAR feature_unc_savedfilecheckW[] =
00071     {'F','E','A','T','U','R','E','_','U','N','C','_','S','A','V','E','D','F','I','L','E','C','H','E','C','K',0};
00072 static const WCHAR feature_get_url_dom_filepath_unencodedW[] =
00073     {'F','E','A','T','U','R','E','_','G','E','T','_','U','R','L','_','D','O','M','_',
00074      'F','I','L','E','P','A','T','H','_','U','N','E','N','C','O','D','E','D',0};
00075 static const WCHAR feature_tabbed_browsingW[] =
00076     {'F','E','A','T','U','R','E','_','T','A','B','B','E','D','_','B','R','O','W','S','I','N','G',0};
00077 static const WCHAR feature_ssluxW[] =
00078     {'F','E','A','T','U','R','E','_','S','S','L','U','X',0};
00079 static const WCHAR feature_disable_navigation_soundsW[] =
00080     {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','N','A','V','I','G','A','T','I','O','N','_',
00081      'S','O','U','N','D','S',0};
00082 static const WCHAR feature_disable_legacy_compressionW[] =
00083     {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','L','E','G','A','C','Y','_',
00084      'C','O','M','P','R','E','S','S','I','O','N',0};
00085 static const WCHAR feature_force_addr_and_statusW[] =
00086     {'F','E','A','T','U','R','E','_','F','O','R','C','E','_','A','D','D','R','_','A','N','D','_',
00087      'S','T','A','T','U','S',0};
00088 static const WCHAR feature_xmlhttpW[] =
00089     {'F','E','A','T','U','R','E','_','X','M','L','H','T','T','P',0};
00090 static const WCHAR feature_disable_telnet_protocolW[] =
00091     {'F','E','A','T','U','R','E','_','D','I','S','A','B','L','E','_','T','E','L','N','E','T','_',
00092      'P','R','O','T','O','C','O','L',0};
00093 static const WCHAR feature_feedsW[] =
00094     {'F','E','A','T','U','R','E','_','F','E','E','D','S',0};
00095 static const WCHAR feature_block_input_promptsW[] =
00096     {'F','E','A','T','U','R','E','_','B','L','O','C','K','_','I','N','P','U','T','_','P','R','O','M','P','T','S',0};
00097 
00098 static CRITICAL_SECTION process_features_cs;
00099 static CRITICAL_SECTION_DEBUG process_features_cs_dbg =
00100 {
00101     0, 0, &process_features_cs,
00102     { &process_features_cs_dbg.ProcessLocksList, &process_features_cs_dbg.ProcessLocksList },
00103       0, 0, { (DWORD_PTR)(__FILE__ ": process features") }
00104 };
00105 static CRITICAL_SECTION process_features_cs = { &process_features_cs_dbg, -1, 0, 0, 0, 0 };
00106 
00107 typedef struct feature_control {
00108     LPCWSTR feature_name;
00109     BOOL    enabled;
00110     BOOL    check_registry;
00111 } feature_control;
00112 
00113 /* IMPORTANT!!!
00114  *
00115  * This array is indexed using INTERNETFEATURELIST values, so everything must
00116  * appear in the same order as it does in INTERNETFEATURELIST.
00117  */
00118 static feature_control process_feature_controls[FEATURE_ENTRY_COUNT] = {
00119     {feature_object_cachingW,                   TRUE ,TRUE},
00120     {feature_zone_elevationW,                   FALSE,TRUE},
00121     {feature_mime_handlingW,                    FALSE,TRUE},
00122     {feature_mime_sniffingW,                    FALSE,TRUE},
00123     {feature_window_restrictionsW,              FALSE,TRUE},
00124     {feature_weboc_popupmanagementW,            FALSE,TRUE},
00125     {feature_behaviorsW,                        TRUE ,TRUE},
00126     {feature_disable_mk_protocolW,              TRUE ,TRUE},
00127     {feature_localmachine_lockdownW,            FALSE,TRUE},
00128     {feature_securitybandW,                     FALSE,TRUE},
00129     {feature_restrict_activexinstallW,          FALSE,TRUE},
00130     {feature_validate_navigate_urlW,            FALSE,TRUE},
00131     {feature_restrict_filedownloadW,            FALSE,TRUE},
00132     {feature_addon_managementW,                 FALSE,TRUE},
00133     {feature_protocol_lockdownW,                FALSE,TRUE},
00134     {feature_http_username_password_disableW,   FALSE,TRUE},
00135     {feature_safe_bindtoobjectW,                FALSE,TRUE},
00136     {feature_unc_savedfilecheckW,               FALSE,TRUE},
00137     {feature_get_url_dom_filepath_unencodedW,   TRUE ,TRUE},
00138     {feature_tabbed_browsingW,                  FALSE,TRUE},
00139     {feature_ssluxW,                            FALSE,TRUE},
00140     {feature_disable_navigation_soundsW,        FALSE,TRUE},
00141     {feature_disable_legacy_compressionW,       TRUE ,TRUE},
00142     {feature_force_addr_and_statusW,            FALSE,TRUE},
00143     {feature_xmlhttpW,                          TRUE ,TRUE},
00144     {feature_disable_telnet_protocolW,          FALSE,TRUE},
00145     {feature_feedsW,                            FALSE,TRUE},
00146     {feature_block_input_promptsW,              FALSE,TRUE}
00147 };
00148 
00149 static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
00150 {
00151     WCHAR *ptr;
00152     DWORD len = 0;
00153 
00154     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00155 
00156     if(flags)
00157         ERR("wrong flags\n");
00158     
00159     ptr = strchrW(url, ':');
00160     if(ptr)
00161         len = ptr-url;
00162 
00163     if(rsize)
00164         *rsize = len;
00165 
00166     if(len >= size)
00167         return E_POINTER;
00168 
00169     if(len)
00170         memcpy(result, url, len*sizeof(WCHAR));
00171     result[len] = 0;
00172 
00173     return S_OK;
00174 }
00175 
00176 static HRESULT parse_canonicalize_url(LPCWSTR url, DWORD flags, LPWSTR result,
00177         DWORD size, DWORD *rsize)
00178 {
00179     IInternetProtocolInfo *protocol_info;
00180     DWORD prsize = size;
00181     HRESULT hres;
00182 
00183     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00184 
00185     protocol_info = get_protocol_info(url);
00186 
00187     if(protocol_info) {
00188         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_CANONICALIZE,
00189                 flags, result, size, rsize, 0);
00190         IInternetProtocolInfo_Release(protocol_info);
00191         if(SUCCEEDED(hres))
00192             return hres;
00193     }
00194 
00195     hres = UrlCanonicalizeW(url, result, &prsize, flags);
00196 
00197     if(rsize)
00198         *rsize = prsize;
00199     return hres;
00200 }
00201 
00202 static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
00203 {
00204     IInternetProtocolInfo *protocol_info;
00205     HRESULT hres;
00206 
00207     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00208 
00209     protocol_info = get_protocol_info(url);
00210 
00211     if(protocol_info) {
00212         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL,
00213                 flags, result, size, rsize, 0);
00214         IInternetProtocolInfo_Release(protocol_info);
00215         return hres;
00216     }
00217 
00218     return E_FAIL;
00219 }
00220 
00221 static HRESULT parse_encode(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
00222 {
00223     IInternetProtocolInfo *protocol_info;
00224     DWORD prsize;
00225     HRESULT hres;
00226 
00227     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00228 
00229     protocol_info = get_protocol_info(url);
00230 
00231     if(protocol_info) {
00232         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ENCODE,
00233                 flags, result, size, rsize, 0);
00234         IInternetProtocolInfo_Release(protocol_info);
00235         if(SUCCEEDED(hres))
00236             return hres;
00237     }
00238 
00239     prsize = size;
00240     hres = UrlUnescapeW((LPWSTR)url, result, &prsize, flags);
00241 
00242     if(rsize)
00243         *rsize = prsize;
00244 
00245     return hres;
00246 }
00247 
00248 static HRESULT parse_path_from_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
00249 {
00250     IInternetProtocolInfo *protocol_info;
00251     DWORD prsize;
00252     HRESULT hres;
00253 
00254     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00255 
00256     protocol_info = get_protocol_info(url);
00257 
00258     if(protocol_info) {
00259         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_PATH_FROM_URL,
00260                 flags, result, size, rsize, 0);
00261         IInternetProtocolInfo_Release(protocol_info);
00262         if(SUCCEEDED(hres))
00263             return hres;
00264     }
00265 
00266     prsize = size;
00267     hres = PathCreateFromUrlW(url, result, &prsize, 0);
00268 
00269     if(rsize)
00270         *rsize = prsize;
00271     return hres;
00272 }
00273 
00274 static HRESULT parse_security_domain(LPCWSTR url, DWORD flags, LPWSTR result,
00275         DWORD size, DWORD *rsize)
00276 {
00277     IInternetProtocolInfo *protocol_info;
00278     HRESULT hres;
00279 
00280     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00281 
00282     protocol_info = get_protocol_info(url);
00283 
00284     if(protocol_info) {
00285         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN,
00286                 flags, result, size, rsize, 0);
00287         IInternetProtocolInfo_Release(protocol_info);
00288         if(SUCCEEDED(hres))
00289             return hres;
00290     }
00291 
00292     return E_FAIL;
00293 }
00294 
00295 static HRESULT parse_domain(LPCWSTR url, DWORD flags, LPWSTR result,
00296         DWORD size, DWORD *rsize)
00297 {
00298     IInternetProtocolInfo *protocol_info;
00299     HRESULT hres;
00300 
00301     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00302 
00303     protocol_info = get_protocol_info(url);
00304 
00305     if(protocol_info) {
00306         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_DOMAIN,
00307                 flags, result, size, rsize, 0);
00308         IInternetProtocolInfo_Release(protocol_info);
00309         if(SUCCEEDED(hres))
00310             return hres;
00311     }
00312 
00313     hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
00314     if(rsize)
00315         *rsize = size;
00316 
00317     if(hres == E_POINTER)
00318         return S_FALSE;
00319 
00320     if(FAILED(hres))
00321         return E_FAIL;
00322     return S_OK;
00323 }
00324 
00325 static HRESULT parse_rootdocument(LPCWSTR url, DWORD flags, LPWSTR result,
00326         DWORD size, DWORD *rsize)
00327 {
00328     IInternetProtocolInfo *protocol_info;
00329     PARSEDURLW url_info;
00330     HRESULT hres;
00331 
00332     TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
00333 
00334     protocol_info = get_protocol_info(url);
00335 
00336     if(protocol_info) {
00337         hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ROOTDOCUMENT,
00338                 flags, result, size, rsize, 0);
00339         IInternetProtocolInfo_Release(protocol_info);
00340         if(SUCCEEDED(hres))
00341             return hres;
00342     }
00343 
00344     url_info.cbSize = sizeof(url_info);
00345     if(FAILED(ParseURLW(url, &url_info)))
00346         return E_FAIL;
00347 
00348     switch(url_info.nScheme) {
00349         case URL_SCHEME_FTP:
00350         case URL_SCHEME_HTTP:
00351         case URL_SCHEME_HTTPS:
00352             if(url_info.cchSuffix<3 || *(url_info.pszSuffix)!='/'
00353                     || *(url_info.pszSuffix+1)!='/')
00354                 return E_FAIL;
00355 
00356             if(size < url_info.cchProtocol+3) {
00357                 size = 0;
00358                 hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
00359 
00360                 if(rsize)
00361                     *rsize = size+url_info.cchProtocol+3;
00362 
00363                 if(hres == E_POINTER)
00364                     return S_FALSE;
00365 
00366                 return hres;
00367             }
00368 
00369             size -= url_info.cchProtocol+3;
00370             hres = UrlGetPartW(url, result+url_info.cchProtocol+3,
00371                     &size, URL_PART_HOSTNAME, flags);
00372 
00373             if(hres == E_POINTER)
00374                 return S_FALSE;
00375 
00376             if(FAILED(hres))
00377                 return E_FAIL;
00378 
00379             if(rsize)
00380                 *rsize = size+url_info.cchProtocol+3;
00381 
00382             memcpy(result, url, (url_info.cchProtocol+3)*sizeof(WCHAR));
00383             return hres;
00384         default:
00385             return E_FAIL;
00386     }
00387 }
00388 
00389 /**************************************************************************
00390  *          CoInternetParseUrl    (URLMON.@)
00391  */
00392 HRESULT WINAPI CoInternetParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwFlags,
00393         LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
00394 {
00395     if(dwReserved)
00396         WARN("dwReserved = %d\n", dwReserved);
00397 
00398     switch(ParseAction) {
00399     case PARSE_CANONICALIZE:
00400         return parse_canonicalize_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00401     case PARSE_SECURITY_URL:
00402         return parse_security_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00403     case PARSE_ENCODE:
00404         return parse_encode(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00405     case PARSE_PATH_FROM_URL:
00406         return parse_path_from_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00407     case PARSE_SCHEMA:
00408         return parse_schema(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00409     case PARSE_SECURITY_DOMAIN:
00410         return parse_security_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00411     case PARSE_DOMAIN:
00412         return parse_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00413     case PARSE_ROOTDOCUMENT:
00414         return parse_rootdocument(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
00415     default:
00416         FIXME("not supported action %d\n", ParseAction);
00417     }
00418 
00419     return E_NOTIMPL;
00420 }
00421 
00422 /**************************************************************************
00423  *          CoInternetCombineUrl    (URLMON.@)
00424  */
00425 HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
00426         DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult,
00427         DWORD dwReserved)
00428 {
00429     IInternetProtocolInfo *protocol_info;
00430     DWORD size = cchResult;
00431     HRESULT hres;
00432     
00433     TRACE("(%s,%s,0x%08x,%p,%d,%p,%d)\n", debugstr_w(pwzBaseUrl),
00434           debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, pcchResult,
00435           dwReserved);
00436 
00437     protocol_info = get_protocol_info(pwzBaseUrl);
00438 
00439     if(protocol_info) {
00440         hres = IInternetProtocolInfo_CombineUrl(protocol_info, pwzBaseUrl, pwzRelativeUrl,
00441                 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
00442         IInternetProtocolInfo_Release(protocol_info);
00443         if(SUCCEEDED(hres))
00444             return hres;
00445     }
00446 
00447 
00448     hres = UrlCombineW(pwzBaseUrl, pwzRelativeUrl, pwzResult, &size, dwCombineFlags);
00449 
00450     if(pcchResult)
00451         *pcchResult = size;
00452 
00453     return hres;
00454 }
00455 
00456 /**************************************************************************
00457  *          CoInternetCompareUrl    (URLMON.@)
00458  */
00459 HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
00460 {
00461     IInternetProtocolInfo *protocol_info;
00462     HRESULT hres;
00463 
00464     TRACE("(%s,%s,%08x)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
00465 
00466     protocol_info = get_protocol_info(pwzUrl1);
00467 
00468     if(protocol_info) {
00469         hres = IInternetProtocolInfo_CompareUrl(protocol_info, pwzUrl1, pwzUrl2, dwCompareFlags);
00470         IInternetProtocolInfo_Release(protocol_info);
00471         if(SUCCEEDED(hres))
00472             return hres;
00473     }
00474 
00475     return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags) ? S_FALSE : S_OK;
00476 }
00477 
00478 /***********************************************************************
00479  *           CoInternetQueryInfo (URLMON.@)
00480  *
00481  * Retrieves information relevant to a specified URL
00482  *
00483  */
00484 HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
00485         DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD *pcbBuffer,
00486         DWORD dwReserved)
00487 {
00488     IInternetProtocolInfo *protocol_info;
00489     HRESULT hres;
00490 
00491     TRACE("(%s, %x, %x, %p, %x, %p, %x): stub\n", debugstr_w(pwzUrl),
00492           QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
00493 
00494     protocol_info = get_protocol_info(pwzUrl);
00495 
00496     if(protocol_info) {
00497         hres = IInternetProtocolInfo_QueryInfo(protocol_info, pwzUrl, QueryOption, dwQueryFlags,
00498                 pvBuffer, cbBuffer, pcbBuffer, dwReserved);
00499         IInternetProtocolInfo_Release(protocol_info);
00500 
00501         return SUCCEEDED(hres) ? hres : E_FAIL;
00502     }
00503 
00504     switch(QueryOption) {
00505     case QUERY_USES_NETWORK:
00506         if(!pvBuffer || cbBuffer < sizeof(DWORD))
00507             return E_FAIL;
00508 
00509         *(DWORD*)pvBuffer = 0;
00510         if(pcbBuffer)
00511             *pcbBuffer = sizeof(DWORD);
00512         break;
00513 
00514     default:
00515         FIXME("Not supported option %d\n", QueryOption);
00516         return E_NOTIMPL;
00517     }
00518 
00519     return S_OK;
00520 }
00521 
00522 static void set_feature_on_process(INTERNETFEATURELIST feature, BOOL enable)
00523 {
00524     EnterCriticalSection(&process_features_cs);
00525 
00526     process_feature_controls[feature].enabled = enable;
00527     process_feature_controls[feature].check_registry = FALSE;
00528 
00529     LeaveCriticalSection(&process_features_cs);
00530 }
00531 
00532 static HRESULT set_internet_feature(INTERNETFEATURELIST feature, DWORD flags, BOOL enable)
00533 {
00534     const DWORD supported_flags = SET_FEATURE_ON_PROCESS;
00535 
00536     if(feature >= FEATURE_ENTRY_COUNT)
00537         return E_FAIL;
00538 
00539     if(flags & ~supported_flags) {
00540         FIXME("Unsupported flags: %08x\n", flags & ~supported_flags);
00541         return E_NOTIMPL;
00542     }
00543 
00544     if(flags & SET_FEATURE_ON_PROCESS)
00545         set_feature_on_process(feature, enable);
00546 
00547     return S_OK;
00548 }
00549 
00550 static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPCWSTR process_name, BOOL *enabled)
00551 {
00552     BOOL ret = FALSE;
00553     HKEY feature;
00554     DWORD res;
00555 
00556     static const WCHAR wildcardW[] = {'*',0};
00557 
00558     res = RegOpenKeyW(feature_control, feature_name, &feature);
00559     if(res == ERROR_SUCCESS) {
00560         DWORD type, value, size;
00561 
00562         size = sizeof(DWORD);
00563         res = RegQueryValueExW(feature, process_name, NULL, &type, (BYTE*)&value, &size);
00564         if(type != REG_DWORD)
00565             WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(process_name));
00566 
00567         if(res == ERROR_SUCCESS && type == REG_DWORD) {
00568             *enabled = value == 1;
00569             ret = TRUE;
00570         } else {
00571             size = sizeof(DWORD);
00572             res = RegQueryValueExW(feature, wildcardW, NULL, &type, (BYTE*)&value, &size);
00573             if(type != REG_DWORD)
00574                 WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(wildcardW));
00575 
00576             if(res == ERROR_SUCCESS && type == REG_DWORD) {
00577                 *enabled = value == 1;
00578                 ret = TRUE;
00579             }
00580         }
00581         RegCloseKey(feature);
00582     }
00583 
00584     return ret;
00585 }
00586 
00587 /* Assumes 'process_features_cs' is held. */
00588 static HRESULT load_process_feature(INTERNETFEATURELIST feature)
00589 {
00590     DWORD res;
00591     HKEY feature_control;
00592     WCHAR module_name[MAX_PATH];
00593     LPCWSTR process_name, feature_name;
00594     HRESULT hres = S_FALSE;
00595     BOOL check_hklm = FALSE;
00596     BOOL enabled;
00597 
00598     if (!GetModuleFileNameW(NULL, module_name, sizeof(module_name)/sizeof(WCHAR))) {
00599         ERR("Failed to get module file name: %u\n", GetLastError());
00600         return E_UNEXPECTED;
00601     }
00602 
00603     process_name = strrchrW(module_name, '\\');
00604     if(!process_name) {
00605         ERR("Invalid module file name: %s\n", debugstr_w(module_name));
00606         return E_UNEXPECTED;
00607     }
00608 
00609     /* Skip past the '\\' in front of the filename. */
00610     ++process_name;
00611 
00612     feature_name = process_feature_controls[feature].feature_name;
00613 
00614     res = RegOpenKeyW(HKEY_CURRENT_USER, feature_control_keyW, &feature_control);
00615     if(res == ERROR_SUCCESS) {
00616         if(get_feature_from_reg(feature_control, feature_name, process_name, &enabled)) {
00617             hres = enabled ? S_OK : S_FALSE;
00618             process_feature_controls[feature].enabled = enabled;
00619         } else
00620             /* We didn't find anything in HKCU, so check HKLM. */
00621             check_hklm = TRUE;
00622 
00623         RegCloseKey(feature_control);
00624     }
00625 
00626     if(check_hklm) {
00627         res = RegOpenKeyW(HKEY_LOCAL_MACHINE, feature_control_keyW, &feature_control);
00628         if(res == ERROR_SUCCESS) {
00629             if(get_feature_from_reg(feature_control, feature_name, process_name, &enabled)) {
00630                 hres = enabled ? S_OK : S_FALSE;
00631                 process_feature_controls[feature].enabled = enabled;
00632             }
00633             RegCloseKey(feature_control);
00634         }
00635     }
00636 
00637     /* Don't bother checking the registry again for this feature. */
00638     process_feature_controls[feature].check_registry = FALSE;
00639 
00640     return hres;
00641 }
00642 
00643 static HRESULT get_feature_from_process(INTERNETFEATURELIST feature)
00644 {
00645     HRESULT hres;
00646 
00647     EnterCriticalSection(&process_features_cs);
00648 
00649     /* Try loading the feature from the registry, if it hasn't already
00650      * been done.
00651      */
00652     if(process_feature_controls[feature].check_registry) {
00653         hres = load_process_feature(feature);
00654         if(FAILED(hres)) {
00655             LeaveCriticalSection(&process_features_cs);
00656             return hres;
00657         }
00658     }
00659 
00660     hres = process_feature_controls[feature].enabled ? S_OK : S_FALSE;
00661 
00662     LeaveCriticalSection(&process_features_cs);
00663 
00664     return hres;
00665 }
00666 
00667 static HRESULT get_internet_feature(INTERNETFEATURELIST feature, DWORD flags)
00668 {
00669     HRESULT hres;
00670 
00671     if(feature >= FEATURE_ENTRY_COUNT)
00672         return E_FAIL;
00673 
00674     if(flags == GET_FEATURE_FROM_PROCESS)
00675         hres = get_feature_from_process(feature);
00676     else {
00677         FIXME("Unsupported flags: %08x\n", flags);
00678         hres = E_NOTIMPL;
00679     }
00680 
00681     return hres;
00682 }
00683 
00684 /***********************************************************************
00685  *             CoInternetSetFeatureEnabled (URLMON.@)
00686  */
00687 HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags, BOOL fEnable)
00688 {
00689     TRACE("(%d, %08x, %x)\n", FeatureEntry, dwFlags, fEnable);
00690     return set_internet_feature(FeatureEntry, dwFlags, fEnable);
00691 }
00692 
00693 /***********************************************************************
00694  *             CoInternetIsFeatureEnabled (URLMON.@)
00695  */
00696 HRESULT WINAPI CoInternetIsFeatureEnabled(INTERNETFEATURELIST FeatureEntry, DWORD dwFlags)
00697 {
00698     TRACE("(%d, %08x)\n", FeatureEntry, dwFlags);
00699     return get_internet_feature(FeatureEntry, dwFlags);
00700 }

Generated on Fri May 25 2012 04:24:46 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.