Convert NtQueryKey and NtEnumerateKey to the new request mechanism.
Fixed a few bugs.

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index fca82b1..26aa450 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -289,32 +289,58 @@
 DWORD WINAPI RegEnumKeyExW( HKEY hkey, DWORD index, LPWSTR name, LPDWORD name_len,
                             LPDWORD reserved, LPWSTR class, LPDWORD class_len, FILETIME *ft )
 {
-    DWORD ret, len, cls_len;
-    struct enum_key_request *req = get_req_buffer();
+    NTSTATUS status;
+    char buffer[256], *buf_ptr = buffer;
+    KEY_NODE_INFORMATION *info = (KEY_NODE_INFORMATION *)buffer;
+    DWORD total_size;
 
     TRACE( "(0x%x,%ld,%p,%p(%ld),%p,%p,%p,%p)\n", hkey, index, name, name_len,
            name_len ? *name_len : -1, reserved, class, class_len, ft );
 
     if (reserved) return ERROR_INVALID_PARAMETER;
 
-    req->hkey = hkey;
-    req->index = index;
-    if ((ret = reg_server_call( REQ_ENUM_KEY )) != ERROR_SUCCESS) return ret;
+    status = NtEnumerateKey( hkey, index, KeyNodeInformation,
+                             buffer, sizeof(buffer), &total_size );
 
-    len = strlenW( req->name ) + 1;
-    cls_len = strlenW( req->class ) + 1;
-    if (len > *name_len) return ERROR_MORE_DATA;
-    if (class_len && (cls_len > *class_len)) return ERROR_MORE_DATA;
-
-    memcpy( name, req->name, len * sizeof(WCHAR) );
-    *name_len = len - 1;
-    if (class_len)
+    while (status == STATUS_BUFFER_OVERFLOW)
     {
-        if (class) memcpy( class, req->class, cls_len * sizeof(WCHAR) );
-        *class_len = cls_len - 1;
+        /* retry with a dynamically allocated buffer */
+        if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+        if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+            return ERROR_NOT_ENOUGH_MEMORY;
+        info = (KEY_NODE_INFORMATION *)buf_ptr;
+        status = NtEnumerateKey( hkey, index, KeyNodeInformation,
+                                 buf_ptr, total_size, &total_size );
     }
-    if (ft) RtlSecondsSince1970ToTime( req->modif, ft );
-    return ERROR_SUCCESS;
+
+    if (!status)
+    {
+        DWORD len = info->NameLength / sizeof(WCHAR);
+        DWORD cls_len = info->ClassLength / sizeof(WCHAR);
+
+        if (ft) *ft = info->LastWriteTime;
+
+        if (len >= *name_len || (class_len && (cls_len >= *class_len)))
+            status = STATUS_BUFFER_OVERFLOW;
+        else
+        {
+            *name_len = len;
+            memcpy( name, info->Name, info->NameLength );
+            name[len] = 0;
+            if (class_len)
+            {
+                *class_len = cls_len;
+                if (class)
+                {
+                    memcpy( class, buf_ptr + info->ClassOffset, info->ClassLength );
+                    class[cls_len] = 0;
+                }
+            }
+        }
+    }
+
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    return RtlNtStatusToDosError( status );
 }
 
 
