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

Alexandre Julliard julliard at winehq.org
Tue Mar 24 15:28:16 CDT 2020


Module: wine
Branch: master
Commit: 5721d5f8da0ca59248b11f8e0b0b93c7fc667290
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5721d5f8da0ca59248b11f8e0b0b93c7fc667290

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar 24 12:48:19 2020 +0100

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

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/atom.c     |  2 +-
 server/object.c   |  2 +-
 server/registry.c | 20 +++++++++-----------
 server/unicode.c  | 15 +++++++++++++++
 server/unicode.h  |  1 +
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/server/atom.c b/server/atom.c
index cd1508322c..11f4b46ffb 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -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;
diff --git a/server/object.c b/server/object.c
index ee89b8698d..0cac62ca6d 100644
--- a/server/object.c
+++ b/server/object.c
@@ -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
diff --git a/server/registry.c b/server/registry.c
index 54a6d6918b..dcbb3f791e 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -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);
diff --git a/server/unicode.c b/server/unicode.c
index f77aa95ff2..eb06284c56 100644
--- a/server/unicode.c
+++ b/server/unicode.c
@@ -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);
diff --git a/server/unicode.h b/server/unicode.h
index b69557363f..99f248bd68 100644
--- a/server/unicode.h
+++ b/server/unicode.h
@@ -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] );




More information about the wine-cvs mailing list