kernelbase: Add GetAcceptLanguages().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-05-23 14:20:22 +03:00 committed by Alexandre Julliard
parent d97a164cd4
commit 6892d0a559
3 changed files with 132 additions and 2 deletions

View File

@ -403,8 +403,8 @@
@ stdcall GenerateConsoleCtrlEvent(long long) kernel32.GenerateConsoleCtrlEvent
# @ stub GenerateGPNotificationInternal
@ stdcall GetACP() kernel32.GetACP
@ stdcall GetAcceptLanguagesA(ptr ptr) shlwapi.GetAcceptLanguagesA
@ stdcall GetAcceptLanguagesW(ptr ptr) shlwapi.GetAcceptLanguagesW
@ stdcall GetAcceptLanguagesA(ptr ptr)
@ stdcall GetAcceptLanguagesW(ptr ptr)
@ stdcall GetAce(ptr long ptr) advapi32.GetAce
@ stdcall GetAclInformation(ptr ptr long long) advapi32.GetAclInformation
# @ stub GetAdjustObjectAttributesForPrivateNamespaceRoutine

View File

@ -26,6 +26,7 @@
#include "shlwapi.h"
#include "wine/debug.h"
#include "wine/heap.h"
#include "winternl.h"
WINE_DEFAULT_DEBUG_CHANNEL(kernelbase);
@ -165,3 +166,124 @@ HRESULT WINAPI QISearch(void *base, const QITAB *table, REFIID riid, void **obj)
*obj = NULL;
return E_NOINTERFACE;
}
HRESULT WINAPI GetAcceptLanguagesA(LPSTR langbuf, DWORD *buflen)
{
DWORD buflenW, convlen;
WCHAR *langbufW;
HRESULT hr;
TRACE("%p, %p, *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1);
if (!langbuf || !buflen || !*buflen)
return E_FAIL;
buflenW = *buflen;
langbufW = heap_alloc(sizeof(WCHAR) * buflenW);
hr = GetAcceptLanguagesW(langbufW, &buflenW);
if (hr == S_OK)
{
convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf, *buflen, NULL, NULL);
convlen--; /* do not count the terminating 0 */
}
else /* copy partial string anyway */
{
convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, *buflen, langbuf, *buflen, NULL, NULL);
if (convlen < *buflen)
{
langbuf[convlen] = 0;
convlen--; /* do not count the terminating 0 */
}
else
{
convlen = *buflen;
}
}
*buflen = buflenW ? convlen : 0;
heap_free(langbufW);
return hr;
}
static HRESULT lcid_to_rfc1766(LCID lcid, WCHAR *rfc1766, INT len)
{
WCHAR buffer[6 /* MAX_RFC1766_NAME */];
INT n = GetLocaleInfoW(lcid, LOCALE_SISO639LANGNAME, buffer, ARRAY_SIZE(buffer));
INT i;
if (n)
{
i = PRIMARYLANGID(lcid);
if ((((i == LANG_ENGLISH) || (i == LANG_CHINESE) || (i == LANG_ARABIC)) &&
(SUBLANGID(lcid) == SUBLANG_DEFAULT)) ||
(SUBLANGID(lcid) > SUBLANG_DEFAULT)) {
buffer[n - 1] = '-';
i = GetLocaleInfoW(lcid, LOCALE_SISO3166CTRYNAME, buffer + n, ARRAY_SIZE(buffer) - n);
if (!i)
buffer[n - 1] = '\0';
}
else
i = 0;
LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, buffer, n + i, rfc1766, len);
return ((n + i) > len) ? E_INVALIDARG : S_OK;
}
return E_FAIL;
}
HRESULT WINAPI GetAcceptLanguagesW(WCHAR *langbuf, DWORD *buflen)
{
static const WCHAR keyW[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
static const WCHAR valueW[] = {'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
DWORD mystrlen, mytype;
WCHAR *mystr;
LCID mylcid;
HKEY mykey;
LONG lres;
DWORD len;
TRACE("%p, %p, *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1);
if (!langbuf || !buflen || !*buflen)
return E_FAIL;
mystrlen = (*buflen > 20) ? *buflen : 20 ;
len = mystrlen * sizeof(WCHAR);
mystr = heap_alloc(len);
mystr[0] = 0;
RegOpenKeyW(HKEY_CURRENT_USER, keyW, &mykey);
lres = RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &len);
RegCloseKey(mykey);
len = lstrlenW(mystr);
if (!lres && (*buflen > len))
{
lstrcpyW(langbuf, mystr);
*buflen = len;
heap_free(mystr);
return S_OK;
}
/* Did not find a value in the registry or the user buffer is too small */
mylcid = GetUserDefaultLCID();
lcid_to_rfc1766(mylcid, mystr, mystrlen);
len = lstrlenW(mystr);
memcpy(langbuf, mystr, min(*buflen, len + 1)*sizeof(WCHAR));
heap_free(mystr);
if (*buflen > len)
{
*buflen = len;
return S_OK;
}
*buflen = 0;
return E_NOT_SUFFICIENT_BUFFER;
}

View File

@ -31,6 +31,14 @@ extern "C" {
#include <pshpack8.h>
#ifndef NO_SHLWAPI_HTTP
HRESULT WINAPI GetAcceptLanguagesA(char *buffer, DWORD *buff_len);
HRESULT WINAPI GetAcceptLanguagesW(WCHAR *buffer, DWORD *buff_len);
#define GetAcceptLanguages WINELIB_NAME_AW(GetAcceptLanguages)
#endif /* NO_SHLWAPI_HTTP */
#ifndef NO_SHLWAPI_REG
/* Registry functions */