[PATCH 2/2] shlwapi/tests: Use defined settings, when testing GetAcceptLanguages[try 2]

Detlef Riekenberg wine.dev at web.de
Thu Feb 4 13:21:08 CST 2010


The old tests depend on user language settings, used
SetLastError(ERROR_SUCCESS) before and GetLastError()
after the api call for a function, that returns a HRESULT
and didn't know how the default language fallback works

Tested on all winetestbot machines

try 2:
I moved the deletion of 2 broken GetLastError() tests from
Patch 2 to Patch 1.

--
By by ... Detlef
---
 dlls/shlwapi/tests/ordinal.c |  364 +++++++++++++++++++++++++++---------------
 1 files changed, 237 insertions(+), 127 deletions(-)

diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index 9b75a87..24f0a61 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -27,6 +27,7 @@
 #include "ole2.h"
 #include "oaidl.h"
 #include "ocidl.h"
+#include "mlang.h"
 
 /* Function ptrs for ordinal calls */
 static HMODULE hShlwapi;
@@ -43,145 +44,251 @@ static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DIS
 static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
 static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
 
+static HMODULE hmlang;
+static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
+
+static const CHAR ie_international[] = {
+    '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 CHAR acceptlanguage[] = {
+    'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
+
+
 static void test_GetAcceptLanguagesA(void)
-{   HRESULT retval;
-    DWORD buffersize, buffersize2, exactsize;
-    char buffer[100];
+{
+    static LPCSTR table[] = {"de,en-gb;q=0.7,en;q=0.3",
+                             "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
+                             "winetest",    /* content is ignored */
+                             "de-de,de;q=0.5",
+                             "de",
+                             NULL};
+
+    HRESULT retval;
+    DWORD exactsize;
+    char original[512];
+    char language[32];
+    char buffer[64];
+    HKEY hroot = NULL;
+    LONG res_query = ERROR_SUCCESS;
+    LONG lres;
+    HRESULT hr;
+    DWORD maxlen = sizeof(buffer) - 2;
+    DWORD len;
+    LCID lcid;
+    LPCSTR entry;
+    INT i = 0;
 
     if (!pGetAcceptLanguagesA) {
         win_skip("GetAcceptLanguagesA is not available\n");
-	return;
+        return;
     }
 
-    buffersize = sizeof(buffer);
-    memset(buffer, 0, sizeof(buffer));
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( buffer, &buffersize);
-    if (!retval && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
-        win_skip("GetAcceptLanguagesA is not implemented\n");
+    lcid = GetUserDefaultLCID();
+
+    /* Get the original Value */
+    lres = RegOpenKeyA(HKEY_CURRENT_USER, ie_international, &hroot);
+    if (lres) {
+        win_skip("RegOpenKey(%s) failed: %d\n", ie_international, lres);
         return;
     }
-    trace("GetAcceptLanguagesA: retval %08x, size %08x, buffer (%s),"
-	" last error %u\n", retval, buffersize, buffer, GetLastError());
-    if(retval != S_OK) {
-	trace("GetAcceptLanguagesA: skipping tests\n");
-	return;
+    len = sizeof(original);
+    original[0] = 0;
+    res_query = RegQueryValueExA(hroot, acceptlanguage, 0, NULL, (PBYTE)original, &len);
+
+    RegDeleteValue(hroot, acceptlanguage);
+
+    /* Some windows versions use "lang-COUNTRY" as default */
+    memset(language, 0, sizeof(language));
+    len = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, language, sizeof(language));
+
+    if (len) {
+        lstrcat(language, "-");
+        memset(buffer, 0, sizeof(buffer));
+        len = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer, sizeof(buffer) - len - 1);
+        lstrcat(language, buffer);
+    }
+    else
+    {
+        /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
+        memset(language, 0, sizeof(language));
+        len = GetLocaleInfoA(lcid, LOCALE_SNAME, language, sizeof(language));
+    }
+
+    /* get the default value */
+    len = maxlen;
+    memset(buffer, '#', maxlen);
+    buffer[maxlen] = 0;
+    hr = pGetAcceptLanguagesA( buffer, &len);
+
+    if (hr != S_OK) {
+        win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr);
+        goto restore_original;
+    }
+
+    if (lstrcmpA(buffer, language)) {
+        /* some windows versions use "lang" or "lang-country" as default */
+        language[0] = 0;
+        if (pLcidToRfc1766A) {
+            hr = pLcidToRfc1766A(lcid, language, sizeof(language));
+            ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language);
+        }
     }
-    ok( (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()) || 
-	(ERROR_CLASS_DOES_NOT_EXIST == GetLastError()) ||
-	(ERROR_PROC_NOT_FOUND == GetLastError()) ||
-	(ERROR_SUCCESS == GetLastError()), "last error set to %u\n", GetLastError());
-    exactsize = strlen(buffer);
-
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( NULL, NULL);
-    ok(retval == E_FAIL ||
-       retval == E_INVALIDARG, /* w2k8 */
-       "function result wrong: got %08x; expected E_FAIL\n", retval);
-    ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
-
-    buffersize = sizeof(buffer);
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( NULL, &buffersize);
-    ok(retval == E_FAIL ||
-       retval == E_INVALIDARG, /* w2k8 */
-       "function result wrong: got %08x; expected E_FAIL\n", retval);
-    ok(buffersize == sizeof(buffer) ||
-       buffersize == 0, /* w2k8*/
-       "buffersize was changed and is not 0; size (%d))\n", buffersize);
-    ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
-
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( buffer, NULL);
-    ok(retval == E_FAIL ||
-       retval == E_INVALIDARG, /* w2k8 */
-       "function result wrong: got %08x; expected E_FAIL\n", retval);
-    ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
-
-    buffersize = 0;
-    memset(buffer, 0, sizeof(buffer));
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( buffer, &buffersize);
-    ok(retval == E_FAIL ||
-       retval == E_INVALIDARG, /* w2k8 */
-       "function result wrong: got %08x; expected E_FAIL\n", retval);
-    ok(buffersize == 0,
-       "buffersize wrong(changed) got %08x; expected 0 (2nd parameter; not on Win2k)\n", buffersize);
-    ok(ERROR_SUCCESS == GetLastError(), "last error set to %u\n", GetLastError());
-
-    buffersize = buffersize2 = 1;
-    memset(buffer, 0, sizeof(buffer));
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( buffer, &buffersize);
-    switch(retval) {
-	case 0L:
-            if(buffersize == exactsize) {
-            ok( (ERROR_SUCCESS == GetLastError()) ||
-		(ERROR_PROC_NOT_FOUND == GetLastError()) || (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()),
-                "last error wrong: got %u; expected ERROR_SUCCESS(NT4)/"
-		"ERROR_PROC_NOT_FOUND(NT4)/ERROR_NO_IMPERSONATION_TOKEN(XP)\n", GetLastError());
-            ok(exactsize == strlen(buffer),
-                 "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), exactsize);
-            } else if((buffersize +1) == buffersize2) {
-                ok(ERROR_SUCCESS == GetLastError(),
-                    "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
-                ok(buffersize == strlen(buffer),
-                    "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
-            } else
-                ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
-                    retval, buffersize, buffer, GetLastError());
-            break;
-	case E_INVALIDARG:
-            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());
-            ok(buffersize2 == strlen(buffer),
-               "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
-            break;
-        case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win7 */
-            ok(buffersize == 0,
-               "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
-            break;
-        default:
-            ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
-                retval, buffersize, buffer, GetLastError());
-            break;
+
+    ok(!lstrcmpA(buffer, language),
+        "have '%s' (searching for '%s')\n", language, buffer);
+
+    if (lstrcmpA(buffer, language)) {
+        win_skip("no more ideas, how to build the default language '%s'\n", buffer);
+        goto restore_original;
     }
 
-    buffersize = buffersize2 = exactsize;
-    memset(buffer, 0, sizeof(buffer));
-    SetLastError(ERROR_SUCCESS);
-    retval = pGetAcceptLanguagesA( buffer, &buffersize);
-    switch(retval) {
-	case 0L:
-            ok(ERROR_SUCCESS == GetLastError(),
-                 "last error wrong: got %u; expected ERROR_SUCCESS\n", GetLastError());
-            if((buffersize == exactsize) /* XP */ ||
-               ((buffersize +1)== exactsize) /* 98 */)
-                ok(buffersize == strlen(buffer),
-                    "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize);
-            else
-                ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
-                    retval, buffersize, buffer, GetLastError());
-            break;
-	case E_INVALIDARG:
-            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());
-            ok(buffersize2 == strlen(buffer),
-               "buffer content (length) wrong: got %08x, expected %08x\n", lstrlenA(buffer), buffersize2);
-            break;
-	case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): /* Win 7 */
-            ok(buffersize == 0,
-               "buffersize wrong: got %08x, expected 0 (2nd parameter;Win2k)\n", buffersize);
-            break;
-        default:
-            ok( 0, "retval %08x, size %08x, buffer (%s), last error %u\n",
-                retval, buffersize, buffer, GetLastError());
-            break;
+    trace("detected default: %s\n", language);
+    while (entry = table[i]) {
+
+        exactsize = strlen(entry);
+
+        lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, entry, exactsize + 1);
+        ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry);
+
+        /* len includes space for the terminating 0 before vista/w2k8 */ 
+        len = exactsize + 2;
+        memset(buffer, '#', maxlen);
+        buffer[maxlen] = 0;
+        hr = pGetAcceptLanguagesA( buffer, &len);
+        ok(((hr == E_INVALIDARG) && (len == 0)) ||
+            (SUCCEEDED(hr) &&
+            ((len == exactsize) || (len == exactsize+1)) &&
+            !lstrcmpA(buffer, entry)),
+            "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
+
+        len = exactsize + 1;
+        memset(buffer, '#', maxlen);
+        buffer[maxlen] = 0;
+        hr = pGetAcceptLanguagesA( buffer, &len);
+        ok(((hr == E_INVALIDARG) && (len == 0)) ||
+            (SUCCEEDED(hr) &&
+            ((len == exactsize) || (len == exactsize+1)) &&
+            !lstrcmpA(buffer, entry)),
+            "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
+
+        len = exactsize;
+        memset(buffer, '#', maxlen);
+        buffer[maxlen] = 0;
+        hr = pGetAcceptLanguagesA( buffer, &len);
+
+        /* There is no space for the string in the registry.
+           When the buffer is large enough, the default language is returned
+
+           When the buffer is to small for that fallback, win7_32 and w2k8_64
+           and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but
+           recent os succeed and return a partial result while
+           older os succeed and overflow the buffer */
+
+        ok(((hr == E_INVALIDARG) && (len == 0)) ||
+            (((hr == S_OK) && !lstrcmpA(buffer, language)  && (len == lstrlenA(language))) ||
+            ((hr == S_OK) && !memcmp(buffer, language, len)) ||
+            ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
+            "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
+
+        if (exactsize > 1) {
+            len = exactsize - 1;
+            memset(buffer, '#', maxlen);
+            buffer[maxlen] = 0;
+            hr = pGetAcceptLanguagesA( buffer, &len);
+            ok(((hr == E_INVALIDARG) && (len == 0)) ||
+                (((hr == S_OK) && !lstrcmpA(buffer, language)  && (len == lstrlenA(language))) ||
+                ((hr == S_OK) && !memcmp(buffer, language, len)) ||
+                ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
+                "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
+        }
+
+        len = 1;
+        memset(buffer, '#', maxlen);
+        buffer[maxlen] = 0;
+        hr = pGetAcceptLanguagesA( buffer, &len);
+        ok(((hr == E_INVALIDARG) && (len == 0)) ||
+            (((hr == S_OK) && !lstrcmpA(buffer, language)  && (len == lstrlenA(language))) ||
+            ((hr == S_OK) && !memcmp(buffer, language, len)) ||
+            ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
+            "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
+
+        len = maxlen;
+        hr = pGetAcceptLanguagesA( NULL, &len);
+
+        /* w2k3 and below: E_FAIL and untouched len,
+           since w2k8: S_OK and needed size (excluding 0) */
+        ok( ((hr == S_OK) && (len == exactsize)) ||
+            ((hr == E_FAIL) && (len == maxlen)),
+            "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
+
+        i++;
+    }
+
+    /* without a value in the registry, a default language is returned */
+    RegDeleteValue(hroot, acceptlanguage);
+
+    len = maxlen;
+    memset(buffer, '#', maxlen);
+    buffer[maxlen] = 0;
+    hr = pGetAcceptLanguagesA( buffer, &len);
+    ok( ((hr == S_OK) && (len == lstrlenA(language))),
+        "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
+        hr, len, buffer, lstrlenA(language), language);
+
+    len = 2;
+    memset(buffer, '#', maxlen);
+    buffer[maxlen] = 0;
+    hr = pGetAcceptLanguagesA( buffer, &len);
+    ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
+        ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
+        "=2: got 0x%x with %d and %s\n", hr, len, buffer);
+
+    len = 1;
+    memset(buffer, '#', maxlen);
+    buffer[maxlen] = 0;
+    hr = pGetAcceptLanguagesA( buffer, &len);
+    /* When the buffer is to small, win7_32 and w2k8_64 and above fail with
+       HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed
+       and return a partial 0 terminated result while other versions
+       fail with E_INVALIDARG and return a partial unterminated result */
+    ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
+        ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
+        "=1: got 0x%x with %d and %s\n", hr, len, buffer);
+
+    len = 0;
+    memset(buffer, '#', maxlen);
+    buffer[maxlen] = 0;
+    hr = pGetAcceptLanguagesA( buffer, &len);
+    /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */ 
+    ok((hr == E_FAIL) || (hr == E_INVALIDARG),
+        "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
+
+    memset(buffer, '#', maxlen);
+    buffer[maxlen] = 0;
+    hr = pGetAcceptLanguagesA( buffer, NULL);
+    /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */ 
+    ok((hr == E_FAIL) || (hr == E_INVALIDARG),
+        "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
+
+
+    hr = pGetAcceptLanguagesA( NULL, NULL);
+    /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */ 
+    ok((hr == E_FAIL) || (hr == E_INVALIDARG),
+        "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
+
+restore_original:
+    if (!res_query) {
+        len = lstrlenA(original);
+        lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, original, len ? len + 1: 0);
+        ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres);
     }
+    else
+    {
+        RegDeleteValue(hroot, acceptlanguage);
+    }
+    RegCloseKey(hroot);
 }
 
 static void test_SHSearchMapInt(void)
@@ -1307,6 +1414,9 @@ START_TEST(ordinal)
   pConnectToConnectionPoint=(void*)GetProcAddress(hShlwapi,(char*)168);
   pSHPropertyBag_ReadLONG=(void*)GetProcAddress(hShlwapi,(char*)496);
 
+  hmlang = LoadLibraryA("mlang.dll");
+  pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A");
+
   test_GetAcceptLanguagesA();
   test_SHSearchMapInt();
   test_alloc_shared();
-- 
1.6.5




More information about the wine-patches mailing list