diff --git a/server/atom.c b/server/atom.c index 11f4b46ffb2..57aff7b8918 100644 --- a/server/atom.c +++ b/server/atom.c @@ -163,15 +163,6 @@ static atom_t add_atom_entry( struct atom_table *table, struct atom_entry *entry return entry->atom; } -/* compute the hash code for a string */ -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 < str->len / sizeof(WCHAR); i++) hash ^= toupperW(str->str[i]) + i; - return hash % table->entries_count; -} - /* dump an atom table */ static void atom_table_dump( struct object *obj, int verbose ) { @@ -224,7 +215,7 @@ static struct atom_entry *find_atom_entry( struct atom_table *table, const struc 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 ); + unsigned short hash = hash_strW( str->str, str->len, table->entries_count ); atom_t atom = 0; if (!str->len) @@ -293,7 +284,8 @@ static atom_t find_atom( struct atom_table *table, const struct unicode_str *str set_error( STATUS_INVALID_PARAMETER ); return 0; } - if (table && (entry = find_atom_entry( table, str, atom_hash(table, str) ))) + if (table && (entry = find_atom_entry( table, str, + hash_strW( str->str, str->len, table->entries_count )))) return entry->atom; set_error( STATUS_OBJECT_NAME_NOT_FOUND ); return 0; @@ -350,7 +342,7 @@ atom_t find_global_atom( struct winstation *winstation, const struct unicode_str struct atom_entry *entry; if (!str->len || str->len > MAX_ATOM_LEN || !table) return 0; - if ((entry = find_atom_entry( table, str, atom_hash(table, str) ))) + if ((entry = find_atom_entry( table, str, hash_strW( str->str, str->len, table->entries_count )))) return entry->atom; return 0; } diff --git a/server/object.c b/server/object.c index 0cac62ca6d2..dacfe1d71a0 100644 --- a/server/object.c +++ b/server/object.c @@ -127,17 +127,9 @@ void *memdup( const void *data, size_t len ) /*****************************************************************/ -static int get_name_hash( const struct namespace *namespace, const WCHAR *name, data_size_t len ) -{ - WCHAR hash = 0; - len /= sizeof(WCHAR); - while (len--) hash ^= tolowerW(*name++); - return hash % namespace->hash_size; -} - void namespace_add( struct namespace *namespace, struct object_name *ptr ) { - int hash = get_name_hash( namespace, ptr->name, ptr->len ); + unsigned int hash = hash_strW( ptr->name, ptr->len, namespace->hash_size ); list_add_head( &namespace->names[hash], &ptr->entry ); } @@ -450,7 +442,7 @@ struct object *find_object( const struct namespace *namespace, const struct unic if (!name || !name->len) return NULL; - list = &namespace->names[ get_name_hash( namespace, name->str, name->len ) ]; + list = &namespace->names[ hash_strW( name->str, name->len, namespace->hash_size ) ]; LIST_FOR_EACH( p, list ) { const struct object_name *ptr = LIST_ENTRY( p, struct object_name, entry ); diff --git a/server/unicode.c b/server/unicode.c index eb06284c56b..8d6c411cb66 100644 --- a/server/unicode.c +++ b/server/unicode.c @@ -66,6 +66,14 @@ int memicmp_strW( const WCHAR *str1, const WCHAR *str2, data_size_t len ) return ret; } +unsigned int hash_strW( const WCHAR *str, data_size_t len, unsigned int hash_size ) +{ + unsigned int i, hash = 0; + + for (i = 0; i < len / sizeof(WCHAR); i++) hash = hash * 65599 + to_lower( str[i] ); + return hash % hash_size; +} + WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret ) { data_size_t i, len = strlen(str); diff --git a/server/unicode.h b/server/unicode.h index 99f248bd681..cfeceb88b9d 100644 --- a/server/unicode.h +++ b/server/unicode.h @@ -28,6 +28,7 @@ #include "object.h" extern int memicmp_strW( const WCHAR *str1, const WCHAR *str2, data_size_t len ); +extern unsigned int hash_strW( const WCHAR *str, data_size_t len, unsigned int hash_size ); extern WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret ); extern int parse_strW( WCHAR *buffer, data_size_t *len, const char *src, char endchar ); extern int dump_strW( const WCHAR *str, data_size_t len, FILE *f, const char escape[2] );