Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensession.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2005-2006 Jacek Caban for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "urlmon_main.h" 00020 #include "winreg.h" 00021 00022 #include "wine/debug.h" 00023 00024 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 00025 00026 typedef struct name_space { 00027 LPWSTR protocol; 00028 IClassFactory *cf; 00029 CLSID clsid; 00030 BOOL urlmon; 00031 00032 struct name_space *next; 00033 } name_space; 00034 00035 typedef struct mime_filter { 00036 IClassFactory *cf; 00037 CLSID clsid; 00038 LPWSTR mime; 00039 00040 struct mime_filter *next; 00041 } mime_filter; 00042 00043 static name_space *name_space_list = NULL; 00044 static mime_filter *mime_filter_list = NULL; 00045 00046 static CRITICAL_SECTION session_cs; 00047 static CRITICAL_SECTION_DEBUG session_cs_dbg = 00048 { 00049 0, 0, &session_cs, 00050 { &session_cs_dbg.ProcessLocksList, &session_cs_dbg.ProcessLocksList }, 00051 0, 0, { (DWORD_PTR)(__FILE__ ": session") } 00052 }; 00053 static CRITICAL_SECTION session_cs = { &session_cs_dbg, -1, 0, 0, 0, 0 }; 00054 00055 static const WCHAR internet_settings_keyW[] = 00056 {'S','O','F','T','W','A','R','E', 00057 '\\','M','i','c','r','o','s','o','f','t', 00058 '\\','W','i','n','d','o','w','s', 00059 '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n', 00060 '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0}; 00061 00062 static name_space *find_name_space(LPCWSTR protocol) 00063 { 00064 name_space *iter; 00065 00066 for(iter = name_space_list; iter; iter = iter->next) { 00067 if(!strcmpW(iter->protocol, protocol)) 00068 return iter; 00069 } 00070 00071 return NULL; 00072 } 00073 00074 static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid, IClassFactory **ret) 00075 { 00076 WCHAR str_clsid[64]; 00077 HKEY hkey = NULL; 00078 DWORD res, type, size; 00079 CLSID clsid; 00080 LPWSTR wszKey; 00081 HRESULT hres; 00082 00083 static const WCHAR wszProtocolsKey[] = 00084 {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'}; 00085 static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; 00086 00087 wszKey = heap_alloc(sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR)); 00088 memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey)); 00089 memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR)); 00090 00091 res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey); 00092 heap_free(wszKey); 00093 if(res != ERROR_SUCCESS) { 00094 TRACE("Could not open protocol handler key\n"); 00095 return MK_E_SYNTAX; 00096 } 00097 00098 size = sizeof(str_clsid); 00099 res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size); 00100 RegCloseKey(hkey); 00101 if(res != ERROR_SUCCESS || type != REG_SZ) { 00102 WARN("Could not get protocol CLSID res=%d\n", res); 00103 return MK_E_SYNTAX; 00104 } 00105 00106 hres = CLSIDFromString(str_clsid, &clsid); 00107 if(FAILED(hres)) { 00108 WARN("CLSIDFromString failed: %08x\n", hres); 00109 return hres; 00110 } 00111 00112 if(pclsid) 00113 *pclsid = clsid; 00114 00115 if(!ret) 00116 return S_OK; 00117 00118 hres = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)ret); 00119 return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX; 00120 } 00121 00122 static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL urlmon_protocol) 00123 { 00124 name_space *new_name_space; 00125 00126 new_name_space = heap_alloc(sizeof(name_space)); 00127 00128 if(!urlmon_protocol) 00129 IClassFactory_AddRef(cf); 00130 new_name_space->cf = cf; 00131 new_name_space->clsid = *clsid; 00132 new_name_space->urlmon = urlmon_protocol; 00133 new_name_space->protocol = heap_strdupW(protocol); 00134 00135 EnterCriticalSection(&session_cs); 00136 00137 new_name_space->next = name_space_list; 00138 name_space_list = new_name_space; 00139 00140 LeaveCriticalSection(&session_cs); 00141 00142 return S_OK; 00143 } 00144 00145 static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol) 00146 { 00147 name_space *iter, *last = NULL; 00148 00149 EnterCriticalSection(&session_cs); 00150 00151 for(iter = name_space_list; iter; iter = iter->next) { 00152 if(iter->cf == cf && !strcmpW(iter->protocol, protocol)) 00153 break; 00154 last = iter; 00155 } 00156 00157 if(iter) { 00158 if(last) 00159 last->next = iter->next; 00160 else 00161 name_space_list = iter->next; 00162 } 00163 00164 LeaveCriticalSection(&session_cs); 00165 00166 if(iter) { 00167 if(!iter->urlmon) 00168 IClassFactory_Release(iter->cf); 00169 heap_free(iter->protocol); 00170 heap_free(iter); 00171 } 00172 00173 return S_OK; 00174 } 00175 00176 00177 void register_urlmon_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL do_register) 00178 { 00179 if(do_register) 00180 register_namespace(cf, clsid, protocol, TRUE); 00181 else 00182 unregister_namespace(cf, protocol); 00183 } 00184 00185 BOOL is_registered_protocol(LPCWSTR url) 00186 { 00187 DWORD schema_len; 00188 WCHAR schema[64]; 00189 HRESULT hres; 00190 00191 hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), 00192 &schema_len, 0); 00193 if(FAILED(hres)) 00194 return FALSE; 00195 00196 return get_protocol_cf(schema, schema_len, NULL, NULL) == S_OK; 00197 } 00198 00199 IInternetProtocolInfo *get_protocol_info(LPCWSTR url) 00200 { 00201 IInternetProtocolInfo *ret = NULL; 00202 IClassFactory *cf; 00203 name_space *ns; 00204 WCHAR schema[64]; 00205 DWORD schema_len; 00206 HRESULT hres; 00207 00208 hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), 00209 &schema_len, 0); 00210 if(FAILED(hres) || !schema_len) 00211 return NULL; 00212 00213 EnterCriticalSection(&session_cs); 00214 00215 ns = find_name_space(schema); 00216 if(ns && !ns->urlmon) { 00217 hres = IClassFactory_QueryInterface(ns->cf, &IID_IInternetProtocolInfo, (void**)&ret); 00218 if(FAILED(hres)) 00219 hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret); 00220 } 00221 00222 LeaveCriticalSection(&session_cs); 00223 00224 if(ns && SUCCEEDED(hres)) 00225 return ret; 00226 00227 hres = get_protocol_cf(schema, schema_len, NULL, &cf); 00228 if(FAILED(hres)) 00229 return NULL; 00230 00231 hres = IClassFactory_QueryInterface(cf, &IID_IInternetProtocolInfo, (void**)&ret); 00232 if(FAILED(hres)) 00233 IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret); 00234 IClassFactory_Release(cf); 00235 00236 return ret; 00237 } 00238 00239 HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, BOOL *urlmon_protocol, IClassFactory **ret) 00240 { 00241 name_space *ns; 00242 BSTR scheme; 00243 HRESULT hres; 00244 00245 *ret = NULL; 00246 00247 /* FIXME: Avoid GetSchemeName call for known schemes */ 00248 hres = IUri_GetSchemeName(uri, &scheme); 00249 if(FAILED(hres)) 00250 return hres; 00251 00252 EnterCriticalSection(&session_cs); 00253 00254 ns = find_name_space(scheme); 00255 if(ns) { 00256 *ret = ns->cf; 00257 IClassFactory_AddRef(*ret); 00258 if(clsid) 00259 *clsid = ns->clsid; 00260 if(urlmon_protocol) 00261 *urlmon_protocol = ns->urlmon; 00262 } 00263 00264 LeaveCriticalSection(&session_cs); 00265 00266 if(*ret) { 00267 hres = S_OK; 00268 }else { 00269 if(urlmon_protocol) 00270 *urlmon_protocol = FALSE; 00271 hres = get_protocol_cf(scheme, SysStringLen(scheme), clsid, ret); 00272 } 00273 00274 SysFreeString(scheme); 00275 return hres; 00276 } 00277 00278 IInternetProtocol *get_mime_filter(LPCWSTR mime) 00279 { 00280 IClassFactory *cf = NULL; 00281 IInternetProtocol *ret; 00282 mime_filter *iter; 00283 HRESULT hres; 00284 00285 EnterCriticalSection(&session_cs); 00286 00287 for(iter = mime_filter_list; iter; iter = iter->next) { 00288 if(!strcmpW(iter->mime, mime)) { 00289 cf = iter->cf; 00290 break; 00291 } 00292 } 00293 00294 LeaveCriticalSection(&session_cs); 00295 00296 if(!cf) 00297 return NULL; 00298 00299 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&ret); 00300 if(FAILED(hres)) { 00301 WARN("CreateInstance failed: %08x\n", hres); 00302 return NULL; 00303 } 00304 00305 return ret; 00306 } 00307 00308 static HRESULT WINAPI InternetSession_QueryInterface(IInternetSession *iface, 00309 REFIID riid, void **ppv) 00310 { 00311 TRACE("(%s %p)\n", debugstr_guid(riid), ppv); 00312 00313 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetSession, riid)) { 00314 *ppv = iface; 00315 IInternetSession_AddRef(iface); 00316 return S_OK; 00317 } 00318 00319 *ppv = NULL; 00320 return E_NOINTERFACE; 00321 } 00322 00323 static ULONG WINAPI InternetSession_AddRef(IInternetSession *iface) 00324 { 00325 TRACE("()\n"); 00326 URLMON_LockModule(); 00327 return 2; 00328 } 00329 00330 static ULONG WINAPI InternetSession_Release(IInternetSession *iface) 00331 { 00332 TRACE("()\n"); 00333 URLMON_UnlockModule(); 00334 return 1; 00335 } 00336 00337 static HRESULT WINAPI InternetSession_RegisterNameSpace(IInternetSession *iface, 00338 IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzProtocol, ULONG cPatterns, 00339 const LPCWSTR *ppwzPatterns, DWORD dwReserved) 00340 { 00341 TRACE("(%p %s %s %d %p %d)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzProtocol), 00342 cPatterns, ppwzPatterns, dwReserved); 00343 00344 if(cPatterns || ppwzPatterns) 00345 FIXME("patterns not supported\n"); 00346 if(dwReserved) 00347 WARN("dwReserved = %d\n", dwReserved); 00348 00349 if(!pCF || !pwzProtocol) 00350 return E_INVALIDARG; 00351 00352 return register_namespace(pCF, rclsid, pwzProtocol, FALSE); 00353 } 00354 00355 static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *iface, 00356 IClassFactory *pCF, LPCWSTR pszProtocol) 00357 { 00358 TRACE("(%p %s)\n", pCF, debugstr_w(pszProtocol)); 00359 00360 if(!pCF || !pszProtocol) 00361 return E_INVALIDARG; 00362 00363 return unregister_namespace(pCF, pszProtocol); 00364 } 00365 00366 static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface, 00367 IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzType) 00368 { 00369 mime_filter *filter; 00370 00371 TRACE("(%p %s %s)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzType)); 00372 00373 filter = heap_alloc(sizeof(mime_filter)); 00374 00375 IClassFactory_AddRef(pCF); 00376 filter->cf = pCF; 00377 filter->clsid = *rclsid; 00378 filter->mime = heap_strdupW(pwzType); 00379 00380 EnterCriticalSection(&session_cs); 00381 00382 filter->next = mime_filter_list; 00383 mime_filter_list = filter; 00384 00385 LeaveCriticalSection(&session_cs); 00386 00387 return S_OK; 00388 } 00389 00390 static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *iface, 00391 IClassFactory *pCF, LPCWSTR pwzType) 00392 { 00393 mime_filter *iter, *prev = NULL; 00394 00395 TRACE("(%p %s)\n", pCF, debugstr_w(pwzType)); 00396 00397 EnterCriticalSection(&session_cs); 00398 00399 for(iter = mime_filter_list; iter; iter = iter->next) { 00400 if(iter->cf == pCF && !strcmpW(iter->mime, pwzType)) 00401 break; 00402 prev = iter; 00403 } 00404 00405 if(iter) { 00406 if(prev) 00407 prev->next = iter->next; 00408 else 00409 mime_filter_list = iter->next; 00410 } 00411 00412 LeaveCriticalSection(&session_cs); 00413 00414 if(iter) { 00415 IClassFactory_Release(iter->cf); 00416 heap_free(iter->mime); 00417 heap_free(iter); 00418 } 00419 00420 return S_OK; 00421 } 00422 00423 static HRESULT WINAPI InternetSession_CreateBinding(IInternetSession *iface, 00424 LPBC pBC, LPCWSTR szUrl, IUnknown *pUnkOuter, IUnknown **ppUnk, 00425 IInternetProtocol **ppOInetProt, DWORD dwOption) 00426 { 00427 BindProtocol *protocol; 00428 HRESULT hres; 00429 00430 TRACE("(%p %s %p %p %p %08x)\n", pBC, debugstr_w(szUrl), pUnkOuter, ppUnk, 00431 ppOInetProt, dwOption); 00432 00433 if(pBC || pUnkOuter || ppUnk || dwOption) 00434 FIXME("Unsupported arguments\n"); 00435 00436 hres = create_binding_protocol(FALSE, &protocol); 00437 if(FAILED(hres)) 00438 return hres; 00439 00440 *ppOInetProt = (IInternetProtocol*)&protocol->IInternetProtocolEx_iface; 00441 return S_OK; 00442 } 00443 00444 static HRESULT WINAPI InternetSession_SetSessionOption(IInternetSession *iface, 00445 DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength, DWORD dwReserved) 00446 { 00447 FIXME("(%08x %p %d %d)\n", dwOption, pBuffer, dwBufferLength, dwReserved); 00448 return E_NOTIMPL; 00449 } 00450 00451 static const IInternetSessionVtbl InternetSessionVtbl = { 00452 InternetSession_QueryInterface, 00453 InternetSession_AddRef, 00454 InternetSession_Release, 00455 InternetSession_RegisterNameSpace, 00456 InternetSession_UnregisterNameSpace, 00457 InternetSession_RegisterMimeFilter, 00458 InternetSession_UnregisterMimeFilter, 00459 InternetSession_CreateBinding, 00460 InternetSession_SetSessionOption 00461 }; 00462 00463 static IInternetSession InternetSession = { &InternetSessionVtbl }; 00464 00465 /*********************************************************************** 00466 * CoInternetGetSession (URLMON.@) 00467 * 00468 * Create a new internet session and return an IInternetSession interface 00469 * representing it. 00470 * 00471 * PARAMS 00472 * dwSessionMode [I] Mode for the internet session 00473 * ppIInternetSession [O] Destination for creates IInternetSession object 00474 * dwReserved [I] Reserved, must be 0. 00475 * 00476 * RETURNS 00477 * Success: S_OK. ppIInternetSession contains the IInternetSession interface. 00478 * Failure: E_INVALIDARG, if any argument is invalid, or 00479 * E_OUTOFMEMORY if memory allocation fails. 00480 */ 00481 HRESULT WINAPI CoInternetGetSession(DWORD dwSessionMode, IInternetSession **ppIInternetSession, 00482 DWORD dwReserved) 00483 { 00484 TRACE("(%d %p %d)\n", dwSessionMode, ppIInternetSession, dwReserved); 00485 00486 if(dwSessionMode) 00487 ERR("dwSessionMode=%d\n", dwSessionMode); 00488 if(dwReserved) 00489 ERR("dwReserved=%d\n", dwReserved); 00490 00491 IInternetSession_AddRef(&InternetSession); 00492 *ppIInternetSession = &InternetSession; 00493 return S_OK; 00494 } 00495 00496 /************************************************************************** 00497 * UrlMkGetSessionOption (URLMON.@) 00498 */ 00499 static BOOL get_url_encoding(HKEY root, DWORD *encoding) 00500 { 00501 DWORD size = sizeof(DWORD), res, type; 00502 HKEY hkey; 00503 00504 static const WCHAR wszUrlEncoding[] = {'U','r','l','E','n','c','o','d','i','n','g',0}; 00505 00506 res = RegOpenKeyW(root, internet_settings_keyW, &hkey); 00507 if(res != ERROR_SUCCESS) 00508 return FALSE; 00509 00510 res = RegQueryValueExW(hkey, wszUrlEncoding, NULL, &type, (LPBYTE)encoding, &size); 00511 RegCloseKey(hkey); 00512 00513 return res == ERROR_SUCCESS; 00514 } 00515 00516 static LPWSTR user_agent; 00517 00518 static void ensure_useragent(void) 00519 { 00520 DWORD size = sizeof(DWORD), res, type; 00521 HKEY hkey; 00522 00523 static const WCHAR user_agentW[] = {'U','s','e','r',' ','A','g','e','n','t',0}; 00524 00525 if(user_agent) 00526 return; 00527 00528 res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings_keyW, &hkey); 00529 if(res != ERROR_SUCCESS) 00530 return; 00531 00532 res = RegQueryValueExW(hkey, user_agentW, NULL, &type, NULL, &size); 00533 if(res == ERROR_SUCCESS && type == REG_SZ) { 00534 user_agent = heap_alloc(size); 00535 res = RegQueryValueExW(hkey, user_agentW, NULL, &type, (LPBYTE)user_agent, &size); 00536 if(res != ERROR_SUCCESS) { 00537 heap_free(user_agent); 00538 user_agent = NULL; 00539 } 00540 }else { 00541 WARN("Could not find User Agent value: %u\n", res); 00542 } 00543 00544 RegCloseKey(hkey); 00545 } 00546 00547 LPWSTR get_useragent(void) 00548 { 00549 LPWSTR ret; 00550 00551 ensure_useragent(); 00552 00553 EnterCriticalSection(&session_cs); 00554 ret = heap_strdupW(user_agent); 00555 LeaveCriticalSection(&session_cs); 00556 00557 return ret; 00558 } 00559 00560 HRESULT WINAPI UrlMkGetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength, 00561 DWORD* pdwBufferLength, DWORD dwReserved) 00562 { 00563 TRACE("(%x, %p, %d, %p)\n", dwOption, pBuffer, dwBufferLength, pdwBufferLength); 00564 00565 if(dwReserved) 00566 WARN("dwReserved = %d\n", dwReserved); 00567 00568 switch(dwOption) { 00569 case URLMON_OPTION_USERAGENT: { 00570 HRESULT hres = E_OUTOFMEMORY; 00571 DWORD size; 00572 00573 if(!pdwBufferLength) 00574 return E_INVALIDARG; 00575 00576 EnterCriticalSection(&session_cs); 00577 00578 ensure_useragent(); 00579 if(user_agent) { 00580 size = WideCharToMultiByte(CP_ACP, 0, user_agent, -1, NULL, 0, NULL, NULL); 00581 *pdwBufferLength = size; 00582 if(size <= dwBufferLength) { 00583 if(pBuffer) 00584 WideCharToMultiByte(CP_ACP, 0, user_agent, -1, pBuffer, size, NULL, NULL); 00585 else 00586 hres = E_INVALIDARG; 00587 } 00588 } 00589 00590 LeaveCriticalSection(&session_cs); 00591 00592 /* Tests prove that we have to return E_OUTOFMEMORY on success. */ 00593 return hres; 00594 } 00595 case URLMON_OPTION_URL_ENCODING: { 00596 DWORD encoding = 0; 00597 00598 if(!pBuffer || dwBufferLength < sizeof(DWORD) || !pdwBufferLength) 00599 return E_INVALIDARG; 00600 00601 if(!get_url_encoding(HKEY_CURRENT_USER, &encoding)) 00602 get_url_encoding(HKEY_LOCAL_MACHINE, &encoding); 00603 00604 *pdwBufferLength = sizeof(DWORD); 00605 *(DWORD*)pBuffer = encoding ? URL_ENCODING_DISABLE_UTF8 : URL_ENCODING_ENABLE_UTF8; 00606 return S_OK; 00607 } 00608 default: 00609 FIXME("unsupported option %x\n", dwOption); 00610 } 00611 00612 return E_INVALIDARG; 00613 } 00614 00615 /************************************************************************** 00616 * UrlMkSetSessionOption (URLMON.@) 00617 */ 00618 HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength, 00619 DWORD Reserved) 00620 { 00621 TRACE("(%x %p %x)\n", dwOption, pBuffer, dwBufferLength); 00622 00623 switch(dwOption) { 00624 case URLMON_OPTION_USERAGENT: { 00625 LPWSTR new_user_agent; 00626 char *buf = pBuffer; 00627 DWORD len, size; 00628 00629 if(!pBuffer || !dwBufferLength) 00630 return E_INVALIDARG; 00631 00632 for(len=0; len<dwBufferLength && buf[len]; len++); 00633 00634 TRACE("Setting user agent %s\n", debugstr_an(buf, len)); 00635 00636 size = MultiByteToWideChar(CP_ACP, 0, buf, len, NULL, 0); 00637 new_user_agent = heap_alloc((size+1)*sizeof(WCHAR)); 00638 if(!new_user_agent) 00639 return E_OUTOFMEMORY; 00640 MultiByteToWideChar(CP_ACP, 0, buf, len, new_user_agent, size); 00641 new_user_agent[size] = 0; 00642 00643 EnterCriticalSection(&session_cs); 00644 00645 heap_free(user_agent); 00646 user_agent = new_user_agent; 00647 00648 LeaveCriticalSection(&session_cs); 00649 break; 00650 } 00651 default: 00652 FIXME("Unknown option %x\n", dwOption); 00653 return E_INVALIDARG; 00654 } 00655 00656 return S_OK; 00657 } 00658 00659 /************************************************************************** 00660 * ObtainUserAgentString (URLMON.@) 00661 */ 00662 HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize) 00663 { 00664 DWORD size; 00665 HRESULT hres = E_FAIL; 00666 00667 TRACE("(%d %p %p)\n", dwOption, pcszUAOut, cbSize); 00668 00669 if(!pcszUAOut || !cbSize) 00670 return E_INVALIDARG; 00671 00672 EnterCriticalSection(&session_cs); 00673 00674 ensure_useragent(); 00675 if(user_agent) { 00676 size = WideCharToMultiByte(CP_ACP, 0, user_agent, -1, NULL, 0, NULL, NULL); 00677 00678 if(size <= *cbSize) { 00679 WideCharToMultiByte(CP_ACP, 0, user_agent, -1, pcszUAOut, *cbSize, NULL, NULL); 00680 hres = S_OK; 00681 }else { 00682 hres = E_OUTOFMEMORY; 00683 } 00684 00685 *cbSize = size; 00686 } 00687 00688 LeaveCriticalSection(&session_cs); 00689 return hres; 00690 } 00691 00692 void free_session(void) 00693 { 00694 heap_free(user_agent); 00695 } Generated on Sun May 27 2012 04:24:30 for ReactOS by
1.7.6.1
|