- Merge from trunk
[reactos.git] / dll / win32 / msi / string.c
index 3bdc436..5644749 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 2002-2004, Mike McCormack for CodeWeavers
  * Copyright 2007 Robert Shearman for CodeWeavers
+ * Copyright 2010 Hans Leidekker for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 WINE_DEFAULT_DEBUG_CHANNEL(msidb);
 
-#define LONG_STR_BYTES 3
-
 typedef struct _msistring
 {
-    UINT persistent_refcount;
-    UINT nonpersistent_refcount;
+    USHORT persistent_refcount;
+    USHORT nonpersistent_refcount;
     LPWSTR str;
 } msistring;
 
@@ -188,7 +187,7 @@ static void insert_string_sorted( string_table *st, UINT string_id )
     st->sortcount++;
 }
 
-static void set_st_entry( string_table *st, UINT n, LPWSTR str, UINT refcount, enum StringPersistence persistence )
+static void set_st_entry( string_table *st, UINT n, LPWSTR str, USHORT refcount, enum StringPersistence persistence )
 {
     if (persistence == StringPersistent)
     {
@@ -237,7 +236,7 @@ static UINT msi_string2idA( const string_table *st, LPCSTR buffer, UINT *id )
     return r;
 }
 
-static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT refcount, enum StringPersistence persistence )
+static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, USHORT refcount, enum StringPersistence persistence )
 {
     LPWSTR str;
     int sz;
@@ -288,42 +287,28 @@ static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, U
     return n;
 }
 
-int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence )
+int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcount, enum StringPersistence persistence )
 {
+    UINT n;
     LPWSTR str;
 
-    /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
-
     if( !data )
         return 0;
     if( !data[0] )
         return 0;
-    if( n > 0 )
-    {
-        if( st->strings[n].persistent_refcount ||
-            st->strings[n].nonpersistent_refcount )
-            return -1;
-    }
-    else
+
+    if( msi_string2idW( st, data, &n ) == ERROR_SUCCESS )
     {
-        if( ERROR_SUCCESS == msi_string2idW( st, data, &n ) )
-        {
-            if (persistence == StringPersistent)
-                st->strings[n].persistent_refcount += refcount;
-            else
-                st->strings[n].nonpersistent_refcount += refcount;
-            return n;
-        }
-        n = st_find_free_entry( st );
-        if( n == -1 )
-            return -1;
+        if (persistence == StringPersistent)
+            st->strings[n].persistent_refcount += refcount;
+        else
+            st->strings[n].nonpersistent_refcount += refcount;
+        return n;
     }
 
-    if( n < 1 )
-    {
-        ERR("invalid index adding %s (%d)\n", debugstr_w( data ), n );
+    n = st_find_free_entry( st );
+    if( n == -1 )
         return -1;
-    }
 
     /* allocate a new string */
     if(len<0)
@@ -578,7 +563,7 @@ end:
     return st;
 }
 
-UINT msi_save_string_table( const string_table *st, IStorage *storage )
+UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *bytes_per_strref )
 {
     UINT i, datasize = 0, poolsize = 0, sz, used, r, codepage, n;
     UINT ret = ERROR_FUNCTION_FAILED;
@@ -607,8 +592,16 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage )
 
     used = 0;
     codepage = st->codepage;
-    pool[0]=codepage&0xffff;
-    pool[1]=(codepage>>16);
+    pool[0] = codepage & 0xffff;
+    pool[1] = codepage >> 16;
+    if (st->maxcount > 0xffff)
+    {
+        pool[1] |= 0x8000;
+        *bytes_per_strref = LONG_STR_BYTES;
+    }
+    else
+        *bytes_per_strref = sizeof(USHORT);
+
     n = 1;
     for( i=1; i<st->maxcount; i++ )
     {