server: Add a helper function for case-insensitive Unicode string comparisons.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Alexandre Julliard 2020-03-24 12:48:19 +01:00
parent faaea5cd00
commit 5721d5f8da
5 changed files with 27 additions and 13 deletions

View File

@ -214,7 +214,7 @@ static struct atom_entry *find_atom_entry( struct atom_table *table, const struc
struct atom_entry *entry = table->entries[hash]; struct atom_entry *entry = table->entries[hash];
while (entry) while (entry)
{ {
if (entry->len == str->len && !memicmpW( entry->str, str->str, str->len/sizeof(WCHAR) )) break; if (entry->len == str->len && !memicmp_strW( entry->str, str->str, str->len )) break;
entry = entry->next; entry = entry->next;
} }
return entry; return entry;

View File

@ -457,7 +457,7 @@ struct object *find_object( const struct namespace *namespace, const struct unic
if (ptr->len != name->len) continue; if (ptr->len != name->len) continue;
if (attributes & OBJ_CASE_INSENSITIVE) if (attributes & OBJ_CASE_INSENSITIVE)
{ {
if (!strncmpiW( ptr->name, name->str, name->len/sizeof(WCHAR) )) if (!memicmp_strW( ptr->name, name->str, name->len ))
return grab_object( ptr->obj ); return grab_object( ptr->obj );
} }
else else

View File

@ -177,8 +177,7 @@ static const struct object_ops key_ops =
static inline int is_wow6432node( const WCHAR *name, unsigned int len ) static inline int is_wow6432node( const WCHAR *name, unsigned int len )
{ {
return (len == sizeof(wow6432node) && return (len == sizeof(wow6432node) && !memicmp_strW( name, wow6432node, sizeof( wow6432node )));
!memicmpW( name, wow6432node, ARRAY_SIZE( wow6432node )));
} }
/* /*
@ -438,8 +437,7 @@ static inline void get_req_path( struct unicode_str *str, int skip_root )
str->str = get_req_data(); str->str = get_req_data();
str->len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR); str->len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR);
if (skip_root && str->len >= sizeof(root_name) && if (skip_root && str->len >= sizeof(root_name) && !memicmp_strW( str->str, root_name, sizeof(root_name) ))
!memicmpW( str->str, root_name, ARRAY_SIZE( root_name )))
{ {
str->str += ARRAY_SIZE( root_name ); str->str += ARRAY_SIZE( root_name );
str->len -= sizeof(root_name); str->len -= sizeof(root_name);
@ -647,7 +645,7 @@ static struct key *find_subkey( const struct key *key, const struct unicode_str
{ {
i = (min + max) / 2; i = (min + max) / 2;
len = min( key->subkeys[i]->namelen, name->len ); len = min( key->subkeys[i]->namelen, name->len );
res = memicmpW( key->subkeys[i]->name, name->str, len / sizeof(WCHAR) ); res = memicmp_strW( key->subkeys[i]->name, name->str, len );
if (!res) res = key->subkeys[i]->namelen - name->len; if (!res) res = key->subkeys[i]->namelen - name->len;
if (!res) if (!res)
{ {
@ -691,7 +689,7 @@ static struct key *follow_symlink( struct key *key, int iteration )
path.str = value->data; path.str = value->data;
path.len = (value->len / sizeof(WCHAR)) * sizeof(WCHAR); path.len = (value->len / sizeof(WCHAR)) * sizeof(WCHAR);
if (path.len <= sizeof(root_name)) return NULL; if (path.len <= sizeof(root_name)) return NULL;
if (memicmpW( path.str, root_name, ARRAY_SIZE( root_name ))) return NULL; if (memicmp_strW( path.str, root_name, sizeof(root_name) )) return NULL;
path.str += ARRAY_SIZE( root_name ); path.str += ARRAY_SIZE( root_name );
path.len -= sizeof(root_name); path.len -= sizeof(root_name);
@ -1054,7 +1052,7 @@ static struct key_value *find_value( const struct key *key, const struct unicode
{ {
i = (min + max) / 2; i = (min + max) / 2;
len = min( key->values[i].namelen, name->len ); len = min( key->values[i].namelen, name->len );
res = memicmpW( key->values[i].name, name->str, len / sizeof(WCHAR) ); res = memicmp_strW( key->values[i].name, name->str, len );
if (!res) res = key->values[i].namelen - name->len; if (!res) res = key->values[i].namelen - name->len;
if (!res) if (!res)
{ {
@ -1116,7 +1114,7 @@ static void set_value( struct key *key, const struct unicode_str *name,
if (key->flags & KEY_SYMLINK) if (key->flags & KEY_SYMLINK)
{ {
if (type != REG_LINK || name->len != symlink_str.len || if (type != REG_LINK || name->len != symlink_str.len ||
memicmpW( name->str, symlink_str.str, name->len / sizeof(WCHAR) )) memicmp_strW( name->str, symlink_str.str, name->len ))
{ {
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
return; return;
@ -1614,7 +1612,7 @@ static int get_prefix_len( struct key *key, const char *name, struct file_load_i
len = (p - info->tmp) * sizeof(WCHAR); len = (p - info->tmp) * sizeof(WCHAR);
for (res = 1; key != root_key; res++) for (res = 1; key != root_key; res++)
{ {
if (len == key->namelen && !memicmpW( info->tmp, key->name, len / sizeof(WCHAR) )) break; if (len == key->namelen && !memicmp_strW( info->tmp, key->name, len )) break;
key = key->parent; key = key->parent;
} }
if (key == root_key) res = 0; /* no matching name */ if (key == root_key) res = 0; /* no matching name */
@ -2051,7 +2049,7 @@ DECL_HANDLER(create_key)
class.len = (class.len / sizeof(WCHAR)) * sizeof(WCHAR); class.len = (class.len / sizeof(WCHAR)) * sizeof(WCHAR);
if (!objattr->rootdir && name.len >= sizeof(root_name) && if (!objattr->rootdir && name.len >= sizeof(root_name) &&
!memicmpW( name.str, root_name, ARRAY_SIZE( root_name ))) !memicmp_strW( name.str, root_name, sizeof(root_name) ))
{ {
name.str += ARRAY_SIZE( root_name ); name.str += ARRAY_SIZE( root_name );
name.len -= sizeof(root_name); name.len -= sizeof(root_name);
@ -2209,7 +2207,7 @@ DECL_HANDLER(load_registry)
} }
if (!objattr->rootdir && name.len >= sizeof(root_name) && if (!objattr->rootdir && name.len >= sizeof(root_name) &&
!memicmpW( name.str, root_name, ARRAY_SIZE( root_name ))) !memicmp_strW( name.str, root_name, sizeof(root_name) ))
{ {
name.str += ARRAY_SIZE( root_name ); name.str += ARRAY_SIZE( root_name );
name.len -= sizeof(root_name); name.len -= sizeof(root_name);

View File

@ -51,6 +51,21 @@ static inline char to_hex( char ch )
return tolower(ch) - 'a' + 10; return tolower(ch) - 'a' + 10;
} }
static inline WCHAR to_lower( WCHAR ch )
{
extern const WCHAR wine_casemap_lower[];
return ch + wine_casemap_lower[wine_casemap_lower[ch >> 8] + (ch & 0xff)];
}
int memicmp_strW( const WCHAR *str1, const WCHAR *str2, data_size_t len )
{
int ret = 0;
for (len /= sizeof(WCHAR); len; str1++, str2++, len--)
if ((ret = to_lower(*str1) - to_lower(*str2))) break;
return ret;
}
WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret ) WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret )
{ {
data_size_t i, len = strlen(str); data_size_t i, len = strlen(str);

View File

@ -27,6 +27,7 @@
#include "wine/unicode.h" #include "wine/unicode.h"
#include "object.h" #include "object.h"
extern int memicmp_strW( const WCHAR *str1, const WCHAR *str2, data_size_t len );
extern WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret ); 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 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] ); extern int dump_strW( const WCHAR *str, data_size_t len, FILE *f, const char escape[2] );