From 943a71e4531279bd83d0dd49fd5c78e54184fb59 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 19 Mar 2004 19:14:12 +0000 Subject: [PATCH] Fix handle allocation and the CREATE TABLE query. --- dlls/msi/create.c | 10 ++-- dlls/msi/handle.c | 5 +- dlls/msi/msi.c | 14 +++--- dlls/msi/msipriv.h | 2 +- dlls/msi/msiquery.c | 6 +-- dlls/msi/record.c | 29 +++++------ dlls/msi/string.c | 118 ++++++++++++++++++++++++++++++-------------- dlls/msi/suminfo.c | 10 +--- dlls/msi/table.c | 14 +++--- 9 files changed, 121 insertions(+), 87 deletions(-) diff --git a/dlls/msi/create.c b/dlls/msi/create.c index 1222832ff9..5e9a0bf875 100644 --- a/dlls/msi/create.c +++ b/dlls/msi/create.c @@ -110,11 +110,6 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) 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 @@ static UINT CREATE_execute( struct tagMSIVIEW *view, MSIHANDLE record ) 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 ) diff --git a/dlls/msi/handle.c b/dlls/msi/handle.c index afca63754e..363c715895 100644 --- a/dlls/msi/handle.c +++ b/dlls/msi/handle.c @@ -33,11 +33,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); 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; idestructor = destroy; msihandletable[i] = info; + *out = (void*) &info[1]; return (MSIHANDLE) (i+1); } diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index e9c204948b..e1f29b5b4a 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -231,7 +231,8 @@ UINT WINAPI MsiOpenDatabaseW( 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 @@ UINT WINAPI MsiOpenDatabaseW( 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; diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 595c385512..da1625a80c 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -156,7 +156,7 @@ typedef struct tagMSIHANDLEINFO 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); diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c index c35a89a5be..f6054040c2 100644 --- a/dlls/msi/msiquery.c +++ b/dlls/msi/msiquery.c @@ -135,12 +135,10 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, 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; query->db = db; diff --git a/dlls/msi/record.c b/dlls/msi/record.c index b22b4c2732..cf67da2f7b 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -99,14 +99,11 @@ MSIHANDLE WINAPI MsiCreateRecord( unsigned int cParams ) 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 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal 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 @@ UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField ) { MSIRECORD *rec; + BOOL r = TRUE; TRACE("%ld %d\n", handle,iField ); @@ -258,13 +256,10 @@ BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField ) if( !rec ) return ERROR_INVALID_HANDLE; - if( iField > rec->count ) - return TRUE; + r = ( iField > rec->count ) || + ( 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, diff --git a/dlls/msi/string.c b/dlls/msi/string.c index 610cd72bc5..69dcf5960b 100644 --- a/dlls/msi/string.c +++ b/dlls/msi/string.c @@ -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 ) { - /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */ - if( !data[0] ) return 0; if( n > 0 ) @@ -209,48 +207,45 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, UINT len, UINT 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 ) { - UINT len; - LPSTR str; + if( id == 0 ) + return ""; - TRACE("Finding string %d of %d\n", string_no, st->count); - if( string_no >= st->count ) - return ERROR_FUNCTION_FAILED; + if( id >= st->count ) + return NULL; - if( string_no && !st->strings[string_no].refcount ) - return ERROR_FUNCTION_FAILED; + if( id && !st->strings[id].refcount ) + return NULL; - str = st->strings[string_no].str; - len = strlen( str ); - - if( !buffer ) - { - *sz = MultiByteToWideChar(CP_ACP,0,str,len,NULL,0); - return ERROR_SUCCESS; - } - - len = MultiByteToWideChar(CP_ACP,0,str,len+1,buffer,*sz); - if (!len) buffer[*sz-1] = 0; - else *sz = len; - - return ERROR_SUCCESS; + return st->strings[id].str; } -UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz ) +/* + * 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 ) + TRACE("Finding string %d of %d\n", id, st->count); + + str = string_lookup_id( st, id ); + if( !str ) return ERROR_FUNCTION_FAILED; - if( string_no && !st->strings[string_no].refcount ) - return ERROR_FUNCTION_FAILED; - - str = st->strings[string_no].str; - len = strlen( str ); + len = MultiByteToWideChar(CP_UTF8,0,str,-1,NULL,0); if( !buffer ) { @@ -258,14 +253,57 @@ UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz ) return ERROR_SUCCESS; } - if (len >= *sz) len = *sz - 1; - memcpy( buffer, str, len ); - buffer[len] = 0; - *sz = len+1; + *sz = MultiByteToWideChar(CP_UTF8,0,str,-1,buffer,*sz); return ERROR_SUCCESS; } +/* + * 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; + const char *str; + + TRACE("Finding string %d of %d\n", id, st->count); + + str = string_lookup_id( st, id ); + if( !str ) + return ERROR_FUNCTION_FAILED; + + len = strlen( str ) + 1; + + if( !buffer ) + { + *sz = len; + return ERROR_SUCCESS; + } + + 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 @@ UINT msi_string2id( string_table *st, LPCWSTR buffer, UINT *id ) 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; diff --git a/dlls/msi/suminfo.c b/dlls/msi/suminfo.c index a2f1c6cb31..fe14c859e9 100644 --- a/dlls/msi/suminfo.c +++ b/dlls/msi/suminfo.c @@ -120,20 +120,14 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, } 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; - } - IPropertyStorage_AddRef(ps); suminfo->propstg = ps; *phSummaryInfo = handle; diff --git a/dlls/msi/table.c b/dlls/msi/table.c index dd7c51eb85..8220f11320 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -553,9 +553,9 @@ HRESULT init_string_table( IStorage *stg ) 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 @@ HRESULT init_string_table( IStorage *stg ) 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 @@ UINT save_string_table( MSIDATABASE *db ) } used = 0; - for( i=0; istrings, i, data+used, &sz ); if( r != ERROR_SUCCESS ) { + ERR("failed to fetch string\n"); sz = 0; } else @@ -791,7 +794,6 @@ LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid) 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;