@@ -324,32 +350,64 @@
 DWORD WINAPI RegEnumKeyExA( HKEY hkey, DWORD index, LPSTR name, LPDWORD name_len,
                             LPDWORD reserved, LPSTR class, LPDWORD class_len, FILETIME *ft )
 {
-    DWORD ret, len, cls_len;
-    struct enum_key_request *req = get_req_buffer();
+    NTSTATUS status;
+    char buffer[256], *buf_ptr = buffer;
+    KEY_NODE_INFORMATION *info = (KEY_NODE_INFORMATION *)buffer;
+    DWORD total_size;
 
     TRACE( "(0x%x,%ld,%p,%p(%ld),%p,%p,%p,%p)\n", hkey, index, name, name_len,
            name_len ? *name_len : -1, reserved, class, class_len, ft );
 
     if (reserved) return ERROR_INVALID_PARAMETER;
 
-    req->hkey = hkey;
-    req->index = index;
-    if ((ret = reg_server_call( REQ_ENUM_KEY )) != ERROR_SUCCESS) return ret;
+    status = NtEnumerateKey( hkey, index, KeyNodeInformation,
+                             buffer, sizeof(buffer), &total_size );
 
-    len = strlenW( req->name ) + 1;
-    cls_len = strlenW( req->class ) + 1;
-    if (len > *name_len) return ERROR_MORE_DATA;
-    if (class_len && (cls_len > *class_len)) return ERROR_MORE_DATA;
-
-    memcpyWtoA( name, req->name, len );
-    *name_len = len - 1;
-    if (class_len)
+    while (status == STATUS_BUFFER_OVERFLOW)
     {
-        if (class) memcpyWtoA( class, req->class, cls_len );
-        *class_len = cls_len - 1;
+        /* retry with a dynamically allocated buffer */
+        if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+        if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+            return ERROR_NOT_ENOUGH_MEMORY;
+        info = (KEY_NODE_INFORMATION *)buf_ptr;
+        status = NtEnumerateKey( hkey, index, KeyNodeInformation,
+                                 buf_ptr, total_size, &total_size );
     }
-    if (ft) RtlSecondsSince1970ToTime( req->modif, ft );
-    return ERROR_SUCCESS;
+
+    if (!status)
+    {
+        DWORD len = WideCharToMultiByte( CP_ACP, 0, info->Name, info->NameLength/sizeof(WCHAR),
+                                         NULL, 0, NULL, NULL );
+        DWORD cls_len = WideCharToMultiByte( CP_ACP, 0, (WCHAR *)(buf_ptr + info->ClassOffset),
+                                             info->ClassLength / sizeof(WCHAR),
+                                             NULL, 0, NULL, NULL );
+
+        if (ft) *ft = info->LastWriteTime;
+
+        if (len >= *name_len || (class_len && (cls_len >= *class_len)))
+            status = STATUS_BUFFER_OVERFLOW;
+        else
+        {
+            *name_len = len;
+            WideCharToMultiByte( CP_ACP, 0, info->Name, info->NameLength/sizeof(WCHAR),
+                                 name, len, NULL, NULL );
+            name[len] = 0;
+            if (class_len)
+            {
+                *class_len = cls_len;
+                if (class)
+                {
+                    WideCharToMultiByte( CP_ACP, 0, (WCHAR *)(buf_ptr + info->ClassOffset),
+                                         info->ClassLength / sizeof(WCHAR),
+                                         class, cls_len, NULL, NULL );
+                    class[cls_len] = 0;
+                }
+            }
+        }
+    }
+
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    return RtlNtStatusToDosError( status );
 }
 
 
@@ -398,9 +456,10 @@
                                LPDWORD values, LPDWORD max_value, LPDWORD max_data,
                                LPDWORD security, FILETIME *modif )
 {
-    DWORD ret;
-    struct query_key_info_request *req = get_req_buffer();
-
+    NTSTATUS status;
+    char buffer[256], *buf_ptr = buffer;
+    KEY_FULL_INFORMATION *info = (KEY_FULL_INFORMATION *)buffer;
+    DWORD total_size;
 
     TRACE( "(0x%x,%p,%ld,%p,%p,%p,%p,%p,%p,%p,%p)\n", hkey, class, class_len ? *class_len : 0,
            reserved, subkeys, max_subkey, values, max_value, max_data, security, modif );
@@ -408,27 +467,48 @@
     if (class && !class_len && !(GetVersion() & 0x80000000 /*NT*/))
         return ERROR_INVALID_PARAMETER;
 
-    req->hkey = hkey;
-    if ((ret = reg_server_call( REQ_QUERY_KEY_INFO )) != ERROR_SUCCESS) return ret;
+    status = NtQueryKey( hkey, KeyFullInformation, buffer, sizeof(buffer), &total_size );
 
     if (class)
     {
-        if (class_len && (strlenW(req->class) + 1 > *class_len))
+        /* retry with a dynamically allocated buffer */
+        while (status == STATUS_BUFFER_OVERFLOW)
         {
-            *class_len = strlenW(req->class);
-            return ERROR_MORE_DATA;
+            if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+            if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+                return ERROR_NOT_ENOUGH_MEMORY;
+            info = (KEY_FULL_INFORMATION *)buf_ptr;
+            status = NtQueryKey( hkey, KeyFullInformation, buf_ptr, total_size, &total_size );
         }
-        strcpyW( class, req->class );
+
+        if (!status)
+        {
+            if (class_len && (info->ClassLength/sizeof(WCHAR) + 1 > *class_len))
+            {
+                status = STATUS_BUFFER_OVERFLOW;
+            }
+            else
+            {
+                memcpy( class, buf_ptr + info->ClassOffset, info->ClassLength );
+                class[info->ClassLength/sizeof(WCHAR)] = 0;
+            }
+        }
     }
-    if (class_len) *class_len = strlenW( req->class );
-    if (subkeys) *subkeys = req->subkeys;
-    if (max_subkey) *max_subkey = req->max_subkey;
-    if (max_class) *max_class = req->max_class;
-    if (values) *values = req->values;
-    if (max_value) *max_value = req->max_value;
-    if (max_data) *max_data = req->max_data;
-    if (modif) RtlSecondsSince1970ToTime( req->modif, modif );
-    return ERROR_SUCCESS;
+
+    if (!status || status == STATUS_BUFFER_OVERFLOW)
+    {
+        if (class_len) *class_len = info->ClassLength / sizeof(WCHAR);
+        if (subkeys) *subkeys = info->SubKeys;
+        if (max_subkey) *max_subkey = info->MaxNameLen;
+        if (max_class) *max_class = info->MaxClassLen;
+        if (values) *values = info->Values;
+        if (max_value) *max_value = info->MaxValueNameLen;
+        if (max_data) *max_data = info->MaxValueDataLen;
+        if (modif) *modif = info->LastWriteTime;
+    }
+
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    return RtlNtStatusToDosError( status );
 }
 
 
