[PATCH 2/2] shlwapi/tests: Use defined settings, when testing GetAcceptLanguages[try 2]
Detlef Riekenberg
wine.dev at web.de
Thu Feb 4 13:45:59 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