Commit 25e070c0 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Use a unicode_str to represent atom names.

parent 92c8cac2
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#define MIN_HASH_SIZE 4 #define MIN_HASH_SIZE 4
#define MAX_HASH_SIZE 0x200 #define MAX_HASH_SIZE 0x200
#define MAX_ATOM_LEN 255 #define MAX_ATOM_LEN (255 * sizeof(WCHAR))
#define MIN_STR_ATOM 0xc000 #define MIN_STR_ATOM 0xc000
#define MAX_ATOMS 0x4000 #define MAX_ATOMS 0x4000
...@@ -160,11 +160,11 @@ static atom_t add_atom_entry( struct atom_table *table, struct atom_entry *entry ...@@ -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 */ /* 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 int i;
unsigned short hash = 0; 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; return hash % table->entries_count;
} }
...@@ -184,7 +184,7 @@ static void atom_table_dump( struct object *obj, int verbose ) ...@@ -184,7 +184,7 @@ static void atom_table_dump( struct object *obj, int verbose )
if (!entry) continue; if (!entry) continue;
fprintf( stderr, " %04x: ref=%d pinned=%c hash=%d \"", fprintf( stderr, " %04x: ref=%d pinned=%c hash=%d \"",
entry->atom, entry->count, entry->pinned ? 'Y' : 'N', entry->hash ); 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" ); fprintf( stderr, "\"\n" );
} }
} }
...@@ -204,42 +204,42 @@ static void atom_table_destroy( struct object *obj ) ...@@ -204,42 +204,42 @@ static void atom_table_destroy( struct object *obj )
} }
/* find an atom entry in its hash list */ /* find an atom entry in its hash list */
static struct atom_entry *find_atom_entry( struct atom_table *table, const WCHAR *str, static struct atom_entry *find_atom_entry( struct atom_table *table, const struct unicode_str *str,
data_size_t len, unsigned short hash ) unsigned short hash )
{ {
struct atom_entry *entry = table->entries[hash]; struct atom_entry *entry = table->entries[hash];
while (entry) 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; entry = entry->next;
} }
return entry; return entry;
} }
/* add an atom to the table */ /* 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; struct atom_entry *entry;
unsigned short hash = atom_hash( table, str, len ); unsigned short hash = atom_hash( table, str );
atom_t atom = 0; atom_t atom = 0;
if (!len) if (!str->len)
{ {
set_error( STATUS_OBJECT_NAME_INVALID ); set_error( STATUS_OBJECT_NAME_INVALID );
return 0; return 0;
} }
if (len > MAX_ATOM_LEN) if (str->len > MAX_ATOM_LEN)
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return 0; 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++; entry->count++;
return entry->atom; 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 ))) 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 ...@@ -249,8 +249,8 @@ static atom_t add_atom( struct atom_table *table, const WCHAR *str, data_size_t
entry->count = 1; entry->count = 1;
entry->pinned = 0; entry->pinned = 0;
entry->hash = hash; entry->hash = hash;
entry->len = len; entry->len = str->len;
memcpy( entry->str, str, len * sizeof(WCHAR) ); memcpy( entry->str, str->str, str->len );
} }
else free( entry ); else free( entry );
} }
...@@ -275,21 +275,21 @@ static void delete_atom( struct atom_table *table, atom_t atom, int if_pinned ) ...@@ -275,21 +275,21 @@ static void delete_atom( struct atom_table *table, atom_t atom, int if_pinned )
} }
/* find an atom in the table */ /* 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; struct atom_entry *entry;
if (!len) if (!str->len)
{ {
set_error( STATUS_OBJECT_NAME_INVALID ); set_error( STATUS_OBJECT_NAME_INVALID );
return 0; return 0;
} }
if (len > MAX_ATOM_LEN) if (str->len > MAX_ATOM_LEN)
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return 0; 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; return entry->atom;
set_error( STATUS_OBJECT_NAME_NOT_FOUND ); set_error( STATUS_OBJECT_NAME_NOT_FOUND );
return 0; return 0;
...@@ -332,21 +332,21 @@ static struct atom_table *get_table( obj_handle_t h, int create ) ...@@ -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 */ /* 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 ); 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 );
} }
/* 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( 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_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 (!str->len || str->len > MAX_ATOM_LEN || !global_table) return 0;
if ((entry = find_atom_entry( global_table, str, len, atom_hash(global_table, str, len) ))) if ((entry = find_atom_entry( global_table, str, atom_hash(global_table, str) )))
return entry->atom; return entry->atom;
return 0; return 0;
} }
...@@ -381,10 +381,13 @@ void release_global_atom( struct winstation *winstation, atom_t atom ) ...@@ -381,10 +381,13 @@ void release_global_atom( struct winstation *winstation, atom_t atom )
/* add a global atom */ /* add a global atom */
DECL_HANDLER(add_atom) DECL_HANDLER(add_atom)
{ {
struct unicode_str name;
struct atom_table *table = get_table( req->table, 1 ); struct atom_table *table = get_table( req->table, 1 );
if (table) 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 ); release_object( table );
} }
} }
...@@ -403,10 +406,13 @@ DECL_HANDLER(delete_atom) ...@@ -403,10 +406,13 @@ DECL_HANDLER(delete_atom)
/* find a global atom */ /* find a global atom */
DECL_HANDLER(find_atom) DECL_HANDLER(find_atom)
{ {
struct unicode_str name;
struct atom_table *table = get_table( req->table, 0 ); struct atom_table *table = get_table( req->table, 0 );
if (table) 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 ); release_object( table );
} }
} }
...@@ -421,12 +427,10 @@ DECL_HANDLER(get_atom_information) ...@@ -421,12 +427,10 @@ DECL_HANDLER(get_atom_information)
if ((entry = get_atom_entry( table, req->atom ))) if ((entry = get_atom_entry( table, req->atom )))
{ {
data_size_t len = entry->len * sizeof(WCHAR); set_reply_data( entry->str, min( entry->len, get_reply_max_size() ));
if (get_reply_max_size())
set_reply_data( entry->str, min( len, get_reply_max_size()));
reply->count = entry->count; reply->count = entry->count;
reply->pinned = entry->pinned; reply->pinned = entry->pinned;
reply->total = len; reply->total = entry->len;
} }
else reply->count = -1; else reply->count = -1;
release_object( table ); release_object( table );
......
...@@ -142,11 +142,13 @@ void *get_class_client_ptr( struct window_class *class ) ...@@ -142,11 +142,13 @@ 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 unicode_str name;
atom_t atom; 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; if (!atom) return;
} }
else else
...@@ -187,10 +189,11 @@ DECL_HANDLER(create_class) ...@@ -187,10 +189,11 @@ DECL_HANDLER(create_class)
DECL_HANDLER(destroy_class) DECL_HANDLER(destroy_class)
{ {
struct window_class *class; struct window_class *class;
struct unicode_str name;
atom_t atom = req->atom; atom_t atom = req->atom;
if (get_req_data_size()) get_req_unicode_str( &name );
atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); if (name.len) atom = find_global_atom( NULL, &name );
if (!(class = find_class( current->process, atom, req->instance ))) if (!(class = find_class( current->process, atom, req->instance )))
set_win32_error( ERROR_CLASS_DOES_NOT_EXIST ); set_win32_error( ERROR_CLASS_DOES_NOT_EXIST );
......
...@@ -197,8 +197,8 @@ extern void init_signals(void); ...@@ -197,8 +197,8 @@ extern void init_signals(void);
/* atom functions */ /* atom functions */
extern atom_t add_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 WCHAR *str, data_size_t len ); 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 int grab_global_atom( struct winstation *winstation, atom_t atom );
extern void release_global_atom( struct winstation *winstation, atom_t atom ); extern void release_global_atom( struct winstation *winstation, atom_t atom );
......
...@@ -1709,6 +1709,7 @@ static void set_window_region( struct window *win, struct region *region, int re ...@@ -1709,6 +1709,7 @@ static void set_window_region( struct window *win, struct region *region, int re
DECL_HANDLER(create_window) DECL_HANDLER(create_window)
{ {
struct window *win, *parent, *owner = NULL; struct window *win, *parent, *owner = NULL;
struct unicode_str cls_name;
atom_t atom; atom_t atom;
reply->handle = 0; reply->handle = 0;
...@@ -1730,10 +1731,8 @@ DECL_HANDLER(create_window) ...@@ -1730,10 +1731,8 @@ DECL_HANDLER(create_window)
while (!is_desktop_window(owner->parent)) owner = owner->parent; while (!is_desktop_window(owner->parent)) owner = owner->parent;
} }
if (get_req_data_size()) get_req_unicode_str( &cls_name );
atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); atom = cls_name.len ? find_global_atom( NULL, &cls_name ) : req->atom;
else
atom = req->atom;
if (!(win = create_window( parent, owner, atom, req->instance ))) return; if (!(win = create_window( parent, owner, atom, req->instance ))) return;
...@@ -1905,6 +1904,7 @@ DECL_HANDLER(get_window_children) ...@@ -1905,6 +1904,7 @@ DECL_HANDLER(get_window_children)
int total = 0; int total = 0;
user_handle_t *data; user_handle_t *data;
data_size_t len; data_size_t len;
struct unicode_str cls_name;
atom_t atom = req->atom; atom_t atom = req->atom;
if (req->desktop) if (req->desktop)
...@@ -1918,11 +1918,8 @@ DECL_HANDLER(get_window_children) ...@@ -1918,11 +1918,8 @@ DECL_HANDLER(get_window_children)
if (!parent) return; if (!parent) return;
if (get_req_data_size()) get_req_unicode_str( &cls_name );
{ if (cls_name.len && !(atom = find_global_atom( NULL, &cls_name ))) return;
atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
if (!atom) return;
}
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
{ {
...@@ -2336,13 +2333,15 @@ DECL_HANDLER(redraw_window) ...@@ -2336,13 +2333,15 @@ DECL_HANDLER(redraw_window)
/* set a window property */ /* set a window property */
DECL_HANDLER(set_window_property) DECL_HANDLER(set_window_property)
{ {
struct unicode_str name;
struct window *win = get_window( req->window ); struct window *win = get_window( req->window );
if (!win) return; 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) if (atom)
{ {
set_property( win, atom, req->handle, PROP_TYPE_STRING ); set_property( win, atom, req->handle, PROP_TYPE_STRING );
...@@ -2356,13 +2355,13 @@ DECL_HANDLER(set_window_property) ...@@ -2356,13 +2355,13 @@ DECL_HANDLER(set_window_property)
/* remove a window property */ /* remove a window property */
DECL_HANDLER(remove_window_property) DECL_HANDLER(remove_window_property)
{ {
struct unicode_str name;
struct window *win = get_window( req->window ); struct window *win = get_window( req->window );
get_req_unicode_str( &name );
if (win) if (win)
{ {
atom_t atom = req->atom; atom_t atom = name.len ? find_global_atom( NULL, &name ) : req->atom;
if (get_req_data_size()) atom = find_global_atom( NULL, get_req_data(),
get_req_data_size() / sizeof(WCHAR) );
if (atom) reply->handle = remove_property( win, atom ); if (atom) reply->handle = remove_property( win, atom );
} }
} }
...@@ -2371,13 +2370,13 @@ DECL_HANDLER(remove_window_property) ...@@ -2371,13 +2370,13 @@ DECL_HANDLER(remove_window_property)
/* get a window property */ /* get a window property */
DECL_HANDLER(get_window_property) DECL_HANDLER(get_window_property)
{ {
struct unicode_str name;
struct window *win = get_window( req->window ); struct window *win = get_window( req->window );
get_req_unicode_str( &name );
if (win) if (win)
{ {
atom_t atom = req->atom; atom_t atom = name.len ? find_global_atom( NULL, &name ) : req->atom;
if (get_req_data_size()) atom = find_global_atom( NULL, get_req_data(),
get_req_data_size() / sizeof(WCHAR) );
if (atom) reply->handle = get_property( win, atom ); if (atom) reply->handle = get_property( win, atom );
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment