advapi32/tests: Add tests for RegQueryInfoKey. (try 2)

Thomas Faber thomas.faber at reactos.org
Wed May 13 10:02:56 CDT 2015


Try 2:
- Use memcmp instead of comparing individual array elements
- Add test for the invalid parameter combination
   lpClass != NULL && lpcClass == NULL
-------------- next part --------------
From e6cfdf886b84811b5217fd19da3848fa54fff3c4 Mon Sep 17 00:00:00 2001
From: Thomas Faber <thomas.faber at reactos.org>
Date: Wed, 13 May 2015 10:52:51 -0400
Subject: advapi32/tests: Add tests for RegQueryInfoKey.

---
 dlls/advapi32/tests/registry.c |  216 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 216 insertions(+), 0 deletions(-)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index f0cfb5c..20b9bd8 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -1666,6 +1666,221 @@ cleanup:
     RegCloseKey(subkey);
 }
 
+static void test_reg_query_info(void)
+{
+    HKEY subkey;
+    HKEY subsubkey;
+    LONG ret;
+    char classbuffer[32];
+    WCHAR classbufferW[32];
+    char expectbuffer[32];
+    WCHAR expectbufferW[32];
+    char subkey_class[] = "subkey class";
+    WCHAR subkey_classW[] = {'s','u','b','k','e','y',' ','c','l','a','s','s',0};
+    char subsubkey_class[] = "subsubkey class";
+    DWORD classlen;
+    DWORD subkeys, maxsubkeylen, maxclasslen;
+    DWORD values, maxvaluenamelen, maxvaluelen;
+    DWORD sdlen;
+    FILETIME lastwrite;
+
+    ret = RegCreateKeyExA(hkey_main, "subkey", 0, subkey_class, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    /* all parameters NULL */
+    ret = RegQueryInfoKeyA(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_INVALID_HANDLE, "ret = %d\n", ret);
+
+    ret = RegQueryInfoKeyW(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_INVALID_HANDLE, "ret = %d\n", ret);
+
+    /* not requesting any information */
+    ret = RegQueryInfoKeyA(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+
+    ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+
+    /* class without length is invalid */
+    memset(classbuffer, 0x55, sizeof(classbuffer));
+    ret = RegQueryInfoKeyA(subkey, classbuffer, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_INVALID_PARAMETER, "ret = %d\n", ret);
+    ok(classbuffer[0] == 0x55, "classbuffer[0] = 0x%x\n", classbuffer[0]);
+
+    memset(classbufferW, 0x55, sizeof(classbufferW));
+    ret = RegQueryInfoKeyW(subkey, classbufferW, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_INVALID_PARAMETER, "ret = %d\n", ret);
+    ok(classbufferW[0] == 0x5555, "classbufferW[0] = 0x%x\n", classbufferW[0]);
+
+    /* empty key */
+    ret = RegQueryInfoKeyA(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == strlen(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);
+
+    ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == strlen(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);
+
+    ret = RegCreateKeyExA(subkey, "subsubkey", 0, subsubkey_class, 0, KEY_ALL_ACCESS, NULL, &subsubkey, NULL);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    ret = RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE*)"data", 5);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    /* with subkey & default value */
+    ret = RegQueryInfoKeyA(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite);
+    todo_wine ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == strlen(subkey_class), "classlen = %u\n", classlen);
+    ok(subkeys == 1, "subkeys = %u\n", subkeys);
+    ok(maxsubkeylen == strlen("subsubkey"), "maxsubkeylen = %u\n", maxsubkeylen);
+    ok(maxclasslen == strlen(subsubkey_class), "maxclasslen = %u\n", maxclasslen);
+    ok(values == 1, "values = %u\n", values);
+    ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen);
+    ok(maxvaluelen == sizeof("data") * sizeof(WCHAR), "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);
+
+    ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == strlen(subkey_class), "classlen = %u\n", classlen);
+    ok(subkeys == 1, "subkeys = %u\n", subkeys);
+    ok(maxsubkeylen == strlen("subsubkey"), "maxsubkeylen = %u\n", maxsubkeylen);
+    ok(maxclasslen == strlen(subsubkey_class), "maxclasslen = %u\n", maxclasslen);
+    ok(values == 1, "values = %u\n", values);
+    ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen);
+    ok(maxvaluelen == sizeof("data") * sizeof(WCHAR), "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);
+
+    ret = RegSetValueExA(subkey, "value one", 0, REG_SZ, (const BYTE*)"first value data", 17);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    ret = RegSetValueExA(subkey, "value 2", 0, REG_SZ, (const BYTE*)"second value data", 18);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    /* with named value */
+    ret = RegQueryInfoKeyA(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite);
+    todo_wine ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(values == 3, "values = %u\n", values);
+    ok(maxvaluenamelen == strlen("value one"), "maxvaluenamelen = %u\n", maxvaluenamelen);
+    ok(maxvaluelen == sizeof("second value data") * sizeof(WCHAR), "maxvaluelen = %u\n", maxvaluelen);
+
+    ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(values == 3, "values = %u\n", values);
+    ok(maxvaluenamelen == strlen("value one"), "maxvaluenamelen = %u\n", maxvaluenamelen);
+    ok(maxvaluelen == sizeof("second value data") * sizeof(WCHAR), "maxvaluelen = %u\n", maxvaluelen);
+
+    /* class name with zero size buffer */
+    memset(classbuffer, 0x55, sizeof(classbuffer));
+    classlen = 0;
+    ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    todo_wine ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == strlen(subkey_class) /* win2k */ ||
+       classlen == 0, "classlen = %u\n", classlen);
+    memset(expectbuffer, 0x55, sizeof(expectbuffer));
+    ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)), "classbuffer was modified\n");
+
+    memset(classbufferW, 0x55, sizeof(classbufferW));
+    classlen = 0;
+    ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    todo_wine ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == strlen(subkey_class) /* win2k */ ||
+       classlen == 0, "classlen = %u\n", classlen);
+    memset(expectbufferW, 0x55, sizeof(expectbufferW));
+    ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW was modified\n");
+
+    /* class name with one char buffer */
+    memset(classbuffer, 0x55, sizeof(classbuffer));
+    classlen = 1;
+    ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_MORE_DATA, "ret = %d\n", ret);
+    todo_wine ok(classlen == 0, "classlen = %u\n", classlen);
+    memset(expectbuffer, 0x55, sizeof(expectbuffer));
+    expectbuffer[0] = 0;
+    todo_wine ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)), "classbuffer was modified\n");
+
+    memset(classbufferW, 0x55, sizeof(classbufferW));
+    classlen = 1;
+    ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    todo_wine ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %d\n", ret);
+    ok(classlen == 0 /* win8 */ ||
+       classlen == strlen(subkey_class), "classlen = %u\n", classlen);
+    memset(expectbufferW, 0x55, sizeof(expectbufferW));
+    ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW was modified\n");
+
+    /* class name with buffer one char too small */
+    memset(classbuffer, 0x55, sizeof(classbuffer));
+    classlen = sizeof(subkey_class) - 1;
+    ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_MORE_DATA, "ret = %d\n", ret);
+    todo_wine ok(classlen == sizeof(subkey_class) - 2, "classlen = %u\n", classlen);
+    memset(expectbuffer, 0x55, sizeof(expectbuffer));
+    strcpy(expectbuffer, subkey_class);
+    expectbuffer[sizeof(subkey_class) - 2] = 0;
+    expectbuffer[sizeof(subkey_class) - 1] = 0x55;
+    todo_wine ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)),
+       "classbuffer = %.*s, expected %s\n",
+       (int)sizeof(classbuffer), classbuffer, expectbuffer);
+
+    memset(classbufferW, 0x55, sizeof(classbufferW));
+    classlen = sizeof(subkey_class) - 1;
+    ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    todo_wine ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %d\n", ret);
+    ok(classlen == sizeof(subkey_class) - 2 /* win8 */ ||
+       classlen == strlen(subkey_class), "classlen = %u\n", classlen);
+    memset(expectbufferW, 0x55, sizeof(expectbufferW));
+    ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW was modified\n");
+
+    /* class name with large enough buffer */
+    memset(classbuffer, 0x55, sizeof(classbuffer));
+    classlen = sizeof(subkey_class);
+    ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == sizeof(subkey_class) - 1, "classlen = %u\n", classlen);
+    memset(expectbuffer, 0x55, sizeof(expectbuffer));
+    strcpy(expectbuffer, subkey_class);
+    ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)),
+       "classbuffer = \"%.*s\", expected %s\n",
+       (int)sizeof(classbuffer), classbuffer, expectbuffer);
+
+    memset(classbufferW, 0x55, sizeof(classbufferW));
+    classlen = sizeof(subkey_class);
+    ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == ERROR_SUCCESS, "ret = %d\n", ret);
+    ok(classlen == sizeof(subkey_class) - 1, "classlen = %u\n", classlen);
+    memset(expectbufferW, 0x55, sizeof(expectbufferW));
+    lstrcpyW(expectbufferW, subkey_classW);
+    ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)),
+       "classbufferW = %s, expected %s\n",
+       wine_dbgstr_wn(classbufferW, sizeof(classbufferW) / sizeof(WCHAR)), wine_dbgstr_w(expectbufferW));
+
+    RegDeleteKeyA(subsubkey, "");
+    RegCloseKey(subsubkey);
+    RegDeleteKeyA(subkey, "");
+    RegCloseKey(subkey);
+}
+
 static void test_string_termination(void)
 {
     HKEY subkey;
@@ -2959,6 +3174,7 @@ START_TEST(registry)
     test_reg_close_key();
     test_reg_delete_key();
     test_reg_query_value();
+    test_reg_query_info();
     test_string_termination();
     test_symlinks();
     test_redirection();
-- 
1.7.1


More information about the wine-patches mailing list