mirror of
https://github.com/reactos/wine.git
synced 2025-02-04 02:56:31 +00:00
Fix handle allocation and the CREATE TABLE query.
This commit is contained in:
parent
a86a022256
commit
943a71e453
@ -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;
|
||||
|
||||
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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user