[2/7] msi: Use strcmpW instead of lstrcmpW to compare database strings.

Hans Leidekker hans at codeweavers.com
Wed Oct 6 08:43:54 CDT 2010


An installer I have here uses \1 and \2 as delimiters in property strings.
It turns out that on Wine lstrcmp("\1", "\2") returns 0, not -1, which causes
the string table implementation to return the wrong value. This should be fixed,
but it's better if database string comparisons do not depend on thread locale.
---
 dlls/msi/cond.y   |   28 ++++++++++++++--------------
 dlls/msi/record.c |    3 ++-
 dlls/msi/string.c |    4 ++--
 dlls/msi/table.c  |   30 ++++++++++++++++++------------
 dlls/msi/where.c  |    3 ++-
 5 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/dlls/msi/cond.y b/dlls/msi/cond.y
index 03ea493..93e2e01 100644
--- a/dlls/msi/cond.y
+++ b/dlls/msi/cond.y
@@ -466,7 +466,7 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
         int l = lstrlenW( a );
         int r = lstrlenW( b );
         if (r > l) return 0;
-        return 0 == lstrcmpW( a + (l - r), b );
+        return strcmpW( a + (l - r), b ) == 0;
     }
     case COND_ILHS:
     	return 0 == strncmpiW( a, b, lstrlenW( b ) );
@@ -475,7 +475,7 @@ static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
         int l = lstrlenW( a );
         int r = lstrlenW( b );
         if (r > l) return 0;
-        return 0 == lstrcmpiW( a + (l - r), b );
+        return strcmpiW( a + (l - r), b ) == 0;
     }
     default:
     	ERR("invalid substring operator\n");
@@ -500,29 +500,29 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert )
     switch (operator)
     {
     case COND_LT:
-        return -1 == lstrcmpW( a, b );
+        return strcmpW( a, b ) < 0;
     case COND_GT:
-        return  1 == lstrcmpW( a, b );
+        return strcmpW( a, b ) > 0;
     case COND_EQ:
-        return  0 == lstrcmpW( a, b );
+        return strcmpW( a, b ) == 0;
     case COND_NE:
-        return  0 != lstrcmpW( a, b );
+        return strcmpW( a, b ) != 0;
     case COND_GE:
-        return -1 != lstrcmpW( a, b );
+        return strcmpW( a, b ) >= 0;
     case COND_LE:
-        return  1 != lstrcmpW( a, b );
+        return strcmpW( a, b ) <= 0;
     case COND_ILT:
-        return -1 == lstrcmpiW( a, b );
+        return strcmpiW( a, b ) < 0;
     case COND_IGT:
-        return  1 == lstrcmpiW( a, b );
+        return strcmpiW( a, b ) > 0;
     case COND_IEQ:
-        return  0 == lstrcmpiW( a, b );
+        return strcmpiW( a, b ) == 0;
     case COND_INE:
-        return  0 != lstrcmpiW( a, b );
+        return strcmpiW( a, b ) != 0;
     case COND_IGE:
-        return -1 != lstrcmpiW( a, b );
+        return strcmpiW( a, b ) >= 0;
     case COND_ILE:
-        return  1 != lstrcmpiW( a, b );
+        return strcmpiW( a, b ) <= 0;
     default:
         ERR("invalid string operator\n");
         return 0;
diff --git a/dlls/msi/record.c b/dlls/msi/record.c
index 7bc8281..fc30f79 100644
--- a/dlls/msi/record.c
+++ b/dlls/msi/record.c
@@ -27,6 +27,7 @@
 #include "winuser.h"
 #include "winerror.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 #include "msi.h"
 #include "msiquery.h"
 #include "msipriv.h"
@@ -1016,7 +1017,7 @@ BOOL MSI_RecordsAreEqual(MSIRECORD *a, MSIRECORD *b)
                 break;
 
             case MSIFIELD_WSTR:
-                if (lstrcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal))
+                if (strcmpW(a->fields[i].u.szwVal, b->fields[i].u.szwVal))
                     return FALSE;
                 break;
 
diff --git a/dlls/msi/string.c b/dlls/msi/string.c
index 21b1db2..80057b8 100644
--- a/dlls/msi/string.c
+++ b/dlls/msi/string.c
@@ -163,7 +163,7 @@ static int find_insert_index( const string_table *st, UINT string_id )
     while (low <= high)
     {
         i = (low + high) / 2;
-        c = lstrcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str );
+        c = strcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str );
 
         if (c < 0)
             high = i - 1;
@@ -403,7 +403,7 @@ UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id )
     while (low <= high)
     {
         i = (low + high) / 2;
-        c = lstrcmpW( str, st->strings[st->sorted[i]].str );
+        c = strcmpW( str, st->strings[st->sorted[i]].str );
 
         if (c < 0)
             high = i - 1;
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index 9fbb0a1..cc39dbc 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1300,10 +1300,13 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT
     else if ( columninfo.type & MSITYPE_STRING )
     {
         LPCWSTR sval = MSI_RecordGetString( rec, iField );
-
-        r = msi_string2idW(tv->db->strings, sval, pvalue);
-        if (r != ERROR_SUCCESS)
-           return ERROR_NOT_FOUND;
+        if (sval)
+        {
+            r = msi_string2idW(tv->db->strings, sval, pvalue);
+            if (r != ERROR_SUCCESS)
+                return ERROR_NOT_FOUND;
+        }
+        else *pvalue = 0;
     }
     else if ( 2 == bytes_per_column( tv->db, &columninfo ) )
     {
@@ -1386,7 +1389,6 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI
                     LPCWSTR sval = MSI_RecordGetString( rec, i + 1 );
                     val = msi_addstringW( tv->db->strings, sval, -1, 1,
                       persistent ? StringPersistent : StringNonPersistent );
-
                 }
                 else
                 {
@@ -2588,15 +2590,19 @@ static UINT* msi_record_to_row( const MSITABLEVIEW *tv, MSIRECORD *rec )
              ! MSITYPE_IS_BINARY(tv->columns[i].type) )
         {
             str = MSI_RecordGetString( rec, i+1 );
-            r = msi_string2idW( tv->db->strings, str, &data[i] );
-
-            /* if there's no matching string in the string table,
-               these keys can't match any record, so fail now. */
-            if( ERROR_SUCCESS != r )
+            if (str)
             {
-                msi_free( data );
-                return NULL;
+                r = msi_string2idW( tv->db->strings, str, &data[i] );
+
+                /* if there's no matching string in the string table,
+                   these keys can't match any record, so fail now. */
+                if( ERROR_SUCCESS != r )
+                {
+                    msi_free( data );
+                    return NULL;
+                }
             }
+            else data[i] = 0;
         }
         else
         {
diff --git a/dlls/msi/where.c b/dlls/msi/where.c
index 4c4db49..7cafa2a 100644
--- a/dlls/msi/where.c
+++ b/dlls/msi/where.c
@@ -24,6 +24,7 @@
 #include "winbase.h"
 #include "winerror.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 #include "msi.h"
 #include "msiquery.h"
 #include "objbase.h"
@@ -306,7 +307,7 @@ static UINT STRCMP_Evaluate( MSIWHEREVIEW *wv, UINT row, const struct expr *cond
     else if( r_str && ! l_str )
         sr = -1;
     else
-        sr = lstrcmpW( l_str, r_str );
+        sr = strcmpW( l_str, r_str );
 
     *val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) ||
            ( cond->u.expr.op == OP_NE && ( sr != 0 ) );
-- 
1.7.1








More information about the wine-patches mailing list