From 3d95eef66f75a5c933666d8face08b7073733a17 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 25 Mar 2021 19:34:22 +0100 Subject: [PATCH] urlmon: Support version option in ObtainUserAgentString. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/urlmon/session.c | 104 ++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/dlls/urlmon/session.c b/dlls/urlmon/session.c index b74d56166d9..0a1be0ba367 100644 --- a/dlls/urlmon/session.c +++ b/dlls/urlmon/session.c @@ -505,61 +505,95 @@ static BOOL get_url_encoding(HKEY root, DWORD *encoding) static LPWSTR user_agent; -static size_t obtain_user_agent(WCHAR *ret, size_t size) +static size_t obtain_user_agent(unsigned int version, WCHAR *ret, size_t size) { OSVERSIONINFOW info = {sizeof(info)}; const WCHAR *os_type, *is_nt; - DWORD res, idx=0; + BOOL is_wow, quirks = FALSE; + DWORD res; size_t len = 0; - BOOL is_wow; HKEY key; - EnterCriticalSection(&session_cs); - if(user_agent) { - len = wcslen(user_agent) + 1; - memcpy(ret, user_agent, min(size, len) * sizeof(WCHAR)); + if(version & 0x1000) { + version &= ~0x1000; + if(version == 7) + quirks = TRUE; + else + version = 7; + }else if(version < 7) { + version = 7; + } + if(version > 11) { + FIXME("Unsupported version %u\n", version); + version = 11; + } + + if(version < 7 || (version == 7 && !quirks)) { + EnterCriticalSection(&session_cs); + if(user_agent) { + len = wcslen(user_agent) + 1; + memcpy(ret, user_agent, min(size, len) * sizeof(WCHAR)); + } + LeaveCriticalSection(&session_cs); + if(len) return len; + } + + swprintf(ret, size, L"Mozilla/%s (", version < 9 ? L"4.0" : L"5.0"); + len = lstrlenW(ret); + if(version < 11) { + swprintf(ret + len, size - len, L"compatible; MSIE %u.0; ", version); + len += wcslen(ret + len); } - LeaveCriticalSection(&session_cs); - if(len) return len; GetVersionExW(&info); is_nt = info.dwPlatformId == VER_PLATFORM_WIN32_NT ? L"NT " : L""; if(sizeof(void*) == 8) +#ifdef __x86_64__ os_type = L"Win64; x64; "; +#else + os_type = L"Win64; "; +#endif else if(IsWow64Process(GetCurrentProcess(), &is_wow) && is_wow) os_type = L"WOW64; "; else os_type = L""; - swprintf(ret, size, L"Mozilla/4.0 (compatible; MSIE 7.0; Windows %s%d.%d; %sTrident/7.0", - is_nt, info.dwMajorVersion, info.dwMinorVersion, os_type); + swprintf(ret + len, size - len, L"Windows %s%d.%d; %s", is_nt, info.dwMajorVersion, + info.dwMinorVersion, os_type); len = lstrlenW(ret); - res = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" - "Internet Settings\\5.0\\User Agent\\Post Platform", &key); - if(res == ERROR_SUCCESS) { - DWORD value_len; - - while(1) { - if(idx) { - ret[len++] = ';'; - ret[len++] = ' '; - } - value_len = size - len - 2; - res = RegEnumValueW(key, idx, ret + len, &value_len, NULL, NULL, NULL, NULL); - if(res != ERROR_SUCCESS) - break; - idx++; - - len += value_len; - } - - RegCloseKey(key); + if(!quirks) { + wcscpy(ret + len, L"Trident/7.0"); + len += ARRAY_SIZE(L"Trident/7.0") - 1; } - ret[len++] = ')'; - ret[len++] = 0; + if(version < 9) { + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" + "Internet Settings\\5.0\\User Agent\\Post Platform", &key); + if(res == ERROR_SUCCESS) { + DWORD value_len, idx; + + for(idx = 0;; idx++) { + if(idx) { + ret[len++] = ';'; + ret[len++] = ' '; + } + value_len = size - len - 2; + res = RegEnumValueW(key, idx, ret + len, &value_len, NULL, NULL, NULL, NULL); + if(res != ERROR_SUCCESS) + break; + + len += value_len; + } + + RegCloseKey(key); + if(idx) len -= 2; + } + } + wcscpy(ret + len, version >= 11 ? L"; rv:11.0) like Gecko" : L")"); + len += wcslen(ret + len) + 1; + TRACE("Using user agent %s\n", debugstr_w(ret)); return len; } @@ -570,7 +604,7 @@ static void ensure_user_agent(void) if(!user_agent) { WCHAR buf[1024]; - obtain_user_agent(buf, ARRAY_SIZE(buf)); + obtain_user_agent(0, buf, ARRAY_SIZE(buf)); user_agent = heap_strdupW(buf); } @@ -704,7 +738,7 @@ HRESULT WINAPI ObtainUserAgentString(DWORD option, char *ret, DWORD *ret_size) if(!ret || !ret_size) return E_INVALIDARG; - len = obtain_user_agent(buf, ARRAY_SIZE(buf)); + len = obtain_user_agent(option, buf, ARRAY_SIZE(buf)); size = WideCharToMultiByte(CP_ACP, 0, buf, len, NULL, 0, NULL, NULL); if(size <= *ret_size) WideCharToMultiByte(CP_ACP, 0, buf, len, ret, *ret_size+1, NULL, NULL);