diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-10 14:35:15 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-10 14:35:15 +0100 |
commit | ada3b04b2246c13449e6b32b3857d7b86a8958f8 (patch) | |
tree | 2f49c248b3fa97fe30b11fd38f68d66407a0e2e8 /libmsi | |
parent | 7c218b82e38738f17fef56b660f256fa6e9ede1f (diff) | |
download | msitools-ada3b04b2246c13449e6b32b3857d7b86a8958f8.tar.gz msitools-ada3b04b2246c13449e6b32b3857d7b86a8958f8.tar.xz msitools-ada3b04b2246c13449e6b32b3857d7b86a8958f8.zip |
move non-query functions to database.c
Diffstat (limited to 'libmsi')
-rw-r--r-- | libmsi/database.c | 311 | ||||
-rw-r--r-- | libmsi/msiquery.c | 311 |
2 files changed, 311 insertions, 311 deletions
diff --git a/libmsi/database.c b/libmsi/database.c index 283350d..b4132d9 100644 --- a/libmsi/database.c +++ b/libmsi/database.c @@ -2294,3 +2294,314 @@ LibmsiDBState libmsi_database_get_state( LibmsiDatabase *db ) return ret; } + +unsigned _libmsi_database_apply_transform( LibmsiDatabase *db, + const char *szTransformFile, int iErrorCond ) +{ + HRESULT r; + unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; + IStorage *stg = NULL; + STATSTG stat; + WCHAR *szwTransformFile = NULL; + + TRACE("%p %s %d\n", db, debugstr_a(szTransformFile), iErrorCond); + szwTransformFile = strdupAtoW(szTransformFile); + if (!szwTransformFile) goto end; + + r = StgOpenStorage( szwTransformFile, NULL, + STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg); + if ( FAILED(r) ) + { + WARN("failed to open transform 0x%08x\n", r); + return ret; + } + + r = IStorage_Stat( stg, &stat, STATFLAG_NONAME ); + if ( FAILED( r ) ) + goto end; + + if ( memcmp( &stat.clsid, &clsid_msi_transform, 16 ) != 0 ) + goto end; + + if( TRACE_ON( msi ) ) + enum_stream_names( stg ); + + ret = msi_table_apply_transform( db, stg ); + +end: + msi_free(szwTransformFile); + IStorage_Release( stg ); + + return ret; +} + +LibmsiResult libmsi_database_apply_transform( LibmsiDatabase *db, + const char *szTransformFile, int iErrorCond) +{ + unsigned r; + + msiobj_addref( &db->hdr ); + if( !db ) + return LIBMSI_RESULT_INVALID_HANDLE; + r = _libmsi_database_apply_transform( db, szTransformFile, iErrorCond ); + msiobj_release( &db->hdr ); + return r; +} + +static unsigned commit_storage( const WCHAR *name, IStorage *stg, void *opaque) +{ + LibmsiDatabase *db = opaque; + STATSTG stat; + IStream *outstg; + ULARGE_INTEGER cbRead, cbWritten; + unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; + HRESULT r; + + TRACE("%s %p %p\n", debugstr_w(name), stg, opaque); + + r = IStorage_CreateStorage( db->outfile, name, + STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &outstg); + if ( FAILED(r) ) + return LIBMSI_RESULT_FUNCTION_FAILED; + + r = IStorage_CopyTo( stg, 0, NULL, NULL, outstg ); + if ( FAILED(r) ) + goto end; + + ret = LIBMSI_RESULT_SUCCESS; + +end: + IStorage_Release(outstg); + return ret; +} + +static unsigned commit_stream( const WCHAR *name, IStream *stm, void *opaque) +{ + LibmsiDatabase *db = opaque; + STATSTG stat; + IStream *outstm; + ULARGE_INTEGER cbRead, cbWritten; + unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; + HRESULT r; + WCHAR decname[0x40]; + + decode_streamname(name, decname); + TRACE("%s(%s) %p %p\n", debugstr_w(name), debugstr_w(decname), stm, opaque); + + IStream_Stat(stm, &stat, STATFLAG_NONAME); + r = IStorage_CreateStream( db->outfile, name, + STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &outstm); + if ( FAILED(r) ) + return LIBMSI_RESULT_FUNCTION_FAILED; + + IStream_SetSize( outstm, stat.cbSize ); + + r = IStream_CopyTo( stm, outstm, stat.cbSize, &cbRead, &cbWritten ); + if ( FAILED(r) ) + goto end; + + if (cbRead.QuadPart != stat.cbSize.QuadPart) + goto end; + if (cbWritten.QuadPart != stat.cbSize.QuadPart) + goto end; + + ret = LIBMSI_RESULT_SUCCESS; + +end: + IStream_Release(outstm); + return ret; +} + +LibmsiResult libmsi_database_commit( LibmsiDatabase *db ) +{ + unsigned r = LIBMSI_RESULT_SUCCESS; + unsigned bytes_per_strref; + HRESULT hr; + + TRACE("%d\n", db); + + if( !db ) + return LIBMSI_RESULT_INVALID_HANDLE; + + msiobj_addref( &db->hdr ); + if (db->mode == LIBMSI_DB_OPEN_READONLY) + goto end; + + /* FIXME: lock the database */ + + r = msi_save_string_table( db->strings, db, &bytes_per_strref ); + if( r != LIBMSI_RESULT_SUCCESS ) + { + WARN("failed to save string table r=%08x\n",r); + goto end; + } + + r = msi_enum_db_storages( db, commit_storage, db ); + if (r != LIBMSI_RESULT_SUCCESS) + { + WARN("failed to save storages r=%08x\n",r); + goto end; + } + + r = msi_enum_db_streams( db, commit_stream, db ); + if (r != LIBMSI_RESULT_SUCCESS) + { + WARN("failed to save streams r=%08x\n",r); + goto end; + } + + r = _libmsi_database_commit_tables( db, bytes_per_strref ); + if (r != LIBMSI_RESULT_SUCCESS) + { + WARN("failed to save tables r=%08x\n",r); + goto end; + } + + db->bytes_per_strref = bytes_per_strref; + + /* FIXME: unlock the database */ + + hr = IStorage_Commit( db->outfile, 0 ); + if (FAILED( hr )) + { + WARN("failed to commit changes 0x%08x\n", hr); + r = LIBMSI_RESULT_FUNCTION_FAILED; + goto end; + } + + _libmsi_database_close(db, true); + _libmsi_database_open(db); + _libmsi_database_start_transaction(db, LIBMSI_DB_OPEN_TRANSACT); + +end: + msiobj_release( &db->hdr ); + + return r; +} + +struct msi_primary_key_record_info +{ + unsigned n; + LibmsiRecord *rec; +}; + +static unsigned msi_primary_key_iterator( LibmsiRecord *rec, void *param ) +{ + struct msi_primary_key_record_info *info = param; + const WCHAR *name; + const WCHAR *table; + unsigned type; + + type = libmsi_record_get_integer( rec, 4 ); + if( type & MSITYPE_KEY ) + { + info->n++; + if( info->rec ) + { + if ( info->n == 1 ) + { + table = _libmsi_record_get_string_raw( rec, 1 ); + _libmsi_record_set_stringW( info->rec, 0, table); + } + + name = _libmsi_record_get_string_raw( rec, 3 ); + _libmsi_record_set_stringW( info->rec, info->n, name ); + } + } + + return LIBMSI_RESULT_SUCCESS; +} + +unsigned _libmsi_database_get_primary_keys( LibmsiDatabase *db, + const WCHAR *table, LibmsiRecord **prec ) +{ + static const WCHAR sql[] = { + 's','e','l','e','c','t',' ','*',' ', + 'f','r','o','m',' ','`','_','C','o','l','u','m','n','s','`',' ', + 'w','h','e','r','e',' ', + '`','T','a','b','l','e','`',' ','=',' ','\'','%','s','\'',0 }; + struct msi_primary_key_record_info info; + LibmsiQuery *query = NULL; + unsigned r; + + if (!table_view_exists( db, table )) + return LIBMSI_RESULT_INVALID_TABLE; + + r = _libmsi_query_open( db, &query, sql, table ); + if( r != LIBMSI_RESULT_SUCCESS ) + return r; + + /* count the number of primary key records */ + info.n = 0; + info.rec = 0; + r = _libmsi_query_iterate_records( query, 0, msi_primary_key_iterator, &info ); + if( r == LIBMSI_RESULT_SUCCESS ) + { + TRACE("Found %d primary keys\n", info.n ); + + /* allocate a record and fill in the names of the tables */ + info.rec = libmsi_record_create( info.n ); + info.n = 0; + r = _libmsi_query_iterate_records( query, 0, msi_primary_key_iterator, &info ); + if( r == LIBMSI_RESULT_SUCCESS ) + *prec = info.rec; + else + msiobj_release( &info.rec->hdr ); + } + msiobj_release( &query->hdr ); + + return r; +} + +LibmsiResult libmsi_database_get_primary_keys(LibmsiDatabase *db, + const char *table, LibmsiRecord **prec) +{ + WCHAR *szwTable = NULL; + unsigned r; + + TRACE("%d %s %p\n", db, debugstr_a(table), prec); + + if( table ) + { + szwTable = strdupAtoW( table ); + if( !szwTable ) + return LIBMSI_RESULT_OUTOFMEMORY; + } + + if( !db ) + return LIBMSI_RESULT_INVALID_HANDLE; + + msiobj_addref( &db->hdr ); + r = _libmsi_database_get_primary_keys( db, szwTable, prec ); + msiobj_release( &db->hdr ); + msi_free( szwTable ); + + return r; +} + +LibmsiCondition libmsi_database_is_table_persistent( + LibmsiDatabase *db, const char *szTableName) +{ + WCHAR *szwTableName = NULL; + LibmsiCondition r; + + TRACE("%x %s\n", db, debugstr_a(szTableName)); + + if( szTableName ) + { + szwTableName = strdupAtoW( szTableName ); + if( !szwTableName ) + return LIBMSI_CONDITION_ERROR; + } + + msiobj_addref( &db->hdr ); + if( !db ) + return LIBMSI_CONDITION_ERROR; + + r = _libmsi_database_is_table_persistent( db, szwTableName ); + + msiobj_release( &db->hdr ); + msi_free( szwTableName ); + + return r; +} diff --git a/libmsi/msiquery.c b/libmsi/msiquery.c index 7976ade..d020e16 100644 --- a/libmsi/msiquery.c +++ b/libmsi/msiquery.c @@ -540,314 +540,3 @@ LibmsiDBError libmsi_query_get_error( LibmsiQuery *query, char *buffer, unsigned msiobj_release( &query->hdr ); return r; } - -unsigned _libmsi_database_apply_transform( LibmsiDatabase *db, - const char *szTransformFile, int iErrorCond ) -{ - HRESULT r; - unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; - IStorage *stg = NULL; - STATSTG stat; - WCHAR *szwTransformFile = NULL; - - TRACE("%p %s %d\n", db, debugstr_a(szTransformFile), iErrorCond); - szwTransformFile = strdupAtoW(szTransformFile); - if (!szwTransformFile) goto end; - - r = StgOpenStorage( szwTransformFile, NULL, - STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg); - if ( FAILED(r) ) - { - WARN("failed to open transform 0x%08x\n", r); - return ret; - } - - r = IStorage_Stat( stg, &stat, STATFLAG_NONAME ); - if ( FAILED( r ) ) - goto end; - - if ( memcmp( &stat.clsid, &clsid_msi_transform, 16 ) != 0 ) - goto end; - - if( TRACE_ON( msi ) ) - enum_stream_names( stg ); - - ret = msi_table_apply_transform( db, stg ); - -end: - msi_free(szwTransformFile); - IStorage_Release( stg ); - - return ret; -} - -LibmsiResult libmsi_database_apply_transform( LibmsiDatabase *db, - const char *szTransformFile, int iErrorCond) -{ - unsigned r; - - msiobj_addref( &db->hdr ); - if( !db ) - return LIBMSI_RESULT_INVALID_HANDLE; - r = _libmsi_database_apply_transform( db, szTransformFile, iErrorCond ); - msiobj_release( &db->hdr ); - return r; -} - -static unsigned commit_storage( const WCHAR *name, IStorage *stg, void *opaque) -{ - LibmsiDatabase *db = opaque; - STATSTG stat; - IStream *outstg; - ULARGE_INTEGER cbRead, cbWritten; - unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; - HRESULT r; - - TRACE("%s %p %p\n", debugstr_w(name), stg, opaque); - - r = IStorage_CreateStorage( db->outfile, name, - STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &outstg); - if ( FAILED(r) ) - return LIBMSI_RESULT_FUNCTION_FAILED; - - r = IStorage_CopyTo( stg, 0, NULL, NULL, outstg ); - if ( FAILED(r) ) - goto end; - - ret = LIBMSI_RESULT_SUCCESS; - -end: - IStorage_Release(outstg); - return ret; -} - -static unsigned commit_stream( const WCHAR *name, IStream *stm, void *opaque) -{ - LibmsiDatabase *db = opaque; - STATSTG stat; - IStream *outstm; - ULARGE_INTEGER cbRead, cbWritten; - unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED; - HRESULT r; - WCHAR decname[0x40]; - - decode_streamname(name, decname); - TRACE("%s(%s) %p %p\n", debugstr_w(name), debugstr_w(decname), stm, opaque); - - IStream_Stat(stm, &stat, STATFLAG_NONAME); - r = IStorage_CreateStream( db->outfile, name, - STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &outstm); - if ( FAILED(r) ) - return LIBMSI_RESULT_FUNCTION_FAILED; - - IStream_SetSize( outstm, stat.cbSize ); - - r = IStream_CopyTo( stm, outstm, stat.cbSize, &cbRead, &cbWritten ); - if ( FAILED(r) ) - goto end; - - if (cbRead.QuadPart != stat.cbSize.QuadPart) - goto end; - if (cbWritten.QuadPart != stat.cbSize.QuadPart) - goto end; - - ret = LIBMSI_RESULT_SUCCESS; - -end: - IStream_Release(outstm); - return ret; -} - -LibmsiResult libmsi_database_commit( LibmsiDatabase *db ) -{ - unsigned r = LIBMSI_RESULT_SUCCESS; - unsigned bytes_per_strref; - HRESULT hr; - - TRACE("%d\n", db); - - if( !db ) - return LIBMSI_RESULT_INVALID_HANDLE; - - msiobj_addref( &db->hdr ); - if (db->mode == LIBMSI_DB_OPEN_READONLY) - goto end; - - /* FIXME: lock the database */ - - r = msi_save_string_table( db->strings, db, &bytes_per_strref ); - if( r != LIBMSI_RESULT_SUCCESS ) - { - WARN("failed to save string table r=%08x\n",r); - goto end; - } - - r = msi_enum_db_storages( db, commit_storage, db ); - if (r != LIBMSI_RESULT_SUCCESS) - { - WARN("failed to save storages r=%08x\n",r); - goto end; - } - - r = msi_enum_db_streams( db, commit_stream, db ); - if (r != LIBMSI_RESULT_SUCCESS) - { - WARN("failed to save streams r=%08x\n",r); - goto end; - } - - r = _libmsi_database_commit_tables( db, bytes_per_strref ); - if (r != LIBMSI_RESULT_SUCCESS) - { - WARN("failed to save tables r=%08x\n",r); - goto end; - } - - db->bytes_per_strref = bytes_per_strref; - - /* FIXME: unlock the database */ - - hr = IStorage_Commit( db->outfile, 0 ); - if (FAILED( hr )) - { - WARN("failed to commit changes 0x%08x\n", hr); - r = LIBMSI_RESULT_FUNCTION_FAILED; - goto end; - } - - _libmsi_database_close(db, true); - _libmsi_database_open(db); - _libmsi_database_start_transaction(db, LIBMSI_DB_OPEN_TRANSACT); - -end: - msiobj_release( &db->hdr ); - - return r; -} - -struct msi_primary_key_record_info -{ - unsigned n; - LibmsiRecord *rec; -}; - -static unsigned msi_primary_key_iterator( LibmsiRecord *rec, void *param ) -{ - struct msi_primary_key_record_info *info = param; - const WCHAR *name; - const WCHAR *table; - unsigned type; - - type = libmsi_record_get_integer( rec, 4 ); - if( type & MSITYPE_KEY ) - { - info->n++; - if( info->rec ) - { - if ( info->n == 1 ) - { - table = _libmsi_record_get_string_raw( rec, 1 ); - _libmsi_record_set_stringW( info->rec, 0, table); - } - - name = _libmsi_record_get_string_raw( rec, 3 ); - _libmsi_record_set_stringW( info->rec, info->n, name ); - } - } - - return LIBMSI_RESULT_SUCCESS; -} - -unsigned _libmsi_database_get_primary_keys( LibmsiDatabase *db, - const WCHAR *table, LibmsiRecord **prec ) -{ - static const WCHAR sql[] = { - 's','e','l','e','c','t',' ','*',' ', - 'f','r','o','m',' ','`','_','C','o','l','u','m','n','s','`',' ', - 'w','h','e','r','e',' ', - '`','T','a','b','l','e','`',' ','=',' ','\'','%','s','\'',0 }; - struct msi_primary_key_record_info info; - LibmsiQuery *query = NULL; - unsigned r; - - if (!table_view_exists( db, table )) - return LIBMSI_RESULT_INVALID_TABLE; - - r = _libmsi_query_open( db, &query, sql, table ); - if( r != LIBMSI_RESULT_SUCCESS ) - return r; - - /* count the number of primary key records */ - info.n = 0; - info.rec = 0; - r = _libmsi_query_iterate_records( query, 0, msi_primary_key_iterator, &info ); - if( r == LIBMSI_RESULT_SUCCESS ) - { - TRACE("Found %d primary keys\n", info.n ); - - /* allocate a record and fill in the names of the tables */ - info.rec = libmsi_record_create( info.n ); - info.n = 0; - r = _libmsi_query_iterate_records( query, 0, msi_primary_key_iterator, &info ); - if( r == LIBMSI_RESULT_SUCCESS ) - *prec = info.rec; - else - msiobj_release( &info.rec->hdr ); - } - msiobj_release( &query->hdr ); - - return r; -} - -LibmsiResult libmsi_database_get_primary_keys(LibmsiDatabase *db, - const char *table, LibmsiRecord **prec) -{ - WCHAR *szwTable = NULL; - unsigned r; - - TRACE("%d %s %p\n", db, debugstr_a(table), prec); - - if( table ) - { - szwTable = strdupAtoW( table ); - if( !szwTable ) - return LIBMSI_RESULT_OUTOFMEMORY; - } - - if( !db ) - return LIBMSI_RESULT_INVALID_HANDLE; - - msiobj_addref( &db->hdr ); - r = _libmsi_database_get_primary_keys( db, szwTable, prec ); - msiobj_release( &db->hdr ); - msi_free( szwTable ); - - return r; -} - -LibmsiCondition libmsi_database_is_table_persistent( - LibmsiDatabase *db, const char *szTableName) -{ - WCHAR *szwTableName = NULL; - LibmsiCondition r; - - TRACE("%x %s\n", db, debugstr_a(szTableName)); - - if( szTableName ) - { - szwTableName = strdupAtoW( szTableName ); - if( !szwTableName ) - return LIBMSI_CONDITION_ERROR; - } - - msiobj_addref( &db->hdr ); - if( !db ) - return LIBMSI_CONDITION_ERROR; - - r = _libmsi_database_is_table_persistent( db, szwTableName ); - - msiobj_release( &db->hdr ); - msi_free( szwTableName ); - - return r; -} |