advapi32: Fix todos for RegQueryInfoKey.

Thomas Faber thomas.faber at reactos.org
Sun May 17 11:09:38 CDT 2015


- Don't fail if *class_len == 0
- Write back partial results in RegQueryInfoKeyA
- Use STATUS_BUFFER_TOO_SMALL instead of STATUS_BUFFER_OVERFLOW in
   RegQueryInfoKeyW (since it does not return partial results)
-------------- next part --------------
From e4b6ee479c8ca7f99e5d3d19e71a3b03043be9cf Mon Sep 17 00:00:00 2001
From: Thomas Faber <thomas.faber at reactos.org>
Date: Sun, 17 May 2015 11:50:12 -0400
Subject: advapi32: Fix todos for RegQueryInfoKey.

---
 dlls/advapi32/registry.c       |   25 +++++++++++++------------
 dlls/advapi32/tests/registry.c |   20 ++++++++++----------
 2 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 06833d6..bd5d315 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -849,7 +849,7 @@ LSTATUS WINAPI RegQueryInfoKeyW( HKEY hkey, LPWSTR class, LPDWORD class_len, LPD
     status = NtQueryKey( hkey, KeyFullInformation, buffer, sizeof(buffer), &total_size );
     if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
 
-    if (class)
+    if (class && class_len && *class_len)
     {
         /* retry with a dynamically allocated buffer */
         while (status == STATUS_BUFFER_OVERFLOW)
@@ -865,7 +865,7 @@ LSTATUS WINAPI RegQueryInfoKeyW( HKEY hkey, LPWSTR class, LPDWORD class_len, LPD
 
         if (class_len && (info->ClassLength/sizeof(WCHAR) + 1 > *class_len))
         {
-            status = STATUS_BUFFER_OVERFLOW;
+            status = STATUS_BUFFER_TOO_SMALL;
         }
         else
         {
@@ -1049,17 +1049,18 @@ LSTATUS WINAPI RegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDW
 
         if (status) goto done;
 
-        RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength);
-        if (class_len)
-        {
-            if (len + 1 > *class_len) status = STATUS_BUFFER_OVERFLOW;
-            *class_len = len;
-        }
-        if (class && !status)
+        len = 0;
+        if (class && class_len) len = *class_len;
+        RtlUnicodeToMultiByteN( class, len, class_len,
+                                (WCHAR *)(buf_ptr + info->ClassOffset), info->ClassLength );
+        if (len)
         {
-            RtlUnicodeToMultiByteN( class, len, NULL, (WCHAR *)(buf_ptr + info->ClassOffset),
-                                    info->ClassLength );
-            class[len] = 0;
+            class[len - 1] = 0;
+            if (*class_len + 1 > len)
+            {
+                status = STATUS_BUFFER_OVERFLOW;
+                *class_len -= 1;
+            }
         }
     }
     else status = STATUS_SUCCESS;
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index 20b9bd8..c801384 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -1747,7 +1747,7 @@ static void test_reg_query_info(void)
 
     /* 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(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);
@@ -1780,7 +1780,7 @@ static void test_reg_query_info(void)
 
     /* 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(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);
@@ -1795,7 +1795,7 @@ static void test_reg_query_info(void)
     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(ret == ERROR_SUCCESS, "ret = %d\n", ret);
     ok(classlen == strlen(subkey_class) /* win2k */ ||
        classlen == 0, "classlen = %u\n", classlen);
     memset(expectbuffer, 0x55, sizeof(expectbuffer));
@@ -1804,7 +1804,7 @@ static void test_reg_query_info(void)
     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(ret == ERROR_SUCCESS, "ret = %d\n", ret);
     ok(classlen == strlen(subkey_class) /* win2k */ ||
        classlen == 0, "classlen = %u\n", classlen);
     memset(expectbufferW, 0x55, sizeof(expectbufferW));
@@ -1815,15 +1815,15 @@ static void test_reg_query_info(void)
     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);
+    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");
+    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(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));
@@ -1834,19 +1834,19 @@ static void test_reg_query_info(void)
     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);
+    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)),
+    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(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));
-- 
1.7.1


More information about the wine-patches mailing list