summaryrefslogtreecommitdiffstats
path: root/libmsi/libmsi-database.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-12-11 11:35:57 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2012-12-11 11:38:05 +0100
commitcb4d4b7214170989fbce773bcf2dc0ca0581f4af (patch)
tree43cad405aa6ae7bb8064f1be47cad94dc255ba5c /libmsi/libmsi-database.c
parent4a33d8ff9f1e0593bd49922cd46aa3e6a7aa1273 (diff)
parentae4c81e4fca5bb5816b5cbabb17a7dcc22f58a3b (diff)
downloadmsitools-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.c415
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;
}