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:
parent
6fd3c47c4f
commit
c3ac57dd86
|
@ -284,12 +284,9 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str, size_t len
|
|||
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 winstation *winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS );
|
||||
|
||||
if (!winstation) return NULL;
|
||||
|
||||
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 );
|
||||
}
|
||||
release_object( winstation );
|
||||
return global_table;
|
||||
}
|
||||
|
||||
static struct atom_table *get_table( obj_handle_t h, int create )
|
||||
{
|
||||
struct atom_table *table;
|
||||
struct atom_table *table = NULL;
|
||||
|
||||
if (h)
|
||||
{
|
||||
|
@ -314,24 +310,30 @@ static struct atom_table *get_table( obj_handle_t h, int create )
|
|||
}
|
||||
else
|
||||
{
|
||||
table = get_global_table( 1 );
|
||||
if (table) grab_object( table );
|
||||
struct winstation *winstation = get_process_winstation( current->process,
|
||||
WINSTA_ACCESSGLOBALATOMS );
|
||||
if (winstation)
|
||||
{
|
||||
table = get_global_table( winstation, 1 );
|
||||
if (table) grab_object( table );
|
||||
release_object( winstation );
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
return add_atom( global_table, str, len );
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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 */
|
||||
int grab_global_atom( atom_t atom )
|
||||
int grab_global_atom( struct winstation *winstation, atom_t 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)
|
||||
{
|
||||
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 */
|
||||
void release_global_atom( atom_t atom )
|
||||
void release_global_atom( struct winstation *winstation, atom_t 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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "object.h"
|
||||
#include "process.h"
|
||||
#include "user.h"
|
||||
#include "winuser.h"
|
||||
|
||||
struct window_class
|
||||
{
|
||||
|
@ -156,6 +157,7 @@ void *get_class_client_ptr( struct window_class *class )
|
|||
DECL_HANDLER(create_class)
|
||||
{
|
||||
struct window_class *class;
|
||||
struct winstation *winstation;
|
||||
|
||||
if (!req->local && req->atom == DESKTOP_ATOM)
|
||||
{
|
||||
|
@ -175,11 +177,19 @@ DECL_HANDLER(create_class)
|
|||
set_error( STATUS_INVALID_PARAMETER );
|
||||
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 )))
|
||||
{
|
||||
release_global_atom( req->atom );
|
||||
release_global_atom( winstation, req->atom );
|
||||
release_object( winstation );
|
||||
return;
|
||||
}
|
||||
class->atom = req->atom;
|
||||
|
@ -187,6 +197,7 @@ DECL_HANDLER(create_class)
|
|||
class->style = req->style;
|
||||
class->win_extra = req->win_extra;
|
||||
class->client_ptr = req->client_ptr;
|
||||
release_object( winstation );
|
||||
}
|
||||
|
||||
/* destroy a window class */
|
||||
|
@ -249,9 +260,16 @@ DECL_HANDLER(set_class_info)
|
|||
|
||||
if (req->flags & SET_CLASS_ATOM)
|
||||
{
|
||||
if (!grab_global_atom( req->atom )) return;
|
||||
release_global_atom( class->atom );
|
||||
struct winstation *winstation = get_process_winstation( current->process,
|
||||
WINSTA_ACCESSGLOBALATOMS );
|
||||
if (!grab_global_atom( winstation, req->atom ))
|
||||
{
|
||||
release_object( winstation );
|
||||
return;
|
||||
}
|
||||
release_global_atom( winstation, class->atom );
|
||||
class->atom = req->atom;
|
||||
release_object( winstation );
|
||||
}
|
||||
if (req->flags & SET_CLASS_STYLE) class->style = req->style;
|
||||
if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra;
|
||||
|
|
|
@ -43,6 +43,7 @@ struct file;
|
|||
struct wait_queue_entry;
|
||||
struct async;
|
||||
struct async_queue;
|
||||
struct winstation;
|
||||
|
||||
/* operations valid on all objects */
|
||||
struct object_ops
|
||||
|
@ -157,10 +158,10 @@ extern void close_signals(void);
|
|||
|
||||
/* atom functions */
|
||||
|
||||
extern atom_t add_global_atom( const WCHAR *str, size_t len );
|
||||
extern atom_t find_global_atom( const WCHAR *str, size_t len );
|
||||
extern int grab_global_atom( atom_t atom );
|
||||
extern void release_global_atom( atom_t atom );
|
||||
extern atom_t add_global_atom( struct winstation *winstation, 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( struct winstation *winstation, atom_t atom );
|
||||
extern void release_global_atom( struct winstation *winstation, atom_t atom );
|
||||
|
||||
/* global variables */
|
||||
|
||||
|
|
|
@ -200,8 +200,8 @@ static int add_handle_to_array( struct user_handle_array *array, user_handle_t h
|
|||
}
|
||||
|
||||
/* set a window property */
|
||||
static void set_property( struct window *win, atom_t atom, obj_handle_t handle,
|
||||
enum property_type type )
|
||||
static void set_property( struct winstation *winstation, struct window *win,
|
||||
atom_t atom, obj_handle_t handle, enum property_type type )
|
||||
{
|
||||
int i, free = -1;
|
||||
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 */
|
||||
if (!grab_global_atom( atom )) return;
|
||||
if (!grab_global_atom( winstation, atom )) return;
|
||||
if (free == -1)
|
||||
{
|
||||
/* 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) )))
|
||||
{
|
||||
set_error( STATUS_NO_MEMORY );
|
||||
release_global_atom( atom );
|
||||
release_global_atom( winstation, atom );
|
||||
return;
|
||||
}
|
||||
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 */
|
||||
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;
|
||||
|
||||
|
@ -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].atom == atom)
|
||||
{
|
||||
release_global_atom( atom );
|
||||
release_global_atom( winstation, atom );
|
||||
win->properties[i].type = PROP_TYPE_FREE;
|
||||
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 */
|
||||
inline static void destroy_properties( struct window *win )
|
||||
{
|
||||
struct winstation *winstation;
|
||||
int i;
|
||||
|
||||
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++)
|
||||
{
|
||||
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 );
|
||||
release_object( winstation );
|
||||
}
|
||||
|
||||
/* destroy a window */
|
||||
|
@ -1878,34 +1883,42 @@ DECL_HANDLER(redraw_window)
|
|||
/* set a window property */
|
||||
DECL_HANDLER(set_window_property)
|
||||
{
|
||||
struct winstation *winstation;
|
||||
struct window *win = get_window( req->window );
|
||||
|
||||
if (!win) return;
|
||||
if (!(winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS ))) return;
|
||||
|
||||
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)
|
||||
{
|
||||
set_property( win, atom, req->handle, PROP_TYPE_STRING );
|
||||
release_global_atom( atom );
|
||||
set_property( winstation, win, atom, req->handle, PROP_TYPE_STRING );
|
||||
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 */
|
||||
DECL_HANDLER(remove_window_property)
|
||||
{
|
||||
struct winstation *winstation;
|
||||
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;
|
||||
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) );
|
||||
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 */
|
||||
DECL_HANDLER(get_window_property)
|
||||
{
|
||||
struct winstation *winstation;
|
||||
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;
|
||||
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) );
|
||||
if (atom) reply->handle = get_property( win, atom );
|
||||
release_object( winstation );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue