Commit 735ac6eb authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

urlmon: Add basic implementation of MapBrowserEmulationModeToUserAgent.

This is necessary for mshtml's navigator userAgent to work properly, since some apps expect it. The second argument seems to be output pointer that gets allocated (by CoTaskMemAlloc, or something compatible with it), but the first argument seems to be a pointer to an unknown struct, which makes it almost impossible to guess reliably what it does by just inspecting its behavior... Thankfully, it seems only the first DWORD field is necessary for this. Changing it returns the user agent for that given mode, if the rest is zeros. Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent d4a2f4d4
......@@ -504,6 +504,7 @@ static BOOL get_url_encoding(HKEY root, DWORD *encoding)
}
static LPWSTR user_agent;
static BOOL user_agent_set;
static size_t obtain_user_agent(unsigned int version, WCHAR *ret, size_t size)
{
......@@ -710,6 +711,7 @@ HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBuf
heap_free(user_agent);
user_agent = new_user_agent;
user_agent_set = TRUE;
update_user_agent(user_agent);
LeaveCriticalSection(&session_cs);
......@@ -748,6 +750,44 @@ HRESULT WINAPI ObtainUserAgentString(DWORD option, char *ret, DWORD *ret_size)
return hres;
}
/***********************************************************************
* MapBrowserEmulationModeToUserAgent (URLMON.445)
* Undocumented, added in IE8
*/
HRESULT WINAPI MapBrowserEmulationModeToUserAgent(const void *arg, WCHAR **ret)
{
DWORD size, version;
const WCHAR *ua;
WCHAR buf[1024];
TRACE("%p %p: semi-stub\n", arg, ret);
if(user_agent_set) {
/* Native ignores first arg if custom user agent has been set, doesn't crash even if NULL */
size = (wcslen(user_agent) + 1) * sizeof(WCHAR);
ua = user_agent;
}else {
*ret = NULL;
/* First arg seems to be a pointer to a structure of unknown size, and crashes
if it's too small (or filled with arbitrary values from the stack). For our
purposes, we only check first field which seems to be the requested version. */
version = *(DWORD*)arg;
if(version == 5)
version = 7;
if(version < 7 || version > 11)
return E_FAIL;
size = obtain_user_agent(version, buf, ARRAY_SIZE(buf)) * sizeof(WCHAR);
ua = buf;
}
if(!(*ret = CoTaskMemAlloc(size)))
return E_OUTOFMEMORY;
memcpy(*ret, ua, size);
return S_OK;
}
void free_session(void)
{
name_space *ns_iter, *ns_last;
......
......@@ -83,6 +83,7 @@ static HRESULT (WINAPI *pCompareSecurityIds)(BYTE*,DWORD,BYTE*,DWORD,DWORD);
static HRESULT (WINAPI *pCoInternetIsFeatureEnabled)(INTERNETFEATURELIST,DWORD);
static HRESULT (WINAPI *pCoInternetSetFeatureEnabled)(INTERNETFEATURELIST,DWORD,BOOL);
static HRESULT (WINAPI *pIEInstallScope)(DWORD*);
static HRESULT (WINAPI *pMapBrowserEmulationModeToUserAgent)(const void*,WCHAR**);
static WCHAR *a2co(const char *str)
{
......@@ -2721,6 +2722,59 @@ static void test_bsc_marshaling(void)
TerminateThread(thread, 0);
}
static void test_MapBrowserEmulationModeToUserAgent(BOOL custom_ua)
{
/* Undocumented structure of unknown size, crashes if it's too small (with arbitrary values from stack) */
struct
{
DWORD version;
char unknown[252];
} arg;
static char test_str[] = "test";
const char *custom_ua_msg = "";
HRESULT hres;
unsigned i;
WCHAR *ua;
if(!pMapBrowserEmulationModeToUserAgent) {
win_skip("MapBrowserEmulationModeToUserAgent not available\n");
return;
}
memset(&arg, 0, sizeof(arg));
if(custom_ua) {
hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, sizeof(test_str), 0);
ok(hres == S_OK, "UrlMkSetSessionOption failed: %08lx\n", hres);
custom_ua_msg = " (with custom ua)";
}
for(i = 0; i < 12; i++) {
arg.version = i;
ua = (WCHAR*)0xdeadbeef;
hres = pMapBrowserEmulationModeToUserAgent(&arg, &ua);
ok(hres == (i == 5 || i >= 7 || custom_ua ? S_OK : E_FAIL),
"[%u] MapBrowserEmulationModeToUserAgent%s returned %08lx\n", i, custom_ua_msg, hres);
if(hres != S_OK)
ok(ua == NULL, "[%u] ua%s = %p\n", i, custom_ua_msg, ua);
else {
char buf[1024];
DWORD size = sizeof(buf);
WCHAR *ua2;
if(custom_ua)
ua2 = a2co(test_str);
else {
hres = pObtainUserAgentString(i, buf, &size);
ok(hres == S_OK, "[%u] ObtainUserAgentString%s failed: %08lx\n", i, custom_ua_msg, hres);
ua2 = a2co(buf);
}
ok(!lstrcmpW(ua, ua2), "[%u] ua%s = %s, expected %s\n", i, custom_ua_msg, wine_dbgstr_w(ua), wine_dbgstr_w(ua2));
CoTaskMemFree(ua2);
CoTaskMemFree(ua);
}
}
}
START_TEST(misc)
{
HMODULE hurlmon;
......@@ -2745,6 +2799,7 @@ START_TEST(misc)
pCoInternetIsFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabled");
pCoInternetSetFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetSetFeatureEnabled");
pIEInstallScope = (void*) GetProcAddress(hurlmon, "IEInstallScope");
pMapBrowserEmulationModeToUserAgent = (void*) GetProcAddress(hurlmon, (const char*)445);
if (!pCoInternetCompareUrl || !pCoInternetGetSecurityUrl ||
!pCoInternetGetSession || !pCoInternetParseUrl || !pCompareSecurityIds) {
......@@ -2757,6 +2812,7 @@ START_TEST(misc)
if(argc <= 2 || strcmp(argv[2], "internet_features")) {
register_protocols();
test_MapBrowserEmulationModeToUserAgent(FALSE);
test_CreateFormatEnum();
test_RegisterFormatEnumerator();
test_CoInternetParseUrl();
......@@ -2773,6 +2829,7 @@ START_TEST(misc)
test_MkParseDisplayNameEx();
test_IsValidURL();
test_bsc_marshaling();
test_MapBrowserEmulationModeToUserAgent(TRUE);
}
test_internet_features();
......
......@@ -110,6 +110,6 @@
410 stdcall @(long long) LogSqmBits
423 stdcall @(long long long long) LogSqmUXCommandOffsetInternal
444 stdcall @(long long long) MapUriToBrowserEmulationState
445 stdcall @(long long) MapBrowserEmulationModeToUserAgent
445 stdcall @(ptr ptr) MapBrowserEmulationModeToUserAgent
446 stdcall @(long) CoInternetGetBrowserProfile
455 stdcall @() FlushUrlmonZonesCache
......@@ -792,16 +792,6 @@ int WINAPI MapUriToBrowserEmulationState(DWORD unk1, DWORD unk2, DWORD unk3)
}
/***********************************************************************
* MapBrowserEmulationModeToUserAgent (URLMON.445)
* Undocumented, added in IE8
*/
int WINAPI MapBrowserEmulationModeToUserAgent(DWORD unk1, DWORD unk2)
{
FIXME("stub: %ld %ld\n", unk1, unk2);
return 0;
}
/***********************************************************************
* CoInternetGetBrowserProfile (URLMON.446)
* Undocumented, added in IE8
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment