Commit 943a71e4 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Fix handle allocation and the CREATE TABLE query.

parent a86a0222
...@@ -110,11 +110,6 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) ...@@ -110,11 +110,6 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record )
if( r ) if( r )
return 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 * need to set the table, column number, col name and type
* for each column we enter in the table * for each column we enter in the table
...@@ -122,6 +117,11 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) ...@@ -122,6 +117,11 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record )
nField = 1; nField = 1;
for( col = cv->col_info; col; col = col->next ) 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 ); column_val = msi_addstringW( cv->db->strings, 0, col->colname, -1, 1 );
TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val ); TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val );
if( column_val < 0 ) if( column_val < 0 )
......
...@@ -33,11 +33,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); ...@@ -33,11 +33,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
MSIHANDLEINFO *msihandletable[MSIMAXHANDLES]; 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; MSIHANDLEINFO *info;
UINT i; UINT i;
*out = NULL;
/* find a slot */ /* find a slot */
for(i=0; i<MSIMAXHANDLES; i++) for(i=0; i<MSIMAXHANDLES; i++)
if( !msihandletable[i] ) if( !msihandletable[i] )
...@@ -55,6 +57,7 @@ MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy) ...@@ -55,6 +57,7 @@ MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy)
info->destructor = destroy; info->destructor = destroy;
msihandletable[i] = info; msihandletable[i] = info;
*out = (void*) &info[1];
return (MSIHANDLE) (i+1); return (MSIHANDLE) (i+1);
} }
......
...@@ -231,7 +231,8 @@ UINT WINAPI MsiOpenDatabaseW( ...@@ -231,7 +231,8 @@ UINT WINAPI MsiOpenDatabaseW(
return ERROR_FUNCTION_FAILED; 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 ) if( !handle )
{ {
FIXME("Failed to allocate a handle\n"); FIXME("Failed to allocate a handle\n");
...@@ -239,15 +240,12 @@ UINT WINAPI MsiOpenDatabaseW( ...@@ -239,15 +240,12 @@ UINT WINAPI MsiOpenDatabaseW(
goto end; 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->storage = stg;
db->mode = szMode; db->mode = szMode;
/* db->strings = NULL;
db->first_table = NULL;
db->last_table = NULL; */
ret = load_string_table( db ); ret = load_string_table( db );
if( ret != ERROR_SUCCESS ) if( ret != ERROR_SUCCESS )
goto end; goto end;
......
...@@ -156,7 +156,7 @@ typedef struct tagMSIHANDLEINFO ...@@ -156,7 +156,7 @@ typedef struct tagMSIHANDLEINFO
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type); 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 */ /* add this table to the list of cached tables in the database */
extern void add_table(MSIDATABASE *db, MSITABLE *table); extern void add_table(MSIDATABASE *db, MSITABLE *table);
......
...@@ -135,12 +135,10 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, ...@@ -135,12 +135,10 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
/* pre allocate a handle to hold a pointer to the view */ /* 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 ) if( !handle )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
query = msihandle2msiinfo( handle, MSIHANDLETYPE_VIEW );
if( !query )
return ERROR_FUNCTION_FAILED;
query->row = 0; query->row = 0;
query->db = db; query->db = db;
......
...@@ -99,14 +99,11 @@ MSIHANDLE WINAPI MsiCreateRecord( unsigned int cParams ) ...@@ -99,14 +99,11 @@ MSIHANDLE WINAPI MsiCreateRecord( unsigned int cParams )
TRACE("%d\n", cParams); TRACE("%d\n", cParams);
sz = sizeof (MSIRECORD) + sizeof(MSIFIELD)*(cParams+1) ; 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 ) if( !handle )
return 0; return 0;
rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
if( !rec )
return 0;
rec->count = cParams; rec->count = cParams;
return handle; return handle;
...@@ -238,12 +235,12 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal ...@@ -238,12 +235,12 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal
if( !rec ) if( !rec )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
if( iField > rec->count ) if( iField <= rec->count )
return ERROR_INVALID_FIELD; {
MSI_FreeField( &rec->fields[iField] );
MSI_FreeField( &rec->fields[iField] ); rec->fields[iField].type = MSIFIELD_INT;
rec->fields[iField].type = MSIFIELD_INT; rec->fields[iField].u.iVal = iVal;
rec->fields[iField].u.iVal = iVal; }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -251,6 +248,7 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal ...@@ -251,6 +248,7 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal
BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField ) BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField )
{ {
MSIRECORD *rec; MSIRECORD *rec;
BOOL r = TRUE;
TRACE("%ld %d\n", handle,iField ); TRACE("%ld %d\n", handle,iField );
...@@ -258,13 +256,10 @@ BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField ) ...@@ -258,13 +256,10 @@ BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField )
if( !rec ) if( !rec )
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
if( iField > rec->count ) r = ( iField > rec->count ) ||
return TRUE; ( rec->fields[iField].type == MSIFIELD_NULL );
if( rec->fields[iField].type == MSIFIELD_NULL )
return TRUE;
return FALSE; return r;
} }
UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField, UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField,
......
...@@ -131,8 +131,6 @@ static void st_mark_entry_used( string_table *st, int n ) ...@@ -131,8 +131,6 @@ static void st_mark_entry_used( string_table *st, int n )
int msi_addstring( string_table *st, UINT n, const CHAR *data, UINT len, UINT refcount ) 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] ) if( !data[0] )
return 0; return 0;
if( n > 0 ) if( n > 0 )
...@@ -209,48 +207,81 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, UINT len, UINT ...@@ -209,48 +207,81 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, UINT len, UINT
return n; 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; UINT len;
LPSTR str; const char *str;
TRACE("Finding string %d of %d\n", string_no, st->count); TRACE("Finding string %d of %d\n", id, st->count);
if( string_no >= st->count )
return ERROR_FUNCTION_FAILED;
if( string_no && !st->strings[string_no].refcount ) str = string_lookup_id( st, id );
if( !str )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
str = st->strings[string_no].str; len = MultiByteToWideChar(CP_UTF8,0,str,-1,NULL,0);
len = strlen( str );
if( !buffer ) if( !buffer )
{ {
*sz = MultiByteToWideChar(CP_ACP,0,str,len,NULL,0); *sz = len;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
len = MultiByteToWideChar(CP_ACP,0,str,len+1,buffer,*sz); *sz = MultiByteToWideChar(CP_UTF8,0,str,-1,buffer,*sz);
if (!len) buffer[*sz-1] = 0;
else *sz = len;
return ERROR_SUCCESS; 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; UINT len;
LPSTR str; const char *str;
TRACE("Finding string %d of %d\n", string_no, st->count); TRACE("Finding string %d of %d\n", id, st->count);
if( string_no >= st->count )
return ERROR_FUNCTION_FAILED;
if( string_no && !st->strings[string_no].refcount ) str = string_lookup_id( st, id );
if( !str )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
str = st->strings[string_no].str; len = strlen( str ) + 1;
len = strlen( str );
if( !buffer ) if( !buffer )
{ {
...@@ -258,14 +289,21 @@ UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz ) ...@@ -258,14 +289,21 @@ UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
if (len >= *sz) len = *sz - 1; if( *sz < len )
memcpy( buffer, str, len ); *sz = len;
buffer[len] = 0; memcpy( buffer, str, *sz );
*sz = len+1; *sz = len;
return ERROR_SUCCESS; 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 ) UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id )
{ {
int hash; int hash;
...@@ -294,6 +332,12 @@ UINT msi_string2id( string_table *st, LPCWSTR buffer, UINT *id ) ...@@ -294,6 +332,12 @@ UINT msi_string2id( string_table *st, LPCWSTR buffer, UINT *id )
TRACE("Finding string %s in string table\n", debugstr_w(buffer) ); 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 ); sz = WideCharToMultiByte( CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL );
if( sz <= 0 ) if( sz <= 0 )
return r; return r;
......
...@@ -120,20 +120,14 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, ...@@ -120,20 +120,14 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
} }
handle = alloc_msihandle( MSIHANDLETYPE_SUMMARYINFO, handle = alloc_msihandle( MSIHANDLETYPE_SUMMARYINFO,
sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo ); sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo,
(void**) &suminfo );
if( !handle ) if( !handle )
{ {
ret = ERROR_FUNCTION_FAILED; ret = ERROR_FUNCTION_FAILED;
goto end; goto end;
} }
suminfo = msihandle2msiinfo( handle, MSIHANDLETYPE_SUMMARYINFO );
if( !suminfo )
{
ret = ERROR_FUNCTION_FAILED;
goto end;
}
IPropertyStorage_AddRef(ps); IPropertyStorage_AddRef(ps);
suminfo->propstg = ps; suminfo->propstg = ps;
*phSummaryInfo = handle; *phSummaryInfo = handle;
......
...@@ -553,9 +553,9 @@ HRESULT init_string_table( IStorage *stg ) ...@@ -553,9 +553,9 @@ HRESULT init_string_table( IStorage *stg )
IStream *stm = NULL; IStream *stm = NULL;
WCHAR encname[0x20]; 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, r = IStorage_CreateStream( stg, encname,
STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
if( r ) if( r )
...@@ -573,8 +573,8 @@ HRESULT init_string_table( IStorage *stg ) ...@@ -573,8 +573,8 @@ HRESULT init_string_table( IStorage *stg )
return E_FAIL; return E_FAIL;
} }
/* create the StringPool stream... make it zero length */ /* create the StringData stream... make it zero length */
encode_streamname(TRUE, szStringPool, encname); encode_streamname(TRUE, szStringData, encname);
r = IStorage_CreateStream( stg, encname, r = IStorage_CreateStream( stg, encname,
STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
if( r ) if( r )
...@@ -671,12 +671,15 @@ UINT save_string_table( MSIDATABASE *db ) ...@@ -671,12 +671,15 @@ UINT save_string_table( MSIDATABASE *db )
} }
used = 0; 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; sz = datasize - used;
r = msi_id2stringA( db->strings, i, data+used, &sz ); r = msi_id2stringA( db->strings, i, data+used, &sz );
if( r != ERROR_SUCCESS ) if( r != ERROR_SUCCESS )
{ {
ERR("failed to fetch string\n");
sz = 0; sz = 0;
} }
else else
...@@ -791,7 +794,6 @@ LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid) ...@@ -791,7 +794,6 @@ LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid)
r = msi_id2stringW( db->strings, stringid, NULL, &sz ); r = msi_id2stringW( db->strings, stringid, NULL, &sz );
if( r != ERROR_SUCCESS ) if( r != ERROR_SUCCESS )
return NULL; return NULL;
sz ++; /* space for NUL char */
str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR)); str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR));
if( !str ) if( !str )
return str; return str;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment