server: Use a unicode_str to represent atom names.

This commit is contained in:
Alexandre Julliard 2008-06-25 14:03:08 +02:00
parent 92c8cac214
commit 25e070c0ac
4 changed files with 59 additions and 53 deletions

View File

@ -43,7 +43,7 @@
#define MIN_HASH_SIZE 4
#define MAX_HASH_SIZE 0x200
#define MAX_ATOM_LEN 255
#define MAX_ATOM_LEN (255 * sizeof(WCHAR))
#define MIN_STR_ATOM 0xc000
#define MAX_ATOMS 0x4000
@ -160,11 +160,11 @@ static atom_t add_atom_entry( struct atom_table *table, struct atom_entry *entry
}
/* compute the hash code for a string */
static unsigned short atom_hash( struct atom_table *table, const WCHAR *str, data_size_t len )
static unsigned short atom_hash( struct atom_table *table, const struct unicode_str *str )
{
unsigned int i;
unsigned short hash = 0;
for (i = 0; i < len; i++) hash ^= toupperW(str[i]) + i;
for (i = 0; i < str->len / sizeof(WCHAR); i++) hash ^= toupperW(str->str[i]) + i;
return hash % table->entries_count;
}
@ -184,7 +184,7 @@ static void atom_table_dump( struct object *obj, int verbose )
if (!entry) continue;
fprintf( stderr, " %04x: ref=%d pinned=%c hash=%d \"",
entry->atom, entry->count, entry->pinned ? 'Y' : 'N', entry->hash );
dump_strW( entry->str, entry->len, stderr, "\"\"");
dump_strW( entry->str, entry->len / sizeof(WCHAR), stderr, "\"\"");
fprintf( stderr, "\"\n" );
}
}
@ -204,42 +204,42 @@ static void atom_table_destroy( struct object *obj )
}
/* find an atom entry in its hash list */
static struct atom_entry *find_atom_entry( struct atom_table *table, const WCHAR *str,
data_size_t len, unsigned short hash )
static struct atom_entry *find_atom_entry( struct atom_table *table, const struct unicode_str *str,
unsigned short hash )
{
struct atom_entry *entry = table->entries[hash];
while (entry)
{
if (entry->len == len && !memicmpW( entry->str, str, len )) break;
if (entry->len == str->len && !memicmpW( entry->str, str->str, str->len/sizeof(WCHAR) )) break;
entry = entry->next;
}
return entry;
}
/* add an atom to the table */
static atom_t add_atom( struct atom_table *table, const WCHAR *str, data_size_t len )
static atom_t add_atom( struct atom_table *table, const struct unicode_str *str )
{
struct atom_entry *entry;
unsigned short hash = atom_hash( table, str, len );
unsigned short hash = atom_hash( table, str );
atom_t atom = 0;
if (!len)
if (!str->len)
{
set_error( STATUS_OBJECT_NAME_INVALID );
return 0;
}
if (len > MAX_ATOM_LEN)
if (str->len > MAX_ATOM_LEN)
{
set_error( STATUS_INVALID_PARAMETER );
return 0;
}
if ((entry = find_atom_entry( table, str, len, hash ))) /* exists already */
if ((entry = find_atom_entry( table, str, hash ))) /* exists already */
{
entry->count++;
return entry->atom;
}
if ((entry = mem_alloc( sizeof(*entry) + (len - 1) * sizeof(WCHAR) )))
if ((entry = mem_alloc( FIELD_OFFSET( struct atom_entry, str[str->len / sizeof(WCHAR)] ) )))
{
if ((atom = add_atom_entry( table, entry )))
{
@ -249,8 +249,8 @@ static atom_t add_atom( struct atom_table *table, const WCHAR *str, data_size_t
entry->count = 1;
entry->pinned = 0;
entry->hash = hash;
entry->len = len;
memcpy( entry->str, str, len * sizeof(WCHAR) );
entry->len = str->len;
memcpy( entry->str, str->str, str->len );
}
else free( entry );
}
@ -275,21 +275,21 @@ static void delete_atom( struct atom_table *table, atom_t atom, int if_pinned )
}
/* find an atom in the table */
static atom_t find_atom( struct atom_table *table, const WCHAR *str, data_size_t len )
static atom_t find_atom( struct atom_table *table, const struct unicode_str *str )
{
struct atom_entry *entry;
if (!len)
if (!str->len)
{
set_error( STATUS_OBJECT_NAME_INVALID );
return 0;
}
if (len > MAX_ATOM_LEN)
if (str->len > MAX_ATOM_LEN)
{
set_error( STATUS_INVALID_PARAMETER );
return 0;
}
if (table && (entry = find_atom_entry( table, str, len, atom_hash(table, str, len) )))
if (table && (entry = find_atom_entry( table, str, atom_hash(table, str) )))
return entry->atom;
set_error( STATUS_OBJECT_NAME_NOT_FOUND );
return 0;
@ -332,21 +332,21 @@ static struct atom_table *get_table( obj_handle_t h, int create )
}
/* add an atom in the global table; used for window properties */
atom_t add_global_atom( struct winstation *winstation, const WCHAR *str, data_size_t len )
atom_t add_global_atom( struct winstation *winstation, const struct unicode_str *str )
{
struct atom_table *global_table = get_global_table( winstation, 1 );
if (!global_table) return 0;
return add_atom( global_table, str, len );
return add_atom( global_table, str );
}
/* find an atom in the global table; used for window properties */
atom_t find_global_atom( struct winstation *winstation, const WCHAR *str, data_size_t len )
atom_t find_global_atom( struct winstation *winstation, const struct unicode_str *str )
{
struct atom_table *global_table = get_global_table( winstation, 0 );
struct atom_entry *entry;
if (!len || len > MAX_ATOM_LEN || !global_table) return 0;
if ((entry = find_atom_entry( global_table, str, len, atom_hash(global_table, str, len) )))
if (!str->len || str->len > MAX_ATOM_LEN || !global_table) return 0;
if ((entry = find_atom_entry( global_table, str, atom_hash(global_table, str) )))
return entry->atom;
return 0;
}
@ -381,10 +381,13 @@ void release_global_atom( struct winstation *winstation, atom_t atom )
/* add a global atom */
DECL_HANDLER(add_atom)
{
struct unicode_str name;
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) );
get_req_unicode_str( &name );
reply->atom = add_atom( table, &name );
release_object( table );
}
}
@ -403,10 +406,13 @@ DECL_HANDLER(delete_atom)
/* find a global atom */
DECL_HANDLER(find_atom)
{
struct unicode_str name;
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) );
get_req_unicode_str( &name );
reply->atom = find_atom( table, &name );
release_object( table );
}
}
@ -421,12 +427,10 @@ DECL_HANDLER(get_atom_information)
if ((entry = get_atom_entry( table, req->atom )))
{
data_size_t len = entry->len * sizeof(WCHAR);
if (get_reply_max_size())
set_reply_data( entry->str, min( len, get_reply_max_size()));
set_reply_data( entry->str, min( entry->len, get_reply_max_size() ));
reply->count = entry->count;
reply->pinned = entry->pinned;
reply->total = len;
reply->total = entry->len;
}
else reply->count = -1;
release_object( table );

View File

@ -142,11 +142,13 @@ void *get_class_client_ptr( struct window_class *class )
DECL_HANDLER(create_class)
{
struct window_class *class;
struct unicode_str name;
atom_t atom;
if (get_req_data_size())
get_req_unicode_str( &name );
if (name.len)
{
atom = add_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
atom = add_global_atom( NULL, &name );
if (!atom) return;
}
else
@ -187,10 +189,11 @@ DECL_HANDLER(create_class)
DECL_HANDLER(destroy_class)
{
struct window_class *class;
struct unicode_str name;
atom_t atom = req->atom;
if (get_req_data_size())
atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
get_req_unicode_str( &name );
if (name.len) atom = find_global_atom( NULL, &name );
if (!(class = find_class( current->process, atom, req->instance )))
set_win32_error( ERROR_CLASS_DOES_NOT_EXIST );

View File

@ -197,8 +197,8 @@ extern void init_signals(void);
/* atom functions */
extern atom_t add_global_atom( struct winstation *winstation, const WCHAR *str, data_size_t len );
extern atom_t find_global_atom( struct winstation *winstation, const WCHAR *str, data_size_t len );
extern atom_t add_global_atom( struct winstation *winstation, const struct unicode_str *str );
extern atom_t find_global_atom( struct winstation *winstation, const struct unicode_str *str );
extern int grab_global_atom( struct winstation *winstation, atom_t atom );
extern void release_global_atom( struct winstation *winstation, atom_t atom );

View File

@ -1709,6 +1709,7 @@ static void set_window_region( struct window *win, struct region *region, int re
DECL_HANDLER(create_window)
{
struct window *win, *parent, *owner = NULL;
struct unicode_str cls_name;
atom_t atom;
reply->handle = 0;
@ -1730,10 +1731,8 @@ DECL_HANDLER(create_window)
while (!is_desktop_window(owner->parent)) owner = owner->parent;
}
if (get_req_data_size())
atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
else
atom = req->atom;
get_req_unicode_str( &cls_name );
atom = cls_name.len ? find_global_atom( NULL, &cls_name ) : req->atom;
if (!(win = create_window( parent, owner, atom, req->instance ))) return;
@ -1905,6 +1904,7 @@ DECL_HANDLER(get_window_children)
int total = 0;
user_handle_t *data;
data_size_t len;
struct unicode_str cls_name;
atom_t atom = req->atom;
if (req->desktop)
@ -1918,11 +1918,8 @@ DECL_HANDLER(get_window_children)
if (!parent) return;
if (get_req_data_size())
{
atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
if (!atom) return;
}
get_req_unicode_str( &cls_name );
if (cls_name.len && !(atom = find_global_atom( NULL, &cls_name ))) return;
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
{
@ -2336,13 +2333,15 @@ DECL_HANDLER(redraw_window)
/* set a window property */
DECL_HANDLER(set_window_property)
{
struct unicode_str name;
struct window *win = get_window( req->window );
if (!win) return;
if (get_req_data_size())
get_req_unicode_str( &name );
if (name.len)
{
atom_t atom = add_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
atom_t atom = add_global_atom( NULL, &name );
if (atom)
{
set_property( win, atom, req->handle, PROP_TYPE_STRING );
@ -2356,13 +2355,13 @@ DECL_HANDLER(set_window_property)
/* remove a window property */
DECL_HANDLER(remove_window_property)
{
struct unicode_str name;
struct window *win = get_window( req->window );
get_req_unicode_str( &name );
if (win)
{
atom_t atom = req->atom;
if (get_req_data_size()) atom = find_global_atom( NULL, get_req_data(),
get_req_data_size() / sizeof(WCHAR) );
atom_t atom = name.len ? find_global_atom( NULL, &name ) : req->atom;
if (atom) reply->handle = remove_property( win, atom );
}
}
@ -2371,13 +2370,13 @@ DECL_HANDLER(remove_window_property)
/* get a window property */
DECL_HANDLER(get_window_property)
{
struct unicode_str name;
struct window *win = get_window( req->window );
get_req_unicode_str( &name );
if (win)
{
atom_t atom = req->atom;
if (get_req_data_size()) atom = find_global_atom( NULL, get_req_data(),
get_req_data_size() / sizeof(WCHAR) );
atom_t atom = name.len ? find_global_atom( NULL, &name ) : req->atom;
if (atom) reply->handle = get_property( win, atom );
}
}