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

diff --git a/server/registry.c b/server/registry.c
index 8d355c5..944d731 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -560,57 +560,80 @@
     return key;
 }
 
-/* find a subkey of a given key by its index */
-static void enum_key( struct key *parent, int index, WCHAR *name, WCHAR *class, time_t *modif )
+/* query information about a key or a subkey */
+static size_t enum_key( struct key *key, int index, struct enum_key_request *req )
 {
-    struct key *key;
-
-    if ((index < 0) || (index > parent->last_subkey)) set_error( STATUS_NO_MORE_ENTRIES );
-    else
-    {
-        key = parent->subkeys[index];
-        *modif = key->modif;
-        strcpyW( name, key->name );
-        if (key->class) strcpyW( class, key->class );  /* FIXME: length */
-        else *class = 0;
-        if (debug_level > 1) dump_operation( key, NULL, "Enum" );
-    }
-}
-
-/* query information about a key */
-static void query_key( struct key *key, struct query_key_info_request *req )
-{
-    int i, len;
+    int i;
+    size_t len, namelen, classlen;
     int max_subkey = 0, max_class = 0;
     int max_value = 0, max_data = 0;
+    WCHAR *data = get_req_data(req);
 
-    for (i = 0; i <= key->last_subkey; i++)
+    if (index != -1)  /* -1 means use the specified key directly */
     {
-        struct key *subkey = key->subkeys[i];
-        len = strlenW( subkey->name );
-        if (len > max_subkey) max_subkey = len;
-        if (!subkey->class) continue;
-        len = strlenW( subkey->class );
-        if (len > max_class) max_class = len;
+        if ((index < 0) || (index > key->last_subkey))
+        {
+            set_error( STATUS_NO_MORE_ENTRIES );
+            return 0;
+        }
+        key = key->subkeys[index];
     }
-    for (i = 0; i <= key->last_value; i++)
+
+    if (req->full)
     {
-        len = strlenW( key->values[i].name );
-        if (len > max_value) max_value = len;
-        len = key->values[i].len;
-        if (len > max_data) max_data = len;
+        for (i = 0; i <= key->last_subkey; i++)
+        {
+            struct key *subkey = key->subkeys[i];
+            len = strlenW( subkey->name );
+            if (len > max_subkey) max_subkey = len;
+            if (!subkey->class) continue;
+            len = strlenW( subkey->class );
+            if (len > max_class) max_class = len;
+        }
+        for (i = 0; i <= key->last_value; i++)
+        {
+            len = strlenW( key->values[i].name );
+            if (len > max_value) max_value = len;
+            len = key->values[i].len;
+            if (len > max_data) max_data = len;
+        }
+        req->max_subkey = max_subkey;
+        req->max_class  = max_class;
+        req->max_value  = max_value;
+        req->max_data   = max_data;
     }
-    req->subkeys    = key->last_subkey + 1;
-    req->max_subkey = max_subkey;
-    req->max_class  = max_class;
-    req->values     = key->last_value + 1;
-    req->max_value  = max_value;
-    req->max_data   = max_data;
-    req->modif      = key->modif;
-    strcpyW( req->name, key->name);
-    if (key->class) strcpyW( req->class, key->class );  /* FIXME: length */
-    else req->class[0] = 0;
-    if (debug_level > 1) dump_operation( key, NULL, "Query" );
+    else
+    {
+        req->max_subkey = 0;
+        req->max_class  = 0;
+        req->max_value  = 0;
+        req->max_data   = 0;
+    }
+    req->subkeys = key->last_subkey + 1;
+    req->values  = key->last_value + 1;
+    req->modif   = key->modif;
+
+    namelen = strlenW(key->name) * sizeof(WCHAR);
+    classlen = key->class ? strlenW(key->class) * sizeof(WCHAR) : 0;
+
+    len = namelen + classlen + sizeof(WCHAR);
+    if (len > get_req_data_size(req))
+    {
+        len = get_req_data_size(req);
+        if (len < sizeof(WCHAR)) return 0;
+    }
+
+    *data++ = namelen;
+    len -= sizeof(WCHAR);
+    if (len > namelen)
+    {
+        memcpy( data, key->name, namelen );
+        memcpy( (char *)data + namelen, key->class, min(classlen,len-namelen) );
+    }
+    else memcpy( data, key->name, len );
+
+    if (debug_level > 1) dump_operation( key, NULL, "Enum" );
+    return len + sizeof(WCHAR);
 }
 
 /* delete a key and its values */
