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

session.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 doxygen 1.7.6.1

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