Store the global atom table in the process window station.

This commit is contained in:
Alexandre Julliard 2005-07-07 11:29:23 +00:00
parent 04d05c9611
commit 248f4b29fe
5 changed files with 74 additions and 25 deletions

View File

@ -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;

View File

@ -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 );

View File

@ -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);

View File

@ -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 );

View File

@ -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 )