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 )
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 )
......
......@@ -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; i<MSIMAXHANDLES; i++)
if( !msihandletable[i] )
......@@ -55,6 +57,7 @@ MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy)
info->destructor = destroy;
msihandletable[i] = info;
*out = (void*) &info[1];
return (MSIHANDLE) (i+1);
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
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,
......
......@@ -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,81 @@ 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 )
{
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 @@ 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;
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;
......
......@@ -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;
......
......@@ -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; 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 @@ 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;
......
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