@@ -1537,31 +1560,29 @@
 
     if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS;  /* FIXME: needs general solution */
     req->hkey = -1;
+    if (!(name = copy_req_path( req, &len ))) return;
     if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ )))
     {
-        if ((name = copy_req_path( req, &len )))
+        if (len == get_req_data_size(req))  /* no class specified */
         {
-            if (len == get_req_data_size(req))  /* no class specified */
-            {
-                key = create_key( parent, name, NULL, req->options, req->modif, &req->created );
-            }
-            else
-            {
-                const WCHAR *class_ptr = (WCHAR *)((char *)get_req_data(req) + len);
+            key = create_key( parent, name, NULL, req->options, req->modif, &req->created );
+        }
+        else
+        {
+            const WCHAR *class_ptr = (WCHAR *)((char *)get_req_data(req) + len);
 
-                if ((class = req_strdupW( req, class_ptr, get_req_data_size(req) - len )))
-                {
-                    key = create_key( parent, name, class, req->options,
-                                      req->modif, &req->created );
-                    free( class );
-                }
-            }
-            if (key)
+            if ((class = req_strdupW( req, class_ptr, get_req_data_size(req) - len )))
             {
-                req->hkey = alloc_handle( current->process, key, access, 0 );
-                release_object( key );
+                key = create_key( parent, name, class, req->options,
+                                  req->modif, &req->created );
+                free( class );
             }
         }
+        if (key)
+        {
+            req->hkey = alloc_handle( current->process, key, access, 0 );
+            release_object( key );
+        }
         release_object( parent );
     }
 }
@@ -1602,26 +1623,15 @@
 DECL_HANDLER(enum_key)
 {
     struct key *key;
+    size_t len = 0;
 
-    req->name[0] = req->class[0] = 0;
-    if ((key = get_hkey_obj( req->hkey, KEY_ENUMERATE_SUB_KEYS )))
+    if ((key = get_hkey_obj( req->hkey,
+                             req->index == -1 ? KEY_QUERY_VALUE : KEY_ENUMERATE_SUB_KEYS )))
     {
-        enum_key( key, req->index, req->name, req->class, &req->modif );
+        len = enum_key( key, req->index, req );
         release_object( key );
     }
-}
-
-/* query information about a registry key */
-DECL_HANDLER(query_key_info)
-{
-    struct key *key;
-
-    req->name[0] = req->class[0] = 0;
-    if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE )))
-    {
-        query_key( key, req );
-        release_object( key );
-    }
+    set_req_data_size( req, len );
 }
 
 /* set a value of a registry key */
@@ -1631,15 +1641,13 @@
     WCHAR *name;
     size_t len;
 
+    if (!(name = copy_req_path( req, &len ))) return;
     if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE )))
     {
-        if ((name = copy_req_path( req, &len )))
-        {
-            size_t datalen = get_req_data_size(req) - len;
-            const char *data = (char *)get_req_data(req) + len;
+        size_t datalen = get_req_data_size(req) - len;
+        const char *data = (char *)get_req_data(req) + len;
 
-            set_value( key, name, req->type, req->total, req->offset, datalen, data );
-        }
+        set_value( key, name, req->type, req->total, req->offset, datalen, data );
         release_object( key );
     }
 }
@@ -1649,19 +1657,17 @@
 {
     struct key *key;
     WCHAR *name;
-    size_t len;
+    size_t len = 0, tmp;
 
     req->len = 0;
+    if (!(name = copy_req_path( req, &tmp ))) return;
     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE )))
     {
-        if ((name = copy_req_path( req, &len )))
-        {
-            len = get_value( key, name, req->offset, get_req_data_size(req),
-                             &req->type, &req->len, get_req_data(req) );
-            set_req_data_size( req, len );
-        }
+        len = get_value( key, name, req->offset, get_req_data_size(req),
+                         &req->type, &req->len, get_req_data(req) );
         release_object( key );
     }
+    set_req_data_size( req, len );
 }
 
 /* enumerate the value of a registry key */