This patch is a dirty hack to add a server call to Wine that associates a global handle with data. I was initially going to use this as part of the VirtualAllocEx family of calls, but scapped the idea. I didn't want to waste my work, so it's here for posterity. server: add call to associate data with a global handle --- include/wine/server_protocol.h | 51 ++++++++++++++++++++++++ server/handle.c | 85 ++++++++++++++++++++++++++++++++++++++++ server/protocol.def | 24 +++++++++++ server/request.h | 6 +++ server/trace.c | 39 ++++++++++++++++++ 5 files changed, 203 insertions(+), 2 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index e77e84e..941ba6d 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1684,6 +1684,46 @@ struct set_debugger_kill_on_exit_reply +struct create_server_data_request +{ + struct request_header __header; + /* VARARG(data,bytes); */ +}; +struct create_server_data_reply +{ + struct reply_header __header; + obj_handle_t handle; +}; + + + +struct get_server_data_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_server_data_reply +{ + struct reply_header __header; + unsigned int len; + /* VARARG(data,bytes); */ +}; + + + +struct set_server_data_request +{ + struct request_header __header; + obj_handle_t handle; + /* VARARG(data,bytes); */ +}; +struct set_server_data_reply +{ + struct reply_header __header; +}; + + + struct read_process_memory_request { struct request_header __header; @@ -3863,6 +3903,9 @@ enum request REQ_debug_process, REQ_debug_break, REQ_set_debugger_kill_on_exit, + REQ_create_server_data, + REQ_get_server_data, + REQ_set_server_data, REQ_read_process_memory, REQ_write_process_memory, REQ_create_key, @@ -4086,6 +4129,9 @@ union generic_request struct debug_process_request debug_process_request; struct debug_break_request debug_break_request; struct set_debugger_kill_on_exit_request set_debugger_kill_on_exit_request; + struct create_server_data_request create_server_data_request; + struct get_server_data_request get_server_data_request; + struct set_server_data_request set_server_data_request; struct read_process_memory_request read_process_memory_request; struct write_process_memory_request write_process_memory_request; struct create_key_request create_key_request; @@ -4307,6 +4353,9 @@ union generic_reply struct debug_process_reply debug_process_reply; struct debug_break_reply debug_break_reply; struct set_debugger_kill_on_exit_reply set_debugger_kill_on_exit_reply; + struct create_server_data_reply create_server_data_reply; + struct get_server_data_reply get_server_data_reply; + struct set_server_data_reply set_server_data_reply; struct read_process_memory_reply read_process_memory_reply; struct write_process_memory_reply write_process_memory_reply; struct create_key_reply create_key_reply; @@ -4438,6 +4487,6 @@ union generic_reply struct get_service_thread_mutex_reply get_service_thread_mutex_reply; }; -#define SERVER_PROTOCOL_VERSION 243 +#define SERVER_PROTOCOL_VERSION 245 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/handle.c b/server/handle.c index c3765eb..0092bb4 100644 --- a/server/handle.c +++ b/server/handle.c @@ -382,9 +382,13 @@ struct object *get_handle_obj( struct pr struct handle_entry *entry; struct object *obj; + if (!(obj = get_magic_handle( handle ))) { - if (!(entry = get_handle( process, handle ))) return NULL; + if (!(entry = get_handle( process, handle ))) + { + return NULL; + } if ((entry->access & access) != access) { printf("no access to %x::%x\n", process, handle); @@ -587,3 +591,82 @@ DECL_HANDLER(dup_handle) release_object( src ); } } + +struct data { + struct object obj; + data_size_t len; + void *data; +}; + +static void data_dump( struct object *obj, int verbose) +{ +} + +static void data_destroy( struct object *obj ) +{ + struct data *data = obj; + free( data->data ); +} + +static const struct object_ops data_ops = +{ + sizeof(struct data), /* size */ + data_dump, /* dump */ + no_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satisfied */ + no_signal, /* signal */ + no_get_fd, /* get_fd */ + no_map_access, /* map_access */ + no_lookup_name, /* lookup_name */ + no_close_handle, /* close_handle */ + data_destroy /* destroy */ +}; + +/* Create a data object on server */ +DECL_HANDLER(create_server_data) +{ + struct data *data; + if (!(data = alloc_object( &data_ops ))) + return; + + data->data = mem_alloc( get_req_data_size() ); + data->len = get_req_data_size(); + memcpy( data->data, get_req_data(), data->len ); + reply->handle = alloc_global_handle( data, 0 ); + printf("set to %s\n", data->data); +} + +/* Get data from server data object */ +DECL_HANDLER(get_server_data) +{ + struct data *data; + struct process *p; + + p = get_process_from_handle( 0xffffffff, 0 ); + data = get_handle_obj( p, req->handle, 0, &data_ops ); + release_object( p ); + + set_reply_data( data->data, data->len ); + reply->len = data->len; + + release_object( data ); +} + +/* Set server data object */ +DECL_HANDLER(set_server_data) +{ + struct data *data; + struct process *p; + + p = get_process_from_handle( 0xffffffff, 0 ); + data = get_handle_obj( p, req->handle, 0, &data_ops ); + + free( data->data ); + data->data = mem_alloc( get_req_data_size() ); + data->len = get_req_data_size(); + memcpy( data->data, get_req_data(), data->len ); + + release_object( data ); +} diff --git a/server/protocol.def b/server/protocol.def index e5a17a3..d8a947b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1239,6 +1239,30 @@ #define SNAP_MODULE 0x00000008 @END +/* Create a data object on server */ +@REQ(create_server_data) + VARARG(data,bytes); /* initial data and size */ +@REPLY + obj_handle_t handle; /* data handle */ +@END + + +/* Get data from server data object */ +@REQ(get_server_data) + obj_handle_t handle; /* data handle */ +@REPLY + unsigned int len; /* data length */ + VARARG(data,bytes); /* data */ +@END + + +/* Set server data object */ +@REQ(set_server_data) + obj_handle_t handle; /* data handle */ + VARARG(data,bytes); /* data */ +@END + + /* Read data from a process address space */ @REQ(read_process_memory) obj_handle_t handle; /* process handle */ diff --git a/server/request.h b/server/request.h index 386f03e..67ea09e 100644 --- a/server/request.h +++ b/server/request.h @@ -197,6 +197,9 @@ DECL_HANDLER(continue_debug_event); DECL_HANDLER(debug_process); DECL_HANDLER(debug_break); DECL_HANDLER(set_debugger_kill_on_exit); +DECL_HANDLER(create_server_data); +DECL_HANDLER(get_server_data); +DECL_HANDLER(set_server_data); DECL_HANDLER(read_process_memory); DECL_HANDLER(write_process_memory); DECL_HANDLER(create_key); @@ -419,6 +422,9 @@ static const req_handler req_handlers[RE (req_handler)req_debug_process, (req_handler)req_debug_break, (req_handler)req_set_debugger_kill_on_exit, + (req_handler)req_create_server_data, + (req_handler)req_get_server_data, + (req_handler)req_set_server_data, (req_handler)req_read_process_memory, (req_handler)req_write_process_memory, (req_handler)req_create_key, diff --git a/server/trace.c b/server/trace.c index bf92731..f922f3c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1693,6 +1693,36 @@ static void dump_set_debugger_kill_on_ex fprintf( stderr, " kill_on_exit=%d", req->kill_on_exit ); } +static void dump_create_server_data_request( const struct create_server_data_request *req ) +{ + fprintf( stderr, " data=" ); + dump_varargs_bytes( cur_size ); +} + +static void dump_create_server_data_reply( const struct create_server_data_reply *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_get_server_data_request( const struct get_server_data_request *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_get_server_data_reply( const struct get_server_data_reply *req ) +{ + fprintf( stderr, " len=%08x,", req->len ); + fprintf( stderr, " data=" ); + dump_varargs_bytes( cur_size ); +} + +static void dump_set_server_data_request( const struct set_server_data_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " data=" ); + dump_varargs_bytes( cur_size ); +} + static void dump_read_process_memory_request( const struct read_process_memory_request *req ) { fprintf( stderr, " handle=%p,", req->handle ); @@ -3386,6 +3416,9 @@ static const dump_func req_dumpers[REQ_N (dump_func)dump_debug_process_request, (dump_func)dump_debug_break_request, (dump_func)dump_set_debugger_kill_on_exit_request, + (dump_func)dump_create_server_data_request, + (dump_func)dump_get_server_data_request, + (dump_func)dump_set_server_data_request, (dump_func)dump_read_process_memory_request, (dump_func)dump_write_process_memory_request, (dump_func)dump_create_key_request, @@ -3605,6 +3638,9 @@ static const dump_func reply_dumpers[REQ (dump_func)0, (dump_func)dump_debug_break_reply, (dump_func)0, + (dump_func)dump_create_server_data_reply, + (dump_func)dump_get_server_data_reply, + (dump_func)0, (dump_func)dump_read_process_memory_reply, (dump_func)0, (dump_func)dump_create_key_reply, @@ -3824,6 +3860,9 @@ static const char * const req_names[REQ_ "debug_process", "debug_break", "set_debugger_kill_on_exit", + "create_server_data", + "get_server_data", + "set_server_data", "read_process_memory", "write_process_memory", "create_key",