sync msi with wine 1.1.35

svn path=/trunk/; revision=44693
This commit is contained in:
Christoph von Wittich 2009-12-22 09:28:03 +00:00
parent 917a4bead6
commit 67cca04bc0
23 changed files with 1529 additions and 777 deletions

View file

@ -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))

View file

@ -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)

View file

@ -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

View file

@ -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);
}

View file

@ -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,

View file

@ -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;

View file

@ -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");

View file

@ -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;

View file

@ -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)

View file

@ -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 *);

View file

@ -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);

View file

@ -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

View file

@ -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.

View file

@ -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;

View file

@ -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 )

View file

@ -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;

View file

@ -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 );
}
;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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 );
}
}

View file

@ -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: