[PATCH 1/2] shlwapi: Return correct strings in GetAcceptLanguages [try 2]
Detlef Riekenberg
wine.dev at web.de
Thu Feb 4 13:20:49 CST 2010
I moved the deletion of 2 broken GetLastError() tests from
Patch 2 to Patch 1.
The tests now succeed also on an unconfigured Wine without a failure.
(unconfigured AcceptLanguages registry entry)
--
By by ... Detlef
---
dlls/shlwapi/ordinal.c | 88 ++++++++++++++++++++++++-----------------
dlls/shlwapi/tests/ordinal.c | 4 --
2 files changed, 51 insertions(+), 41 deletions(-)
diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 9bb26cf..fc15a5f 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -47,6 +47,7 @@
#include "shellapi.h"
#include "commdlg.h"
#include "mshtmhst.h"
+#include "mlang.h"
#include "wine/unicode.h"
#include "wine/debug.h"
@@ -450,14 +451,14 @@ RegisterDefaultAcceptHeaders_Exit:
*
* PARAMS
* langbuf [O] Destination for language string
- * buflen [I] Length of langbuf
+ * buflen [I] Length of langbuf in characters
* [0] Success: used length of langbuf
*
* RETURNS
- * Success: S_OK. langbuf is set to the language string found.
+ * Success: S_OK. langbuf is set to the language string found. (used length in buflen)
* Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
* does not contain the setting.
- * E_INVALIDARG, If the buffer is not big enough
+ * HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), If the buffer is not big enough
*/
HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
{
@@ -468,55 +469,56 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
'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};
- static const WCHAR enusW[] = {'e','n','-','u','s',0};
DWORD mystrlen, mytype;
+ DWORD len;
HKEY mykey;
HRESULT retval;
LCID mylcid;
WCHAR *mystr;
+ LONG lres;
+
+ TRACE("(%p, %p) *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1);
if(!langbuf || !buflen || !*buflen)
- return E_FAIL;
+ return E_FAIL;
- mystrlen = (*buflen > 20) ? *buflen : 20 ;
- mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
+ mystrlen = ((*buflen > 20) ? *buflen : 20 );
+ len = mystrlen * sizeof(WCHAR);
+ mystr = HeapAlloc(GetProcessHeap(), 0, len + sizeof(WCHAR));
+ mystr[0] = 0;
RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
- if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
- /* Did not find value */
- mylcid = GetUserDefaultLCID();
- /* somehow the mylcid translates into "en-us"
- * this is similar to "LOCALE_SABBREVLANGNAME"
- * which could be gotten via GetLocaleInfo.
- * The only problem is LOCALE_SABBREVLANGUAGE" is
- * a 3 char string (first 2 are country code and third is
- * letter for "sublanguage", which does not come close to
- * "en-us"
- */
- lstrcpyW(mystr, enusW);
- mystrlen = lstrlenW(mystr);
- } else {
- /* handle returned string */
- FIXME("missing code\n");
- }
- memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
+ lres = RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &len);
+ RegCloseKey(mykey);
+ len = lstrlenW(mystr);
- if(*buflen > strlenW(mystr)) {
- *buflen = strlenW(mystr);
- retval = S_OK;
- } else {
- *buflen = 0;
- retval = E_INVALIDARG;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ if (!lres && (*buflen > len)) {
+ lstrcpyW(langbuf, mystr);
+ *buflen = len;
+ HeapFree(GetProcessHeap(), 0, mystr);
+ return S_OK;
}
- RegCloseKey(mykey);
+
+ /* Did not find a value in the registry or the user buffer is to small */
+ mylcid = GetUserDefaultLCID();
+ retval = LcidToRfc1766W(mylcid, mystr, mystrlen);
+ len = lstrlenW(mystr);
+
+ memcpy( langbuf, mystr, min(*buflen, len+1)*sizeof(WCHAR) );
HeapFree(GetProcessHeap(), 0, mystr);
- return retval;
+
+ if (*buflen > len) {
+ *buflen = len;
+ return S_OK;
+ }
+
+ *buflen = 0;
+ return __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
/*************************************************************************
* @ [SHLWAPI.14]
*
- * Ascii version of GetAcceptLanguagesW.
+ * See GetAcceptLanguagesW.
*/
HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
{
@@ -524,6 +526,8 @@ HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
DWORD buflenW, convlen;
HRESULT retval;
+ TRACE("(%p, %p) *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1);
+
if(!langbuf || !buflen || !*buflen) return E_FAIL;
buflenW = *buflen;
@@ -533,12 +537,22 @@ HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
if (retval == 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;
+ if (convlen < *buflen)
+ {
+ langbuf[convlen] = 0;
+ convlen--; /* do not count the terminating 0 */
+ }
+ else
+ {
+ convlen = *buflen;
+ }
}
+
*buflen = buflenW ? convlen : 0;
HeapFree(GetProcessHeap(), 0, langbufW);
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index 31fced9..9b75a87 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -142,8 +142,6 @@ static void test_GetAcceptLanguagesA(void)
case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win7 */
ok(buffersize == 0,
"buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
- ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
- "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
break;
default:
ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
@@ -178,8 +176,6 @@ static void test_GetAcceptLanguagesA(void)
case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win 7 */
ok(buffersize == 0,
"buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
- ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
- "last error wrong: got %u; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
break;
default:
ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
--
1.6.5
More information about the wine-patches
mailing list