Commit 018f8014 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move user_handles from user32.

parent 3e4f83f7
...@@ -50,19 +50,6 @@ extern void USER_unload_driver(void) DECLSPEC_HIDDEN; ...@@ -50,19 +50,6 @@ extern void USER_unload_driver(void) DECLSPEC_HIDDEN;
struct received_message_info; struct received_message_info;
struct user_object
{
HANDLE handle;
unsigned int type;
};
#define OBJ_OTHER_PROCESS ((void *)1) /* returned by get_user_handle_ptr on unknown handles */
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN;
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN;
void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
/* type of message-sending functions that need special WM_CHAR handling */ /* type of message-sending functions that need special WM_CHAR handling */
enum wm_char_mapping enum wm_char_mapping
{ {
......
...@@ -36,9 +36,6 @@ ...@@ -36,9 +36,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DEFAULT_DEBUG_CHANNEL(win);
#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
static DWORD process_layout = ~0u; static DWORD process_layout = ~0u;
...@@ -87,31 +84,12 @@ static inline void set_win_data( void *ptr, LONG_PTR val, UINT size ) ...@@ -87,31 +84,12 @@ static inline void set_win_data( void *ptr, LONG_PTR val, UINT size )
} }
static void *user_handles[NB_USER_HANDLES];
/*********************************************************************** /***********************************************************************
* alloc_user_handle * alloc_user_handle
*/ */
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type )
{ {
HANDLE handle = 0; return UlongToHandle( NtUserCallTwoParam( (UINT_PTR)ptr, type, NtUserAllocHandle ));
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;
InterlockedExchangePointer( &user_handles[index], ptr );
}
return handle;
} }
...@@ -120,23 +98,7 @@ HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) ...@@ -120,23 +98,7 @@ HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type )
*/ */
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) void *get_user_handle_ptr( HANDLE handle, unsigned int type )
{ {
struct user_object *ptr; return (void *)NtUserCallTwoParam( HandleToUlong(handle), type, NtUserGetHandlePtr );
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;
} }
...@@ -155,21 +117,7 @@ void release_user_handle_ptr( void *ptr ) ...@@ -155,21 +117,7 @@ void release_user_handle_ptr( void *ptr )
*/ */
void *free_user_handle( HANDLE handle, unsigned int type ) void *free_user_handle( HANDLE handle, unsigned int type )
{ {
struct user_object *ptr; return UlongToHandle( NtUserCallTwoParam( HandleToUlong(handle), type, NtUserFreeHandle ));
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 )) ptr = NULL;
else InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
}
SERVER_END_REQ;
USER_Unlock();
}
return ptr;
} }
...@@ -182,7 +130,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, ...@@ -182,7 +130,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
HINSTANCE instance, BOOL unicode, HINSTANCE instance, BOOL unicode,
DWORD style, DWORD ex_style ) DWORD style, DWORD ex_style )
{ {
WORD index;
WND *win; WND *win;
HWND handle = 0, full_parent = 0, full_owner = 0; HWND handle = 0, full_parent = 0, full_owner = 0;
struct tagCLASS *class = NULL; struct tagCLASS *class = NULL;
...@@ -253,8 +200,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, ...@@ -253,8 +200,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
USER_Lock(); USER_Lock();
index = USER_HANDLE_TO_INDEX(handle);
assert( index < NB_USER_HANDLES );
win->obj.handle = handle; win->obj.handle = handle;
win->obj.type = NTUSER_OBJ_WINDOW; win->obj.type = NTUSER_OBJ_WINDOW;
win->parent = full_parent; win->parent = full_parent;
...@@ -264,7 +209,7 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, ...@@ -264,7 +209,7 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
win->cbWndExtra = extra_bytes; win->cbWndExtra = extra_bytes;
win->dpi = dpi; win->dpi = dpi;
win->dpi_awareness = awareness; win->dpi_awareness = awareness;
InterlockedExchangePointer( &user_handles[index], win ); NtUserCallTwoParam( HandleToUlong(handle), (UINT_PTR)win, NtUserSetHandlePtr );
if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE; if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE;
return win; return win;
} }
...@@ -278,7 +223,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name, ...@@ -278,7 +223,6 @@ static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
static void free_window_handle( HWND hwnd ) static void free_window_handle( HWND hwnd )
{ {
struct user_object *ptr; struct user_object *ptr;
WORD index = USER_HANDLE_TO_INDEX(hwnd);
if ((ptr = get_user_handle_ptr( hwnd, NTUSER_OBJ_WINDOW )) && ptr != OBJ_OTHER_PROCESS) if ((ptr = get_user_handle_ptr( hwnd, NTUSER_OBJ_WINDOW )) && ptr != OBJ_OTHER_PROCESS)
{ {
...@@ -286,7 +230,7 @@ static void free_window_handle( HWND hwnd ) ...@@ -286,7 +230,7 @@ static void free_window_handle( HWND hwnd )
{ {
req->handle = wine_server_user_handle( hwnd ); req->handle = wine_server_user_handle( hwnd );
wine_server_call( req ); wine_server_call( req );
InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr ); NtUserCallTwoParam( HandleToUlong(hwnd), 0, NtUserSetHandlePtr );
} }
SERVER_END_REQ; SERVER_END_REQ;
USER_Unlock(); USER_Unlock();
...@@ -1156,20 +1100,7 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) ...@@ -1156,20 +1100,7 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
*/ */
static WND *next_thread_window( HWND *hwnd ) static WND *next_thread_window( HWND *hwnd )
{ {
struct user_object *ptr; return (WND *)NtUserCallOneParam( (UINT_PTR)hwnd, NtUserNextThreadWindow );
WND *win;
WORD index = *hwnd ? USER_HANDLE_TO_INDEX( *hwnd ) + 1 : 0;
while (index < NB_USER_HANDLES)
{
if (!(ptr = user_handles[index++])) continue;
if (ptr->type != NTUSER_OBJ_WINDOW) continue;
win = (WND *)ptr;
if (win->tid != GetCurrentThreadId()) continue;
*hwnd = ptr->handle;
return win;
}
return NULL;
} }
...@@ -1187,7 +1118,7 @@ void destroy_thread_windows(void) ...@@ -1187,7 +1118,7 @@ void destroy_thread_windows(void)
while ((win = next_thread_window( &hwnd ))) while ((win = next_thread_window( &hwnd )))
{ {
free_dce( win->dce, win->obj.handle ); free_dce( win->dce, win->obj.handle );
InterlockedCompareExchangePointer( &user_handles[USER_HANDLE_TO_INDEX(hwnd)], NULL, win ); NtUserCallTwoParam( HandleToUlong(hwnd), 0, NtUserSetHandlePtr );
win->obj.handle = *free_list_ptr; win->obj.handle = *free_list_ptr;
free_list_ptr = (WND **)&win->obj.handle; free_list_ptr = (WND **)&win->obj.handle;
} }
......
...@@ -33,43 +33,6 @@ ...@@ -33,43 +33,6 @@
struct tagCLASS; struct tagCLASS;
struct tagDIALOGINFO; struct tagDIALOGINFO;
typedef struct tagWND
{
struct user_object obj; /* object header */
HWND parent; /* Window parent */
HWND owner; /* Window owner */
struct tagCLASS *class; /* Window class */
struct dce *dce; /* DCE pointer */
WNDPROC winproc; /* Window procedure */
DWORD tid; /* Owner thread id */
HINSTANCE hInstance; /* Window hInstance (from CreateWindow) */
RECT client_rect; /* Client area rel. to parent client area */
RECT window_rect; /* Whole window rel. to parent client area */
RECT visible_rect; /* Visible part of the whole rect, rel. to parent client area */
RECT normal_rect; /* Normal window rect saved when maximized/minimized */
POINT min_pos; /* Position for minimized window */
POINT max_pos; /* Position for maximized window */
LPWSTR text; /* Window text */
void *pScroll; /* Scroll-bar info */
DWORD dwStyle; /* Window style (from CreateWindow) */
DWORD dwExStyle; /* Extended style (from CreateWindowEx) */
UINT_PTR wIDmenu; /* ID or hmenu (from CreateWindow) */
DWORD helpContext; /* Help context ID */
UINT flags; /* Misc. flags (see below) */
HMENU hSysMenu; /* window's copy of System Menu */
HICON hIcon; /* window's icon */
HICON hIconSmall; /* window's small icon */
HICON hIconSmall2; /* window's secondary small icon, derived from hIcon */
UINT dpi; /* window DPI */
DPI_AWARENESS dpi_awareness; /* DPI awareness */
struct window_surface *surface; /* Window surface if any */
struct tagDIALOGINFO *dlgInfo;/* Dialog additional info (dialogs only) */
int pixel_format; /* Pixel format set by the graphics driver */
int cbWndExtra; /* class cbWndExtra at window creation */
DWORD_PTR userdata; /* User private data */
DWORD wExtra[1]; /* Window extra bytes */
} WND;
/* WND flags values */ /* WND flags values */
#define WIN_RESTORE_MAX 0x0001 /* Maximize when restoring */ #define WIN_RESTORE_MAX 0x0001 /* Maximize when restoring */
#define WIN_NEED_SIZE 0x0002 /* Internal WM_SIZE is needed */ #define WIN_NEED_SIZE 0x0002 /* Internal WM_SIZE is needed */
......
...@@ -34,6 +34,59 @@ struct user_callbacks ...@@ -34,6 +34,59 @@ struct user_callbacks
HWND (WINAPI *pWindowFromDC)( HDC ); HWND (WINAPI *pWindowFromDC)( HDC );
}; };
struct user_object
{
HANDLE handle;
unsigned int type;
};
#define OBJ_OTHER_PROCESS ((void *)1) /* returned by get_user_handle_ptr on unknown handles */
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN;
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
void set_user_handle_ptr( HANDLE handle, struct user_object *ptr ) DECLSPEC_HIDDEN;
void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN;
void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
typedef struct tagWND
{
struct user_object obj; /* object header */
HWND parent; /* Window parent */
HWND owner; /* Window owner */
struct tagCLASS *class; /* Window class */
struct dce *dce; /* DCE pointer */
WNDPROC winproc; /* Window procedure */
DWORD tid; /* Owner thread id */
HINSTANCE hInstance; /* Window hInstance (from CreateWindow) */
RECT client_rect; /* Client area rel. to parent client area */
RECT window_rect; /* Whole window rel. to parent client area */
RECT visible_rect; /* Visible part of the whole rect, rel. to parent client area */
RECT normal_rect; /* Normal window rect saved when maximized/minimized */
POINT min_pos; /* Position for minimized window */
POINT max_pos; /* Position for maximized window */
WCHAR *text; /* Window text */
void *pScroll; /* Scroll-bar info */
DWORD dwStyle; /* Window style (from CreateWindow) */
DWORD dwExStyle; /* Extended style (from CreateWindowEx) */
UINT_PTR wIDmenu; /* ID or hmenu (from CreateWindow) */
DWORD helpContext; /* Help context ID */
UINT flags; /* Misc. flags (see below) */
HMENU hSysMenu; /* window's copy of System Menu */
HICON hIcon; /* window's icon */
HICON hIconSmall; /* window's small icon */
HICON hIconSmall2; /* window's secondary small icon, derived from hIcon */
UINT dpi; /* window DPI */
DPI_AWARENESS dpi_awareness; /* DPI awareness */
struct window_surface *surface; /* Window surface if any */
struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */
int pixel_format; /* Pixel format set by the graphics driver */
int cbWndExtra; /* class cbWndExtra at window creation */
DWORD_PTR userdata; /* User private data */
DWORD wExtra[1]; /* Window extra bytes */
} WND;
WND *next_thread_window_ptr( HWND *hwnd );
/* this is the structure stored in TEB->Win32ClientInfo */ /* this is the structure stored in TEB->Win32ClientInfo */
/* no attempt is made to keep the layout compatible with the Windows one */ /* no attempt is made to keep the layout compatible with the Windows one */
struct user_thread_info struct user_thread_info
......
...@@ -4589,6 +4589,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) ...@@ -4589,6 +4589,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
case 1: user_unlock(); return 0; case 1: user_unlock(); return 0;
default: user_check_not_lock(); return 0; default: user_check_not_lock(); return 0;
} }
case NtUserNextThreadWindow:
return (UINT_PTR)next_thread_window_ptr( (HWND *)arg );
case NtUserSetCallbacks: case NtUserSetCallbacks:
return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg ); return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg );
default: default:
...@@ -4615,9 +4617,18 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code ...@@ -4615,9 +4617,18 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code
case NtUserUnhookWindowsHook: case NtUserUnhookWindowsHook:
return unhook_windows_hook( arg1, (HOOKPROC)arg2 ); return unhook_windows_hook( arg1, (HOOKPROC)arg2 );
/* temporary exports */ /* temporary exports */
case NtUserAllocHandle:
return HandleToUlong( alloc_user_handle( (struct user_object *)arg1, arg2 ));
case NtUserFreeHandle:
return (UINT_PTR)free_user_handle( UlongToHandle(arg1), arg2 );
case NtUserGetHandlePtr:
return (UINT_PTR)get_user_handle_ptr( UlongToHandle(arg1), arg2 );
case NtUserRegisterWindowSurface: case NtUserRegisterWindowSurface:
register_window_surface( (struct window_surface *)arg1, (struct window_surface *)arg2 ); register_window_surface( (struct window_surface *)arg1, (struct window_surface *)arg2 );
return 0; return 0;
case NtUserSetHandlePtr:
set_user_handle_ptr( UlongToHandle(arg1), (struct user_object *)arg2 );
return 0;
default: default:
FIXME( "invalid code %u\n", code ); FIXME( "invalid code %u\n", code );
return 0; return 0;
......
...@@ -24,15 +24,124 @@ ...@@ -24,15 +24,124 @@
#endif #endif
#include <pthread.h> #include <pthread.h>
#include <assert.h>
#include "ntstatus.h" #include "ntstatus.h"
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include "win32u_private.h" #include "win32u_private.h"
#include "ntuser_private.h"
#include "wine/server.h" #include "wine/server.h"
#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
static void *user_handles[NB_USER_HANDLES];
static struct list window_surfaces = LIST_INIT( window_surfaces ); static struct list window_surfaces = LIST_INIT( window_surfaces );
static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER;
/***********************************************************************
* alloc_user_handle
*/
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int 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;
InterlockedExchangePointer( &user_handles[index], ptr );
}
return handle;
}
/***********************************************************************
* get_user_handle_ptr
*/
void *get_user_handle_ptr( HANDLE handle, unsigned int 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;
}
/***********************************************************************
* set_user_handle_ptr
*/
void set_user_handle_ptr( HANDLE handle, struct user_object *ptr )
{
WORD index = USER_HANDLE_TO_INDEX(handle);
assert( index < NB_USER_HANDLES );
InterlockedExchangePointer( &user_handles[index], ptr );
}
/***********************************************************************
* free_user_handle
*/
void *free_user_handle( HANDLE handle, unsigned int 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 )) ptr = NULL;
else InterlockedCompareExchangePointer( &user_handles[index], NULL, ptr );
}
SERVER_END_REQ;
user_unlock();
}
return ptr;
}
/***********************************************************************
* next_thread_window
*/
WND *next_thread_window_ptr( HWND *hwnd )
{
struct user_object *ptr;
WND *win;
WORD index = *hwnd ? USER_HANDLE_TO_INDEX( *hwnd ) + 1 : 0;
while (index < NB_USER_HANDLES)
{
if (!(ptr = user_handles[index++])) continue;
if (ptr->type != NTUSER_OBJ_WINDOW) continue;
win = (WND *)ptr;
if (win->tid != GetCurrentThreadId()) continue;
*hwnd = ptr->handle;
return win;
}
return NULL;
}
/******************************************************************* /*******************************************************************
* register_window_surface * register_window_surface
* *
......
...@@ -88,6 +88,7 @@ enum ...@@ -88,6 +88,7 @@ enum
NtUserGetDeskPattern, NtUserGetDeskPattern,
NtUserIncrementKeyStateCounter, NtUserIncrementKeyStateCounter,
NtUserLock, NtUserLock,
NtUserNextThreadWindow,
NtUserSetCallbacks, NtUserSetCallbacks,
}; };
...@@ -100,7 +101,11 @@ enum ...@@ -100,7 +101,11 @@ enum
NtUserMonitorFromRect, NtUserMonitorFromRect,
NtUserUnhookWindowsHook, NtUserUnhookWindowsHook,
/* temporary exports */ /* temporary exports */
NtUserAllocHandle,
NtUserFreeHandle,
NtUserGetHandlePtr,
NtUserRegisterWindowSurface, NtUserRegisterWindowSurface,
NtUserSetHandlePtr,
}; };
/* color index used to retrieve system 55aa brush */ /* color index used to retrieve system 55aa brush */
......
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