Explicitly pass the winstation to the atom functions so that they can

be used even when current is not set.
This commit is contained in:
Alexandre Julliard 2005-07-08 14:23:27 +00:00
parent 6fd3c47c4f
commit c3ac57dd86
4 changed files with 80 additions and 42 deletions

View File

@ -284,12 +284,9 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str, size_t len
return 0; return 0;
} }
static struct atom_table *get_global_table( int create ) static struct atom_table *get_global_table( struct winstation *winstation, int create )
{ {
struct atom_table *global_table; struct atom_table *global_table;
struct winstation *winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS );
if (!winstation) return NULL;
if (!(global_table = get_winstation_atom_table( winstation ))) if (!(global_table = get_winstation_atom_table( winstation )))
{ {
@ -300,13 +297,12 @@ static struct atom_table *get_global_table( int create )
} }
else set_error( STATUS_OBJECT_NAME_NOT_FOUND ); else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
} }
release_object( winstation );
return global_table; return global_table;
} }
static struct atom_table *get_table( obj_handle_t h, int create ) static struct atom_table *get_table( obj_handle_t h, int create )
{ {
struct atom_table *table; struct atom_table *table = NULL;
if (h) if (h)
{ {
@ -314,24 +310,30 @@ static struct atom_table *get_table( obj_handle_t h, int create )
} }
else else
{ {
table = get_global_table( 1 ); struct winstation *winstation = get_process_winstation( current->process,
if (table) grab_object( table ); WINSTA_ACCESSGLOBALATOMS );
if (winstation)
{
table = get_global_table( winstation, 1 );
if (table) grab_object( table );
release_object( winstation );
}
} }
return table; return table;
} }
/* add an atom in the global table; used for window properties */ /* add an atom in the global table; used for window properties */
atom_t add_global_atom( const WCHAR *str, size_t len ) atom_t add_global_atom( struct winstation *winstation, const WCHAR *str, size_t len )
{ {
struct atom_table *global_table = get_global_table( 1 ); struct atom_table *global_table = get_global_table( winstation, 1 );
if (!global_table) return 0; if (!global_table) return 0;
return add_atom( global_table, str, len ); return add_atom( global_table, str, len );
} }
/* find an atom in the global table; used for window properties */ /* find an atom in the global table; used for window properties */
atom_t find_global_atom( const WCHAR *str, size_t len ) atom_t find_global_atom( struct winstation *winstation, const WCHAR *str, size_t len )
{ {
struct atom_table *global_table = get_global_table( 0 ); struct atom_table *global_table = get_global_table( winstation, 0 );
struct atom_entry *entry; struct atom_entry *entry;
if (!len || len > MAX_ATOM_LEN || !global_table) return 0; if (!len || len > MAX_ATOM_LEN || !global_table) return 0;
@ -341,11 +343,11 @@ atom_t find_global_atom( const WCHAR *str, size_t len )
} }
/* increment the ref count of a global atom; used for window properties */ /* increment the ref count of a global atom; used for window properties */
int grab_global_atom( atom_t atom ) int grab_global_atom( struct winstation *winstation, atom_t atom )
{ {
if (atom >= MIN_STR_ATOM) if (atom >= MIN_STR_ATOM)
{ {
struct atom_table *global_table = get_global_table( 0 ); struct atom_table *global_table = get_global_table( winstation, 0 );
if (global_table) if (global_table)
{ {
struct atom_entry *entry = get_atom_entry( global_table, atom ); struct atom_entry *entry = get_atom_entry( global_table, atom );
@ -358,11 +360,11 @@ int grab_global_atom( atom_t atom )
} }
/* decrement the ref count of a global atom; used for window properties */ /* decrement the ref count of a global atom; used for window properties */
void release_global_atom( atom_t atom ) void release_global_atom( struct winstation *winstation, atom_t atom )
{ {
if (atom >= MIN_STR_ATOM) if (atom >= MIN_STR_ATOM)
{ {
struct atom_table *global_table = get_global_table( 0 ); struct atom_table *global_table = get_global_table( winstation, 0 );
if (global_table) delete_atom( global_table, atom, 1 ); if (global_table) delete_atom( global_table, atom, 1 );
} }
} }

View File

@ -33,6 +33,7 @@
#include "object.h" #include "object.h"
#include "process.h" #include "process.h"
#include "user.h" #include "user.h"
#include "winuser.h"
struct window_class struct window_class
{ {
@ -156,6 +157,7 @@ void *get_class_client_ptr( struct window_class *class )
DECL_HANDLER(create_class) DECL_HANDLER(create_class)
{ {
struct window_class *class; struct window_class *class;
struct winstation *winstation;
if (!req->local && req->atom == DESKTOP_ATOM) if (!req->local && req->atom == DESKTOP_ATOM)
{ {
@ -175,11 +177,19 @@ DECL_HANDLER(create_class)
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
} }
if (!grab_global_atom( req->atom )) return;
if (!(winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS )))
return;
if (!grab_global_atom( winstation, req->atom ))
{
release_object( winstation );
return;
}
if (!(class = create_class( current->process, req->extra, req->local ))) if (!(class = create_class( current->process, req->extra, req->local )))
{ {
release_global_atom( req->atom ); release_global_atom( winstation, req->atom );
release_object( winstation );
return; return;
} }
class->atom = req->atom; class->atom = req->atom;
@ -187,6 +197,7 @@ DECL_HANDLER(create_class)
class->style = req->style; class->style = req->style;
class->win_extra = req->win_extra; class->win_extra = req->win_extra;
class->client_ptr = req->client_ptr; class->client_ptr = req->client_ptr;
release_object( winstation );
} }
/* destroy a window class */ /* destroy a window class */
@ -249,9 +260,16 @@ DECL_HANDLER(set_class_info)
if (req->flags & SET_CLASS_ATOM) if (req->flags & SET_CLASS_ATOM)
{ {
if (!grab_global_atom( req->atom )) return; struct winstation *winstation = get_process_winstation( current->process,
release_global_atom( class->atom ); WINSTA_ACCESSGLOBALATOMS );
if (!grab_global_atom( winstation, req->atom ))
{
release_object( winstation );
return;
}
release_global_atom( winstation, class->atom );
class->atom = req->atom; class->atom = req->atom;
release_object( winstation );
} }
if (req->flags & SET_CLASS_STYLE) class->style = req->style; if (req->flags & SET_CLASS_STYLE) class->style = req->style;
if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra; if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra;

View File

@ -43,6 +43,7 @@ struct file;
struct wait_queue_entry; struct wait_queue_entry;
struct async; struct async;
struct async_queue; struct async_queue;
struct winstation;
/* operations valid on all objects */ /* operations valid on all objects */
struct object_ops struct object_ops
@ -157,10 +158,10 @@ extern void close_signals(void);
/* atom functions */ /* atom functions */
extern atom_t add_global_atom( const WCHAR *str, size_t len ); extern atom_t add_global_atom( struct winstation *winstation, const WCHAR *str, size_t len );
extern atom_t find_global_atom( const WCHAR *str, size_t len ); extern atom_t find_global_atom( struct winstation *winstation, const WCHAR *str, size_t len );
extern int grab_global_atom( atom_t atom ); extern int grab_global_atom( struct winstation *winstation, atom_t atom );
extern void release_global_atom( atom_t atom ); extern void release_global_atom( struct winstation *winstation, atom_t atom );
/* global variables */ /* global variables */

View File

@ -200,8 +200,8 @@ static int add_handle_to_array( struct user_handle_array *array, user_handle_t h
} }
/* set a window property */ /* set a window property */
static void set_property( struct window *win, atom_t atom, obj_handle_t handle, static void set_property( struct winstation *winstation, struct window *win,
enum property_type type ) atom_t atom, obj_handle_t handle, enum property_type type )
{ {
int i, free = -1; int i, free = -1;
struct property *new_props; struct property *new_props;
@ -223,7 +223,7 @@ static void set_property( struct window *win, atom_t atom, obj_handle_t handle,
} }
/* need to add an entry */ /* need to add an entry */
if (!grab_global_atom( atom )) return; if (!grab_global_atom( winstation, atom )) return;
if (free == -1) if (free == -1)
{ {
/* no free entry */ /* no free entry */
@ -234,7 +234,7 @@ static void set_property( struct window *win, atom_t atom, obj_handle_t handle,
sizeof(*new_props) * (win->prop_alloc + 16) ))) sizeof(*new_props) * (win->prop_alloc + 16) )))
{ {
set_error( STATUS_NO_MEMORY ); set_error( STATUS_NO_MEMORY );
release_global_atom( atom ); release_global_atom( winstation, atom );
return; return;
} }
win->prop_alloc += 16; win->prop_alloc += 16;
@ -248,7 +248,7 @@ static void set_property( struct window *win, atom_t atom, obj_handle_t handle,
} }
/* remove a window property */ /* remove a window property */
static obj_handle_t remove_property( struct window *win, atom_t atom ) static obj_handle_t remove_property( struct winstation *winstation, struct window *win, atom_t atom )
{ {
int i; int i;
@ -257,7 +257,7 @@ static obj_handle_t remove_property( struct window *win, atom_t atom )
if (win->properties[i].type == PROP_TYPE_FREE) continue; if (win->properties[i].type == PROP_TYPE_FREE) continue;
if (win->properties[i].atom == atom) if (win->properties[i].atom == atom)
{ {
release_global_atom( atom ); release_global_atom( winstation, atom );
win->properties[i].type = PROP_TYPE_FREE; win->properties[i].type = PROP_TYPE_FREE;
return win->properties[i].handle; return win->properties[i].handle;
} }
@ -283,15 +283,20 @@ static obj_handle_t get_property( struct window *win, atom_t atom )
/* destroy all properties of a window */ /* destroy all properties of a window */
inline static void destroy_properties( struct window *win ) inline static void destroy_properties( struct window *win )
{ {
struct winstation *winstation;
int i; int i;
if (!win->properties) return; if (!win->properties) return;
/* FIXME: winstation pointer should be taken from window */
if (!(winstation = get_process_winstation( win->thread->process, WINSTA_ACCESSGLOBALATOMS )))
return;
for (i = 0; i < win->prop_inuse; i++) for (i = 0; i < win->prop_inuse; i++)
{ {
if (win->properties[i].type == PROP_TYPE_FREE) continue; if (win->properties[i].type == PROP_TYPE_FREE) continue;
release_global_atom( win->properties[i].atom ); release_global_atom( winstation, win->properties[i].atom );
} }
free( win->properties ); free( win->properties );
release_object( winstation );
} }
/* destroy a window */ /* destroy a window */
@ -1878,34 +1883,42 @@ DECL_HANDLER(redraw_window)
/* set a window property */ /* set a window property */
DECL_HANDLER(set_window_property) DECL_HANDLER(set_window_property)
{ {
struct winstation *winstation;
struct window *win = get_window( req->window ); struct window *win = get_window( req->window );
if (!win) return; if (!win) return;
if (!(winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS ))) return;
if (get_req_data_size()) if (get_req_data_size())
{ {
atom_t atom = add_global_atom( get_req_data(), get_req_data_size() / sizeof(WCHAR) ); atom_t atom = add_global_atom( winstation, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
if (atom) if (atom)
{ {
set_property( win, atom, req->handle, PROP_TYPE_STRING ); set_property( winstation, win, atom, req->handle, PROP_TYPE_STRING );
release_global_atom( atom ); release_global_atom( winstation, atom );
} }
} }
else set_property( win, req->atom, req->handle, PROP_TYPE_ATOM ); else set_property( winstation, win, req->atom, req->handle, PROP_TYPE_ATOM );
release_object( winstation );
} }
/* remove a window property */ /* remove a window property */
DECL_HANDLER(remove_window_property) DECL_HANDLER(remove_window_property)
{ {
struct winstation *winstation;
struct window *win = get_window( req->window ); struct window *win = get_window( req->window );
reply->handle = 0;
if (win) if (!win) return;
if ((winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS )))
{ {
atom_t atom = req->atom; atom_t atom = req->atom;
if (get_req_data_size()) atom = find_global_atom( get_req_data(), if (get_req_data_size()) atom = find_global_atom( winstation, get_req_data(),
get_req_data_size() / sizeof(WCHAR) ); get_req_data_size() / sizeof(WCHAR) );
if (atom) reply->handle = remove_property( win, atom ); if (atom) reply->handle = remove_property( winstation, win, atom );
release_object( winstation );
} }
} }
@ -1913,14 +1926,18 @@ DECL_HANDLER(remove_window_property)
/* get a window property */ /* get a window property */
DECL_HANDLER(get_window_property) DECL_HANDLER(get_window_property)
{ {
struct winstation *winstation;
struct window *win = get_window( req->window ); struct window *win = get_window( req->window );
reply->handle = 0;
if (win) if (!win) return;
if ((winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS )))
{ {
atom_t atom = req->atom; atom_t atom = req->atom;
if (get_req_data_size()) atom = find_global_atom( get_req_data(), if (get_req_data_size()) atom = find_global_atom( winstation, get_req_data(),
get_req_data_size() / sizeof(WCHAR) ); get_req_data_size() / sizeof(WCHAR) );
if (atom) reply->handle = get_property( win, atom ); if (atom) reply->handle = get_property( win, atom );
release_object( winstation );
} }
} }