diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-11 11:35:57 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-11 11:38:05 +0100 |
commit | cb4d4b7214170989fbce773bcf2dc0ca0581f4af (patch) | |
tree | 43cad405aa6ae7bb8064f1be47cad94dc255ba5c /libmsi/libmsi-database.c | |
parent | 4a33d8ff9f1e0593bd49922cd46aa3e6a7aa1273 (diff) | |
parent | ae4c81e4fca5bb5816b5cbabb17a7dcc22f58a3b (diff) | |
download | msitools-cb4d4b7214170989fbce773bcf2dc0ca0581f4af.tar.gz msitools-cb4d4b7214170989fbce773bcf2dc0ca0581f4af.tar.xz msitools-cb4d4b7214170989fbce773bcf2dc0ca0581f4af.zip |
Merge branch 'pre-gsf'
Conflicts:
libmsi/Makefile.am
libmsi/handle.c
libmsi/libmsi-database.c
libmsi/libmsi-query.c
libmsi/libmsi-record.c
libmsi/libmsi-summary-info.c
libmsi/msipriv.h
Diffstat (limited to 'libmsi/libmsi-database.c')
-rw-r--r-- | libmsi/libmsi-database.c | 415 |
1 files changed, 259 insertions, 156 deletions
diff --git a/libmsi/libmsi-database.c b/libmsi/libmsi-database.c index 19c7a62..6b9f25f 100644 --- a/libmsi/libmsi-database.c +++ b/libmsi/libmsi-database.c @@ -24,14 +24,28 @@ #include <fcntl.h> #include <sys/stat.h> +#include "libmsi-database.h" + #include "debug.h" #include "libmsi.h" #include "msipriv.h" #include "query.h" -const uint8_t clsid_msi_transform[16] = { 0x82, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 }; -const uint8_t clsid_msi_database[16] = { 0x84, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 }; -const uint8_t clsid_msi_patch[16] = { 0x86, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 }; +enum +{ + PROP_0, + + PROP_PATH, + PROP_MODE, + PROP_OUTPATH, + PROP_PATCH, +}; + +G_DEFINE_TYPE (LibmsiDatabase, libmsi_database, G_TYPE_OBJECT); + +const char clsid_msi_transform[16] = { 0x82, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 }; +const char clsid_msi_database[16] = { 0x84, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 }; +const char clsid_msi_patch[16] = { 0x86, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 }; /* * .MSI file format @@ -63,26 +77,130 @@ typedef struct _LibmsiStream { GsfInput *stm; } LibmsiStream; -static void free_transforms( LibmsiDatabase *db ) +static void +libmsi_database_init (LibmsiDatabase *p) { - while( !list_empty( &db->transforms ) ) - { - LibmsiTransform *t = LIST_ENTRY( list_head( &db->transforms ), - LibmsiTransform, entry ); - list_remove( &t->entry ); + list_init (&p->tables); + list_init (&p->transforms); + list_init (&p->streams); + list_init (&p->storages); +} + +static void +libmsi_database_constructed (GObject *object) +{ + G_OBJECT_CLASS (libmsi_database_parent_class)->constructed (object); +} + +static void +free_transforms (LibmsiDatabase *db) +{ + while (!list_empty(&db->transforms)) { + LibmsiTransform *t = LIST_ENTRY(list_head(&db->transforms), + LibmsiTransform, entry); + list_remove(&t->entry); g_object_unref(G_OBJECT(t->stg)); - msi_free( t ); + msi_free(t); } } -static void _libmsi_database_destroy( LibmsiObject *arg ) +static void +libmsi_database_finalize (GObject *object) { - LibmsiDatabase *db = (LibmsiDatabase *) arg; + LibmsiDatabase *self = LIBMSI_DATABASE (object); + LibmsiDatabase *p = self; + + _libmsi_database_close (self, false); + free_cached_tables (self); + free_transforms (self); - _libmsi_database_close( db, false ); - free_cached_tables( db ); - free_transforms( db ); - msi_free(db->path); + g_free (p->path); + + G_OBJECT_CLASS (libmsi_database_parent_class)->finalize (object); +} + +static void +libmsi_database_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + g_return_if_fail (LIBMSI_IS_DATABASE (object)); + LibmsiDatabase *p = LIBMSI_DATABASE (object); + + switch (prop_id) { + case PROP_PATH: + g_return_if_fail (p->path == NULL); + p->path = g_value_dup_string (value); + break; + case PROP_MODE: + g_return_if_fail (p->mode == NULL); + p->mode = (const char*)g_value_get_int (value); + break; + case PROP_OUTPATH: + g_return_if_fail (p->outpath == NULL); + p->outpath = (const char*)g_value_dup_string (value); + break; + case PROP_PATCH: + p->patch = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +libmsi_database_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + g_return_if_fail (LIBMSI_IS_DATABASE (object)); + LibmsiDatabase *p = LIBMSI_DATABASE (object); + + switch (prop_id) { + case PROP_PATH: + g_value_set_string (value, p->path); + break; + case PROP_MODE: + g_value_set_int (value, (int)p->mode); + break; + case PROP_OUTPATH: + g_value_set_string (value, p->outpath); + break; + case PROP_PATCH: + g_value_set_boolean (value, p->patch); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +libmsi_database_class_init (LibmsiDatabaseClass *klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = libmsi_database_finalize; + object_class->set_property = libmsi_database_set_property; + object_class->get_property = libmsi_database_get_property; + object_class->constructed = libmsi_database_constructed; + + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATH, + g_param_spec_string ("path", "path", "path", NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MODE, + g_param_spec_int ("mode", "mode", "mode", 0, G_MAXINT, 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_OUTPATH, + g_param_spec_string ("outpath", "outpath", "outpath", NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATCH, + g_param_spec_boolean ("patch", "patch", "patch", FALSE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } unsigned msi_open_storage( LibmsiDatabase *db, const char *stname ) @@ -495,7 +613,7 @@ LibmsiResult _libmsi_database_close(LibmsiDatabase *db, bool committed) db->outpath = NULL; } -LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db, const char *szPersist) +LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db) { unsigned ret = LIBMSI_RESULT_SUCCESS; GsfOutput *out; @@ -506,32 +624,31 @@ LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db, const char * if( db->mode == LIBMSI_DB_OPEN_READONLY ) return LIBMSI_RESULT_SUCCESS; - if( szPersist == LIBMSI_DB_OPEN_TRANSACT ) + db->rename_outpath = false; + if( !db->outpath ) { strcpy( path, db->path ); - strcat( path, ".tmp" ); - tmpfile = strdup(path); - szPersist = tmpfile; - } - else if( IS_INTMSIDBOPEN(szPersist) ) - { - ERR("unknown flag %p\n",szPersist); - return LIBMSI_RESULT_INVALID_PARAMETER; + if( db->mode == LIBMSI_DB_OPEN_TRANSACT ) + { + strcat( path, ".tmp" ); + db->rename_outpath = true; + } + db->outpath = strdup(path); } TRACE("%p %s\n", db, szPersist); - out = gsf_output_stdio_new(szPersist, NULL); + out = gsf_output_stdio_new(db->outpath, NULL); if (!out) { - WARN("open file failed for %s\n", debugstr_a(szPersist)); + WARN("open file failed for %s\n", debugstr_a(db->outpath)); return LIBMSI_RESULT_OPEN_FAILED; } stg = gsf_outfile_msole_new(out); g_object_unref(G_OBJECT(out)); if (!stg) { - WARN("open failed for %s\n", debugstr_a(szPersist)); + WARN("open failed for %s\n", debugstr_a(db->outpath)); return LIBMSI_RESULT_OPEN_FAILED; } @@ -546,18 +663,6 @@ LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db, const char * db->outfile = stg; g_object_ref(G_OBJECT(db->outfile)); - if (!strstr( szPersist, G_DIR_SEPARATOR_S )) - { - getcwd( path, MAX_PATH ); - strcat( path, G_DIR_SEPARATOR_S ); - strcat( path, szPersist ); - } - else - strcpy( path, szPersist ); - - db->outpath = strdup( path ); - db->rename_outpath = (tmpfile != NULL); - end: if (ret) { if (db->outfile) @@ -570,6 +675,29 @@ end: return ret; } +LibmsiResult libmsi_database_open(const char *szDBPath, const char *szPersist, LibmsiDatabase **pdb) +{ + char path[MAX_PATH]; + + TRACE("%s %p\n",debugstr_a(szDBPath),szPersist ); + + if( !pdb ) + return LIBMSI_RESULT_INVALID_PARAMETER; + + if (!strstr( szDBPath, G_DIR_SEPARATOR_S )) + { + getcwd( path, MAX_PATH ); + strcat( path, G_DIR_SEPARATOR_S ); + strcat( path, szDBPath ); + } + else + strcpy( path, szDBPath ); + + *pdb = libmsi_database_new (path, szPersist, NULL); + + return *pdb ? LIBMSI_RESULT_SUCCESS : LIBMSI_RESULT_OPEN_FAILED; +} + static char *msi_read_text_archive(const char *path, unsigned *len) { char *data; @@ -837,7 +965,7 @@ static unsigned msi_add_table_to_db(LibmsiDatabase *db, char **columns, char **t r = _libmsi_query_execute(view, NULL); libmsi_query_close(view); - msiobj_release(&view->hdr); + g_object_unref(view); done: msi_free(prelude); @@ -908,7 +1036,7 @@ static unsigned construct_record(unsigned num_columns, char **types, break; default: ERR("Unhandled column type: %c\n", types[i][0]); - msiobj_release(&(*rec)->hdr); + g_object_unref(*rec); return LIBMSI_RESULT_FUNCTION_FAILED; } } @@ -950,11 +1078,11 @@ static unsigned msi_add_records_to_table(LibmsiDatabase *db, char **columns, cha r = view->ops->insert_row(view, rec, -1, false); if (r != LIBMSI_RESULT_SUCCESS) { - msiobj_release(&rec->hdr); + g_object_unref(rec); goto done; } - msiobj_release(&rec->hdr); + g_object_unref(rec); } done: @@ -1088,9 +1216,9 @@ LibmsiResult libmsi_database_import(LibmsiDatabase *db, const char *szFolder, co if( !db ) return LIBMSI_RESULT_INVALID_HANDLE; - msiobj_addref( &db->hdr ); + g_object_ref(db); r = _libmsi_database_import( db, szFolder, szFilename ); - msiobj_release( &db->hdr ); + g_object_unref(db); return r; } @@ -1188,7 +1316,7 @@ static unsigned _libmsi_database_export( LibmsiDatabase *db, const char *table, if (r == LIBMSI_RESULT_SUCCESS) { msi_export_record( fd, rec, 1 ); - msiobj_release( &rec->hdr ); + g_object_unref(rec); } /* write out row 2, the column types */ @@ -1196,7 +1324,7 @@ static unsigned _libmsi_database_export( LibmsiDatabase *db, const char *table, if (r == LIBMSI_RESULT_SUCCESS) { msi_export_record( fd, rec, 1 ); - msiobj_release( &rec->hdr ); + g_object_unref(rec); } /* write out row 3, the table name + keys */ @@ -1205,12 +1333,12 @@ static unsigned _libmsi_database_export( LibmsiDatabase *db, const char *table, { libmsi_record_set_string( rec, 0, table ); msi_export_record( fd, rec, 0 ); - msiobj_release( &rec->hdr ); + g_object_unref(rec); } /* write out row 4 onwards, the data */ r = _libmsi_query_iterate_records( view, 0, msi_export_row, (void *)(intptr_t) fd ); - msiobj_release( &view->hdr ); + g_object_unref(view); } done: @@ -1242,9 +1370,9 @@ LibmsiResult libmsi_database_export( LibmsiDatabase *db, const char *szTable, if( !db ) return LIBMSI_RESULT_INVALID_HANDLE; - msiobj_addref ( &db->hdr ); + g_object_ref(db); r = _libmsi_database_export( db, szTable, fd ); - msiobj_release( &db->hdr ); + g_object_unref(db); return r; } @@ -1316,8 +1444,8 @@ static unsigned merge_verify_colnames(LibmsiQuery *dbview, LibmsiQuery *mergevie } } - msiobj_release(&dbrec->hdr); - msiobj_release(&mergerec->hdr); + g_object_unref(dbrec); + g_object_unref(mergerec); dbrec = mergerec = NULL; r = _libmsi_query_get_column_info(dbview, LIBMSI_COL_INFO_TYPES, &dbrec); @@ -1343,8 +1471,8 @@ static unsigned merge_verify_colnames(LibmsiQuery *dbview, LibmsiQuery *mergevie } done: - msiobj_release(&dbrec->hdr); - msiobj_release(&mergerec->hdr); + g_object_unref(dbrec); + g_object_unref(mergerec); return r; } @@ -1380,8 +1508,8 @@ static unsigned merge_verify_primary_keys(LibmsiDatabase *db, LibmsiDatabase *me } done: - msiobj_release(&dbrec->hdr); - msiobj_release(&mergerec->hdr); + g_object_unref(dbrec); + g_object_unref(mergerec); return r; } @@ -1405,7 +1533,7 @@ static char *get_key_value(LibmsiQuery *view, const char *key, LibmsiRecord *rec msi_free(str); } while (cmp); - msiobj_release(&colnames->hdr); + g_object_unref(colnames); r = _libmsi_record_get_string(rec, i, NULL, &sz); if (r != LIBMSI_RESULT_SUCCESS) @@ -1503,7 +1631,7 @@ static char *create_diff_row_query(LibmsiDatabase *merge, LibmsiQuery *view, done: msi_free(clause); - msiobj_release(&keys->hdr); + g_object_unref(keys); return query; } @@ -1562,8 +1690,8 @@ static unsigned merge_diff_row(LibmsiRecord *rec, void *param) done: msi_free(query); - msiobj_release(&row->hdr); - msiobj_release(&dbview->hdr); + g_object_unref(row); + g_object_unref(dbview); return r; } @@ -1592,7 +1720,7 @@ static unsigned msi_get_table_labels(LibmsiDatabase *db, const char *table, char } end: - msiobj_release( &prec->hdr ); + g_object_unref(prec); return r; } @@ -1621,7 +1749,7 @@ static unsigned msi_get_query_columns(LibmsiQuery *query, char ***columns, unsig *numcolumns = count; end: - msiobj_release( &prec->hdr ); + g_object_unref(prec); return r; } @@ -1649,7 +1777,7 @@ static unsigned msi_get_query_types(LibmsiQuery *query, char ***types, unsigned } end: - msiobj_release( &prec->hdr ); + g_object_unref(prec); return r; } @@ -1662,7 +1790,7 @@ static void merge_free_rows(MERGETABLE *table) MERGEROW *row = LIST_ENTRY(item, MERGEROW, entry); list_remove(&row->entry); - msiobj_release(&row->data->hdr); + g_object_unref(row); msi_free(row); } } @@ -1737,12 +1865,12 @@ static unsigned msi_get_merge_table (LibmsiDatabase *db, const char *name, MERGE table->name = strdup(name); table->numconflicts = 0; - msiobj_release(&mergeview->hdr); + g_object_unref(mergeview); *ptable = table; return LIBMSI_RESULT_SUCCESS; err: - msiobj_release(&mergeview->hdr); + g_object_unref(mergeview); free_merge_table(table); *ptable = NULL; return r; @@ -1796,8 +1924,8 @@ static unsigned merge_diff_tables(LibmsiRecord *rec, void *param) list_add_tail(data->tabledata, &table->entry); done: - msiobj_release(&dbview->hdr); - msiobj_release(&mergeview->hdr); + g_object_unref(dbview); + g_object_unref(mergeview); return r; } @@ -1817,7 +1945,7 @@ static unsigned gather_merge_data(LibmsiDatabase *db, LibmsiDatabase *merge, data.merge = merge; data.tabledata = tabledata; r = _libmsi_query_iterate_records(view, NULL, merge_diff_tables, &data); - msiobj_release(&view->hdr); + g_object_unref(view); return r; } @@ -1870,7 +1998,7 @@ static unsigned update_merge_errors(LibmsiDatabase *db, const char *error, return r; r = _libmsi_query_execute(view, NULL); - msiobj_release(&view->hdr); + g_object_unref(view); if (r != LIBMSI_RESULT_SUCCESS) return r; } @@ -1880,7 +2008,7 @@ static unsigned update_merge_errors(LibmsiDatabase *db, const char *error, return r; r = _libmsi_query_execute(view, NULL); - msiobj_release(&view->hdr); + g_object_unref(view); return r; } @@ -1902,8 +2030,8 @@ LibmsiResult libmsi_database_merge(LibmsiDatabase *db, LibmsiDatabase *merge, if (!db || !merge) return LIBMSI_RESULT_INVALID_HANDLE; - msiobj_addref( &db->hdr ); - msiobj_addref( &merge->hdr ); + g_object_ref(db); + g_object_ref(merge); r = gather_merge_data(db, merge, &tabledata); if (r != LIBMSI_RESULT_SUCCESS) goto done; @@ -1939,8 +2067,8 @@ LibmsiResult libmsi_database_merge(LibmsiDatabase *db, LibmsiDatabase *merge, r = LIBMSI_RESULT_FUNCTION_FAILED; done: - msiobj_release(&db->hdr); - msiobj_release(&merge->hdr); + g_object_unref(db); + g_object_unref(merge); return r; } @@ -1953,10 +2081,10 @@ LibmsiDBState libmsi_database_get_state( LibmsiDatabase *db ) if( !db ) return LIBMSI_RESULT_INVALID_HANDLE; - msiobj_addref( &db->hdr ); + g_object_ref(db); if (db->mode != LIBMSI_DB_OPEN_READONLY ) ret = LIBMSI_DB_STATE_WRITE; - msiobj_release( &db->hdr ); + g_object_unref(db); return ret; } @@ -2108,11 +2236,11 @@ LibmsiResult libmsi_database_apply_transform( LibmsiDatabase *db, { unsigned r; - msiobj_addref( &db->hdr ); + g_object_ref(db); if( !db ) return LIBMSI_RESULT_INVALID_HANDLE; r = _libmsi_database_apply_transform( db, szTransformFile, iErrorCond ); - msiobj_release( &db->hdr ); + g_object_unref(db); return r; } @@ -2202,7 +2330,7 @@ LibmsiResult libmsi_database_commit( LibmsiDatabase *db ) if( !db ) return LIBMSI_RESULT_INVALID_HANDLE; - msiobj_addref( &db->hdr ); + g_object_ref(db); if (db->mode == LIBMSI_DB_OPEN_READONLY) goto end; @@ -2241,11 +2369,12 @@ LibmsiResult libmsi_database_commit( LibmsiDatabase *db ) /* FIXME: unlock the database */ _libmsi_database_close(db, true); + db->mode = LIBMSI_DB_OPEN_TRANSACT; _libmsi_database_open(db); - _libmsi_database_start_transaction(db, LIBMSI_DB_OPEN_TRANSACT); + _libmsi_database_start_transaction(db); end: - msiobj_release( &db->hdr ); + g_object_unref(db); return r; } @@ -2313,9 +2442,9 @@ unsigned _libmsi_database_get_primary_keys( LibmsiDatabase *db, if( r == LIBMSI_RESULT_SUCCESS ) *prec = info.rec; else - msiobj_release( &info.rec->hdr ); + g_object_unref(info.rec); } - msiobj_release( &query->hdr ); + g_object_unref(query); return r; } @@ -2330,9 +2459,9 @@ LibmsiResult libmsi_database_get_primary_keys(LibmsiDatabase *db, if( !db ) return LIBMSI_RESULT_INVALID_HANDLE; - msiobj_addref( &db->hdr ); + g_object_ref(db); r = _libmsi_database_get_primary_keys( db, table, prec ); - msiobj_release( &db->hdr ); + g_object_unref(db); return r; } @@ -2344,93 +2473,67 @@ LibmsiCondition libmsi_database_is_table_persistent( TRACE("%x %s\n", db, debugstr_a(szTableName)); - msiobj_addref( &db->hdr ); + g_object_ref(db); if( !db ) return LIBMSI_CONDITION_ERROR; r = _libmsi_database_is_table_persistent( db, szTableName ); - msiobj_release( &db->hdr ); + g_object_unref(db); return r; } -LibmsiResult libmsi_database_open(const char *szDBPath, const char *szPersist, LibmsiDatabase **pdb) +/* TODO: use GInitable */ +static gboolean +init (LibmsiDatabase *self, GError **error) { - LibmsiDatabase *db = NULL; - unsigned ret = LIBMSI_RESULT_SUCCESS; - const char *szMode; - bool patch = false; - char path[MAX_PATH]; - - TRACE("%s %p\n",debugstr_a(szDBPath),szPersist ); + LibmsiDatabase *p = LIBMSI_DATABASE (self); + LibmsiResult ret; - if( !pdb ) - return LIBMSI_RESULT_INVALID_PARAMETER; - - if (IS_INTMSIDBOPEN(szPersist - LIBMSI_DB_OPEN_PATCHFILE)) - { - TRACE("Database is a patch\n"); - szPersist -= LIBMSI_DB_OPEN_PATCHFILE; - patch = true; - } - - szMode = szPersist; - db = alloc_msiobject( sizeof (LibmsiDatabase), _libmsi_database_destroy ); - if( !db ) - { - FIXME("Failed to allocate a handle\n"); - goto end; + if (p->mode == LIBMSI_DB_OPEN_CREATE) { + p->strings = msi_init_string_table (&p->bytes_per_strref); + } else { + if (_libmsi_database_open(self)) + return FALSE; } - if (!strstr( szDBPath, G_DIR_SEPARATOR_S )) - { - getcwd( path, MAX_PATH ); - strcat( path, G_DIR_SEPARATOR_S ); - strcat( path, szDBPath ); - } - else - strcpy( path, szDBPath ); + p->media_transform_offset = MSI_INITIAL_MEDIA_TRANSFORM_OFFSET; + p->media_transform_disk_id = MSI_INITIAL_MEDIA_TRANSFORM_DISKID; - db->patch = patch; - db->mode = szMode; - list_init( &db->tables ); - list_init( &db->transforms ); - list_init( &db->streams ); - list_init( &db->storages ); + if (TRACE_ON(msi)) + enum_stream_names (p->infile); - if( szPersist != LIBMSI_DB_OPEN_CREATE ) - { - db->path = strdup( path ); - ret = _libmsi_database_open(db); - if (ret) - goto end; - } else { - szPersist = szDBPath; - db->strings = msi_init_string_table( &db->bytes_per_strref ); - } + ret = _libmsi_database_start_transaction (self); - db->media_transform_offset = MSI_INITIAL_MEDIA_TRANSFORM_OFFSET; - db->media_transform_disk_id = MSI_INITIAL_MEDIA_TRANSFORM_DISKID; + return !ret; +} - if( TRACE_ON( msi ) ) - enum_stream_names( db->infile ); +LibmsiDatabase * +libmsi_database_new (const gchar *path, const char *persist, GError **error) +{ + LibmsiDatabase *self; + gboolean patch = false; - if( szPersist == LIBMSI_DB_OPEN_CREATE ) - ret = _libmsi_database_start_transaction(db, szDBPath); - else - ret = _libmsi_database_start_transaction(db, szPersist); - if (ret) - goto end; + g_return_val_if_fail (path != NULL, NULL); - ret = LIBMSI_RESULT_SUCCESS; + if (IS_INTMSIDBOPEN (persist - LIBMSI_DB_OPEN_PATCHFILE)) { + TRACE("Database is a patch\n"); + persist -= LIBMSI_DB_OPEN_PATCHFILE; + patch = true; + } - msiobj_addref( &db->hdr ); - *pdb = db; + self = g_object_new (LIBMSI_TYPE_DATABASE, + "path", path, + "patch", patch, + "outpath", IS_INTMSIDBOPEN(persist) ? NULL : persist, + "mode", (int)(intptr_t)(IS_INTMSIDBOPEN(persist) ? persist : LIBMSI_DB_OPEN_TRANSACT), + NULL); -end: - if( db ) - msiobj_release( &db->hdr ); + if (!init (self, error)) { + g_object_unref (self); + return NULL; + } - return ret; + return self; } |