From 1da7a32b116c169f07bfef060894df2b1f71a4b6 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Thu, 21 Jun 2007 02:12:30 +0200 Subject: [PATCH] advapi32: Add more RegGetValue() conformance tests, and fix Wine accordingly. --- dlls/advapi32/registry.c | 22 +++++++++++++------- dlls/advapi32/tests/registry.c | 38 +++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index cb905ed592f..e62206bcd25 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -1451,6 +1451,8 @@ LONG WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, hKey, debugstr_w(pszSubKey), debugstr_w(pszValue), dwFlags, pdwType, pvData, pcbData, cbData); + if (pvData && !pcbData) + return ERROR_INVALID_PARAMETER; if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND)) return ERROR_INVALID_PARAMETER; @@ -1466,7 +1468,7 @@ LONG WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, * if the passed buffer was too small as the expanded string might be * smaller than the unexpanded one and could fit into cbData bytes. */ if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && - (dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND))) + dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)) { do { HeapFree(GetProcessHeap(), 0, pvBuf); @@ -1478,7 +1480,7 @@ LONG WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, break; } - if (ret == ERROR_MORE_DATA) + if (ret == ERROR_MORE_DATA || !pvData) ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, pvBuf, &cbData); else @@ -1496,6 +1498,7 @@ LONG WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, if (ret == ERROR_SUCCESS) { + /* Recheck dwType in case it changed since the first call */ if (dwType == REG_EXPAND_SZ) { cbData = ExpandEnvironmentStringsW(pvBuf, pvData, @@ -1504,7 +1507,7 @@ LONG WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, if(pcbData && cbData > *pcbData) ret = ERROR_MORE_DATA; } - else if (pcbData) + else if (pvData) CopyMemory(pvData, pvBuf, *pcbData); } @@ -1516,7 +1519,7 @@ LONG WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, ADVAPI_ApplyRestrictions(dwFlags, dwType, cbData, &ret); - if (pcbData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE)) + if (pvData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE)) ZeroMemory(pvData, *pcbData); if (pdwType) *pdwType = dwType; @@ -1543,6 +1546,8 @@ LONG WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, hKey, pszSubKey, pszValue, dwFlags, pdwType, pvData, pcbData, cbData); + if (pvData && !pcbData) + return ERROR_INVALID_PARAMETER; if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND)) return ERROR_INVALID_PARAMETER; @@ -1558,7 +1563,7 @@ LONG WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, * if the passed buffer was too small as the expanded string might be * smaller than the unexpanded one and could fit into cbData bytes. */ if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && - (dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND))) + dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)) { do { HeapFree(GetProcessHeap(), 0, pvBuf); @@ -1570,7 +1575,7 @@ LONG WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, break; } - if (ret == ERROR_MORE_DATA) + if (ret == ERROR_MORE_DATA || !pvData) ret = RegQueryValueExA(hKey, pszValue, NULL, &dwType, pvBuf, &cbData); else @@ -1588,6 +1593,7 @@ LONG WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, if (ret == ERROR_SUCCESS) { + /* Recheck dwType in case it changed since the first call */ if (dwType == REG_EXPAND_SZ) { cbData = ExpandEnvironmentStringsA(pvBuf, pvData, @@ -1596,7 +1602,7 @@ LONG WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, if(pcbData && cbData > *pcbData) ret = ERROR_MORE_DATA; } - else if (pcbData) + else if (pvData) CopyMemory(pvData, pvBuf, *pcbData); } @@ -1608,7 +1614,7 @@ LONG WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, ADVAPI_ApplyRestrictions(dwFlags, dwType, cbData, &ret); - if (pcbData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE)) + if (pvData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE)) ZeroMemory(pvData, *pcbData); if (pdwType) *pdwType = dwType; diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 0cc58f1b1e9..cdd4835030e 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -598,6 +598,10 @@ static void test_get_value(void) return; } + /* Invalid parameter */ + ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD, &type, &dw, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "ret=%d\n", ret); + /* Query REG_DWORD using RRF_RT_REG_DWORD (ok) */ size = type = dw = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD, &type, &dw, &size); @@ -629,6 +633,13 @@ static void test_get_value(void) /* ... except the buffer, which is zeroed out */ ok(dw == 0, "dw=%d\n", dw); + /* Test RRF_ZEROONFAILURE with a NULL buffer... */ + type = size = 0xbadbeef; + ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_SZ|RRF_ZEROONFAILURE, &type, NULL, &size); + ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret); + ok(size == 4, "size=%d\n", size); + ok(type == REG_DWORD, "type=%d\n", type); + /* Query REG_DWORD using RRF_RT_DWORD (ok) */ size = type = dw = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_DWORD, &type, &dw, &size); @@ -678,6 +689,15 @@ static void test_get_value(void) ok(type == REG_SZ, "type=%d\n", type); ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf); + /* Query REG_SZ using RRF_RT_REG_SZ and no buffer (ok) */ + type = 0xdeadbeef; size = 0; + ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ, &type, NULL, &size); + ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); + /* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */ + ok(size == strlen(sTestpath1)+1 || size == strlen(sTestpath1)+2, + "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%d\n", type); + /* Query REG_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (ok) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ|RRF_NOEXPAND, &type, buf, &size); @@ -686,6 +706,14 @@ static void test_get_value(void) ok(type == REG_SZ, "type=%d\n", type); ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf); + /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ and no buffer (ok, expands) */ + size = 0xbadbeef; + ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ, NULL, NULL, &size); + ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); + /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */ + ok((size == strlen(expanded)+1) || (size == strlen(sTestpath1)+1), + "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded), lstrlenA(sTestpath1), size); + /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ (ok, expands) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ, &type, buf, &size); @@ -703,7 +731,15 @@ static void test_get_value(void) ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); ok(type == REG_EXPAND_SZ, "type=%d\n", type); ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf); - + + /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND and no buffer (ok, doesn't expand) */ + size = 0xbadbeef; + ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND, NULL, NULL, &size); + ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); + /* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */ + ok(size == strlen(sTestpath1)+1 || size == strlen(sTestpath1)+2, + "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); + /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (type mismatch) */ ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, NULL, NULL); ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret);