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