summaryrefslogtreecommitdiffstats
path: root/libmsi/msiquery.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmsi/msiquery.c')
-rw-r--r--libmsi/msiquery.c125
1 files changed, 66 insertions, 59 deletions
diff --git a/libmsi/msiquery.c b/libmsi/msiquery.c
index eb215c3..805b5a5 100644
--- a/libmsi/msiquery.c
+++ b/libmsi/msiquery.c
@@ -269,13 +269,13 @@ unsigned msi_view_get_row(LibmsiDatabase *db, LibmsiView *view, unsigned row, Li
if (MSITYPE_IS_BINARY(type))
{
- IStream *stm = NULL;
+ GsfInput *stm = NULL;
ret = view->ops->fetch_stream(view, row, i, &stm);
if ((ret == LIBMSI_RESULT_SUCCESS) && stm)
{
- _libmsi_record_set_IStream(*rec, i, stm);
- IStream_Release(stm);
+ _libmsi_record_set_gsf_input(*rec, i, stm);
+ g_object_unref(G_OBJECT(stm));
}
else
WARN("failed to get stream\n");
@@ -547,29 +547,28 @@ LibmsiDBError libmsi_query_get_error( LibmsiQuery *query, char *buffer, unsigned
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;
+ GsfInput *in;
+ GsfInfile *stg;
+ uint8_t uuid[16];
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) )
+ in = gsf_input_stdio_new(szTransformFile, NULL);
+ if (!in)
{
- WARN("failed to open transform 0x%08x\n", r);
- return ret;
+ WARN("open file failed for transform %s\n", debugstr_a(szTransformFile));
+ return LIBMSI_RESULT_OPEN_FAILED;
}
+ stg = gsf_infile_msole_new( in, NULL );
+ g_object_unref(G_OBJECT(in));
- r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
- if ( FAILED( r ) )
+ if( !gsf_infile_msole_get_class_id (GSF_INFILE_MSOLE(stg), uuid))
+ {
+ FIXME("Failed to stat storage\n");
goto end;
+ }
- if ( memcmp( &stat.clsid, &clsid_msi_transform, 16 ) != 0 )
+ if ( memcmp( uuid, clsid_msi_transform, 16 ) != 0 )
goto end;
if( TRACE_ON( msi ) )
@@ -578,8 +577,7 @@ unsigned _libmsi_database_apply_transform( LibmsiDatabase *db,
ret = msi_table_apply_transform( db, stg );
end:
- msi_free(szwTransformFile);
- IStorage_Release( stg );
+ g_object_unref(G_OBJECT(stg));
return ret;
}
@@ -597,67 +595,85 @@ LibmsiResult libmsi_database_apply_transform( LibmsiDatabase *db,
return r;
}
-static unsigned commit_storage( const WCHAR *name, IStorage *stg, void *opaque)
+static int gsf_infile_copy(GsfInfile *inf, GsfOutfile *outf)
+{
+ int n = gsf_infile_num_children(inf);
+ int i;
+
+ for (i = 0; i < n; i++) {
+ const char *name = gsf_infile_name_by_index(inf, i);
+ GsfInput *child = gsf_infile_child_by_index(inf, i);
+ GsfInfile *childf = GSF_IS_INFILE (child) ? GSF_INFILE (child) : NULL;
+ gboolean is_dir = childf && gsf_infile_num_children (childf) > 0;
+ GsfOutput *dest = gsf_outfile_new_child(outf, name, is_dir);
+ gboolean ok;
+
+ if (is_dir)
+ ok = gsf_infile_copy(childf, GSF_OUTFILE(dest));
+ else
+ ok = gsf_input_copy(child, dest);
+
+ g_object_unref(G_OBJECT(child));
+ g_object_unref(G_OBJECT(dest));
+ if (!ok)
+ return false;
+ }
+ return true;
+}
+
+static unsigned commit_storage( const WCHAR *name, GsfInfile *stg, void *opaque)
{
LibmsiDatabase *db = opaque;
- STATSTG stat;
- IStream *outstg;
- ULARGE_INTEGER cbRead, cbWritten;
+ GsfOutfile *outstg;
unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
- HRESULT r;
+ char *utf8name;
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) )
+ utf8name = strdupWtoUTF8(name);
+ outstg = GSF_OUTFILE(gsf_outfile_new_child( db->outfile, utf8name, true ));
+ msi_free( utf8name );
+ if ( !outstg )
return LIBMSI_RESULT_FUNCTION_FAILED;
- r = IStorage_CopyTo( stg, 0, NULL, NULL, outstg );
- if ( FAILED(r) )
+ if ( !gsf_infile_copy( stg, outstg ) )
goto end;
ret = LIBMSI_RESULT_SUCCESS;
end:
- IStorage_Release(outstg);
+ gsf_output_close(GSF_OUTPUT(outstg));
+ g_object_unref(G_OBJECT(outstg));
return ret;
}
-static unsigned commit_stream( const WCHAR *name, IStream *stm, void *opaque)
+static unsigned commit_stream( const WCHAR *name, GsfInput *stm, void *opaque)
{
LibmsiDatabase *db = opaque;
- STATSTG stat;
- IStream *outstm;
- ULARGE_INTEGER cbRead, cbWritten;
+ GsfOutput *outstm;
unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
- HRESULT r;
WCHAR decname[0x40];
+ char *utf8name;
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) )
+ utf8name = strdupWtoUTF8(name);
+ outstm = gsf_outfile_new_child( db->outfile, utf8name, false );
+ msi_free( utf8name );
+ if ( !outstm )
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)
+ gsf_input_seek (stm, 0, G_SEEK_SET);
+ gsf_output_seek (outstm, 0, G_SEEK_SET);
+ if ( !gsf_input_copy( stm, outstm ))
goto end;
ret = LIBMSI_RESULT_SUCCESS;
end:
- IStream_Release(outstm);
+ gsf_output_close(GSF_OUTPUT(outstm));
+ g_object_unref(G_OBJECT(outstm));
return ret;
}
@@ -665,7 +681,6 @@ LibmsiResult libmsi_database_commit( LibmsiDatabase *db )
{
unsigned r = LIBMSI_RESULT_SUCCESS;
unsigned bytes_per_strref;
- HRESULT hr;
TRACE("%d\n", db);
@@ -710,14 +725,6 @@ LibmsiResult libmsi_database_commit( LibmsiDatabase *db )
/* 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);