mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
sync msi with wine 1.1.35
svn path=/trunk/; revision=44693
This commit is contained in:
parent
917a4bead6
commit
67cca04bc0
23 changed files with 1529 additions and 777 deletions
|
@ -5008,12 +5008,30 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
|
|||
FIXME("Not removing environment variable on uninstall!\n");
|
||||
|
||||
size = 0;
|
||||
type = REG_SZ;
|
||||
res = RegQueryValueExW(env, name, NULL, &type, NULL, &size);
|
||||
if ((res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ||
|
||||
(res == ERROR_SUCCESS && type != REG_SZ && type != REG_EXPAND_SZ))
|
||||
goto done;
|
||||
|
||||
if (res != ERROR_FILE_NOT_FOUND)
|
||||
if ((res == ERROR_FILE_NOT_FOUND || !(flags & ENV_MOD_MASK)))
|
||||
{
|
||||
/* Nothing to do. */
|
||||
if (!value)
|
||||
{
|
||||
res = ERROR_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
size = (lstrlenW(value) + 1) * sizeof(WCHAR);
|
||||
newval = strdupW(value);
|
||||
if (!newval)
|
||||
{
|
||||
res = ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & ENV_ACT_SETABSENT)
|
||||
{
|
||||
|
@ -5038,8 +5056,18 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
|
|||
goto done;
|
||||
}
|
||||
|
||||
size += (lstrlenW(value) + 1) * sizeof(WCHAR);
|
||||
newval = msi_alloc(size);
|
||||
size = (lstrlenW(data) + 1) * sizeof(WCHAR);
|
||||
if (flags & ENV_MOD_MASK)
|
||||
{
|
||||
DWORD mod_size;
|
||||
int multiplier = 0;
|
||||
if (flags & ENV_MOD_APPEND) multiplier++;
|
||||
if (flags & ENV_MOD_PREFIX) multiplier++;
|
||||
mod_size = (lstrlenW(value) + 1) * multiplier;
|
||||
size += mod_size * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
newval = msi_alloc(size);
|
||||
ptr = newval;
|
||||
if (!newval)
|
||||
{
|
||||
|
@ -5047,37 +5075,20 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!(flags & ENV_MOD_MASK))
|
||||
if (flags & ENV_MOD_PREFIX)
|
||||
{
|
||||
lstrcpyW(newval, value);
|
||||
else
|
||||
{
|
||||
if (flags & ENV_MOD_PREFIX)
|
||||
{
|
||||
lstrcpyW(newval, value);
|
||||
lstrcatW(newval, szSemiColon);
|
||||
ptr = newval + lstrlenW(value) + 1;
|
||||
}
|
||||
|
||||
lstrcpyW(ptr, data);
|
||||
|
||||
if (flags & ENV_MOD_APPEND)
|
||||
{
|
||||
lstrcatW(newval, szSemiColon);
|
||||
lstrcatW(newval, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (value)
|
||||
{
|
||||
size = (lstrlenW(value) + 1) * sizeof(WCHAR);
|
||||
newval = msi_alloc(size);
|
||||
if (!newval)
|
||||
{
|
||||
res = ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
lstrcatW(newval, szSemiColon);
|
||||
ptr = newval + lstrlenW(value) + 1;
|
||||
}
|
||||
|
||||
lstrcpyW(newval, value);
|
||||
lstrcpyW(ptr, data);
|
||||
|
||||
if (flags & ENV_MOD_APPEND)
|
||||
{
|
||||
lstrcatW(newval, szSemiColon);
|
||||
lstrcatW(newval, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (newval)
|
||||
|
@ -5288,6 +5299,11 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* file->dest may be shorter after the reallocation, so add a NULL
|
||||
* terminator. This is needed for the call to strrchrW, as there will no
|
||||
* longer be a NULL terminator within the bounds of the allocation in this case.
|
||||
*/
|
||||
file->dest[size - 1] = '\0';
|
||||
lstrcpyW(strrchrW(file->dest, '\\') + 1, file->destname);
|
||||
|
||||
while (!list_empty(&files.entry))
|
||||
|
|
|
@ -125,7 +125,10 @@ static UINT alter_add_column(MSIALTERVIEW *av)
|
|||
return r;
|
||||
|
||||
if (check_column_exists(av->db, av->colinfo->table, av->colinfo->column))
|
||||
{
|
||||
columns->ops->delete(columns);
|
||||
return ERROR_BAD_QUERY_SYNTAX;
|
||||
}
|
||||
|
||||
r = MSI_OpenQuery(av->db, &view, query, av->colinfo->table, av->colinfo->column);
|
||||
if (r == ERROR_SUCCESS)
|
||||
|
|
|
@ -739,6 +739,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
|
|||
size_t dirLen = lstrlenW(dir), fileLen = lstrlenW(sig->File);
|
||||
WCHAR subpath[MAX_PATH];
|
||||
WCHAR *buf;
|
||||
DWORD len;
|
||||
|
||||
static const WCHAR starDotStarW[] = { '*','.','*',0 };
|
||||
|
||||
|
@ -753,7 +754,8 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
|
|||
* here. Add two because we might need to add a backslash if the dir name
|
||||
* isn't backslash-terminated.
|
||||
*/
|
||||
buf = msi_alloc( (dirLen + max(fileLen, strlenW(starDotStarW)) + 2) * sizeof(WCHAR));
|
||||
len = dirLen + max(fileLen, strlenW(starDotStarW)) + 2;
|
||||
buf = msi_alloc(len * sizeof(WCHAR));
|
||||
if (!buf)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
|
@ -815,7 +817,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
|
|||
}
|
||||
}
|
||||
|
||||
if (!*appValue)
|
||||
if (*appValue != buf)
|
||||
msi_free(buf);
|
||||
|
||||
return rc;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -51,13 +51,220 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
|||
* Any binary data in a table is a reference to a stream.
|
||||
*/
|
||||
|
||||
typedef struct tagMSITRANSFORM {
|
||||
struct list entry;
|
||||
IStorage *stg;
|
||||
} MSITRANSFORM;
|
||||
|
||||
typedef struct tagMSISTREAM {
|
||||
struct list entry;
|
||||
IStream *stm;
|
||||
} MSISTREAM;
|
||||
|
||||
static UINT find_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
{
|
||||
MSISTREAM *stream;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( stream, &db->streams, MSISTREAM, entry )
|
||||
{
|
||||
HRESULT r;
|
||||
STATSTG stat;
|
||||
|
||||
r = IStream_Stat( stream->stm, &stat, 0 );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
WARN("failed to stat stream r = %08x!\n", r);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !lstrcmpW( name, stat.pwcsName ) )
|
||||
{
|
||||
TRACE("found %s\n", debugstr_w(name));
|
||||
*stm = stream->stm;
|
||||
CoTaskMemFree( stat.pwcsName );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
CoTaskMemFree( stat.pwcsName );
|
||||
}
|
||||
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||
{
|
||||
IStream *stream;
|
||||
|
||||
if (find_open_stream( db, name, &stream ) == ERROR_SUCCESS)
|
||||
{
|
||||
HRESULT r;
|
||||
LARGE_INTEGER pos;
|
||||
|
||||
r = IStream_Clone( stream, stm );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
WARN("failed to clone stream r = %08x!\n", r);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
pos.QuadPart = 0;
|
||||
r = IStream_Seek( *stm, pos, STREAM_SEEK_SET, NULL );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
IStream_Release( *stm );
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
||||
{
|
||||
LPWSTR encname;
|
||||
HRESULT r;
|
||||
|
||||
encname = encode_streamname(FALSE, stname);
|
||||
|
||||
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
|
||||
|
||||
if (clone_open_stream( db, encname, stm ) == ERROR_SUCCESS)
|
||||
{
|
||||
msi_free( encname );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
r = IStorage_OpenStream( db->storage, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
MSITRANSFORM *transform;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
|
||||
{
|
||||
TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
|
||||
r = IStorage_OpenStream( transform->stg, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
if (SUCCEEDED(r))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msi_free( encname );
|
||||
|
||||
if( SUCCEEDED(r) )
|
||||
{
|
||||
MSISTREAM *stream;
|
||||
|
||||
stream = msi_alloc( sizeof(MSISTREAM) );
|
||||
if( !stream )
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
stream->stm = *stm;
|
||||
IStream_AddRef( *stm );
|
||||
list_add_tail( &db->streams, &stream->entry );
|
||||
}
|
||||
|
||||
return SUCCEEDED(r) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
|
||||
USHORT **pdata, UINT *psz )
|
||||
{
|
||||
HRESULT r;
|
||||
UINT ret = ERROR_FUNCTION_FAILED;
|
||||
VOID *data;
|
||||
ULONG sz, count;
|
||||
IStream *stm = NULL;
|
||||
STATSTG stat;
|
||||
|
||||
r = db_get_raw_stream( db, stname, &stm );
|
||||
if( r != ERROR_SUCCESS)
|
||||
return ret;
|
||||
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
WARN("open stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if( stat.cbSize.QuadPart >> 32 )
|
||||
{
|
||||
WARN("Too big!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
sz = stat.cbSize.QuadPart;
|
||||
data = msi_alloc( sz );
|
||||
if( !data )
|
||||
{
|
||||
WARN("couldn't allocate memory r=%08x!\n", r);
|
||||
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
r = IStream_Read(stm, data, sz, &count );
|
||||
if( FAILED( r ) || ( count != sz ) )
|
||||
{
|
||||
msi_free( data );
|
||||
WARN("read stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*pdata = data;
|
||||
*psz = sz;
|
||||
ret = ERROR_SUCCESS;
|
||||
|
||||
end:
|
||||
IStream_Release( stm );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
|
||||
{
|
||||
MSITRANSFORM *t;
|
||||
|
||||
t = msi_alloc( sizeof *t );
|
||||
t->stg = stg;
|
||||
IStorage_AddRef( stg );
|
||||
list_add_tail( &db->transforms, &t->entry );
|
||||
}
|
||||
|
||||
static void free_transforms( MSIDATABASE *db )
|
||||
{
|
||||
while( !list_empty( &db->transforms ) )
|
||||
{
|
||||
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ),
|
||||
MSITRANSFORM, entry );
|
||||
list_remove( &t->entry );
|
||||
IStorage_Release( t->stg );
|
||||
msi_free( t );
|
||||
}
|
||||
}
|
||||
|
||||
static void free_streams( MSIDATABASE *db )
|
||||
{
|
||||
while( !list_empty( &db->streams ) )
|
||||
{
|
||||
MSISTREAM *s = LIST_ENTRY( list_head( &db->streams ),
|
||||
MSISTREAM, entry );
|
||||
list_remove( &s->entry );
|
||||
IStream_Release( s->stm );
|
||||
msi_free( s );
|
||||
}
|
||||
}
|
||||
|
||||
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
||||
{
|
||||
MSIDATABASE *db = (MSIDATABASE *) arg;
|
||||
|
||||
msi_free(db->path);
|
||||
free_cached_tables( db );
|
||||
msi_free_transforms( db );
|
||||
free_streams( db );
|
||||
free_transforms( db );
|
||||
msi_destroy_stringtable( db->strings );
|
||||
IStorage_Release( db->storage );
|
||||
if (db->deletefile)
|
||||
|
@ -198,6 +405,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
|
|||
db->deletefile = strdupW( szDBPath );
|
||||
list_init( &db->tables );
|
||||
list_init( &db->transforms );
|
||||
list_init( &db->streams );
|
||||
|
||||
db->strings = msi_load_string_table( stg, &db->bytes_per_strref );
|
||||
if( !db->strings )
|
||||
|
@ -493,10 +701,10 @@ done:
|
|||
|
||||
static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_labels, DWORD num_columns)
|
||||
{
|
||||
UINT r;
|
||||
UINT r = ERROR_OUTOFMEMORY;
|
||||
DWORD size;
|
||||
MSIQUERY *view;
|
||||
LPWSTR create_sql;
|
||||
LPWSTR create_sql = NULL;
|
||||
LPWSTR prelude, columns_sql, postlude;
|
||||
|
||||
prelude = msi_build_createsql_prelude(labels[0]);
|
||||
|
@ -504,31 +712,30 @@ static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
|
|||
postlude = msi_build_createsql_postlude(labels + 1, num_labels - 1); /* skip over table name */
|
||||
|
||||
if (!prelude || !columns_sql || !postlude)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
|
||||
size = lstrlenW(prelude) + lstrlenW(columns_sql) + lstrlenW(postlude) + 1;
|
||||
create_sql = msi_alloc(size * sizeof(WCHAR));
|
||||
if (!create_sql)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
goto done;
|
||||
|
||||
lstrcpyW(create_sql, prelude);
|
||||
lstrcatW(create_sql, columns_sql);
|
||||
lstrcatW(create_sql, postlude);
|
||||
|
||||
msi_free(prelude);
|
||||
msi_free(columns_sql);
|
||||
msi_free(postlude);
|
||||
|
||||
r = MSI_DatabaseOpenViewW( db, create_sql, &view );
|
||||
msi_free(create_sql);
|
||||
|
||||
if (r != ERROR_SUCCESS)
|
||||
return r;
|
||||
goto done;
|
||||
|
||||
r = MSI_ViewExecute(view, NULL);
|
||||
MSI_ViewClose(view);
|
||||
msiobj_release(&view->hdr);
|
||||
|
||||
done:
|
||||
msi_free(prelude);
|
||||
msi_free(columns_sql);
|
||||
msi_free(postlude);
|
||||
msi_free(create_sql);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -622,6 +829,7 @@ static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *t
|
|||
while (MSI_ViewFetch(view, &rec) != ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
r = MSI_ViewModify(view, MSIMODIFY_DELETE, rec);
|
||||
msiobj_release(&rec->hdr);
|
||||
if (r != ERROR_SUCCESS)
|
||||
goto done;
|
||||
}
|
||||
|
@ -1451,6 +1659,7 @@ static UINT msi_get_query_types(MSIQUERY *query, LPWSTR **types, DWORD *numtypes
|
|||
goto end;
|
||||
}
|
||||
|
||||
*numtypes = count;
|
||||
for (i=1; i<=count; i++ )
|
||||
{
|
||||
(*types)[i-1] = strdupW(MSI_RecordGetString(prec, i));
|
||||
|
@ -1477,32 +1686,36 @@ static void merge_free_rows(MERGETABLE *table)
|
|||
|
||||
static void free_merge_table(MERGETABLE *table)
|
||||
{
|
||||
UINT i;
|
||||
UINT i;
|
||||
|
||||
if (table->labels != NULL)
|
||||
{
|
||||
for (i = 0; i < table->numlabels; i++)
|
||||
msi_free(table->labels[i]);
|
||||
msi_free(table->labels);
|
||||
}
|
||||
if (table->labels != NULL)
|
||||
{
|
||||
for (i = 0; i < table->numlabels; i++)
|
||||
msi_free(table->labels[i]);
|
||||
|
||||
if (table->columns != NULL)
|
||||
{
|
||||
for (i = 0; i < table->numcolumns; i++)
|
||||
msi_free(table->columns[i]);
|
||||
msi_free(table->columns);
|
||||
}
|
||||
msi_free(table->labels);
|
||||
}
|
||||
|
||||
if (table->types != NULL)
|
||||
{
|
||||
for (i = 0; i < table->numtypes; i++)
|
||||
msi_free(table->types[i]);
|
||||
msi_free(table->types);
|
||||
}
|
||||
msi_free(table->name);
|
||||
merge_free_rows(table);
|
||||
if (table->columns != NULL)
|
||||
{
|
||||
for (i = 0; i < table->numcolumns; i++)
|
||||
msi_free(table->columns[i]);
|
||||
|
||||
msi_free(table);
|
||||
msi_free(table->columns);
|
||||
}
|
||||
|
||||
if (table->types != NULL)
|
||||
{
|
||||
for (i = 0; i < table->numtypes; i++)
|
||||
msi_free(table->types[i]);
|
||||
|
||||
msi_free(table->types);
|
||||
}
|
||||
|
||||
msi_free(table->name);
|
||||
merge_free_rows(table);
|
||||
|
||||
msi_free(table);
|
||||
}
|
||||
|
||||
static UINT msi_get_merge_table (MSIDATABASE *db, LPCWSTR name, MERGETABLE **ptable)
|
||||
|
@ -1753,7 +1966,6 @@ UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge,
|
|||
LIST_FOR_EACH_SAFE(item, cursor, &tabledata)
|
||||
{
|
||||
MERGETABLE *table = LIST_ENTRY(item, MERGETABLE, entry);
|
||||
|
||||
list_remove(&table->entry);
|
||||
free_merge_table(table);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,20 @@ static UINT DROP_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
|
|||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
static UINT DROP_delete( struct tagMSIVIEW *view )
|
||||
{
|
||||
MSIDROPVIEW *dv = (MSIDROPVIEW*)view;
|
||||
|
||||
TRACE("%p\n", dv );
|
||||
|
||||
if( dv->table )
|
||||
dv->table->ops->delete( dv->table );
|
||||
|
||||
msi_free( dv );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static const MSIVIEWOPS drop_ops =
|
||||
{
|
||||
NULL,
|
||||
|
@ -91,7 +105,7 @@ static const MSIVIEWOPS drop_ops =
|
|||
DROP_get_dimensions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DROP_delete,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -155,7 +155,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
|
|||
gle = copy_file(file, source);
|
||||
TRACE("Overwriting existing file: %d\n", gle);
|
||||
}
|
||||
if ((gle == ERROR_SHARING_VIOLATION) || (gle == ERROR_USER_MAPPED_FILE))
|
||||
if (gle == ERROR_SHARING_VIOLATION || gle == ERROR_USER_MAPPED_FILE)
|
||||
{
|
||||
WCHAR tmpfileW[MAX_PATH], *pathW, *p;
|
||||
DWORD len;
|
||||
|
|
|
@ -229,14 +229,18 @@ static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
|||
static UINT JOIN_delete( struct tagMSIVIEW *view )
|
||||
{
|
||||
MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
|
||||
JOINTABLE *table;
|
||||
struct list *item, *cursor;
|
||||
|
||||
TRACE("%p\n", jv );
|
||||
|
||||
LIST_FOR_EACH_ENTRY(table, &jv->tables, JOINTABLE, entry)
|
||||
LIST_FOR_EACH_SAFE(item, cursor, &jv->tables)
|
||||
{
|
||||
JOINTABLE* table = LIST_ENTRY(item, JOINTABLE, entry);
|
||||
|
||||
list_remove(&table->entry);
|
||||
table->view->ops->delete(table->view);
|
||||
table->view = NULL;
|
||||
msi_free(table);
|
||||
}
|
||||
|
||||
msi_free(jv);
|
||||
|
@ -349,11 +353,13 @@ UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR tables )
|
|||
if( r != ERROR_SUCCESS )
|
||||
{
|
||||
WARN("can't create table: %s\n", debugstr_w(tables));
|
||||
msi_free(table);
|
||||
r = ERROR_BAD_QUERY_SYNTAX;
|
||||
goto end;
|
||||
}
|
||||
|
||||
r = table->view->ops->get_dimensions( table->view, NULL, &table->columns );
|
||||
r = table->view->ops->get_dimensions( table->view, NULL,
|
||||
&table->columns );
|
||||
if( r != ERROR_SUCCESS )
|
||||
{
|
||||
ERR("can't get table dimensions\n");
|
||||
|
|
|
@ -334,7 +334,12 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
|
|||
data->curfile = strdupAtoW(pfdin->psz1);
|
||||
if (!data->cb(data->package, data->curfile, MSICABEXTRACT_BEGINEXTRACT, &path,
|
||||
&attrs, data->user))
|
||||
{
|
||||
/* We're not extracting this file, so free the filename. */
|
||||
msi_free(data->curfile);
|
||||
data->curfile = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
TRACE("extracting %s\n", debugstr_w(path));
|
||||
|
||||
|
@ -362,7 +367,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
|
|||
if (handle != INVALID_HANDLE_VALUE) goto done;
|
||||
err = GetLastError();
|
||||
}
|
||||
if ((err == ERROR_SHARING_VIOLATION) || (err == ERROR_USER_MAPPED_FILE))
|
||||
if (err == ERROR_SHARING_VIOLATION || err == ERROR_USER_MAPPED_FILE)
|
||||
{
|
||||
WCHAR tmpfileW[MAX_PATH], *tmppathW, *p;
|
||||
DWORD len;
|
||||
|
|
|
@ -901,7 +901,7 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
|
|||
WCHAR packagecode[GUID_SIZE];
|
||||
BOOL badconfig = FALSE;
|
||||
LONG res;
|
||||
DWORD save, type = REG_NONE;
|
||||
DWORD type = REG_NONE;
|
||||
|
||||
static WCHAR empty[] = {0};
|
||||
static const WCHAR sourcelist[] = {
|
||||
|
@ -1036,22 +1036,26 @@ static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
|
|||
|
||||
if (pcchValueBuf)
|
||||
{
|
||||
save = *pcchValueBuf;
|
||||
|
||||
if (strlenW(val) < *pcchValueBuf)
|
||||
r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
|
||||
else if (szValue->str.a || szValue->str.w)
|
||||
r = ERROR_MORE_DATA;
|
||||
/* If szBuffer (szValue->str) is NULL, there's no need to copy the value
|
||||
* out. Also, *pcchValueBuf may be uninitialized in this case, so we
|
||||
* can't rely on its value.
|
||||
*/
|
||||
if (szValue->str.a || szValue->str.w)
|
||||
{
|
||||
DWORD size = *pcchValueBuf;
|
||||
if (strlenW(val) < size)
|
||||
r = msi_strcpy_to_awstring(val, szValue, &size);
|
||||
else
|
||||
{
|
||||
r = ERROR_MORE_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (!badconfig)
|
||||
*pcchValueBuf = lstrlenW(val);
|
||||
else if (r == ERROR_SUCCESS)
|
||||
{
|
||||
*pcchValueBuf = save;
|
||||
r = ERROR_BAD_CONFIGURATION;
|
||||
}
|
||||
}
|
||||
else if (badconfig)
|
||||
|
||||
if (badconfig)
|
||||
r = ERROR_BAD_CONFIGURATION;
|
||||
|
||||
if (val != empty)
|
||||
|
|
|
@ -80,6 +80,7 @@ typedef struct tagMSIDATABASE
|
|||
LPCWSTR mode;
|
||||
struct list tables;
|
||||
struct list transforms;
|
||||
struct list streams;
|
||||
} MSIDATABASE;
|
||||
|
||||
typedef struct tagMSIVIEW MSIVIEW;
|
||||
|
@ -649,7 +650,6 @@ extern void msiobj_unlock(MSIOBJECTHDR *);
|
|||
extern void msi_free_handle_table(void);
|
||||
|
||||
extern void free_cached_tables( MSIDATABASE *db );
|
||||
extern void msi_free_transforms( MSIDATABASE *db );
|
||||
extern UINT MSI_CommitTables( MSIDATABASE *db );
|
||||
|
||||
|
||||
|
@ -698,6 +698,7 @@ extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
|
|||
BOOL preserve_case );
|
||||
|
||||
/* record internals */
|
||||
extern void MSI_CloseRecord( MSIOBJECTHDR * );
|
||||
extern UINT MSI_RecordSetIStream( MSIRECORD *, UINT, IStream *);
|
||||
extern UINT MSI_RecordGetIStream( MSIRECORD *, UINT, IStream **);
|
||||
extern const WCHAR *MSI_RecordGetString( const MSIRECORD *, UINT );
|
||||
|
@ -718,11 +719,12 @@ extern MSIRECORD *MSI_CloneRecord( MSIRECORD * );
|
|||
extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * );
|
||||
|
||||
/* stream internals */
|
||||
extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
|
||||
extern void enum_stream_names( IStorage *stg );
|
||||
extern LPWSTR encode_streamname(BOOL bTable, LPCWSTR in);
|
||||
extern BOOL decode_streamname(LPCWSTR in, LPWSTR out);
|
||||
|
||||
/* database internals */
|
||||
extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** );
|
||||
extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** );
|
||||
extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** );
|
||||
extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... );
|
||||
|
@ -755,7 +757,7 @@ extern MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *, LPCWSTR );
|
|||
extern UINT MSI_GetComponentStateW( MSIPACKAGE *, LPCWSTR, INSTALLSTATE *, INSTALLSTATE * );
|
||||
extern UINT MSI_GetFeatureStateW( MSIPACKAGE *, LPCWSTR, INSTALLSTATE *, INSTALLSTATE * );
|
||||
extern UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE*, LPCWSTR, INSTALLSTATE );
|
||||
extern LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename );
|
||||
extern UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename );
|
||||
extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR);
|
||||
extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR);
|
||||
extern UINT msi_clone_properties(MSIPACKAGE *);
|
||||
|
|
|
@ -153,21 +153,48 @@ library WindowsInstaller
|
|||
Session* OpenPackage(
|
||||
[in] VARIANT PackagePath,
|
||||
[in, optional, defaultvalue(0)] long Options);
|
||||
[id(DISPID_INSTALLER_OPENPRODUCT)]
|
||||
Session* OpenProduct(
|
||||
[in] BSTR ProductCode);
|
||||
[id(DISPID_INSTALLER_SUMMARYINFORMATION)]
|
||||
SummaryInfo* SummaryInformation(
|
||||
[in] BSTR PackagePath,
|
||||
[in, optional, defaultvalue(0)] long UpdateCount);
|
||||
[id(DISPID_INSTALLER_OPENDATABASE)]
|
||||
Database *OpenDatabase(
|
||||
[in] BSTR DatabasePath,
|
||||
[in] VARIANT OpenMode);
|
||||
[id(DISPID_INSTALLER_ENABLELOG)]
|
||||
void EnableLog(
|
||||
[in] BSTR LogMode,
|
||||
[in] BSTR LogFile);
|
||||
[id(DISPID_INSTALLER_INSTALLPRODUCT)]
|
||||
void InstallProduct(
|
||||
[in] BSTR PackagePath,
|
||||
[in, optional, defaultvalue("0")] BSTR PropertyValues);
|
||||
[id(DISPID_INSTALLER_VERSION)]
|
||||
BSTR Version();
|
||||
[id(DISPID_INSTALLER_LASTERRORRECORD)]
|
||||
Record* LastErrorRecord();
|
||||
[id(DISPID_INSTALLER_REGISTRYVALUE), propget]
|
||||
BSTR RegistryValue(
|
||||
[in] VARIANT Root,
|
||||
[in] BSTR Key,
|
||||
[in, optional] VARIANT Value);
|
||||
[id(DISPID_INSTALLER_ENVIRONMENT), propget]
|
||||
BSTR Environment([in] BSTR Variable);
|
||||
[id(DISPID_INSTALLER_ENVIRONMENT), propput]
|
||||
void Environment(
|
||||
[in] BSTR Variable,
|
||||
[in] BSTR rhs);
|
||||
[id(DISPID_INSTALLER_FILEATTRIBUTES)]
|
||||
long FileAttributes([in] BSTR FilePath);
|
||||
[id(DISPID_INSTALLER_FILESIZE)]
|
||||
long FileSize([in] BSTR FilePath);
|
||||
[id(DISPID_INSTALLER_FILEVERSION)]
|
||||
BSTR FileVersion(
|
||||
[in] BSTR FilePath,
|
||||
[in, optional] VARIANT Language);
|
||||
[id(DISPID_INSTALLER_PRODUCTSTATE), propget]
|
||||
MsiInstallState ProductState(
|
||||
[in] BSTR Product);
|
||||
|
|
|
@ -18,11 +18,19 @@
|
|||
|
||||
#define DISPID_INSTALLER_CREATERECORD 1
|
||||
#define DISPID_INSTALLER_OPENPACKAGE 2
|
||||
#define DISPID_INSTALLER_OPENPRODUCT 3
|
||||
#define DISPID_INSTALLER_OPENDATABASE 4
|
||||
#define DISPID_INSTALLER_SUMMARYINFORMATION 5
|
||||
#define DISPID_INSTALLER_UILEVEL 6
|
||||
#define DISPID_INSTALLER_ENABLELOG 7
|
||||
#define DISPID_INSTALLER_INSTALLPRODUCT 8
|
||||
#define DISPID_INSTALLER_VERSION 9
|
||||
#define DISPID_INSTALLER_LASTERRORRECORD 10
|
||||
#define DISPID_INSTALLER_REGISTRYVALUE 11
|
||||
#define DISPID_INSTALLER_ENVIRONMENT 12
|
||||
#define DISPID_INSTALLER_FILEATTRIBUTES 13
|
||||
#define DISPID_INSTALLER_FILESIZE 15
|
||||
#define DISPID_INSTALLER_FILEVERSION 16
|
||||
#define DISPID_INSTALLER_PRODUCTSTATE 17
|
||||
#define DISPID_INSTALLER_PRODUCTINFO 18
|
||||
#define DISPID_INSTALLER_PRODUCTS 35
|
||||
|
|
|
@ -779,6 +779,16 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void adjust_allusers_property( MSIPACKAGE *package )
|
||||
{
|
||||
/* FIXME: this should depend on the user's privileges */
|
||||
if (msi_get_property_int( package, szAllUsers, 0 ) == 2)
|
||||
{
|
||||
TRACE("resetting ALLUSERS property from 2 to 1\n");
|
||||
MSI_SetPropertyW( package, szAllUsers, szOne );
|
||||
}
|
||||
}
|
||||
|
||||
MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
|
||||
{
|
||||
static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 };
|
||||
|
@ -818,6 +828,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
|
|||
|
||||
if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
|
||||
msi_load_admin_properties( package );
|
||||
|
||||
adjust_allusers_property( package );
|
||||
}
|
||||
|
||||
return package;
|
||||
|
@ -833,7 +845,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
|
|||
* we should read all the tables to memory, then open the
|
||||
* database to read binary streams on demand.
|
||||
*/
|
||||
static LPCWSTR copy_package_to_temp( LPCWSTR szPackage, LPWSTR filename )
|
||||
static UINT copy_package_to_temp( LPCWSTR szPackage, LPWSTR filename )
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
|
@ -842,16 +854,16 @@ static LPCWSTR copy_package_to_temp( LPCWSTR szPackage, LPWSTR filename )
|
|||
|
||||
if( !CopyFileW( szPackage, filename, FALSE ) )
|
||||
{
|
||||
UINT error = GetLastError();
|
||||
ERR("failed to copy package %s to %s (%u)\n", debugstr_w(szPackage), debugstr_w(filename), error);
|
||||
DeleteFileW( filename );
|
||||
ERR("failed to copy package %s\n", debugstr_w(szPackage) );
|
||||
return szPackage;
|
||||
return error;
|
||||
}
|
||||
|
||||
TRACE("Opening relocated package %s\n", debugstr_w( filename ));
|
||||
return filename;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename )
|
||||
UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename )
|
||||
{
|
||||
LPINTERNET_CACHE_ENTRY_INFOW cache_entry;
|
||||
DWORD size = 0;
|
||||
|
@ -867,20 +879,24 @@ LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename )
|
|||
cache_entry = HeapAlloc( GetProcessHeap(), 0, size );
|
||||
if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) )
|
||||
{
|
||||
UINT error = GetLastError();
|
||||
HeapFree( GetProcessHeap(), 0, cache_entry );
|
||||
return szUrl;
|
||||
return error;
|
||||
}
|
||||
|
||||
lstrcpyW( filename, cache_entry->lpszLocalFileName );
|
||||
HeapFree( GetProcessHeap(), 0, cache_entry );
|
||||
return filename;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
hr = URLDownloadToCacheFileW( NULL, szUrl, filename, MAX_PATH, 0, NULL );
|
||||
if ( FAILED(hr) )
|
||||
return szUrl;
|
||||
{
|
||||
WARN("failed to download %s to cache file\n", debugstr_w(szUrl));
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
return filename;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT msi_get_local_package_name( LPWSTR path )
|
||||
|
@ -925,7 +941,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
MSIHANDLE handle;
|
||||
LPWSTR ptr, base_url = NULL;
|
||||
UINT r;
|
||||
WCHAR temppath[MAX_PATH], localfile[MAX_PATH];
|
||||
WCHAR temppath[MAX_PATH], localfile[MAX_PATH], cachefile[MAX_PATH];
|
||||
LPCWSTR file = szPackage;
|
||||
|
||||
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
|
||||
|
@ -952,9 +968,15 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
{
|
||||
if ( UrlIsW( szPackage, URLIS_URL ) )
|
||||
{
|
||||
file = msi_download_file( szPackage, temppath );
|
||||
if ( file != szPackage )
|
||||
file = copy_package_to_temp( file, temppath );
|
||||
r = msi_download_file( szPackage, cachefile );
|
||||
if ( r != ERROR_SUCCESS )
|
||||
return r;
|
||||
|
||||
r = copy_package_to_temp( cachefile, temppath );
|
||||
if ( r != ERROR_SUCCESS )
|
||||
return r;
|
||||
|
||||
file = temppath;
|
||||
|
||||
base_url = strdupW( szPackage );
|
||||
if ( !base_url )
|
||||
|
@ -964,7 +986,13 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
if (ptr) *(ptr + 1) = '\0';
|
||||
}
|
||||
else
|
||||
file = copy_package_to_temp( szPackage, temppath );
|
||||
{
|
||||
r = copy_package_to_temp( szPackage, temppath );
|
||||
if ( r != ERROR_SUCCESS )
|
||||
return r;
|
||||
|
||||
file = temppath;
|
||||
}
|
||||
|
||||
r = msi_get_local_package_name( localfile );
|
||||
if (r != ERROR_SUCCESS)
|
||||
|
@ -979,6 +1007,8 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
return GetLastError();
|
||||
}
|
||||
|
||||
TRACE("Opening relocated package %s\n", debugstr_w( file ));
|
||||
|
||||
/* transforms that add binary streams require that we open the database
|
||||
* read/write, which is safe because we always create a copy that is thrown
|
||||
* away when we're done.
|
||||
|
|
|
@ -64,7 +64,7 @@ static void MSI_FreeField( MSIFIELD *field )
|
|||
}
|
||||
}
|
||||
|
||||
static void MSI_CloseRecord( MSIOBJECTHDR *arg )
|
||||
void MSI_CloseRecord( MSIOBJECTHDR *arg )
|
||||
{
|
||||
MSIRECORD *rec = (MSIRECORD *) arg;
|
||||
UINT i;
|
||||
|
|
|
@ -126,7 +126,10 @@ typedef struct tag_SQL_input
|
|||
LPCWSTR command;
|
||||
DWORD n, len;
|
||||
UINT r;
|
||||
MSIVIEW **view; /* view structure for the resulting query */
|
||||
MSIVIEW **view; /* View structure for the resulting query. This value
|
||||
* tracks the view currently being created so we can free
|
||||
* this view on syntax error.
|
||||
*/
|
||||
struct list *mem;
|
||||
} SQL_input;
|
||||
|
||||
|
@ -147,10 +150,14 @@ static struct expr * EXPR_ival( void *info, int val );
|
|||
static struct expr * EXPR_sval( void *info, const struct sql_str *str );
|
||||
static struct expr * EXPR_wildcard( void *info );
|
||||
|
||||
#define PARSER_BUBBLE_UP_VIEW( sql, result, current_view ) \
|
||||
*sql->view = current_view; \
|
||||
result = current_view
|
||||
|
||||
|
||||
|
||||
/* Line 189 of yacc.c */
|
||||
#line 154 "sql.tab.c"
|
||||
#line 161 "sql.tab.c"
|
||||
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
|
@ -248,7 +255,7 @@ typedef union YYSTYPE
|
|||
{
|
||||
|
||||
/* Line 214 of yacc.c */
|
||||
#line 76 "sql.y"
|
||||
#line 83 "sql.y"
|
||||
|
||||
struct sql_str str;
|
||||
LPWSTR string;
|
||||
|
@ -261,7 +268,7 @@ typedef union YYSTYPE
|
|||
|
||||
|
||||
/* Line 214 of yacc.c */
|
||||
#line 265 "sql.tab.c"
|
||||
#line 272 "sql.tab.c"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
|
@ -273,7 +280,7 @@ typedef union YYSTYPE
|
|||
|
||||
|
||||
/* Line 264 of yacc.c */
|
||||
#line 277 "sql.tab.c"
|
||||
#line 284 "sql.tab.c"
|
||||
|
||||
#ifdef short
|
||||
# undef short
|
||||
|
@ -595,15 +602,15 @@ static const yytype_int8 yyrhs[] =
|
|||
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
|
||||
static const yytype_uint16 yyrline[] =
|
||||
{
|
||||
0, 126, 126, 134, 135, 136, 137, 138, 139, 140,
|
||||
144, 154, 167, 183, 198, 208, 221, 234, 244, 254,
|
||||
267, 271, 278, 291, 301, 311, 318, 327, 331, 335,
|
||||
342, 346, 353, 357, 361, 365, 369, 373, 377, 384,
|
||||
393, 406, 410, 414, 430, 451, 452, 456, 463, 464,
|
||||
480, 490, 502, 507, 516, 522, 528, 534, 540, 546,
|
||||
552, 558, 564, 570, 576, 585, 586, 590, 597, 608,
|
||||
609, 617, 625, 631, 637, 643, 652, 661, 667, 676,
|
||||
683, 691
|
||||
0, 133, 133, 141, 142, 143, 144, 145, 146, 147,
|
||||
151, 162, 176, 193, 209, 220, 234, 248, 259, 270,
|
||||
284, 288, 295, 310, 320, 330, 337, 346, 350, 354,
|
||||
361, 365, 372, 376, 380, 384, 388, 392, 396, 403,
|
||||
412, 425, 429, 433, 448, 468, 469, 473, 480, 481,
|
||||
496, 508, 523, 528, 537, 543, 549, 555, 561, 567,
|
||||
573, 579, 585, 591, 597, 606, 607, 611, 618, 629,
|
||||
630, 638, 646, 652, 658, 664, 673, 682, 688, 697,
|
||||
704, 712
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1612,7 +1619,7 @@ yyreduce:
|
|||
case 2:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 127 "sql.y"
|
||||
#line 134 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
*sql->view = (yyvsp[(1) - (1)].query);
|
||||
|
@ -1622,7 +1629,7 @@ yyreduce:
|
|||
case 10:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 145 "sql.y"
|
||||
#line 152 "sql.y"
|
||||
{
|
||||
SQL_input *sql = (SQL_input*) info;
|
||||
MSIVIEW *insert = NULL;
|
||||
|
@ -1630,14 +1637,15 @@ yyreduce:
|
|||
INSERT_CreateView( sql->db, &insert, (yyvsp[(3) - (10)].string), (yyvsp[(5) - (10)].column_list), (yyvsp[(9) - (10)].column_list), FALSE );
|
||||
if( !insert )
|
||||
YYABORT;
|
||||
(yyval.query) = insert;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), insert );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 155 "sql.y"
|
||||
#line 163 "sql.y"
|
||||
{
|
||||
SQL_input *sql = (SQL_input*) info;
|
||||
MSIVIEW *insert = NULL;
|
||||
|
@ -1645,14 +1653,15 @@ yyreduce:
|
|||
INSERT_CreateView( sql->db, &insert, (yyvsp[(3) - (11)].string), (yyvsp[(5) - (11)].column_list), (yyvsp[(9) - (11)].column_list), TRUE );
|
||||
if( !insert )
|
||||
YYABORT;
|
||||
(yyval.query) = insert;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), insert );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 168 "sql.y"
|
||||
#line 177 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW *create = NULL;
|
||||
|
@ -1666,14 +1675,15 @@ yyreduce:
|
|||
sql->r = r;
|
||||
YYABORT;
|
||||
}
|
||||
(yyval.query) = create;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), create );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 13:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 184 "sql.y"
|
||||
#line 194 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW *create = NULL;
|
||||
|
@ -1683,14 +1693,15 @@ yyreduce:
|
|||
CREATE_CreateView( sql->db, &create, (yyvsp[(3) - (7)].string), (yyvsp[(5) - (7)].column_list), TRUE );
|
||||
if( !create )
|
||||
YYABORT;
|
||||
(yyval.query) = create;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), create );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 14:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 199 "sql.y"
|
||||
#line 210 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW *update = NULL;
|
||||
|
@ -1698,14 +1709,15 @@ yyreduce:
|
|||
UPDATE_CreateView( sql->db, &update, (yyvsp[(2) - (6)].string), (yyvsp[(4) - (6)].column_list), (yyvsp[(6) - (6)].expr) );
|
||||
if( !update )
|
||||
YYABORT;
|
||||
(yyval.query) = update;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), update );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 15:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 209 "sql.y"
|
||||
#line 221 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW *update = NULL;
|
||||
|
@ -1713,14 +1725,15 @@ yyreduce:
|
|||
UPDATE_CreateView( sql->db, &update, (yyvsp[(2) - (4)].string), (yyvsp[(4) - (4)].column_list), NULL );
|
||||
if( !update )
|
||||
YYABORT;
|
||||
(yyval.query) = update;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), update );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 222 "sql.y"
|
||||
#line 235 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW *delete = NULL;
|
||||
|
@ -1728,14 +1741,15 @@ yyreduce:
|
|||
DELETE_CreateView( sql->db, &delete, (yyvsp[(2) - (2)].query) );
|
||||
if( !delete )
|
||||
YYABORT;
|
||||
(yyval.query) = delete;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), delete );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 17:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 235 "sql.y"
|
||||
#line 249 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW *alter = NULL;
|
||||
|
@ -1743,14 +1757,15 @@ yyreduce:
|
|||
ALTER_CreateView( sql->db, &alter, (yyvsp[(3) - (4)].string), NULL, (yyvsp[(4) - (4)].integer) );
|
||||
if( !alter )
|
||||
YYABORT;
|
||||
(yyval.query) = alter;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 18:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 245 "sql.y"
|
||||
#line 260 "sql.y"
|
||||
{
|
||||
SQL_input *sql = (SQL_input *)info;
|
||||
MSIVIEW *alter = NULL;
|
||||
|
@ -1758,14 +1773,15 @@ yyreduce:
|
|||
ALTER_CreateView( sql->db, &alter, (yyvsp[(3) - (5)].string), (yyvsp[(5) - (5)].column_list), 0 );
|
||||
if (!alter)
|
||||
YYABORT;
|
||||
(yyval.query) = alter;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 19:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 255 "sql.y"
|
||||
#line 271 "sql.y"
|
||||
{
|
||||
SQL_input *sql = (SQL_input *)info;
|
||||
MSIVIEW *alter = NULL;
|
||||
|
@ -1773,14 +1789,15 @@ yyreduce:
|
|||
ALTER_CreateView( sql->db, &alter, (yyvsp[(3) - (6)].string), (yyvsp[(5) - (6)].column_list), 1 );
|
||||
if (!alter)
|
||||
YYABORT;
|
||||
(yyval.query) = alter;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 20:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 268 "sql.y"
|
||||
#line 285 "sql.y"
|
||||
{
|
||||
(yyval.integer) = 1;
|
||||
;}
|
||||
|
@ -1789,7 +1806,7 @@ yyreduce:
|
|||
case 21:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 272 "sql.y"
|
||||
#line 289 "sql.y"
|
||||
{
|
||||
(yyval.integer) = -1;
|
||||
;}
|
||||
|
@ -1798,22 +1815,24 @@ yyreduce:
|
|||
case 22:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 279 "sql.y"
|
||||
#line 296 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* drop = NULL;
|
||||
UINT r;
|
||||
|
||||
(yyval.query) = NULL;
|
||||
r = DROP_CreateView( sql->db, &(yyval.query), (yyvsp[(3) - (3)].string) );
|
||||
r = DROP_CreateView( sql->db, &drop, (yyvsp[(3) - (3)].string) );
|
||||
if( r != ERROR_SUCCESS || !(yyval.query) )
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), drop );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 23:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 292 "sql.y"
|
||||
#line 311 "sql.y"
|
||||
{
|
||||
if( SQL_MarkPrimaryKeys( &(yyvsp[(1) - (4)].column_list), (yyvsp[(4) - (4)].column_list) ) )
|
||||
(yyval.column_list) = (yyvsp[(1) - (4)].column_list);
|
||||
|
@ -1825,7 +1844,7 @@ yyreduce:
|
|||
case 24:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 302 "sql.y"
|
||||
#line 321 "sql.y"
|
||||
{
|
||||
column_info *ci;
|
||||
|
||||
|
@ -1840,7 +1859,7 @@ yyreduce:
|
|||
case 25:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 312 "sql.y"
|
||||
#line 331 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = (yyvsp[(1) - (1)].column_list);
|
||||
;}
|
||||
|
@ -1849,7 +1868,7 @@ yyreduce:
|
|||
case 26:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 319 "sql.y"
|
||||
#line 338 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = (yyvsp[(1) - (2)].column_list);
|
||||
(yyval.column_list)->type = ((yyvsp[(2) - (2)].column_type) | MSITYPE_VALID);
|
||||
|
@ -1860,7 +1879,7 @@ yyreduce:
|
|||
case 27:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 328 "sql.y"
|
||||
#line 347 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = (yyvsp[(1) - (1)].column_type);
|
||||
;}
|
||||
|
@ -1869,7 +1888,7 @@ yyreduce:
|
|||
case 28:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 332 "sql.y"
|
||||
#line 351 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = (yyvsp[(1) - (2)].column_type) | MSITYPE_LOCALIZABLE;
|
||||
;}
|
||||
|
@ -1878,7 +1897,7 @@ yyreduce:
|
|||
case 29:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 336 "sql.y"
|
||||
#line 355 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = (yyvsp[(1) - (2)].column_type) | MSITYPE_TEMPORARY;
|
||||
;}
|
||||
|
@ -1887,7 +1906,7 @@ yyreduce:
|
|||
case 30:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 343 "sql.y"
|
||||
#line 362 "sql.y"
|
||||
{
|
||||
(yyval.column_type) |= MSITYPE_NULLABLE;
|
||||
;}
|
||||
|
@ -1896,7 +1915,7 @@ yyreduce:
|
|||
case 31:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 347 "sql.y"
|
||||
#line 366 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = (yyvsp[(1) - (3)].column_type);
|
||||
;}
|
||||
|
@ -1905,7 +1924,7 @@ yyreduce:
|
|||
case 32:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 354 "sql.y"
|
||||
#line 373 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = MSITYPE_STRING | 1;
|
||||
;}
|
||||
|
@ -1914,7 +1933,7 @@ yyreduce:
|
|||
case 33:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 358 "sql.y"
|
||||
#line 377 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[(3) - (4)].column_type);
|
||||
;}
|
||||
|
@ -1923,7 +1942,7 @@ yyreduce:
|
|||
case 34:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 362 "sql.y"
|
||||
#line 381 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = MSITYPE_STRING | 0x400;
|
||||
;}
|
||||
|
@ -1932,7 +1951,7 @@ yyreduce:
|
|||
case 35:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 366 "sql.y"
|
||||
#line 385 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = 2 | 0x400;
|
||||
;}
|
||||
|
@ -1941,7 +1960,7 @@ yyreduce:
|
|||
case 36:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 370 "sql.y"
|
||||
#line 389 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = 2 | 0x400;
|
||||
;}
|
||||
|
@ -1950,7 +1969,7 @@ yyreduce:
|
|||
case 37:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 374 "sql.y"
|
||||
#line 393 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = 4;
|
||||
;}
|
||||
|
@ -1959,7 +1978,7 @@ yyreduce:
|
|||
case 38:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 378 "sql.y"
|
||||
#line 397 "sql.y"
|
||||
{
|
||||
(yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID;
|
||||
;}
|
||||
|
@ -1968,7 +1987,7 @@ yyreduce:
|
|||
case 39:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 385 "sql.y"
|
||||
#line 404 "sql.y"
|
||||
{
|
||||
if( ( (yyvsp[(1) - (1)].integer) > 255 ) || ( (yyvsp[(1) - (1)].integer) < 0 ) )
|
||||
YYABORT;
|
||||
|
@ -1979,7 +1998,7 @@ yyreduce:
|
|||
case 40:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 394 "sql.y"
|
||||
#line 413 "sql.y"
|
||||
{
|
||||
UINT r;
|
||||
|
||||
|
@ -1997,7 +2016,7 @@ yyreduce:
|
|||
case 42:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 411 "sql.y"
|
||||
#line 430 "sql.y"
|
||||
{
|
||||
(yyval.query) = (yyvsp[(2) - (2)].query);
|
||||
;}
|
||||
|
@ -2006,38 +2025,36 @@ yyreduce:
|
|||
case 43:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 415 "sql.y"
|
||||
#line 434 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* distinct = NULL;
|
||||
UINT r;
|
||||
|
||||
(yyval.query) = NULL;
|
||||
r = DISTINCT_CreateView( sql->db, &(yyval.query), (yyvsp[(3) - (3)].query) );
|
||||
r = DISTINCT_CreateView( sql->db, &distinct, (yyvsp[(3) - (3)].query) );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
(yyvsp[(3) - (3)].query)->ops->delete((yyvsp[(3) - (3)].query));
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), distinct );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 44:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 431 "sql.y"
|
||||
#line 449 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* select = NULL;
|
||||
UINT r;
|
||||
|
||||
(yyval.query) = NULL;
|
||||
if( (yyvsp[(1) - (2)].column_list) )
|
||||
{
|
||||
r = SELECT_CreateView( sql->db, &(yyval.query), (yyvsp[(2) - (2)].query), (yyvsp[(1) - (2)].column_list) );
|
||||
r = SELECT_CreateView( sql->db, &select, (yyvsp[(2) - (2)].query), (yyvsp[(1) - (2)].column_list) );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
(yyvsp[(2) - (2)].query)->ops->delete((yyvsp[(2) - (2)].query));
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), select );
|
||||
}
|
||||
else
|
||||
(yyval.query) = (yyvsp[(2) - (2)].query);
|
||||
|
@ -2047,7 +2064,7 @@ yyreduce:
|
|||
case 46:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 453 "sql.y"
|
||||
#line 470 "sql.y"
|
||||
{
|
||||
(yyvsp[(1) - (3)].column_list)->next = (yyvsp[(3) - (3)].column_list);
|
||||
;}
|
||||
|
@ -2056,7 +2073,7 @@ yyreduce:
|
|||
case 47:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 457 "sql.y"
|
||||
#line 474 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = NULL;
|
||||
;}
|
||||
|
@ -2065,54 +2082,58 @@ yyreduce:
|
|||
case 49:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 465 "sql.y"
|
||||
#line 482 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* where = NULL;
|
||||
UINT r;
|
||||
|
||||
(yyval.query) = NULL;
|
||||
r = WHERE_CreateView( sql->db, &(yyval.query), (yyvsp[(1) - (3)].query), (yyvsp[(3) - (3)].expr) );
|
||||
r = WHERE_CreateView( sql->db, &where, (yyvsp[(1) - (3)].query), (yyvsp[(3) - (3)].expr) );
|
||||
if( r != ERROR_SUCCESS )
|
||||
{
|
||||
(yyvsp[(1) - (3)].query)->ops->delete( (yyvsp[(1) - (3)].query) );
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), where );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 50:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 481 "sql.y"
|
||||
#line 497 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* table = NULL;
|
||||
UINT r;
|
||||
|
||||
(yyval.query) = NULL;
|
||||
r = TABLE_CreateView( sql->db, (yyvsp[(2) - (2)].string), &(yyval.query) );
|
||||
r = TABLE_CreateView( sql->db, (yyvsp[(2) - (2)].string), &table );
|
||||
if( r != ERROR_SUCCESS || !(yyval.query) )
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), table );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 51:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 491 "sql.y"
|
||||
#line 509 "sql.y"
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* join = NULL;
|
||||
UINT r;
|
||||
|
||||
r = JOIN_CreateView( sql->db, &(yyval.query), (yyvsp[(2) - (2)].string) );
|
||||
r = JOIN_CreateView( sql->db, &join, (yyvsp[(2) - (2)].string) );
|
||||
if( r != ERROR_SUCCESS )
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), join );
|
||||
;}
|
||||
break;
|
||||
|
||||
case 52:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 503 "sql.y"
|
||||
#line 524 "sql.y"
|
||||
{
|
||||
(yyval.string) = (yyvsp[(1) - (1)].string);
|
||||
;}
|
||||
|
@ -2121,7 +2142,7 @@ yyreduce:
|
|||
case 53:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 508 "sql.y"
|
||||
#line 529 "sql.y"
|
||||
{
|
||||
(yyval.string) = parser_add_table( info, (yyvsp[(3) - (3)].string), (yyvsp[(1) - (3)].string) );
|
||||
if (!(yyval.string))
|
||||
|
@ -2132,7 +2153,7 @@ yyreduce:
|
|||
case 54:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 517 "sql.y"
|
||||
#line 538 "sql.y"
|
||||
{
|
||||
(yyval.expr) = (yyvsp[(2) - (3)].expr);
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2143,7 +2164,7 @@ yyreduce:
|
|||
case 55:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 523 "sql.y"
|
||||
#line 544 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_AND, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2154,7 +2175,7 @@ yyreduce:
|
|||
case 56:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 529 "sql.y"
|
||||
#line 550 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_OR, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2165,7 +2186,7 @@ yyreduce:
|
|||
case 57:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 535 "sql.y"
|
||||
#line 556 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2176,7 +2197,7 @@ yyreduce:
|
|||
case 58:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 541 "sql.y"
|
||||
#line 562 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2187,7 +2208,7 @@ yyreduce:
|
|||
case 59:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 547 "sql.y"
|
||||
#line 568 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2198,7 +2219,7 @@ yyreduce:
|
|||
case 60:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 553 "sql.y"
|
||||
#line 574 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2209,7 +2230,7 @@ yyreduce:
|
|||
case 61:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 559 "sql.y"
|
||||
#line 580 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2220,7 +2241,7 @@ yyreduce:
|
|||
case 62:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 565 "sql.y"
|
||||
#line 586 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2231,7 +2252,7 @@ yyreduce:
|
|||
case 63:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 571 "sql.y"
|
||||
#line 592 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_unary( info, (yyvsp[(1) - (3)].expr), OP_ISNULL );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2242,7 +2263,7 @@ yyreduce:
|
|||
case 64:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 577 "sql.y"
|
||||
#line 598 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_unary( info, (yyvsp[(1) - (4)].expr), OP_NOTNULL );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2253,7 +2274,7 @@ yyreduce:
|
|||
case 67:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 591 "sql.y"
|
||||
#line 612 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = parser_alloc_column( info, NULL, NULL );
|
||||
if( !(yyval.column_list) )
|
||||
|
@ -2265,7 +2286,7 @@ yyreduce:
|
|||
case 68:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 598 "sql.y"
|
||||
#line 619 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = parser_alloc_column( info, NULL, NULL );
|
||||
if( !(yyval.column_list) )
|
||||
|
@ -2278,7 +2299,7 @@ yyreduce:
|
|||
case 70:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 610 "sql.y"
|
||||
#line 631 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = (yyvsp[(1) - (3)].column_list);
|
||||
(yyval.column_list)->next = (yyvsp[(3) - (3)].column_list);
|
||||
|
@ -2288,7 +2309,7 @@ yyreduce:
|
|||
case 71:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 618 "sql.y"
|
||||
#line 639 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = (yyvsp[(1) - (3)].column_list);
|
||||
(yyval.column_list)->val = (yyvsp[(3) - (3)].expr);
|
||||
|
@ -2298,7 +2319,7 @@ yyreduce:
|
|||
case 72:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 626 "sql.y"
|
||||
#line 647 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_ival( info, (yyvsp[(1) - (1)].integer) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2309,7 +2330,7 @@ yyreduce:
|
|||
case 73:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 632 "sql.y"
|
||||
#line 653 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_ival( info, -(yyvsp[(2) - (2)].integer) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2320,7 +2341,7 @@ yyreduce:
|
|||
case 74:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 638 "sql.y"
|
||||
#line 659 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_sval( info, &(yyvsp[(1) - (1)].str) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2331,7 +2352,7 @@ yyreduce:
|
|||
case 75:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 644 "sql.y"
|
||||
#line 665 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_wildcard( info );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2342,7 +2363,7 @@ yyreduce:
|
|||
case 76:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 653 "sql.y"
|
||||
#line 674 "sql.y"
|
||||
{
|
||||
(yyval.expr) = EXPR_column( info, (yyvsp[(1) - (1)].column_list) );
|
||||
if( !(yyval.expr) )
|
||||
|
@ -2353,7 +2374,7 @@ yyreduce:
|
|||
case 77:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 662 "sql.y"
|
||||
#line 683 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = parser_alloc_column( info, (yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string) );
|
||||
if( !(yyval.column_list) )
|
||||
|
@ -2364,7 +2385,7 @@ yyreduce:
|
|||
case 78:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 668 "sql.y"
|
||||
#line 689 "sql.y"
|
||||
{
|
||||
(yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[(1) - (1)].string) );
|
||||
if( !(yyval.column_list) )
|
||||
|
@ -2375,7 +2396,7 @@ yyreduce:
|
|||
case 79:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 677 "sql.y"
|
||||
#line 698 "sql.y"
|
||||
{
|
||||
(yyval.string) = (yyvsp[(1) - (1)].string);
|
||||
;}
|
||||
|
@ -2384,7 +2405,7 @@ yyreduce:
|
|||
case 80:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 684 "sql.y"
|
||||
#line 705 "sql.y"
|
||||
{
|
||||
if ( SQL_getstring( info, &(yyvsp[(1) - (1)].str), &(yyval.string) ) != ERROR_SUCCESS || !(yyval.string) )
|
||||
YYABORT;
|
||||
|
@ -2394,7 +2415,7 @@ yyreduce:
|
|||
case 81:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 692 "sql.y"
|
||||
#line 713 "sql.y"
|
||||
{
|
||||
(yyval.integer) = SQL_getint( info );
|
||||
;}
|
||||
|
@ -2403,7 +2424,7 @@ yyreduce:
|
|||
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 2407 "sql.tab.c"
|
||||
#line 2428 "sql.tab.c"
|
||||
default: break;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
|
||||
|
@ -2615,7 +2636,7 @@ yyreturn:
|
|||
|
||||
|
||||
/* Line 1675 of yacc.c */
|
||||
#line 697 "sql.y"
|
||||
#line 718 "sql.y"
|
||||
|
||||
|
||||
static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table )
|
||||
|
|
|
@ -110,7 +110,7 @@ typedef union YYSTYPE
|
|||
{
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 76 "sql.y"
|
||||
#line 83 "sql.y"
|
||||
|
||||
struct sql_str str;
|
||||
LPWSTR string;
|
||||
|
|
|
@ -47,7 +47,10 @@ typedef struct tag_SQL_input
|
|||
LPCWSTR command;
|
||||
DWORD n, len;
|
||||
UINT r;
|
||||
MSIVIEW **view; /* view structure for the resulting query */
|
||||
MSIVIEW **view; /* View structure for the resulting query. This value
|
||||
* tracks the view currently being created so we can free
|
||||
* this view on syntax error.
|
||||
*/
|
||||
struct list *mem;
|
||||
} SQL_input;
|
||||
|
||||
|
@ -68,6 +71,10 @@ static struct expr * EXPR_ival( void *info, int val );
|
|||
static struct expr * EXPR_sval( void *info, const struct sql_str *str );
|
||||
static struct expr * EXPR_wildcard( void *info );
|
||||
|
||||
#define PARSER_BUBBLE_UP_VIEW( sql, result, current_view ) \
|
||||
*sql->view = current_view; \
|
||||
result = current_view
|
||||
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
|
@ -149,7 +156,8 @@ oneinsert:
|
|||
INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE );
|
||||
if( !insert )
|
||||
YYABORT;
|
||||
$$ = insert;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, insert );
|
||||
}
|
||||
| TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMPORARY
|
||||
{
|
||||
|
@ -159,7 +167,8 @@ oneinsert:
|
|||
INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE );
|
||||
if( !insert )
|
||||
YYABORT;
|
||||
$$ = insert;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, insert );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -178,7 +187,8 @@ onecreate:
|
|||
sql->r = r;
|
||||
YYABORT;
|
||||
}
|
||||
$$ = create;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, create );
|
||||
}
|
||||
| TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
|
||||
{
|
||||
|
@ -190,7 +200,8 @@ onecreate:
|
|||
CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
|
||||
if( !create )
|
||||
YYABORT;
|
||||
$$ = create;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, create );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -203,7 +214,8 @@ oneupdate:
|
|||
UPDATE_CreateView( sql->db, &update, $2, $4, $6 );
|
||||
if( !update )
|
||||
YYABORT;
|
||||
$$ = update;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, update );
|
||||
}
|
||||
| TK_UPDATE table TK_SET update_assign_list
|
||||
{
|
||||
|
@ -213,7 +225,8 @@ oneupdate:
|
|||
UPDATE_CreateView( sql->db, &update, $2, $4, NULL );
|
||||
if( !update )
|
||||
YYABORT;
|
||||
$$ = update;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, update );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -226,7 +239,8 @@ onedelete:
|
|||
DELETE_CreateView( sql->db, &delete, $2 );
|
||||
if( !delete )
|
||||
YYABORT;
|
||||
$$ = delete;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, delete );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -239,7 +253,8 @@ onealter:
|
|||
ALTER_CreateView( sql->db, &alter, $3, NULL, $4 );
|
||||
if( !alter )
|
||||
YYABORT;
|
||||
$$ = alter;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, alter );
|
||||
}
|
||||
| TK_ALTER TK_TABLE table TK_ADD column_and_type
|
||||
{
|
||||
|
@ -249,7 +264,8 @@ onealter:
|
|||
ALTER_CreateView( sql->db, &alter, $3, $5, 0 );
|
||||
if (!alter)
|
||||
YYABORT;
|
||||
$$ = alter;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, alter );
|
||||
}
|
||||
| TK_ALTER TK_TABLE table TK_ADD column_and_type TK_HOLD
|
||||
{
|
||||
|
@ -259,7 +275,8 @@ onealter:
|
|||
ALTER_CreateView( sql->db, &alter, $3, $5, 1 );
|
||||
if (!alter)
|
||||
YYABORT;
|
||||
$$ = alter;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, alter );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -278,12 +295,14 @@ onedrop:
|
|||
TK_DROP TK_TABLE table
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* drop = NULL;
|
||||
UINT r;
|
||||
|
||||
$$ = NULL;
|
||||
r = DROP_CreateView( sql->db, &$$, $3 );
|
||||
r = DROP_CreateView( sql->db, &drop, $3 );
|
||||
if( r != ERROR_SUCCESS || !$$ )
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, drop );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -414,15 +433,14 @@ unorderedsel:
|
|||
| TK_SELECT TK_DISTINCT selectfrom
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* distinct = NULL;
|
||||
UINT r;
|
||||
|
||||
$$ = NULL;
|
||||
r = DISTINCT_CreateView( sql->db, &$$, $3 );
|
||||
r = DISTINCT_CreateView( sql->db, &distinct, $3 );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
$3->ops->delete($3);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, distinct );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -430,17 +448,16 @@ selectfrom:
|
|||
selcollist from
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* select = NULL;
|
||||
UINT r;
|
||||
|
||||
$$ = NULL;
|
||||
if( $1 )
|
||||
{
|
||||
r = SELECT_CreateView( sql->db, &$$, $2, $1 );
|
||||
r = SELECT_CreateView( sql->db, &select, $2, $1 );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
$2->ops->delete($2);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, select );
|
||||
}
|
||||
else
|
||||
$$ = $2;
|
||||
|
@ -464,15 +481,14 @@ from:
|
|||
| fromtable TK_WHERE expr
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* where = NULL;
|
||||
UINT r;
|
||||
|
||||
$$ = NULL;
|
||||
r = WHERE_CreateView( sql->db, &$$, $1, $3 );
|
||||
r = WHERE_CreateView( sql->db, &where, $1, $3 );
|
||||
if( r != ERROR_SUCCESS )
|
||||
{
|
||||
$1->ops->delete( $1 );
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, where );
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -480,21 +496,26 @@ fromtable:
|
|||
TK_FROM table
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* table = NULL;
|
||||
UINT r;
|
||||
|
||||
$$ = NULL;
|
||||
r = TABLE_CreateView( sql->db, $2, &$$ );
|
||||
r = TABLE_CreateView( sql->db, $2, &table );
|
||||
if( r != ERROR_SUCCESS || !$$ )
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, table );
|
||||
}
|
||||
| TK_FROM tablelist
|
||||
{
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
MSIVIEW* join = NULL;
|
||||
UINT r;
|
||||
|
||||
r = JOIN_CreateView( sql->db, &$$, $2 );
|
||||
r = JOIN_CreateView( sql->db, &join, $2 );
|
||||
if( r != ERROR_SUCCESS )
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( sql, $$, join );
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -437,11 +437,13 @@ static UINT STORAGES_delete(struct tagMSIVIEW *view)
|
|||
if (sv->storages[i]->storage)
|
||||
IStorage_Release(sv->storages[i]->storage);
|
||||
|
||||
msi_free(sv->storages[i]->name);
|
||||
msi_free(sv->storages[i]);
|
||||
}
|
||||
|
||||
msi_free(sv->storages);
|
||||
sv->storages = NULL;
|
||||
msi_free(sv);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -400,12 +400,18 @@ static UINT STREAMS_delete(struct tagMSIVIEW *view)
|
|||
|
||||
for (i = 0; i < sv->num_rows; i++)
|
||||
{
|
||||
if (sv->streams[i] && sv->streams[i]->stream)
|
||||
IStream_Release(sv->streams[i]->stream);
|
||||
msi_free(sv->streams[i]);
|
||||
if (sv->streams[i])
|
||||
{
|
||||
if (sv->streams[i]->stream)
|
||||
IStream_Release(sv->streams[i]->stream);
|
||||
|
||||
msi_free(sv->streams[i]->name);
|
||||
msi_free(sv->streams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
msi_free(sv->streams);
|
||||
msi_free(sv);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -40,12 +40,10 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msidb);
|
||||
|
||||
#define HASH_SIZE 0x101
|
||||
#define LONG_STR_BYTES 3
|
||||
|
||||
typedef struct _msistring
|
||||
{
|
||||
int hash_next;
|
||||
UINT persistent_refcount;
|
||||
UINT nonpersistent_refcount;
|
||||
LPWSTR str;
|
||||
|
@ -56,30 +54,14 @@ struct string_table
|
|||
UINT maxcount; /* the number of strings */
|
||||
UINT freeslot;
|
||||
UINT codepage;
|
||||
int hash[HASH_SIZE];
|
||||
msistring *strings; /* an array of strings (in the tree) */
|
||||
UINT sortcount;
|
||||
msistring *strings; /* an array of strings */
|
||||
UINT *sorted; /* index */
|
||||
};
|
||||
|
||||
static UINT msistring_makehash( const WCHAR *str )
|
||||
{
|
||||
UINT hash = 0;
|
||||
|
||||
if (str==NULL)
|
||||
return hash;
|
||||
|
||||
while( *str )
|
||||
{
|
||||
hash ^= *str++;
|
||||
hash *= 53;
|
||||
hash = (hash<<5) | (hash>>27);
|
||||
}
|
||||
return hash % HASH_SIZE;
|
||||
}
|
||||
|
||||
static string_table *init_stringtable( int entries, UINT codepage )
|
||||
{
|
||||
string_table *st;
|
||||
int i;
|
||||
|
||||
if (codepage != CP_ACP && !IsValidCodePage(codepage))
|
||||
{
|
||||
|
@ -92,18 +74,26 @@ static string_table *init_stringtable( int entries, UINT codepage )
|
|||
return NULL;
|
||||
if( entries < 1 )
|
||||
entries = 1;
|
||||
|
||||
st->strings = msi_alloc_zero( sizeof (msistring) * entries );
|
||||
if( !st->strings )
|
||||
{
|
||||
msi_free( st );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
st->sorted = msi_alloc( sizeof (UINT) * entries );
|
||||
if( !st->sorted )
|
||||
{
|
||||
msi_free( st->strings );
|
||||
msi_free( st );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
st->maxcount = entries;
|
||||
st->freeslot = 1;
|
||||
st->codepage = codepage;
|
||||
|
||||
for( i=0; i<HASH_SIZE; i++ )
|
||||
st->hash[i] = -1;
|
||||
st->sortcount = 0;
|
||||
|
||||
return st;
|
||||
}
|
||||
|
@ -119,12 +109,13 @@ VOID msi_destroy_stringtable( string_table *st )
|
|||
msi_free( st->strings[i].str );
|
||||
}
|
||||
msi_free( st->strings );
|
||||
msi_free( st->sorted );
|
||||
msi_free( st );
|
||||
}
|
||||
|
||||
static int st_find_free_entry( string_table *st )
|
||||
{
|
||||
UINT i, sz;
|
||||
UINT i, sz, *s;
|
||||
msistring *p;
|
||||
|
||||
TRACE("%p\n", st);
|
||||
|
@ -146,7 +137,17 @@ static int st_find_free_entry( string_table *st )
|
|||
p = msi_realloc_zero( st->strings, sz*sizeof(msistring) );
|
||||
if( !p )
|
||||
return -1;
|
||||
|
||||
s = msi_realloc( st->sorted, sz*sizeof(UINT) );
|
||||
if( !s )
|
||||
{
|
||||
msi_free( p );
|
||||
return -1;
|
||||
}
|
||||
|
||||
st->strings = p;
|
||||
st->sorted = s;
|
||||
|
||||
st->freeslot = st->maxcount;
|
||||
st->maxcount = sz;
|
||||
if( st->strings[st->freeslot].persistent_refcount ||
|
||||
|
@ -155,10 +156,40 @@ static int st_find_free_entry( string_table *st )
|
|||
return st->freeslot;
|
||||
}
|
||||
|
||||
static int find_insert_index( const string_table *st, UINT string_id )
|
||||
{
|
||||
int i, c, low = 0, high = st->sortcount - 1;
|
||||
|
||||
while (low <= high)
|
||||
{
|
||||
i = (low + high) / 2;
|
||||
c = lstrcmpW( st->strings[string_id].str, st->strings[st->sorted[i]].str );
|
||||
|
||||
if (c < 0)
|
||||
high = i - 1;
|
||||
else if (c > 0)
|
||||
low = i + 1;
|
||||
else
|
||||
return -1; /* already exists */
|
||||
}
|
||||
return high + 1;
|
||||
}
|
||||
|
||||
static void insert_string_sorted( string_table *st, UINT string_id )
|
||||
{
|
||||
int i;
|
||||
|
||||
i = find_insert_index( st, string_id );
|
||||
if (i == -1)
|
||||
return;
|
||||
|
||||
memmove( &st->sorted[i] + 1, &st->sorted[i], (st->sortcount - i) * sizeof(UINT) );
|
||||
st->sorted[i] = string_id;
|
||||
st->sortcount++;
|
||||
}
|
||||
|
||||
static void set_st_entry( string_table *st, UINT n, LPWSTR str, UINT refcount, enum StringPersistence persistence )
|
||||
{
|
||||
UINT hash = msistring_makehash( str );
|
||||
|
||||
if (persistence == StringPersistent)
|
||||
{
|
||||
st->strings[n].persistent_refcount = refcount;
|
||||
|
@ -172,8 +203,7 @@ static void set_st_entry( string_table *st, UINT n, LPWSTR str, UINT refcount, e
|
|||
|
||||
st->strings[n].str = str;
|
||||
|
||||
st->strings[n].hash_next = st->hash[hash];
|
||||
st->hash[hash] = n;
|
||||
insert_string_sorted( st, n );
|
||||
|
||||
if( n < st->maxcount )
|
||||
st->freeslot = n + 1;
|
||||
|
@ -382,14 +412,20 @@ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT
|
|||
*/
|
||||
UINT msi_string2idW( const string_table *st, LPCWSTR str, UINT *id )
|
||||
{
|
||||
UINT n, hash = msistring_makehash( str );
|
||||
msistring *se = st->strings;
|
||||
int i, c, low = 0, high = st->sortcount - 1;
|
||||
|
||||
for (n = st->hash[hash]; n != -1; n = st->strings[n].hash_next )
|
||||
while (low <= high)
|
||||
{
|
||||
if ((str == se[n].str) || !lstrcmpW(str, se[n].str))
|
||||
i = (low + high) / 2;
|
||||
c = lstrcmpW( str, st->strings[st->sorted[i]].str );
|
||||
|
||||
if (c < 0)
|
||||
high = i - 1;
|
||||
else if (c > 0)
|
||||
low = i + 1;
|
||||
else
|
||||
{
|
||||
*id = n;
|
||||
*id = st->sorted[i];
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,11 +83,6 @@ struct tagMSITABLE
|
|||
WCHAR name[1];
|
||||
};
|
||||
|
||||
typedef struct tagMSITRANSFORM {
|
||||
struct list entry;
|
||||
IStorage *stg;
|
||||
} MSITRANSFORM;
|
||||
|
||||
static const WCHAR szStringData[] = {
|
||||
'_','S','t','r','i','n','g','D','a','t','a',0 };
|
||||
static const WCHAR szStringPool[] = {
|
||||
|
@ -154,7 +149,7 @@ static int utf2mime(int x)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
|
||||
LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
|
||||
{
|
||||
DWORD count = MAX_STREAM_NAME;
|
||||
DWORD ch, next;
|
||||
|
@ -332,89 +327,6 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
||||
{
|
||||
LPWSTR encname;
|
||||
HRESULT r;
|
||||
|
||||
encname = encode_streamname(FALSE, stname);
|
||||
|
||||
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
|
||||
|
||||
r = IStorage_OpenStream(db->storage, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm);
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
MSITRANSFORM *transform;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
|
||||
{
|
||||
TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
|
||||
r = IStorage_OpenStream( transform->stg, encname, NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
if (SUCCEEDED(r))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msi_free( encname );
|
||||
|
||||
return SUCCEEDED(r) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
|
||||
USHORT **pdata, UINT *psz )
|
||||
{
|
||||
HRESULT r;
|
||||
UINT ret = ERROR_FUNCTION_FAILED;
|
||||
VOID *data;
|
||||
ULONG sz, count;
|
||||
IStream *stm = NULL;
|
||||
STATSTG stat;
|
||||
|
||||
r = db_get_raw_stream( db, stname, &stm );
|
||||
if( r != ERROR_SUCCESS)
|
||||
return ret;
|
||||
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
|
||||
if( FAILED( r ) )
|
||||
{
|
||||
WARN("open stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if( stat.cbSize.QuadPart >> 32 )
|
||||
{
|
||||
WARN("Too big!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
sz = stat.cbSize.QuadPart;
|
||||
data = msi_alloc( sz );
|
||||
if( !data )
|
||||
{
|
||||
WARN("couldn't allocate memory r=%08x!\n", r);
|
||||
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
r = IStream_Read(stm, data, sz, &count );
|
||||
if( FAILED( r ) || ( count != sz ) )
|
||||
{
|
||||
msi_free( data );
|
||||
WARN("read stream failed r = %08x!\n", r);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*pdata = data;
|
||||
*psz = sz;
|
||||
ret = ERROR_SUCCESS;
|
||||
|
||||
end:
|
||||
IStream_Release( stm );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT write_stream_data( IStorage *stg, LPCWSTR stname,
|
||||
LPCVOID data, UINT sz, BOOL bTable )
|
||||
{
|
||||
|
@ -1042,17 +954,22 @@ static UINT get_tablecolumns( MSIDATABASE *db,
|
|||
static void msi_update_table_columns( MSIDATABASE *db, LPCWSTR name )
|
||||
{
|
||||
MSITABLE *table;
|
||||
LPWSTR tablename;
|
||||
UINT size, offset, old_count;
|
||||
UINT n;
|
||||
|
||||
table = find_cached_table( db, name );
|
||||
/* We may free name in msi_free_colinfo. */
|
||||
tablename = strdupW( name );
|
||||
|
||||
table = find_cached_table( db, tablename );
|
||||
old_count = table->col_count;
|
||||
msi_free_colinfo( table->colinfo, table->col_count );
|
||||
msi_free( table->colinfo );
|
||||
table->colinfo = NULL;
|
||||
|
||||
table_get_column_info( db, name, &table->colinfo, &table->col_count );
|
||||
table_get_column_info( db, tablename, &table->colinfo, &table->col_count );
|
||||
if (!table->col_count)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
size = msi_table_get_row_size( db, table->colinfo, table->col_count );
|
||||
offset = table->colinfo[table->col_count - 1].offset;
|
||||
|
@ -1063,6 +980,9 @@ static void msi_update_table_columns( MSIDATABASE *db, LPCWSTR name )
|
|||
if (old_count < table->col_count)
|
||||
memset( &table->data[n][offset], 0, size - offset );
|
||||
}
|
||||
|
||||
done:
|
||||
msi_free(tablename);
|
||||
}
|
||||
|
||||
/* try to find the table name in the _Tables table */
|
||||
|
@ -1754,15 +1674,14 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row )
|
|||
tv->columns[i].hash_table = NULL;
|
||||
}
|
||||
|
||||
if ( row == num_rows - 1 )
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
for (i = row + 1; i < num_rows; i++)
|
||||
{
|
||||
memcpy(tv->table->data[i - 1], tv->table->data[i], tv->row_size);
|
||||
tv->table->data_persistent[i - 1] = tv->table->data_persistent[i];
|
||||
}
|
||||
|
||||
msi_free(tv->table->data[num_rows - 1]);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1828,6 +1747,9 @@ static UINT msi_refresh_record( struct tagMSIVIEW *view, MSIRECORD *rec, UINT ro
|
|||
if (r != ERROR_SUCCESS)
|
||||
return r;
|
||||
|
||||
/* Close the original record */
|
||||
MSI_CloseRecord(&rec->hdr);
|
||||
|
||||
count = MSI_RecordGetFieldCount(rec);
|
||||
for (i = 0; i < count; i++)
|
||||
MSI_RecordCopyField(curr, i + 1, rec, i + 1);
|
||||
|
@ -2316,7 +2238,6 @@ static UINT TABLE_drop(struct tagMSIVIEW *view)
|
|||
|
||||
list_remove(&tv->table->entry);
|
||||
free_table(tv->table);
|
||||
TABLE_delete(view);
|
||||
|
||||
done:
|
||||
msiobj_release(&rec->hdr);
|
||||
|
@ -3010,25 +2931,3 @@ end:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
|
||||
{
|
||||
MSITRANSFORM *t;
|
||||
|
||||
t = msi_alloc( sizeof *t );
|
||||
t->stg = stg;
|
||||
IStorage_AddRef( stg );
|
||||
list_add_tail( &db->transforms, &t->entry );
|
||||
}
|
||||
|
||||
void msi_free_transforms( MSIDATABASE *db )
|
||||
{
|
||||
while( !list_empty( &db->transforms ) )
|
||||
{
|
||||
MSITRANSFORM *t = LIST_ENTRY( list_head( &db->transforms ),
|
||||
MSITRANSFORM, entry );
|
||||
list_remove( &t->entry );
|
||||
IStorage_Release( t->stg );
|
||||
msi_free( t );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -309,9 +309,7 @@ static UINT STRCMP_Evaluate( MSIWHEREVIEW *wv, UINT row, const struct expr *cond
|
|||
sr = lstrcmpW( l_str, r_str );
|
||||
|
||||
*val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) ||
|
||||
( cond->u.expr.op == OP_NE && ( sr != 0 ) ) ||
|
||||
( cond->u.expr.op == OP_LT && ( sr < 0 ) ) ||
|
||||
( cond->u.expr.op == OP_GT && ( sr > 0 ) );
|
||||
( cond->u.expr.op == OP_NE && ( sr != 0 ) );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -644,8 +642,6 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
|
|||
switch( cond->u.expr.op )
|
||||
{
|
||||
case OP_EQ:
|
||||
case OP_GT:
|
||||
case OP_LT:
|
||||
case OP_NE:
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue