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];
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;
}
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 (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 );
}
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 )
{
return (len == sizeof(wow6432node) &&
!memicmpW( name, wow6432node, ARRAY_SIZE( wow6432node )));
return (len == sizeof(wow6432node) && !memicmp_strW( name, wow6432node, sizeof( wow6432node )));
}
/*
@ -438,8 +437,7 @@ static inline void get_req_path( struct unicode_str *str, int skip_root )
str->str = get_req_data();
str->len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR);
if (skip_root && str->len >= sizeof(root_name) &&
!memicmpW( str->str, root_name, ARRAY_SIZE( root_name )))
if (skip_root && str->len >= sizeof(root_name) && !memicmp_strW( str->str, root_name, sizeof(root_name) ))
{
str->str += ARRAY_SIZE( 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;
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)
{
@ -691,7 +689,7 @@ static struct key *follow_symlink( struct key *key, int iteration )
path.str = value->data;
path.len = (value->len / sizeof(WCHAR)) * sizeof(WCHAR);
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.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;
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)
{
@ -1116,7 +1114,7 @@ static void set_value( struct key *key, const struct unicode_str *name,
if (key->flags & KEY_SYMLINK)
{
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 );
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);
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;
}
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);
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.len -= sizeof(root_name);
@ -2209,7 +2207,7 @@ DECL_HANDLER(load_registry)
}
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.len -= sizeof(root_name);

View File

@ -51,6 +51,21 @@ static inline char to_hex( char ch )
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 )
{
data_size_t i, len = strlen(str);

View File

@ -27,6 +27,7 @@
#include "wine/unicode.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 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] );