Index: modules/rostests/apitests/advapi32/CMakeLists.txt =================================================================== --- modules/rostests/apitests/advapi32/CMakeLists.txt (revision 67443) +++ modules/rostests/apitests/advapi32/CMakeLists.txt (working copy) @@ -6,6 +6,7 @@ LockDatabase.c QueryServiceConfig2.c RegEnumValueW.c + RegQueryInfoKeyW.c RtlEncryptMemory.c SaferIdentifyLevel.c testlist.c) Index: modules/rostests/apitests/advapi32/RegQueryInfoKeyW.c =================================================================== --- modules/rostests/apitests/advapi32/RegQueryInfoKeyW.c (revision 0) +++ modules/rostests/apitests/advapi32/RegQueryInfoKeyW.c (working copy) @@ -0,0 +1,178 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for the RegQueryValueW API + * PROGRAMMER: Victor Martinez Calvo + */ +#include + +#define WIN32_NO_STATUS +#include + +static DWORD delete_key(HKEY hkey) +{ + char name[MAX_PATH]; + DWORD ret; + + if ((ret = RegOpenKeyExA(hkey, "", 0, KEY_ENUMERATE_SUB_KEYS, &hkey))) return ret; + while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name)))) + { + HKEY tmp; + if (!(ret = RegOpenKeyExA(hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp))) + { + ret = delete_key(tmp); + RegCloseKey(tmp); + } + if (ret) break; + } + if (ret != ERROR_NO_MORE_ITEMS) return ret; + RegDeleteKeyA(hkey, ""); + RegCloseKey(hkey); + return 0; +} + +START_TEST(RegQueryInfoKeyW) +{ + HKEY hkey_main; + HKEY subkey; + HKEY subkeylong; + DWORD ret; + const WCHAR string1W[] = {'1', 0}; + const WCHAR string22W[] = {'T','h','i','s','s','t','r','i','n','g','h','a','s','2','2','l','e','t','t','e','r','s', 0}; + + WCHAR Small12[12]; + WCHAR Perfect13[13]; + + WCHAR subkey_class[] = L"subkey class"; + DWORD classlen; + DWORD subkeys, maxsubkeylen, maxclasslen; + DWORD values, maxvaluenamelen, maxvaluelen; + DWORD sdlen; + FILETIME lastwrite; + + /* If the tree key already exist, delete it to ensure proper testing*/ + if (RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\ReactOS\\Test", &hkey_main) == ERROR_SUCCESS) + delete_key( hkey_main ); + + /* Ready to recreate it */ + SetLastError(0xdeadbeef); + ret = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\ReactOS\\Test", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey_main, NULL); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCES S, got %d\n", ret); + ok(GetLastError(), "RegCreateKeyExW failed: %lx\n", GetLastError()); + if(ret != ERROR_SUCCESS) return; + + + SetLastError(0xdeadbeef); + ret = RegCreateKeyExW(hkey_main, L"subkey", 0, L"subkey class", 0, KEY_ALL_ACCESS, NULL, &subkey, NULL); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(GetLastError(), "RegCreateKeyExW failed: %lx\n", GetLastError()); + if (ret != ERROR_SUCCESS) return; + + + //QueryInfo without subkeys. + + // ClassLen with NULL Buffer class and Classlen not set + ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); + ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); + ok(classlen == wcslen(subkey_class), "classlen = %u\n", classlen); + ok(subkeys == 0, "subkeys = %u\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); + ok(values == 0, "values = %u\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); + ok(sdlen != 0, "sdlen = %u\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + + classlen = 0; + // ClassLen with NULL Buffer class and Classlen not set + ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); + ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); + ok(classlen == wcslen(subkey_class), "classlen = %u\n", classlen); + ok(subkeys == 0, "subkeys = %u\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); + ok(values == 0, "values = %u\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); + ok(sdlen != 0, "sdlen = %u\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + + + classlen = sizeof(Small12)/sizeof(WCHAR); + // ClassLen with SMALL12 Buffer class. Class is 12 + NULL + ret = RegQueryInfoKeyW(subkey, Small12, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); + ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %d\n", ret); + ok(classlen == wcslen(subkey_class), "classlen = %u\n", classlen); + ok(subkeys == 0, "subkeys = %u\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); + ok(values == 0, "values = %u\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); + ok(sdlen != 0, "sdlen = %u\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + + classlen = sizeof(Perfect13)/sizeof(WCHAR); + // ClassLen with Perfect13 Buffer class. Class is 12 + NULL + ret = RegQueryInfoKeyW(subkey, Perfect13, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); + ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); + ok(classlen == wcslen(subkey_class), "classlen = %u\n", classlen); + ok(subkeys == 0, "subkeys = %u\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); + ok(values == 0, "values = %u\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); + ok(sdlen != 0, "sdlen = %u\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + + classlen = sizeof(Perfect13)/sizeof(WCHAR) - 1; + // ClassLen with Perfect13 Buffer class. But classlen reporting incorrect Buffer size. + ret = RegQueryInfoKeyW(subkey, Perfect13, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); + ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %d\n", ret); + ok(classlen == wcslen(subkey_class), "classlen = %u\n", classlen); + ok(subkeys == 0, "subkeys = %u\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); + ok(values == 0, "values = %u\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); + ok(sdlen != 0, "sdlen = %u\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + + + SetLastError(0xdeadbeef); + ret = RegCreateKeyExW(subkey, L"subkeylong", 0, L"subkeylong class", 0, KEY_ALL_ACCESS, NULL, &subkeylong, NULL); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(GetLastError(), "RegCreateKeyExW failed: %lx\n", GetLastError()); + + //QueryInfo with a subkey named "subkeylong". + ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); + ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); + ok(classlen == wcslen(subkey_class), "classlen = %u\n", classlen); + ok(subkeys == 1, "subkeys = %u\n", subkeys); + ok(maxsubkeylen == 10, "maxsubkeylen = %u\n", maxsubkeylen); + ok(maxclasslen == 16, "maxclasslen = %u\n", maxclasslen); + ok(values == 0, "values = %u\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); + ok(sdlen != 0, "sdlen = %u\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + + if (ret != ERROR_SUCCESS) return; + RegCloseKey(hkey_main); + RegCloseKey(subkey); + RegCloseKey(subkeylong); + + /* Delete the whole ReactOS tree */ + RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\ReactOS", &hkey_main); + delete_key(hkey_main); + +} Index: modules/rostests/apitests/advapi32/testlist.c =================================================================== --- modules/rostests/apitests/advapi32/testlist.c (revision 67443) +++ modules/rostests/apitests/advapi32/testlist.c (working copy) @@ -9,6 +9,7 @@ extern void func_LockDatabase(void); extern void func_QueryServiceConfig2(void); extern void func_RegEnumValueW(void); +extern void func_RegQueryInfoKeyW(void); extern void func_RtlEncryptMemory(void); extern void func_SaferIdentifyLevel(void); @@ -19,7 +20,8 @@ { "HKEY_CLASSES_ROOT", func_HKEY_CLASSES_ROOT }, { "LockDatabase" , func_LockDatabase }, { "QueryServiceConfig2", func_QueryServiceConfig2 }, { "RegEnumValueW", func_RegEnumValueW}, + { "RegQueryInfoKeyW", func_RegQueryInfoKeyW }, { "RtlEncryptMemory", func_RtlEncryptMemory }, { "SaferIdentifyLevel", func_SaferIdentifyLevel },