MSI: fix handle allocation and the CREATE TABLE query

Mike McCormack mike at codeweavers.com
Thu Mar 18 20:58:07 CST 2004


ChangeLog:
* fix handle allocation and the CREATE TABLE query
-------------- next part --------------
Index: dlls/msi/create.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/create.c,v
retrieving revision 1.2
diff -u -r1.2 create.c
--- dlls/msi/create.c	19 Mar 2004 01:16:36 -0000	1.2
+++ dlls/msi/create.c	19 Mar 2004 02:09:10 -0000
@@ -110,11 +110,6 @@
     if( r )
         return r;
 
-    row = -1;
-    r = tv->ops->insert_row( tv, &row );
-    if( r )
-        goto err;
-
     /*
      * need to set the table, column number, col name and type
      * for each column we enter in the table
@@ -122,6 +117,11 @@
     nField = 1;
     for( col = cv->col_info; col; col = col->next )
     {
+        row = -1;
+        r = tv->ops->insert_row( tv, &row );
+        if( r )
+            goto err;
+
         column_val = msi_addstringW( cv->db->strings, 0, col->colname, -1, 1 );
         TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val );
         if( column_val < 0 )
Index: dlls/msi/handle.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/handle.c,v
retrieving revision 1.3
diff -u -r1.3 handle.c
--- dlls/msi/handle.c	8 Sep 2003 19:38:46 -0000	1.3
+++ dlls/msi/handle.c	19 Mar 2004 02:09:10 -0000
@@ -33,11 +33,13 @@
 
 MSIHANDLEINFO *msihandletable[MSIMAXHANDLES];
 
-MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy)
+MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy, void **out)
 {
     MSIHANDLEINFO *info;
     UINT i;
 
+    *out = NULL;
+
     /* find a slot */
     for(i=0; i<MSIMAXHANDLES; i++)
         if( !msihandletable[i] )
@@ -55,6 +57,7 @@
     info->destructor = destroy;
 
     msihandletable[i] = info;
+    *out = (void*) &info[1];
 
     return (MSIHANDLE) (i+1);
 }
Index: dlls/msi/msi.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.c,v
retrieving revision 1.14
diff -u -r1.14 msi.c
--- dlls/msi/msi.c	19 Mar 2004 01:16:36 -0000	1.14
+++ dlls/msi/msi.c	19 Mar 2004 02:09:10 -0000
@@ -231,7 +231,8 @@
         return ERROR_FUNCTION_FAILED;
     }
 
-    handle = alloc_msihandle(MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE), MSI_CloseDatabase );
+    handle = alloc_msihandle( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
+                              MSI_CloseDatabase, (void**) &db );
     if( !handle )
     {
         FIXME("Failed to allocate a handle\n");
@@ -239,15 +240,12 @@
         goto end;
     }
 
-    db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
-    if( !db )
-    {
-        FIXME("Failed to get handle pointer \n");
-        ret = ERROR_FUNCTION_FAILED;
-        goto end;
-    }
     db->storage = stg;
     db->mode = szMode;
+    /* db->strings = NULL;
+    db->first_table = NULL;
+    db->last_table = NULL; */
+
     ret = load_string_table( db );
     if( ret != ERROR_SUCCESS )
         goto end;
Index: dlls/msi/msipriv.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/msipriv.h,v
retrieving revision 1.8
diff -u -r1.8 msipriv.h
--- dlls/msi/msipriv.h	19 Mar 2004 01:16:36 -0000	1.8
+++ dlls/msi/msipriv.h	19 Mar 2004 02:09:10 -0000
@@ -156,7 +156,7 @@
 
 extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
 
-MSIHANDLE alloc_msihandle(UINT type, UINT extra, msihandledestructor destroy);
+MSIHANDLE alloc_msihandle(UINT type, UINT extra, msihandledestructor destroy, void **out);
 
 /* add this table to the list of cached tables in the database */
 extern void add_table(MSIDATABASE *db, MSITABLE *table);
Index: dlls/msi/msiquery.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/msiquery.c,v
retrieving revision 1.6
diff -u -r1.6 msiquery.c
--- dlls/msi/msiquery.c	18 Mar 2004 04:04:08 -0000	1.6
+++ dlls/msi/msiquery.c	19 Mar 2004 02:09:11 -0000
@@ -135,11 +135,9 @@
         return ERROR_INVALID_HANDLE;
 
     /* pre allocate a handle to hold a pointer to the view */
-    handle = alloc_msihandle( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY), MSI_CloseView );
+    handle = alloc_msihandle( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
+                              MSI_CloseView, (void**) &query );
     if( !handle )
-        return ERROR_FUNCTION_FAILED;
-    query = msihandle2msiinfo( handle, MSIHANDLETYPE_VIEW );
-    if( !query )
         return ERROR_FUNCTION_FAILED;
 
     query->row = 0;
Index: dlls/msi/record.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/record.c,v
retrieving revision 1.3
diff -u -r1.3 record.c
--- dlls/msi/record.c	8 Sep 2003 19:38:46 -0000	1.3
+++ dlls/msi/record.c	19 Mar 2004 02:09:11 -0000
@@ -99,14 +99,11 @@
     TRACE("%d\n", cParams);
 
     sz = sizeof (MSIRECORD) + sizeof(MSIFIELD)*(cParams+1) ;
-    handle = alloc_msihandle( MSIHANDLETYPE_RECORD, sz, MSI_CloseRecord );
+    handle = alloc_msihandle( MSIHANDLETYPE_RECORD, sz,
+                              MSI_CloseRecord, (void**) &rec );
     if( !handle )
         return 0;
 
-    rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
-    if( !rec )
-        return 0;
-
     rec->count = cParams;
 
     return handle;
@@ -238,12 +235,12 @@
     if( !rec )
         return ERROR_INVALID_HANDLE;
 
-    if( iField > rec->count )
-        return ERROR_INVALID_FIELD;
-
-    MSI_FreeField( &rec->fields[iField] );
-    rec->fields[iField].type = MSIFIELD_INT;
-    rec->fields[iField].u.iVal = iVal;
+    if( iField <= rec->count )
+    {
+        MSI_FreeField( &rec->fields[iField] );
+        rec->fields[iField].type = MSIFIELD_INT;
+        rec->fields[iField].u.iVal = iVal;
+    }
 
     return ERROR_SUCCESS;
 }
@@ -251,6 +248,7 @@
 BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField )
 {
     MSIRECORD *rec;
+    BOOL r = TRUE;
 
     TRACE("%ld %d\n", handle,iField );
 
@@ -258,13 +256,10 @@
     if( !rec )
         return ERROR_INVALID_HANDLE;
 
-    if( iField > rec->count ) 
-        return TRUE;
-
-    if( rec->fields[iField].type == MSIFIELD_NULL )
-        return TRUE;
+    r = ( iField > rec->count ) ||
+        ( rec->fields[iField].type == MSIFIELD_NULL );
 
-    return FALSE;
+    return r;
 }
 
 UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField, 
Index: dlls/msi/string.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/string.c,v
retrieving revision 1.3
diff -u -r1.3 string.c
--- dlls/msi/string.c	19 Mar 2004 01:16:36 -0000	1.3
+++ dlls/msi/string.c	19 Mar 2004 02:09:11 -0000
@@ -131,8 +131,6 @@
 
 int msi_addstring( string_table *st, UINT n, const CHAR *data, UINT len, UINT refcount )
 {
-    /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
-
     if( !data[0] )
         return 0;
     if( n > 0 )
@@ -209,48 +207,81 @@
     return n;
 }
 
-UINT msi_id2stringW( string_table *st, UINT string_no, LPWSTR buffer, UINT *sz )
+/* find the string identified by an id - return null if there's none */
+static const char *string_lookup_id( string_table *st, UINT id )
+{
+    if( id == 0 )
+        return "";
+
+    if( id >= st->count )
+        return NULL;
+
+    if( id && !st->strings[id].refcount )
+        return NULL;
+
+    return st->strings[id].str;
+}
+
+/*
+ *  msi_id2stringW
+ *
+ *  [in] st         - pointer to the string table
+ *  [in] id  - id of the string to retreive
+ *  [out] buffer    - destination of the string
+ *  [in/out] sz     - number of bytes available in the buffer on input
+ *                    number of bytes used on output
+ *
+ *   The size includes the terminating nul character.  Short buffers
+ *  will be filled, but not nul terminated.
+ */
+UINT msi_id2stringW( string_table *st, UINT id, LPWSTR buffer, UINT *sz )
 {
     UINT len;
-    LPSTR str;
+    const char *str;
 
-    TRACE("Finding string %d of %d\n", string_no, st->count);
-    if( string_no >= st->count )
-        return ERROR_FUNCTION_FAILED;
+    TRACE("Finding string %d of %d\n", id, st->count);
 
-    if( string_no && !st->strings[string_no].refcount )
+    str = string_lookup_id( st, id );
+    if( !str )
         return ERROR_FUNCTION_FAILED;
 
-    str = st->strings[string_no].str;
-    len = strlen( str );
+    len = MultiByteToWideChar(CP_UTF8,0,str,-1,NULL,0); 
 
     if( !buffer )
     {
-        *sz = MultiByteToWideChar(CP_ACP,0,str,len,NULL,0);
+        *sz = len;
         return ERROR_SUCCESS;
     }
 
-    len = MultiByteToWideChar(CP_ACP,0,str,len+1,buffer,*sz);
-    if (!len) buffer[*sz-1] = 0;
-    else *sz = len;
+    *sz = MultiByteToWideChar(CP_UTF8,0,str,-1,buffer,*sz); 
 
     return ERROR_SUCCESS;
 }
 
-UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz )
+/*
+ *  msi_id2stringA
+ *
+ *  [in] st         - pointer to the string table
+ *  [in] id         - id of the string to retreive
+ *  [out] buffer    - destination of the UTF8 string
+ *  [in/out] sz     - number of bytes available in the buffer on input
+ *                    number of bytes used on output
+ *
+ *   The size includes the terminating nul character.  Short buffers
+ *  will be filled, but not nul terminated.
+ */
+UINT msi_id2stringA( string_table *st, UINT id, LPSTR buffer, UINT *sz )
 {
     UINT len;
-    LPSTR str;
+    const char *str;
 
-    TRACE("Finding string %d of %d\n", string_no, st->count);
-    if( string_no >= st->count )
-        return ERROR_FUNCTION_FAILED;
+    TRACE("Finding string %d of %d\n", id, st->count);
 
-    if( string_no && !st->strings[string_no].refcount )
+    str = string_lookup_id( st, id );
+    if( !str )
         return ERROR_FUNCTION_FAILED;
 
-    str = st->strings[string_no].str;
-    len = strlen( str );
+    len = strlen( str ) + 1;
 
     if( !buffer )
     {
@@ -258,14 +289,21 @@
         return ERROR_SUCCESS;
     }
 
-    if (len >= *sz) len = *sz - 1;
-    memcpy( buffer, str, len );
-    buffer[len] = 0;
-    *sz = len+1;
+    if( *sz < len )
+        *sz = len;
+    memcpy( buffer, str, *sz ); 
+    *sz = len;
 
     return ERROR_SUCCESS;
 }
 
+/*
+ *  msi_string2idA
+ *
+ *  [in] st         - pointer to the string table
+ *  [in] str        - UTF8 string to find in the string table
+ *  [out] id        - id of the string, if found
+ */
 UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id )
 {
     int hash;
@@ -294,6 +332,12 @@
 
     TRACE("Finding string %s in string table\n", debugstr_w(buffer) );
 
+    if( buffer[0] == 0 )
+    {
+        *id = 0;
+        return ERROR_SUCCESS;
+    }
+
     sz = WideCharToMultiByte( CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL );
     if( sz <= 0 )
         return r;
@@ -333,3 +377,4 @@
     }
     return size;
 }
+
Index: dlls/msi/suminfo.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/suminfo.c,v
retrieving revision 1.5
diff -u -r1.5 suminfo.c
--- dlls/msi/suminfo.c	7 Jan 2004 00:47:35 -0000	1.5
+++ dlls/msi/suminfo.c	19 Mar 2004 02:09:11 -0000
@@ -120,15 +120,9 @@
     }
 
     handle = alloc_msihandle( MSIHANDLETYPE_SUMMARYINFO, 
-                  sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
+                  sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo,
+                  (void**) &suminfo );
     if( !handle )
-    {
-        ret = ERROR_FUNCTION_FAILED;
-        goto end;
-    }
-
-    suminfo = msihandle2msiinfo( handle, MSIHANDLETYPE_SUMMARYINFO );
-    if( !suminfo )
     {
         ret = ERROR_FUNCTION_FAILED;
         goto end;
Index: dlls/msi/table.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/table.c,v
retrieving revision 1.9
diff -u -r1.9 table.c
--- dlls/msi/table.c	19 Mar 2004 01:16:36 -0000	1.9
+++ dlls/msi/table.c	19 Mar 2004 02:09:11 -0000
@@ -553,9 +553,9 @@
     IStream *stm = NULL;
     WCHAR encname[0x20];
 
-    encode_streamname(TRUE, szStringData, encname);
+    encode_streamname(TRUE, szStringPool, encname);
 
-    /* create the StringData stream... add the zero string to it*/
+    /* create the StringPool stream... add the zero string to it*/
     r = IStorage_CreateStream( stg, encname,
             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
     if( r ) 
@@ -573,8 +573,8 @@
         return E_FAIL;
     }
 
-    /* create the StringPool stream... make it zero length */
-    encode_streamname(TRUE, szStringPool, encname);
+    /* create the StringData stream... make it zero length */
+    encode_streamname(TRUE, szStringData, encname);
     r = IStorage_CreateStream( stg, encname,
             STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
     if( r ) 
@@ -671,12 +671,15 @@
     }
 
     used = 0;
-    for( i=0; i<count; i++ )
+    pool[0]=0;   /* the first element is always zero */
+    pool[1]=0;
+    for( i=1; i<count; i++ )
     {
         sz = datasize - used;
         r = msi_id2stringA( db->strings, i, data+used, &sz );
         if( r != ERROR_SUCCESS )
         {
+            ERR("failed to fetch string\n");
             sz = 0;
         }
         else
@@ -791,7 +794,6 @@
     r = msi_id2stringW( db->strings, stringid, NULL, &sz );
     if( r != ERROR_SUCCESS )
         return NULL;
-    sz ++; /* space for NUL char */
     str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR));
     if( !str )
         return str;


More information about the wine-patches mailing list