Commit 454355ec authored by Alexandre Julliard's avatar Alexandre Julliard

Convert NtQueryKey and NtEnumerateKey to the new request mechanism.

Fixed a few bugs.
parent 1871e660
...@@ -821,17 +821,11 @@ NTSTATUS WINAPI NtDeleteKey(HANDLE); ...@@ -821,17 +821,11 @@ NTSTATUS WINAPI NtDeleteKey(HANDLE);
NTSTATUS WINAPI NtDeleteValueKey(HANDLE,const UNICODE_STRING*); NTSTATUS WINAPI NtDeleteValueKey(HANDLE,const UNICODE_STRING*);
NTSTATUS WINAPI NtOpenKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSTATUS WINAPI NtOpenKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*);
NTSTATUS WINAPI NtSetValueKey(HANDLE,const UNICODE_STRING*,ULONG,ULONG,const void*,ULONG); NTSTATUS WINAPI NtSetValueKey(HANDLE,const UNICODE_STRING*,ULONG,ULONG,const void*,ULONG);
NTSTATUS WINAPI NtEnumerateKey(HANDLE,ULONG,KEY_INFORMATION_CLASS,void*,DWORD,DWORD*);
NTSTATUS WINAPI NtQueryValueKey(HANDLE,const UNICODE_STRING*,KEY_VALUE_INFORMATION_CLASS, NTSTATUS WINAPI NtQueryValueKey(HANDLE,const UNICODE_STRING*,KEY_VALUE_INFORMATION_CLASS,
void*,DWORD,DWORD*); void*,DWORD,DWORD*);
NTSTATUS WINAPI NtEnumerateKey(
HANDLE KeyHandle,
ULONG Index,
KEY_INFORMATION_CLASS KeyInformationClass,
PVOID KeyInformation,
ULONG Length,
PULONG ResultLength);
NTSTATUS WINAPI NtQueryKey( NTSTATUS WINAPI NtQueryKey(
HANDLE KeyHandle, HANDLE KeyHandle,
......
...@@ -1046,18 +1046,8 @@ struct enum_key_request ...@@ -1046,18 +1046,8 @@ struct enum_key_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int hkey; /* handle to registry key */ IN int hkey; /* handle to registry key */
IN int index; /* index of subkey */ IN int index; /* index of subkey (or -1 for current key) */
OUT time_t modif; /* last modification time */ IN int full; /* return the full info? */
OUT path_t name; /* subkey name */
OUT WCHAR class[1]; /* class name */
};
/* Query information about a registry key */
struct query_key_info_request
{
REQUEST_HEADER; /* request header */
IN int hkey; /* handle to registry key */
OUT int subkeys; /* number of subkeys */ OUT int subkeys; /* number of subkeys */
OUT int max_subkey; /* longest subkey name */ OUT int max_subkey; /* longest subkey name */
OUT int max_class; /* longest class name */ OUT int max_class; /* longest class name */
...@@ -1065,8 +1055,8 @@ struct query_key_info_request ...@@ -1065,8 +1055,8 @@ struct query_key_info_request
OUT int max_value; /* longest value name */ OUT int max_value; /* longest value name */
OUT int max_data; /* longest value data */ OUT int max_data; /* longest value data */
OUT time_t modif; /* last modification time */ OUT time_t modif; /* last modification time */
OUT path_t name; /* key name */ OUT VARARG(name,unicode_len_str); /* key name */
OUT WCHAR class[1]; /* class name */ OUT VARARG(class,unicode_str); /* class name */
}; };
...@@ -1429,7 +1419,6 @@ enum request ...@@ -1429,7 +1419,6 @@ enum request
REQ_OPEN_KEY, REQ_OPEN_KEY,
REQ_DELETE_KEY, REQ_DELETE_KEY,
REQ_ENUM_KEY, REQ_ENUM_KEY,
REQ_QUERY_KEY_INFO,
REQ_SET_KEY_VALUE, REQ_SET_KEY_VALUE,
REQ_GET_KEY_VALUE, REQ_GET_KEY_VALUE,
REQ_ENUM_KEY_VALUE, REQ_ENUM_KEY_VALUE,
...@@ -1545,7 +1534,6 @@ union generic_request ...@@ -1545,7 +1534,6 @@ union generic_request
struct open_key_request open_key; struct open_key_request open_key;
struct delete_key_request delete_key; struct delete_key_request delete_key;
struct enum_key_request enum_key; struct enum_key_request enum_key;
struct query_key_info_request query_key_info;
struct set_key_value_request set_key_value; struct set_key_value_request set_key_value;
struct get_key_value_request get_key_value; struct get_key_value_request get_key_value;
struct enum_key_value_request enum_key_value; struct enum_key_value_request enum_key_value;
...@@ -1574,7 +1562,7 @@ union generic_request ...@@ -1574,7 +1562,7 @@ union generic_request
struct set_serial_info_request set_serial_info; struct set_serial_info_request set_serial_info;
}; };
#define SERVER_PROTOCOL_VERSION 24 #define SERVER_PROTOCOL_VERSION 25
/* ### make_requests end ### */ /* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */ /* Everything above this line is generated automatically by tools/make_requests */
...@@ -1648,13 +1636,13 @@ static inline void server_strcpyAtoW( WCHAR *dst, const char *src ) ...@@ -1648,13 +1636,13 @@ static inline void server_strcpyAtoW( WCHAR *dst, const char *src )
} }
/* get a pointer to the variable part of the request */ /* get a pointer to the variable part of the request */
inline static void *server_data_ptr( void *req ) inline static void *server_data_ptr( const void *req )
{ {
return (union generic_request *)req + 1; return (union generic_request *)req + 1;
} }
/* get the size of the variable part of the request */ /* get the size of the variable part of the request */
inline static size_t server_data_size( void *req ) inline static size_t server_data_size( const void *req )
{ {
return ((struct request_header *)req)->var_size; return ((struct request_header *)req)->var_size;
} }
......
...@@ -560,57 +560,80 @@ static struct key *create_key( struct key *key, WCHAR *name, WCHAR *class, ...@@ -560,57 +560,80 @@ static struct key *create_key( struct key *key, WCHAR *name, WCHAR *class,
return key; return key;
} }
/* find a subkey of a given key by its index */ /* query information about a key or a subkey */
static void enum_key( struct key *parent, int index, WCHAR *name, WCHAR *class, time_t *modif ) static size_t enum_key( struct key *key, int index, struct enum_key_request *req )
{ {
struct key *key; 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);
if ((index < 0) || (index > parent->last_subkey)) set_error( STATUS_NO_MORE_ENTRIES ); if (index != -1) /* -1 means use the specified key directly */
{
if ((index < 0) || (index > key->last_subkey))
{
set_error( STATUS_NO_MORE_ENTRIES );
return 0;
}
key = key->subkeys[index];
}
if (req->full)
{
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;
}
else else
{ {
key = parent->subkeys[index]; req->max_subkey = 0;
*modif = key->modif; req->max_class = 0;
strcpyW( name, key->name ); req->max_value = 0;
if (key->class) strcpyW( class, key->class ); /* FIXME: length */ req->max_data = 0;
else *class = 0;
if (debug_level > 1) dump_operation( key, NULL, "Enum" );
} }
} req->subkeys = key->last_subkey + 1;
req->values = key->last_value + 1;
req->modif = key->modif;
/* query information about a key */ namelen = strlenW(key->name) * sizeof(WCHAR);
static void query_key( struct key *key, struct query_key_info_request *req ) classlen = key->class ? strlenW(key->class) * sizeof(WCHAR) : 0;
{
int i, len;
int max_subkey = 0, max_class = 0;
int max_value = 0, max_data = 0;
for (i = 0; i <= key->last_subkey; i++) len = namelen + classlen + sizeof(WCHAR);
if (len > get_req_data_size(req))
{ {
struct key *subkey = key->subkeys[i]; len = get_req_data_size(req);
len = strlenW( subkey->name ); if (len < sizeof(WCHAR)) return 0;
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++)
*data++ = namelen;
len -= sizeof(WCHAR);
if (len > namelen)
{ {
len = strlenW( key->values[i].name ); memcpy( data, key->name, namelen );
if (len > max_value) max_value = len; memcpy( (char *)data + namelen, key->class, min(classlen,len-namelen) );
len = key->values[i].len; }
if (len > max_data) max_data = len; else memcpy( data, key->name, len );
}
req->subkeys = key->last_subkey + 1; if (debug_level > 1) dump_operation( key, NULL, "Enum" );
req->max_subkey = max_subkey; return len + sizeof(WCHAR);
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" );
} }
/* delete a key and its values */ /* delete a key and its values */
...@@ -1537,31 +1560,29 @@ DECL_HANDLER(create_key) ...@@ -1537,31 +1560,29 @@ DECL_HANDLER(create_key)
if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS; /* FIXME: needs general solution */ if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS; /* FIXME: needs general solution */
req->hkey = -1; req->hkey = -1;
if (!(name = copy_req_path( req, &len ))) return;
if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ ))) 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 );
{ }
key = create_key( parent, name, NULL, req->options, req->modif, &req->created ); else
} {
else const WCHAR *class_ptr = (WCHAR *)((char *)get_req_data(req) + len);
{
const WCHAR *class_ptr = (WCHAR *)((char *)get_req_data(req) + len);
if ((class = req_strdupW( req, class_ptr, get_req_data_size(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)
{ {
req->hkey = alloc_handle( current->process, key, access, 0 ); key = create_key( parent, name, class, req->options,
release_object( key ); req->modif, &req->created );
free( class );
} }
} }
if (key)
{
req->hkey = alloc_handle( current->process, key, access, 0 );
release_object( key );
}
release_object( parent ); release_object( parent );
} }
} }
...@@ -1602,26 +1623,15 @@ DECL_HANDLER(delete_key) ...@@ -1602,26 +1623,15 @@ DECL_HANDLER(delete_key)
DECL_HANDLER(enum_key) DECL_HANDLER(enum_key)
{ {
struct key *key; struct key *key;
size_t len = 0;
req->name[0] = req->class[0] = 0; if ((key = get_hkey_obj( req->hkey,
if ((key = get_hkey_obj( req->hkey, KEY_ENUMERATE_SUB_KEYS ))) req->index == -1 ? KEY_QUERY_VALUE : KEY_ENUMERATE_SUB_KEYS )))
{
enum_key( key, req->index, req->name, req->class, &req->modif );
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 ); len = enum_key( key, req->index, req );
release_object( key ); release_object( key );
} }
set_req_data_size( req, len );
} }
/* set a value of a registry key */ /* set a value of a registry key */
...@@ -1631,15 +1641,13 @@ DECL_HANDLER(set_key_value) ...@@ -1631,15 +1641,13 @@ DECL_HANDLER(set_key_value)
WCHAR *name; WCHAR *name;
size_t len; size_t len;
if (!(name = copy_req_path( req, &len ))) return;
if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE ))) 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 ); release_object( key );
} }
} }
...@@ -1649,19 +1657,17 @@ DECL_HANDLER(get_key_value) ...@@ -1649,19 +1657,17 @@ DECL_HANDLER(get_key_value)
{ {
struct key *key; struct key *key;
WCHAR *name; WCHAR *name;
size_t len; size_t len = 0, tmp;
req->len = 0; req->len = 0;
if (!(name = copy_req_path( req, &tmp ))) return;
if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE ))) 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) );
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 );
}
release_object( key ); release_object( key );
} }
set_req_data_size( req, len );
} }
/* enumerate the value of a registry key */ /* enumerate the value of a registry key */
......
...@@ -176,7 +176,6 @@ DECL_HANDLER(create_key); ...@@ -176,7 +176,6 @@ DECL_HANDLER(create_key);
DECL_HANDLER(open_key); DECL_HANDLER(open_key);
DECL_HANDLER(delete_key); DECL_HANDLER(delete_key);
DECL_HANDLER(enum_key); DECL_HANDLER(enum_key);
DECL_HANDLER(query_key_info);
DECL_HANDLER(set_key_value); DECL_HANDLER(set_key_value);
DECL_HANDLER(get_key_value); DECL_HANDLER(get_key_value);
DECL_HANDLER(enum_key_value); DECL_HANDLER(enum_key_value);
...@@ -291,7 +290,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -291,7 +290,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_open_key, (req_handler)req_open_key,
(req_handler)req_delete_key, (req_handler)req_delete_key,
(req_handler)req_enum_key, (req_handler)req_enum_key,
(req_handler)req_query_key_info,
(req_handler)req_set_key_value, (req_handler)req_set_key_value,
(req_handler)req_get_key_value, (req_handler)req_get_key_value,
(req_handler)req_enum_key_value, (req_handler)req_enum_key_value,
......
...@@ -94,7 +94,7 @@ static void dump_exc_record( const EXCEPTION_RECORD *rec ) ...@@ -94,7 +94,7 @@ static void dump_exc_record( const EXCEPTION_RECORD *rec )
fprintf( stderr, "{code=%lx,flags=%lx,rec=%p,addr=%p,params={", fprintf( stderr, "{code=%lx,flags=%lx,rec=%p,addr=%p,params={",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionRecord, rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionRecord,
rec->ExceptionAddress ); rec->ExceptionAddress );
for (i = 0; i < rec->NumberParameters; i++) for (i = 0; i < min(rec->NumberParameters,EXCEPTION_MAXIMUM_PARAMETERS); i++)
{ {
if (i) fputc( ',', stderr ); if (i) fputc( ',', stderr );
fprintf( stderr, "%lx", rec->ExceptionInformation[i] ); fprintf( stderr, "%lx", rec->ExceptionInformation[i] );
...@@ -156,12 +156,12 @@ static size_t dump_varargs_string( const void *req ) ...@@ -156,12 +156,12 @@ static size_t dump_varargs_string( const void *req )
static size_t dump_varargs_unicode_len_str( const void *req ) static size_t dump_varargs_unicode_len_str( const void *req )
{ {
const WCHAR *str = get_data(req); const WCHAR *str = get_data(req);
WCHAR len = *str++; int len = *str++ + sizeof(WCHAR);
len = min( len, get_size(req) ); len = min( len, get_size(req) );
fprintf( stderr, "L\"" ); fprintf( stderr, "L\"" );
dump_strW( str, len / sizeof(WCHAR), stderr, "\"\"" ); if (len >= sizeof(WCHAR)) dump_strW( str, (len / sizeof(WCHAR)) - 1, stderr, "\"\"" );
fputc( '\"', stderr ); fputc( '\"', stderr );
return len + sizeof(WCHAR); return len;
} }
static size_t dump_varargs_unicode_str( const void *req ) static size_t dump_varargs_unicode_str( const void *req )
...@@ -1184,26 +1184,12 @@ static void dump_delete_key_request( const struct delete_key_request *req ) ...@@ -1184,26 +1184,12 @@ static void dump_delete_key_request( const struct delete_key_request *req )
static void dump_enum_key_request( const struct enum_key_request *req ) static void dump_enum_key_request( const struct enum_key_request *req )
{ {
fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " hkey=%d,", req->hkey );
fprintf( stderr, " index=%d", req->index ); fprintf( stderr, " index=%d,", req->index );
fprintf( stderr, " full=%d", req->full );
} }
static void dump_enum_key_reply( const struct enum_key_request *req ) static void dump_enum_key_reply( const struct enum_key_request *req )
{ {
fprintf( stderr, " modif=%ld,", req->modif );
fprintf( stderr, " name=" );
dump_path_t( req, &req->name );
fprintf( stderr, "," );
fprintf( stderr, " class=" );
dump_unicode_string( req, req->class );
}
static void dump_query_key_info_request( const struct query_key_info_request *req )
{
fprintf( stderr, " hkey=%d", req->hkey );
}
static void dump_query_key_info_reply( const struct query_key_info_request *req )
{
fprintf( stderr, " subkeys=%d,", req->subkeys ); fprintf( stderr, " subkeys=%d,", req->subkeys );
fprintf( stderr, " max_subkey=%d,", req->max_subkey ); fprintf( stderr, " max_subkey=%d,", req->max_subkey );
fprintf( stderr, " max_class=%d,", req->max_class ); fprintf( stderr, " max_class=%d,", req->max_class );
...@@ -1212,10 +1198,10 @@ static void dump_query_key_info_reply( const struct query_key_info_request *req ...@@ -1212,10 +1198,10 @@ static void dump_query_key_info_reply( const struct query_key_info_request *req
fprintf( stderr, " max_data=%d,", req->max_data ); fprintf( stderr, " max_data=%d,", req->max_data );
fprintf( stderr, " modif=%ld,", req->modif ); fprintf( stderr, " modif=%ld,", req->modif );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
dump_path_t( req, &req->name ); cur_pos += dump_varargs_unicode_len_str( req );
fprintf( stderr, "," ); fputc( ',', stderr );
fprintf( stderr, " class=" ); fprintf( stderr, " class=" );
dump_unicode_string( req, req->class ); cur_pos += dump_varargs_unicode_str( req );
} }
static void dump_set_key_value_request( const struct set_key_value_request *req ) static void dump_set_key_value_request( const struct set_key_value_request *req )
...@@ -1574,7 +1560,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -1574,7 +1560,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_key_request, (dump_func)dump_open_key_request,
(dump_func)dump_delete_key_request, (dump_func)dump_delete_key_request,
(dump_func)dump_enum_key_request, (dump_func)dump_enum_key_request,
(dump_func)dump_query_key_info_request,
(dump_func)dump_set_key_value_request, (dump_func)dump_set_key_value_request,
(dump_func)dump_get_key_value_request, (dump_func)dump_get_key_value_request,
(dump_func)dump_enum_key_value_request, (dump_func)dump_enum_key_value_request,
...@@ -1686,7 +1671,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -1686,7 +1671,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_key_reply, (dump_func)dump_open_key_reply,
(dump_func)0, (dump_func)0,
(dump_func)dump_enum_key_reply, (dump_func)dump_enum_key_reply,
(dump_func)dump_query_key_info_reply,
(dump_func)0, (dump_func)0,
(dump_func)dump_get_key_value_reply, (dump_func)dump_get_key_value_reply,
(dump_func)dump_enum_key_value_reply, (dump_func)dump_enum_key_value_reply,
...@@ -1798,7 +1782,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -1798,7 +1782,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_key", "open_key",
"delete_key", "delete_key",
"enum_key", "enum_key",
"query_key_info",
"set_key_value", "set_key_value",
"get_key_value", "get_key_value",
"enum_key_value", "enum_key_value",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment