Store the global atom table in the process window station.
This commit is contained in:
parent
04d05c9611
commit
248f4b29fe
|
@ -32,6 +32,8 @@
|
|||
#include "object.h"
|
||||
#include "process.h"
|
||||
#include "handle.h"
|
||||
#include "user.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#define HASH_SIZE 37
|
||||
#define MIN_HASH_SIZE 4
|
||||
|
@ -80,8 +82,6 @@ static const struct object_ops atom_table_ops =
|
|||
atom_table_destroy /* destroy */
|
||||
};
|
||||
|
||||
static struct atom_table *global_table;
|
||||
|
||||
|
||||
/* create an atom table */
|
||||
static struct atom_table *create_table(int entries_count)
|
||||
|
@ -205,12 +205,6 @@ static struct atom_entry *find_atom_entry( struct atom_table *table, const WCHAR
|
|||
return entry;
|
||||
}
|
||||
|
||||
/* close the atom table; used on server exit */
|
||||
void close_atom_table(void)
|
||||
{
|
||||
if (global_table) release_object( global_table );
|
||||
}
|
||||
|
||||
/* add an atom to the table */
|
||||
static atom_t add_atom( struct atom_table *table, const WCHAR *str, size_t len )
|
||||
{
|
||||
|
@ -290,24 +284,54 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str, size_t len
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct atom_table* get_table( obj_handle_t h )
|
||||
static struct atom_table *get_global_table( int create )
|
||||
{
|
||||
if (h) return (struct atom_table *)get_handle_obj( current->process, h, 0, &atom_table_ops );
|
||||
struct atom_table *global_table;
|
||||
struct winstation *winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS );
|
||||
|
||||
if (!global_table && !(global_table = create_table( HASH_SIZE ))) return NULL;
|
||||
return (struct atom_table *)grab_object( global_table );
|
||||
if (!winstation) return NULL;
|
||||
|
||||
if (!(global_table = get_winstation_atom_table( winstation )))
|
||||
{
|
||||
if (create)
|
||||
{
|
||||
global_table = create_table( HASH_SIZE );
|
||||
if (global_table) set_winstation_atom_table( winstation, global_table );
|
||||
}
|
||||
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;
|
||||
|
||||
if (h)
|
||||
{
|
||||
table = (struct atom_table *)get_handle_obj( current->process, h, 0, &atom_table_ops );
|
||||
}
|
||||
else
|
||||
{
|
||||
table = get_global_table( 1 );
|
||||
if (table) grab_object( table );
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/* add an atom in the global table; used for window properties */
|
||||
atom_t add_global_atom( const WCHAR *str, size_t len )
|
||||
{
|
||||
if (!global_table && !(global_table = create_table( HASH_SIZE ))) return 0;
|
||||
struct atom_table *global_table = get_global_table( 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 )
|
||||
{
|
||||
struct atom_table *global_table = get_global_table( 0 );
|
||||
struct atom_entry *entry;
|
||||
|
||||
if (!len || len > MAX_ATOM_LEN || !global_table) return 0;
|
||||
|
@ -321,9 +345,14 @@ int grab_global_atom( atom_t atom )
|
|||
{
|
||||
if (atom >= MIN_STR_ATOM)
|
||||
{
|
||||
struct atom_entry *entry = get_atom_entry( global_table, atom );
|
||||
if (entry) entry->count++;
|
||||
return (entry != NULL);
|
||||
struct atom_table *global_table = get_global_table( 0 );
|
||||
if (global_table)
|
||||
{
|
||||
struct atom_entry *entry = get_atom_entry( global_table, atom );
|
||||
if (entry) entry->count++;
|
||||
return (entry != NULL);
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
else return 1;
|
||||
}
|
||||
|
@ -331,13 +360,17 @@ 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 )
|
||||
{
|
||||
if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom, 1 );
|
||||
if (atom >= MIN_STR_ATOM)
|
||||
{
|
||||
struct atom_table *global_table = get_global_table( 0 );
|
||||
if (global_table) delete_atom( global_table, atom, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* add a global atom */
|
||||
DECL_HANDLER(add_atom)
|
||||
{
|
||||
struct atom_table *table = get_table( req->table );
|
||||
struct atom_table *table = get_table( req->table, 1 );
|
||||
if (table)
|
||||
{
|
||||
reply->atom = add_atom( table, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
|
||||
|
@ -348,7 +381,7 @@ DECL_HANDLER(add_atom)
|
|||
/* delete a global atom */
|
||||
DECL_HANDLER(delete_atom)
|
||||
{
|
||||
struct atom_table *table = get_table( req->table );
|
||||
struct atom_table *table = get_table( req->table, 0 );
|
||||
if (table)
|
||||
{
|
||||
delete_atom( table, req->atom, 0 );
|
||||
|
@ -359,7 +392,7 @@ DECL_HANDLER(delete_atom)
|
|||
/* find a global atom */
|
||||
DECL_HANDLER(find_atom)
|
||||
{
|
||||
struct atom_table *table = get_table( req->table );
|
||||
struct atom_table *table = get_table( req->table, 0 );
|
||||
if (table)
|
||||
{
|
||||
reply->atom = find_atom( table, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
|
||||
|
@ -370,7 +403,7 @@ DECL_HANDLER(find_atom)
|
|||
/* get global atom name */
|
||||
DECL_HANDLER(get_atom_information)
|
||||
{
|
||||
struct atom_table *table = get_table( req->table );
|
||||
struct atom_table *table = get_table( req->table, 0 );
|
||||
if (table)
|
||||
{
|
||||
struct atom_entry *entry;
|
||||
|
@ -391,7 +424,7 @@ DECL_HANDLER(get_atom_information)
|
|||
/* set global atom name */
|
||||
DECL_HANDLER(set_atom_information)
|
||||
{
|
||||
struct atom_table *table = get_table( req->table );
|
||||
struct atom_table *table = get_table( req->table, 0 );
|
||||
if (table)
|
||||
{
|
||||
struct atom_entry *entry;
|
||||
|
@ -419,7 +452,7 @@ DECL_HANDLER(init_atom_table)
|
|||
/* set global atom name */
|
||||
DECL_HANDLER(empty_atom_table)
|
||||
{
|
||||
struct atom_table *table = get_table( req->table );
|
||||
struct atom_table *table = get_table( req->table, 1 );
|
||||
if (table)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -157,7 +157,6 @@ extern void close_signals(void);
|
|||
|
||||
/* atom functions */
|
||||
|
||||
extern void close_atom_table(void);
|
||||
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 );
|
||||
|
|
|
@ -798,7 +798,6 @@ static void close_socket_timeout( void *arg )
|
|||
close_global_hooks();
|
||||
close_global_handles();
|
||||
close_registry();
|
||||
close_atom_table();
|
||||
dump_objects(); /* dump any remaining objects */
|
||||
#else
|
||||
exit(0);
|
||||
|
|
|
@ -29,6 +29,7 @@ struct window;
|
|||
struct msg_queue;
|
||||
struct hook_table;
|
||||
struct window_class;
|
||||
struct atom_table;
|
||||
struct clipboard;
|
||||
|
||||
enum user_object
|
||||
|
@ -123,7 +124,9 @@ extern void *get_class_client_ptr( struct window_class *class );
|
|||
|
||||
extern struct winstation *get_process_winstation( struct process *process, unsigned int access );
|
||||
extern void set_winstation_clipboard( struct winstation *winstation, struct clipboard *clipboard );
|
||||
extern void set_winstation_atom_table( struct winstation *winstation, struct atom_table *table );
|
||||
extern struct clipboard *get_winstation_clipboard( struct winstation *winstation );
|
||||
extern struct atom_table *get_winstation_atom_table( struct winstation *winstation );
|
||||
extern void connect_process_winstation( struct process *process, const WCHAR *name, size_t len );
|
||||
extern void connect_process_desktop( struct process *process, const WCHAR *name, size_t len );
|
||||
extern void close_thread_desktop( struct thread *thread );
|
||||
|
|
|
@ -42,6 +42,7 @@ struct winstation
|
|||
struct list entry; /* entry in global winstation list */
|
||||
struct list desktops; /* list of desktops of this winstation */
|
||||
struct clipboard *clipboard; /* clipboard information */
|
||||
struct atom_table *atom_table; /* global atom table */
|
||||
};
|
||||
|
||||
struct desktop
|
||||
|
@ -115,6 +116,7 @@ static struct winstation *create_winstation( const WCHAR *name, size_t len, unsi
|
|||
/* initialize it if it didn't already exist */
|
||||
winstation->flags = flags;
|
||||
winstation->clipboard = NULL;
|
||||
winstation->atom_table = NULL;
|
||||
list_add_tail( &winstation_list, &winstation->entry );
|
||||
list_init( &winstation->desktops );
|
||||
}
|
||||
|
@ -143,6 +145,7 @@ static void winstation_destroy( struct object *obj )
|
|||
if (winstation == interactive_winstation) interactive_winstation = NULL;
|
||||
list_remove( &winstation->entry );
|
||||
if (winstation->clipboard) release_object( winstation->clipboard );
|
||||
if (winstation->atom_table) release_object( winstation->atom_table );
|
||||
}
|
||||
|
||||
/* retrieve the process window station, checking the handle access rights */
|
||||
|
@ -164,6 +167,18 @@ struct clipboard *get_winstation_clipboard( struct winstation *winstation )
|
|||
return winstation->clipboard;
|
||||
}
|
||||
|
||||
/* set the pointer to the (opaque) atom table */
|
||||
void set_winstation_atom_table( struct winstation *winstation, struct atom_table *table )
|
||||
{
|
||||
winstation->atom_table = table;
|
||||
}
|
||||
|
||||
/* retrieve the pointer to the (opaque) clipboard info */
|
||||
struct atom_table *get_winstation_atom_table( struct winstation *winstation )
|
||||
{
|
||||
return winstation->atom_table;
|
||||
}
|
||||
|
||||
/* build the full name of a desktop object */
|
||||
static WCHAR *build_desktop_name( const WCHAR *name, size_t len,
|
||||
struct winstation *winstation, size_t *res_len )
|
||||
|
|
Loading…
Reference in New Issue