server: Pass full object attributes in the create_key request.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c4843d4a45
commit
d01deff9cf
@ -56,6 +56,8 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
|
|||||||
PULONG dispos )
|
PULONG dispos )
|
||||||
{
|
{
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
|
data_size_t len;
|
||||||
|
struct object_attributes *objattr;
|
||||||
|
|
||||||
if (!retkey || !attr) return STATUS_ACCESS_VIOLATION;
|
if (!retkey || !attr) return STATUS_ACCESS_VIOLATION;
|
||||||
if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER;
|
if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER;
|
||||||
@ -64,14 +66,13 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
|
|||||||
TRACE( "(%p,%s,%s,%x,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
|
TRACE( "(%p,%s,%s,%x,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
|
||||||
debugstr_us(class), options, access, retkey );
|
debugstr_us(class), options, access, retkey );
|
||||||
|
|
||||||
|
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
|
||||||
|
|
||||||
SERVER_START_REQ( create_key )
|
SERVER_START_REQ( create_key )
|
||||||
{
|
{
|
||||||
req->parent = wine_server_obj_handle( attr->RootDirectory );
|
|
||||||
req->access = access;
|
req->access = access;
|
||||||
req->attributes = attr->Attributes;
|
|
||||||
req->options = options;
|
req->options = options;
|
||||||
req->namelen = attr->ObjectName->Length;
|
wine_server_add_data( req, objattr, len );
|
||||||
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
|
|
||||||
if (class) wine_server_add_data( req, class->Buffer, class->Length );
|
if (class) wine_server_add_data( req, class->Buffer, class->Length );
|
||||||
if (!(ret = wine_server_call( req )))
|
if (!(ret = wine_server_call( req )))
|
||||||
{
|
{
|
||||||
@ -80,7 +81,9 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
TRACE("<- %p\n", *retkey);
|
TRACE("<- %p\n", *retkey);
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2393,13 +2393,11 @@ struct write_process_memory_reply
|
|||||||
struct create_key_request
|
struct create_key_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
obj_handle_t parent;
|
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
unsigned int attributes;
|
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
data_size_t namelen;
|
/* VARARG(objattr,object_attributes); */
|
||||||
/* VARARG(name,unicode_str,namelen); */
|
|
||||||
/* VARARG(class,unicode_str); */
|
/* VARARG(class,unicode_str); */
|
||||||
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
struct create_key_reply
|
struct create_key_reply
|
||||||
{
|
{
|
||||||
@ -6159,6 +6157,6 @@ union generic_reply
|
|||||||
struct terminate_job_reply terminate_job_reply;
|
struct terminate_job_reply terminate_job_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 497
|
#define SERVER_PROTOCOL_VERSION 498
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
@ -1820,12 +1820,9 @@ enum char_info_mode
|
|||||||
|
|
||||||
/* Create a registry key */
|
/* Create a registry key */
|
||||||
@REQ(create_key)
|
@REQ(create_key)
|
||||||
obj_handle_t parent; /* handle to the parent key */
|
|
||||||
unsigned int access; /* desired access rights */
|
unsigned int access; /* desired access rights */
|
||||||
unsigned int attributes; /* object attributes */
|
|
||||||
unsigned int options; /* creation options */
|
unsigned int options; /* creation options */
|
||||||
data_size_t namelen; /* length of key name in bytes */
|
VARARG(objattr,object_attributes); /* object attributes */
|
||||||
VARARG(name,unicode_str,namelen); /* key name */
|
|
||||||
VARARG(class,unicode_str); /* class name */
|
VARARG(class,unicode_str); /* class name */
|
||||||
@REPLY
|
@REPLY
|
||||||
obj_handle_t hkey; /* handle to the created key */
|
obj_handle_t hkey; /* handle to the created key */
|
||||||
|
@ -759,7 +759,8 @@ static struct key *open_key( struct key *key, const struct unicode_str *name, un
|
|||||||
/* create a subkey */
|
/* create a subkey */
|
||||||
static struct key *create_key( struct key *key, const struct unicode_str *name,
|
static struct key *create_key( struct key *key, const struct unicode_str *name,
|
||||||
const struct unicode_str *class, unsigned int options,
|
const struct unicode_str *class, unsigned int options,
|
||||||
unsigned int access, unsigned int attributes, int *created )
|
unsigned int access, unsigned int attributes,
|
||||||
|
const struct security_descriptor *sd, int *created )
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
struct unicode_str token, next;
|
struct unicode_str token, next;
|
||||||
@ -807,6 +808,9 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
|
|||||||
if (options & REG_OPTION_VOLATILE) key->flags |= KEY_VOLATILE;
|
if (options & REG_OPTION_VOLATILE) key->flags |= KEY_VOLATILE;
|
||||||
else key->flags |= KEY_DIRTY;
|
else key->flags |= KEY_DIRTY;
|
||||||
|
|
||||||
|
if (sd) default_set_sd( &key->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
|
||||||
|
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
|
||||||
|
|
||||||
if (debug_level > 1) dump_operation( key, NULL, "Create" );
|
if (debug_level > 1) dump_operation( key, NULL, "Create" );
|
||||||
if (class && class->len)
|
if (class && class->len)
|
||||||
{
|
{
|
||||||
@ -2021,33 +2025,30 @@ DECL_HANDLER(create_key)
|
|||||||
struct key *key = NULL, *parent;
|
struct key *key = NULL, *parent;
|
||||||
struct unicode_str name, class;
|
struct unicode_str name, class;
|
||||||
unsigned int access = req->access;
|
unsigned int access = req->access;
|
||||||
|
const struct security_descriptor *sd;
|
||||||
|
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
|
||||||
|
|
||||||
|
if (!objattr) return;
|
||||||
|
|
||||||
if (!is_wow64_thread( current )) access = (access & ~KEY_WOW64_32KEY) | KEY_WOW64_64KEY;
|
if (!is_wow64_thread( current )) access = (access & ~KEY_WOW64_32KEY) | KEY_WOW64_64KEY;
|
||||||
|
|
||||||
reply->hkey = 0;
|
class.str = get_req_data_after_objattr( objattr, &class.len );
|
||||||
|
class.len = (class.len / sizeof(WCHAR)) * sizeof(WCHAR);
|
||||||
|
|
||||||
if (req->namelen > get_req_data_size())
|
if (!objattr->rootdir && name.len >= sizeof(root_name) &&
|
||||||
|
!memicmpW( name.str, root_name, sizeof(root_name)/sizeof(WCHAR) ))
|
||||||
{
|
{
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
name.str += sizeof(root_name)/sizeof(WCHAR);
|
||||||
return;
|
name.len -= sizeof(root_name);
|
||||||
}
|
}
|
||||||
class.str = (const WCHAR *)get_req_data() + req->namelen / sizeof(WCHAR);
|
|
||||||
class.len = ((get_req_data_size() - req->namelen) / sizeof(WCHAR)) * sizeof(WCHAR);
|
|
||||||
get_req_path( &name, !req->parent );
|
|
||||||
if (name.str > class.str)
|
|
||||||
{
|
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
name.len = (class.str - name.str) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
/* NOTE: no access rights are required from the parent handle to create a key */
|
/* NOTE: no access rights are required from the parent handle to create a key */
|
||||||
if ((parent = get_parent_hkey_obj( req->parent )))
|
if ((parent = get_parent_hkey_obj( objattr->rootdir )))
|
||||||
{
|
{
|
||||||
if ((key = create_key( parent, &name, &class, req->options, access,
|
if ((key = create_key( parent, &name, &class, req->options, access,
|
||||||
req->attributes, &reply->created )))
|
objattr->attributes, sd, &reply->created )))
|
||||||
{
|
{
|
||||||
reply->hkey = alloc_handle( current->process, key, access, req->attributes );
|
reply->hkey = alloc_handle( current->process, key, access, objattr->attributes );
|
||||||
release_object( key );
|
release_object( key );
|
||||||
}
|
}
|
||||||
release_object( parent );
|
release_object( parent );
|
||||||
@ -2194,7 +2195,7 @@ DECL_HANDLER(load_registry)
|
|||||||
{
|
{
|
||||||
int dummy;
|
int dummy;
|
||||||
get_req_path( &name, !req->hkey );
|
get_req_path( &name, !req->hkey );
|
||||||
if ((key = create_key( parent, &name, NULL, 0, KEY_WOW64_64KEY, 0, &dummy )))
|
if ((key = create_key( parent, &name, NULL, 0, KEY_WOW64_64KEY, 0, NULL, &dummy )))
|
||||||
{
|
{
|
||||||
load_registry( key, req->file );
|
load_registry( key, req->file );
|
||||||
release_object( key );
|
release_object( key );
|
||||||
|
@ -1287,12 +1287,9 @@ C_ASSERT( sizeof(struct read_process_memory_reply) == 8 );
|
|||||||
C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, handle) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, handle) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, addr) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, addr) == 16 );
|
||||||
C_ASSERT( sizeof(struct write_process_memory_request) == 24 );
|
C_ASSERT( sizeof(struct write_process_memory_request) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_request, parent) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct create_key_request, access) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_request, access) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct create_key_request, options) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_request, attributes) == 20 );
|
C_ASSERT( sizeof(struct create_key_request) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_request, options) == 24 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_request, namelen) == 28 );
|
|
||||||
C_ASSERT( sizeof(struct create_key_request) == 32 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_reply, hkey) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct create_key_reply, hkey) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_key_reply, created) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct create_key_reply, created) == 12 );
|
||||||
C_ASSERT( sizeof(struct create_key_reply) == 16 );
|
C_ASSERT( sizeof(struct create_key_reply) == 16 );
|
||||||
|
@ -2308,12 +2308,9 @@ static void dump_write_process_memory_request( const struct write_process_memory
|
|||||||
|
|
||||||
static void dump_create_key_request( const struct create_key_request *req )
|
static void dump_create_key_request( const struct create_key_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " parent=%04x", req->parent );
|
fprintf( stderr, " access=%08x", req->access );
|
||||||
fprintf( stderr, ", access=%08x", req->access );
|
|
||||||
fprintf( stderr, ", attributes=%08x", req->attributes );
|
|
||||||
fprintf( stderr, ", options=%08x", req->options );
|
fprintf( stderr, ", options=%08x", req->options );
|
||||||
fprintf( stderr, ", namelen=%u", req->namelen );
|
dump_varargs_object_attributes( ", objattr=", cur_size );
|
||||||
dump_varargs_unicode_str( ", name=", min(cur_size,req->namelen) );
|
|
||||||
dump_varargs_unicode_str( ", class=", cur_size );
|
dump_varargs_unicode_str( ", class=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user