@@ -440,9 +520,10 @@
                                LPDWORD values, LPDWORD max_value, LPDWORD max_data,
                                LPDWORD security, FILETIME *modif )
 {
-    DWORD ret;
-    struct query_key_info_request *req = get_req_buffer();
-
+    NTSTATUS status;
+    char buffer[256], *buf_ptr = buffer;
+    KEY_FULL_INFORMATION *info = (KEY_FULL_INFORMATION *)buffer;
+    DWORD total_size;
 
     TRACE( "(0x%x,%p,%ld,%p,%p,%p,%p,%p,%p,%p,%p)\n", hkey, class, class_len ? *class_len : 0,
            reserved, subkeys, max_subkey, values, max_value, max_data, security, modif );
@@ -450,27 +531,55 @@
     if (class && !class_len && !(GetVersion() & 0x80000000 /*NT*/))
         return ERROR_INVALID_PARAMETER;
 
-    req->hkey = hkey;
-    if ((ret = reg_server_call( REQ_QUERY_KEY_INFO )) != ERROR_SUCCESS) return ret;
+    status = NtQueryKey( hkey, KeyFullInformation, buffer, sizeof(buffer), &total_size );
 
-    if (class)
+    if (class || class_len)
     {
-        if (class_len && (strlenW(req->class) + 1 > *class_len))
+        /* retry with a dynamically allocated buffer */
+        while (status == STATUS_BUFFER_OVERFLOW)
         {
-            *class_len = strlenW(req->class);
-            return ERROR_MORE_DATA;
+            if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+            if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+                return ERROR_NOT_ENOUGH_MEMORY;
+            info = (KEY_FULL_INFORMATION *)buf_ptr;
+            status = NtQueryKey( hkey, KeyFullInformation, buf_ptr, total_size, &total_size );
         }
-        lstrcpyWtoA( class, req->class );
+
+        if (!status)
+        {
+            DWORD len = WideCharToMultiByte( CP_ACP, 0,
+                                             (WCHAR *)(buf_ptr + info->ClassOffset),
+                                             info->ClassLength/sizeof(WCHAR),
+                                             NULL, 0, NULL, NULL );
+            if (class_len)
+            {
+                if (len + 1 > *class_len) status = STATUS_BUFFER_OVERFLOW;
+                *class_len = len;
+            }
+            if (class && !status)
+            {
+                WideCharToMultiByte( CP_ACP, 0,
+                                     (WCHAR *)(buf_ptr + info->ClassOffset),
+                                     info->ClassLength/sizeof(WCHAR),
+                                     class, len, NULL, NULL );
+                class[len] = 0;
+            }
+        }
     }
-    if (class_len) *class_len = strlenW( req->class );
-    if (subkeys) *subkeys = req->subkeys;
-    if (max_subkey) *max_subkey = req->max_subkey;
-    if (max_class) *max_class = req->max_class;
-    if (values) *values = req->values;
-    if (max_value) *max_value = req->max_value;
-    if (max_data) *max_data = req->max_data;
-    if (modif) RtlSecondsSince1970ToTime( req->modif, modif );
-    return ERROR_SUCCESS;
+
+    if (!status || status == STATUS_BUFFER_OVERFLOW)
+    {
+        if (subkeys) *subkeys = info->SubKeys;
+        if (max_subkey) *max_subkey = info->MaxNameLen;
+        if (max_class) *max_class = info->MaxClassLen;
+        if (values) *values = info->Values;
+        if (max_value) *max_value = info->MaxValueNameLen;
+        if (max_data) *max_data = info->MaxValueDataLen;
+        if (modif) *modif = info->LastWriteTime;
+    }
+
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    return RtlNtStatusToDosError( status );
 }
 
 
@@ -689,7 +798,7 @@
     NTSTATUS status;
     UNICODE_STRING name_str;
     DWORD total_size;
-    char buffer[256];
+    char buffer[256], *buf_ptr = buffer;
     KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
     static const int info_size = sizeof(*info) - sizeof(info->Data);
 
@@ -709,16 +818,15 @@
 
     if (data)
     {
-        char *buf_ptr = buffer;
         /* retry with a dynamically allocated buffer */
         while (status == STATUS_BUFFER_OVERFLOW && total_size - info_size <= *count)
         {
             if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
             if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
-                status = STATUS_NO_MEMORY;
-            else
-                status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
-                                          buf_ptr, total_size, &total_size );
+                return ERROR_NOT_ENOUGH_MEMORY;
+            info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
+            status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
+                                      buf_ptr, total_size, &total_size );
         }
 
         if (!status)
@@ -732,13 +840,14 @@
                 if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
             }
         }
-        if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+        else if (status != STATUS_BUFFER_OVERFLOW) goto done;
     }
 
     if (type) *type = info->Type;
     if (count) *count = total_size - info_size;
 
  done:
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
     return RtlNtStatusToDosError(status);
 }
 
@@ -756,7 +865,7 @@
     ANSI_STRING nameA;
     UNICODE_STRING nameW;
     DWORD total_size;
-    char buffer[256];
+    char buffer[256], *buf_ptr = buffer;
     KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
     static const int info_size = sizeof(*info) - sizeof(info->Data);
 
@@ -767,7 +876,8 @@
 
     RtlInitAnsiString( &nameA, name );
     /* FIXME: should use Unicode buffer in TEB */
-    if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE ))) goto done;
+    if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
+        return RtlNtStatusToDosError(status);
 
     status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
                               buffer, sizeof(buffer), &total_size );
@@ -777,16 +887,18 @@
      * because we need to compute the length of the ASCII string. */
     if (data || is_string(info->Type))
     {
-        char *buf_ptr = buffer;
         /* retry with a dynamically allocated buffer */
         while (status == STATUS_BUFFER_OVERFLOW)
         {
             if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
             if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+            {
                 status = STATUS_NO_MEMORY;
-            else
-                status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
-                                          buf_ptr, total_size, &total_size );
+                goto done;
+            }
+            info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
+            status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
+                                      buf_ptr, total_size, &total_size );
         }
 
         if (!status)
@@ -812,23 +924,16 @@
                 total_size = len + info_size;
             }
             else if (data) memcpy( data, buf_ptr + info_size, total_size - info_size );
-
-            /* if the type is REG_SZ and data is not 0-terminated
-             * and there is enough space in the buffer NT appends a \0 */
-            if (total_size - info_size <= *count-sizeof(WCHAR) && is_string(info->Type))
-            {
-                WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
-                if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
-            }
         }
-        if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+        else if (status != STATUS_BUFFER_OVERFLOW) goto done;
     }
 
     if (type) *type = info->Type;
     if (count) *count = total_size - info_size;
-    RtlFreeUnicodeString( &nameW );
 
  done:
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    RtlFreeUnicodeString( &nameW );
     return RtlNtStatusToDosError(status);
 }