From d996f7e334d3274465b75cacf02695b4314040ac Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 12 Oct 2009 14:27:55 +0200 Subject: [PATCH] user32: Add functions for manipulating client-side user handles. --- dlls/user32/user_private.h | 19 +++++++++ dlls/user32/win.c | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 1ff6ef41a59..1020064a0bd 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -170,6 +170,25 @@ extern void USER_unload_driver(void) DECLSPEC_HIDDEN; struct received_message_info; struct hook16_queue_info; +enum user_obj_type +{ + USER_WINDOW = 1, /* window */ + USER_DWP /* DeferWindowPos structure */ +}; + +struct user_object +{ + HANDLE handle; + enum user_obj_type type; +}; + +#define OBJ_OTHER_PROCESS ((void *)1) /* returned by get_user_handle_ptr on unknown handles */ + +HANDLE alloc_user_handle( struct user_object *ptr, enum user_obj_type type ) DECLSPEC_HIDDEN; +void *get_user_handle_ptr( HANDLE handle, enum user_obj_type type ) DECLSPEC_HIDDEN; +void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN; +void *free_user_handle( HANDLE handle, enum user_obj_type type ) DECLSPEC_HIDDEN; + /* type of message-sending functions that need special WM_CHAR handling */ enum wm_char_mapping { diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 44b15b1a9bf..28ea84119b5 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -90,6 +90,89 @@ static inline void set_win_data( void *ptr, LONG_PTR val, UINT size ) static void *user_handles[NB_USER_HANDLES]; +/*********************************************************************** + * alloc_user_handle + */ +HANDLE alloc_user_handle( struct user_object *ptr, enum user_obj_type type ) +{ + HANDLE handle = 0; + + SERVER_START_REQ( alloc_user_handle ) + { + if (!wine_server_call_err( req )) handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + if (handle) + { + UINT index = USER_HANDLE_TO_INDEX( handle ); + + assert( index < NB_USER_HANDLES ); + ptr->handle = handle; + ptr->type = type; + user_handles[index] = ptr; + } + return handle; +} + + +/*********************************************************************** + * get_user_handle_ptr + */ +void *get_user_handle_ptr( HANDLE handle, enum user_obj_type type ) +{ + struct user_object *ptr; + WORD index = USER_HANDLE_TO_INDEX( handle ); + + if (index >= NB_USER_HANDLES) return NULL; + + USER_Lock(); + if ((ptr = user_handles[index])) + { + if (ptr->type == type && + ((UINT)(UINT_PTR)ptr->handle == (UINT)(UINT_PTR)handle || + !HIWORD(handle) || HIWORD(handle) == 0xffff)) + return ptr; + ptr = NULL; + } + else ptr = OBJ_OTHER_PROCESS; + USER_Unlock(); + return ptr; +} + + +/*********************************************************************** + * release_user_handle_ptr + */ +void release_user_handle_ptr( void *ptr ) +{ + USER_Unlock(); +} + + +/*********************************************************************** + * free_user_handle + */ +void *free_user_handle( HANDLE handle, enum user_obj_type type ) +{ + struct user_object *ptr; + WORD index = USER_HANDLE_TO_INDEX( handle ); + + if ((ptr = get_user_handle_ptr( handle, type )) && ptr != OBJ_OTHER_PROCESS) + { + SERVER_START_REQ( free_user_handle ) + { + req->handle = wine_server_user_handle( handle ); + if (!wine_server_call( req )) user_handles[index] = NULL; + else ptr = NULL; + } + SERVER_END_REQ; + release_user_handle_ptr( ptr ); + } + return ptr; +} + + /*********************************************************************** * create_window_handle *