summaryrefslogtreecommitdiffstats
path: root/libmsi/libmsi-database.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmsi/libmsi-database.c')
-rw-r--r--libmsi/libmsi-database.c940
1 files changed, 387 insertions, 553 deletions
diff --git a/libmsi/libmsi-database.c b/libmsi/libmsi-database.c
index ce85457..6b9f25f 100644
--- a/libmsi/libmsi-database.c
+++ b/libmsi/libmsi-database.c
@@ -24,21 +24,11 @@
#include <fcntl.h>
#include <sys/stat.h>
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "windef.h"
-#include "winbase.h"
-#include "winnls.h"
-
#include "libmsi-database.h"
#include "debug.h"
-#include "unicode.h"
#include "libmsi.h"
#include "msipriv.h"
-#include "objidl.h"
-#include "objbase.h"
#include "query.h"
enum
@@ -72,19 +62,19 @@ const char clsid_msi_patch[16] = { 0x86, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0
typedef struct _LibmsiTransform {
struct list entry;
- IStorage *stg;
+ GsfInfile *stg;
} LibmsiTransform;
typedef struct _LibmsiStorage {
struct list entry;
- WCHAR *name;
- IStorage *stg;
+ char *name;
+ GsfInfile *stg;
} LibmsiStorage;
typedef struct _LibmsiStream {
struct list entry;
- WCHAR *name;
- IStream *stm;
+ char *name;
+ GsfInput *stm;
} LibmsiStream;
static void
@@ -213,86 +203,33 @@ libmsi_database_class_init (LibmsiDatabaseClass *klass)
G_PARAM_STATIC_STRINGS));
}
-static HRESULT stream_to_storage(IStream *stm, IStorage **stg)
-{
- ILockBytes *lockbytes = NULL;
- STATSTG stat;
- void *data;
- HRESULT hr;
- unsigned size, read;
- ULARGE_INTEGER offset;
-
- hr = IStream_Stat(stm, &stat, STATFLAG_NONAME);
- if (FAILED(hr))
- return hr;
-
- if (stat.cbSize.QuadPart >> 32)
- {
- ERR("Storage is too large\n");
- return E_FAIL;
- }
-
- size = stat.cbSize.QuadPart;
- data = msi_alloc(size);
- if (!data)
- return E_OUTOFMEMORY;
-
- hr = IStream_Read(stm, data, size, &read);
- if (FAILED(hr) || read != size)
- goto done;
-
- hr = CreateILockBytesOnHGlobal(NULL, true, &lockbytes);
- if (FAILED(hr))
- goto done;
-
- ZeroMemory(&offset, sizeof(ULARGE_INTEGER));
- hr = ILockBytes_WriteAt(lockbytes, offset, data, size, &read);
- if (FAILED(hr) || read != size)
- goto done;
-
- hr = StgOpenStorageOnILockBytes(lockbytes, NULL,
- STGM_READWRITE | STGM_SHARE_DENY_NONE,
- NULL, 0, stg);
- if (FAILED(hr))
- goto done;
-
-done:
- msi_free(data);
- if (lockbytes) ILockBytes_Release(lockbytes);
- return hr;
-}
-
-unsigned msi_open_storage( LibmsiDatabase *db, const WCHAR *stname )
+unsigned msi_open_storage( LibmsiDatabase *db, const char *stname )
{
- unsigned r;
- HRESULT hr;
+ unsigned r = LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
LibmsiStorage *storage;
+ GsfInput *in;
LIST_FOR_EACH_ENTRY( storage, &db->storages, LibmsiStorage, entry )
{
- if( !strcmpW( stname, storage->name ) )
+ if( !strcmp( stname, storage->name ) )
{
- TRACE("found %s\n", debugstr_w(stname));
+ TRACE("found %s\n", debugstr_a(stname));
return;
}
}
if (!(storage = msi_alloc_zero( sizeof(LibmsiStorage) ))) return LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
- storage->name = strdupW( stname );
+ storage->name = strdup( stname );
if (!storage->name)
- {
- r = LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
goto done;
- }
- hr = IStorage_OpenStorage(db->infile, stname, NULL,
- STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0,
- &storage->stg);
- if (FAILED(hr))
- {
- r = LIBMSI_RESULT_FUNCTION_FAILED;
+ in = gsf_infile_child_by_name(db->infile, stname);
+ if (!GSF_IS_INFILE(in))
+ goto done;
+
+ storage->stg = GSF_INFILE(in);
+ if (!storage->stg)
goto done;
- }
list_add_tail( &db->storages, &storage->entry );
r = LIBMSI_RESULT_SUCCESS;
@@ -306,12 +243,11 @@ done:
return r;
}
-unsigned msi_create_storage( LibmsiDatabase *db, const WCHAR *stname, IStream *stm )
+unsigned msi_create_storage( LibmsiDatabase *db, const char *stname, GsfInput *stm )
{
LibmsiStorage *storage;
- IStorage *origstg = NULL;
+ GsfInfile *origstg = NULL;
bool found = false;
- HRESULT hr;
unsigned r;
if ( db->mode == LIBMSI_DB_OPEN_READONLY )
@@ -319,9 +255,9 @@ unsigned msi_create_storage( LibmsiDatabase *db, const WCHAR *stname, IStream *s
LIST_FOR_EACH_ENTRY( storage, &db->storages, LibmsiStorage, entry )
{
- if( !strcmpW( stname, storage->name ) )
+ if( !strcmp( stname, storage->name ) )
{
- TRACE("found %s\n", debugstr_w(stname));
+ TRACE("found %s\n", debugstr_a(stname));
found = true;
break;
}
@@ -329,7 +265,7 @@ unsigned msi_create_storage( LibmsiDatabase *db, const WCHAR *stname, IStream *s
if (!found) {
if (!(storage = msi_alloc_zero( sizeof(LibmsiStorage) ))) return LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
- storage->name = strdupW( stname );
+ storage->name = strdup( stname );
if (!storage->name)
{
msi_free(storage);
@@ -337,19 +273,19 @@ unsigned msi_create_storage( LibmsiDatabase *db, const WCHAR *stname, IStream *s
}
}
- r = stream_to_storage(stm, &origstg);
- if (r != LIBMSI_RESULT_SUCCESS)
+ origstg = gsf_infile_msole_new(stm, NULL);
+ if (origstg == NULL)
goto done;
if (found) {
if (storage->stg)
- IStorage_Release(storage->stg);
+ g_object_unref(G_OBJECT(storage->stg));
} else {
list_add_tail( &db->storages, &storage->entry );
}
storage->stg = origstg;
- IStorage_AddRef(storage->stg);
+ g_object_ref(G_OBJECT(storage->stg));
r = LIBMSI_RESULT_SUCCESS;
@@ -362,38 +298,38 @@ done:
}
if (origstg)
- IStorage_Release(origstg);
+ g_object_unref(G_OBJECT(origstg));
return r;
}
-void msi_destroy_storage( LibmsiDatabase *db, const WCHAR *stname )
+void msi_destroy_storage( LibmsiDatabase *db, const char *stname )
{
LibmsiStorage *storage, *storage2;
LIST_FOR_EACH_ENTRY_SAFE( storage, storage2, &db->storages, LibmsiStorage, entry )
{
- if (!strcmpW( stname, storage->name ))
+ if (!strcmp( stname, storage->name ))
{
- TRACE("destroying %s\n", debugstr_w(stname));
+ TRACE("destroying %s\n", debugstr_a(stname));
list_remove( &storage->entry );
- IStorage_Release( storage->stg );
+ g_object_unref(G_OBJECT(storage->stg));
msi_free( storage );
break;
}
}
}
-static unsigned find_infile_stream( LibmsiDatabase *db, const WCHAR *name, IStream **stm )
+static unsigned find_infile_stream( LibmsiDatabase *db, const char *name, GsfInput **stm )
{
LibmsiStream *stream;
LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry )
{
- if( !strcmpW( name, stream->name ) )
+ if( !strcmp( name, stream->name ) )
{
- TRACE("found %s\n", debugstr_w(name));
+ TRACE("found %s\n", debugstr_a(name));
*stm = stream->stm;
return LIBMSI_RESULT_SUCCESS;
}
@@ -402,69 +338,56 @@ static unsigned find_infile_stream( LibmsiDatabase *db, const WCHAR *name, IStre
return LIBMSI_RESULT_FUNCTION_FAILED;
}
-static unsigned msi_alloc_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm)
+static unsigned msi_alloc_stream( LibmsiDatabase *db, const char *stname, GsfInput *stm)
{
LibmsiStream *stream;
- TRACE("%p %s %p", db, debugstr_w(stname), stm);
+ TRACE("%p %s %p", db, debugstr_a(stname), stm);
if (!(stream = msi_alloc( sizeof(LibmsiStream) ))) return LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
- stream->name = strdupW( stname );
+ stream->name = strdup( stname );
stream->stm = stm;
- IStream_AddRef( stm );
+ g_object_ref(G_OBJECT(stm));
list_add_tail( &db->streams, &stream->entry );
return LIBMSI_RESULT_SUCCESS;
}
-unsigned write_raw_stream_data( LibmsiDatabase *db, const WCHAR *stname,
- const void *data, unsigned sz, IStream **outstm )
+unsigned write_raw_stream_data( LibmsiDatabase *db, const char *stname,
+ const void *data, unsigned sz, GsfInput **outstm )
{
- HRESULT r;
unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
- unsigned count;
- IStream *stm = NULL;
- HANDLE hGlob;
+ GsfInput *stm = NULL;
+ char *mem;
LibmsiStream *stream;
- ULARGE_INTEGER size;
if (db->mode == LIBMSI_DB_OPEN_READONLY)
return LIBMSI_RESULT_FUNCTION_FAILED;
LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry )
{
- if( !strcmpW( stname, stream->name ) )
+ if( !strcmp( stname, stream->name ) )
{
msi_destroy_stream( db, stname );
break;
}
}
- hGlob = GlobalAlloc(GMEM_FIXED, sz);
- if (!hGlob)
+ mem = g_try_malloc(sz == 0 ? 1 : sz);
+ if (!mem)
return LIBMSI_RESULT_FUNCTION_FAILED;
if (data || sz)
- memcpy(hGlob, data, sz);
-
- r = CreateStreamOnHGlobal(hGlob, true, &stm);
- if( FAILED( r ) )
- {
- GlobalFree(hGlob);
- return LIBMSI_RESULT_FUNCTION_FAILED;
- }
-
- /* set the correct size - CreateStreamOnHGlobal screws it up */
- size.QuadPart = sz;
- IStream_SetSize(stm, size);
+ memcpy(mem, data, sz);
+ stm = gsf_input_memory_new(mem, sz, true);
ret = msi_alloc_stream( db, stname, stm);
*outstm = stm;
return ret;
}
-unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *stm )
+unsigned msi_create_stream( LibmsiDatabase *db, const char *stname, GsfInput *stm )
{
LibmsiStream *stream;
- WCHAR *encname = NULL;
+ char *encname = NULL;
unsigned r = LIBMSI_RESULT_FUNCTION_FAILED;
bool found = false;
@@ -475,7 +398,7 @@ unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *st
LIST_FOR_EACH_ENTRY( stream, &db->streams, LibmsiStream, entry )
{
- if( !strcmpW( encname, stream->name ) )
+ if( !strcmp( encname, stream->name ) )
{
found = true;
break;
@@ -484,18 +407,19 @@ unsigned msi_create_stream( LibmsiDatabase *db, const WCHAR *stname, IStream *st
if (found) {
if (stream->stm)
- IStream_Release(stream->stm);
+ g_object_unref(G_OBJECT(stream->stm));
stream->stm = stm;
- IStream_AddRef(stream->stm);
+ g_object_ref(G_OBJECT(stream->stm));
r = LIBMSI_RESULT_SUCCESS;
} else
r = msi_alloc_stream( db, encname, stm );
+ msi_free(encname);
return r;
}
unsigned msi_enum_db_streams(LibmsiDatabase *db,
- unsigned (*fn)(const WCHAR *, IStream *, void *),
+ unsigned (*fn)(const char *, GsfInput *, void *),
void *opaque)
{
unsigned r;
@@ -503,12 +427,12 @@ unsigned msi_enum_db_streams(LibmsiDatabase *db,
LIST_FOR_EACH_ENTRY_SAFE( stream, stream2, &db->streams, LibmsiStream, entry )
{
- IStream *stm;
+ GsfInput *stm;
stm = stream->stm;
- IStream_AddRef(stm);
+ g_object_ref(G_OBJECT(stm));
r = fn( stream->name, stm, opaque);
- IStream_Release(stm);
+ g_object_unref(G_OBJECT(stm));
if (r) {
return r;
@@ -519,7 +443,7 @@ unsigned msi_enum_db_streams(LibmsiDatabase *db,
}
unsigned msi_enum_db_storages(LibmsiDatabase *db,
- unsigned (*fn)(const WCHAR *, IStorage *, void *),
+ unsigned (*fn)(const char *, GsfInfile *, void *),
void *opaque)
{
unsigned r;
@@ -527,12 +451,12 @@ unsigned msi_enum_db_storages(LibmsiDatabase *db,
LIST_FOR_EACH_ENTRY_SAFE( storage, storage2, &db->storages, LibmsiStorage, entry )
{
- IStorage *stg;
+ GsfInfile *stg;
stg = storage->stg;
- IStorage_AddRef(stg);
+ g_object_ref(G_OBJECT(stg));
r = fn( storage->name, stg, opaque);
- IStorage_Release(stg);
+ g_object_unref(G_OBJECT(stg));
if (r) {
return r;
@@ -542,71 +466,64 @@ unsigned msi_enum_db_storages(LibmsiDatabase *db,
return LIBMSI_RESULT_SUCCESS;
}
-unsigned clone_infile_stream( LibmsiDatabase *db, const WCHAR *name, IStream **stm )
+unsigned clone_infile_stream( LibmsiDatabase *db, const char *name, GsfInput **stm )
{
- IStream *stream;
+ GsfInput *stream;
if (find_infile_stream( db, name, &stream ) == LIBMSI_RESULT_SUCCESS)
{
- HRESULT r;
- LARGE_INTEGER pos;
-
- r = IStream_Clone( stream, stm );
- if( FAILED( r ) )
+ stream = gsf_input_dup( stream, NULL );
+ if( !stream )
{
- WARN("failed to clone stream r = %08x!\n", r);
- return LIBMSI_RESULT_FUNCTION_FAILED;
- }
-
- pos.QuadPart = 0;
- r = IStream_Seek( *stm, pos, STREAM_SEEK_SET, NULL );
- if( FAILED( r ) )
- {
- IStream_Release( *stm );
+ WARN("failed to clone stream\n");
return LIBMSI_RESULT_FUNCTION_FAILED;
}
+ gsf_input_seek( stream, 0, G_SEEK_SET );
+ *stm = stream;
return LIBMSI_RESULT_SUCCESS;
}
return LIBMSI_RESULT_FUNCTION_FAILED;
}
-unsigned msi_get_raw_stream( LibmsiDatabase *db, const WCHAR *stname, IStream **stm )
+unsigned msi_get_raw_stream( LibmsiDatabase *db, const char *stname, GsfInput **stm )
{
- HRESULT r;
- WCHAR decoded[MAX_STREAM_NAME_LEN];
+ unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
+ char decoded[MAX_STREAM_NAME_LEN];
LibmsiTransform *transform;
decode_streamname( stname, decoded );
- TRACE("%s -> %s\n", debugstr_w(stname), debugstr_w(decoded));
+ TRACE("%s -> %s\n", debugstr_a(stname), debugstr_a(decoded));
if (clone_infile_stream( db, stname, stm ) == LIBMSI_RESULT_SUCCESS)
return LIBMSI_RESULT_SUCCESS;
LIST_FOR_EACH_ENTRY( transform, &db->transforms, LibmsiTransform, entry )
{
- r = IStorage_OpenStream( transform->stg, stname, NULL,
- STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
- if (SUCCEEDED(r))
- return LIBMSI_RESULT_SUCCESS;
+ *stm = gsf_infile_child_by_name( transform->stg, stname );
+ if (*stm)
+ {
+ ret = LIBMSI_RESULT_SUCCESS;
+ break;
+ }
}
- return LIBMSI_RESULT_FUNCTION_FAILED;
+ return ret;
}
-void msi_destroy_stream( LibmsiDatabase *db, const WCHAR *stname )
+void msi_destroy_stream( LibmsiDatabase *db, const char *stname )
{
LibmsiStream *stream, *stream2;
LIST_FOR_EACH_ENTRY_SAFE( stream, stream2, &db->streams, LibmsiStream, entry )
{
- if (!strcmpW( stname, stream->name ))
+ if (!strcmp( stname, stream->name ))
{
- TRACE("destroying %s\n", debugstr_w(stname));
+ TRACE("destroying %s\n", debugstr_a(stname));
list_remove( &stream->entry );
- IStream_Release( stream->stm );
+ g_object_unref(G_OBJECT(stream->stm));
msi_free( stream );
break;
}
@@ -619,7 +536,7 @@ static void free_storages( LibmsiDatabase *db )
{
LibmsiStorage *s = LIST_ENTRY(list_head( &db->storages ), LibmsiStorage, entry);
list_remove( &s->entry );
- IStorage_Release( s->stg );
+ g_object_unref(G_OBJECT(s->stg));
msi_free( s->name );
msi_free( s );
}
@@ -631,19 +548,19 @@ static void free_streams( LibmsiDatabase *db )
{
LibmsiStream *s = LIST_ENTRY(list_head( &db->streams ), LibmsiStream, entry);
list_remove( &s->entry );
- IStream_Release( s->stm );
+ g_object_unref(G_OBJECT(s->stm));
msi_free( s->name );
msi_free( s );
}
}
-void append_storage_to_db( LibmsiDatabase *db, IStorage *stg )
+void append_storage_to_db( LibmsiDatabase *db, GsfInfile *stg )
{
LibmsiTransform *t;
t = msi_alloc( sizeof *t );
t->stg = stg;
- IStorage_AddRef( stg );
+ g_object_ref(G_OBJECT(t->stg));
list_add_head( &db->transforms, &t->entry );
#if 0
@@ -667,13 +584,14 @@ LibmsiResult _libmsi_database_close(LibmsiDatabase *db, bool committed)
if ( db->infile )
{
- IStorage_Release( db->infile );
+ g_object_unref(G_OBJECT(db->infile));
db->infile = NULL;
}
if ( db->outfile )
{
- IStorage_Release( db->outfile );
+ gsf_output_close(GSF_OUTPUT(db->outfile));
+ g_object_unref(G_OBJECT(db->outfile));
db->outfile = NULL;
}
free_streams( db );
@@ -698,11 +616,10 @@ LibmsiResult _libmsi_database_close(LibmsiDatabase *db, bool committed)
LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db)
{
unsigned ret = LIBMSI_RESULT_SUCCESS;
- IStorage *stg = NULL;
- WCHAR *szwPersist;
+ GsfOutput *out;
+ GsfOutfile *stg = NULL;
char *tmpfile = NULL;
char path[PATH_MAX];
- HRESULT hr;
if( db->mode == LIBMSI_DB_OPEN_READONLY )
return LIBMSI_RESULT_SUCCESS;
@@ -721,33 +638,40 @@ LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db)
TRACE("%p %s\n", db, szPersist);
- szwPersist = strdupAtoW(db->outpath);
- hr = StgCreateDocfile( szwPersist,
- STGM_CREATE|STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg );
-
- msi_free(szwPersist);
-
- if ( SUCCEEDED(hr) )
- hr = IStorage_SetClass( stg, db->patch ? &clsid_msi_patch : &clsid_msi_database );
+ out = gsf_output_stdio_new(db->outpath, NULL);
+ if (!out)
+ {
+ 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(db->outpath));
+ return LIBMSI_RESULT_OPEN_FAILED;
+ }
- if( FAILED( hr ) )
+ if (!gsf_outfile_msole_set_class_id(GSF_OUTFILE_MSOLE(stg),
+ db->patch ? clsid_msi_patch : clsid_msi_database ))
{
- WARN("open failed hr = %08x for %s\n", hr, debugstr_a(db->outpath));
+ WARN("set guid failed\n");
ret = LIBMSI_RESULT_FUNCTION_FAILED;
goto end;
}
db->outfile = stg;
- IStorage_AddRef( db->outfile );
+ g_object_ref(G_OBJECT(db->outfile));
end:
if (ret) {
if (db->outfile)
- IStorage_Release( db->outfile );
+ g_object_unref(G_OBJECT(db->outfile));
db->outfile = NULL;
}
if (stg)
- IStorage_Release( stg );
+ g_object_unref(G_OBJECT(stg));
+ msi_free(tmpfile);
return ret;
}
@@ -760,10 +684,10 @@ LibmsiResult libmsi_database_open(const char *szDBPath, const char *szPersist, L
if( !pdb )
return LIBMSI_RESULT_INVALID_PARAMETER;
- if (!strchr( szDBPath, '\\' ))
+ if (!strstr( szDBPath, G_DIR_SEPARATOR_S ))
{
getcwd( path, MAX_PATH );
- strcat( path, "\\" );
+ strcat( path, G_DIR_SEPARATOR_S );
strcat( path, szDBPath );
}
else
@@ -774,43 +698,23 @@ LibmsiResult libmsi_database_open(const char *szDBPath, const char *szPersist, L
return *pdb ? LIBMSI_RESULT_SUCCESS : LIBMSI_RESULT_OPEN_FAILED;
}
-static WCHAR *msi_read_text_archive(const char *path, unsigned *len)
+static char *msi_read_text_archive(const char *path, unsigned *len)
{
- int fd;
- struct stat st;
- char *data = NULL;
- WCHAR *wdata = NULL;
- ssize_t nread;
+ char *data;
+ size_t nread;
- /* TODO g_file_get_contents */
- fd = open( path, O_RDONLY | O_BINARY);
- if (fd == -1)
+ if (!g_file_get_contents(path, &data, &nread, NULL))
return NULL;
- fstat (fd, &st);
- if (!(data = msi_alloc( st.st_size ))) goto done;
-
- nread = read(fd, data, st.st_size);
- if (nread != st.st_size) goto done;
-
- while (!data[st.st_size - 1]) st.st_size--;
- *len = MultiByteToWideChar( CP_ACP, 0, data, st.st_size, NULL, 0 );
- if ((wdata = msi_alloc( (*len + 1) * sizeof(WCHAR) )))
- {
- MultiByteToWideChar( CP_ACP, 0, data, st.st_size, wdata, *len );
- wdata[*len] = 0;
- }
-
-done:
- close( fd );
- msi_free( data );
- return wdata;
+ while (!data[nread - 1]) nread--;
+ *len = nread;
+ return data;
}
-static void msi_parse_line(WCHAR **line, WCHAR ***entries, unsigned *num_entries, unsigned *len)
+static void msi_parse_line(char **line, char ***entries, unsigned *num_entries, unsigned *len)
{
- WCHAR *ptr = *line;
- WCHAR *save;
+ char *ptr = *line;
+ char *save;
unsigned i, count = 1, chars_left = *len;
*entries = NULL;
@@ -826,7 +730,7 @@ static void msi_parse_line(WCHAR **line, WCHAR ***entries, unsigned *num_entries
chars_left--;
}
- *entries = msi_alloc(count * sizeof(WCHAR *));
+ *entries = msi_alloc(count * sizeof(char *));
if (!*entries)
return;
@@ -877,41 +781,41 @@ static void msi_parse_line(WCHAR **line, WCHAR ***entries, unsigned *num_entries
*num_entries = count;
}
-static WCHAR *msi_build_createsql_prelude(WCHAR *table)
+static char *msi_build_createsql_prelude(char *table)
{
- WCHAR *prelude;
+ char *prelude;
unsigned size;
- static const WCHAR create_fmt[] = {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','%','s','`',' ','(',' ',0};
+ static const char create_fmt[] = "CREATE TABLE `%s` (";
- size = sizeof(create_fmt)/sizeof(create_fmt[0]) + strlenW(table) - 2;
- prelude = msi_alloc(size * sizeof(WCHAR));
+ size = sizeof(create_fmt)/sizeof(create_fmt[0]) + strlen(table) - 2;
+ prelude = msi_alloc(size * sizeof(char));
if (!prelude)
return NULL;
- sprintfW(prelude, create_fmt, table);
+ sprintf(prelude, create_fmt, table);
return prelude;
}
-static WCHAR *msi_build_createsql_columns(WCHAR **columns_data, WCHAR **types, unsigned num_columns)
+static char *msi_build_createsql_columns(char **columns_data, char **types, unsigned num_columns)
{
- WCHAR *columns;
- WCHAR *p;
- const WCHAR *type;
+ char *columns;
+ char *p;
+ const char *type;
unsigned sql_size = 1, i, len;
- WCHAR expanded[128], *ptr;
- WCHAR size[10], comma[2], extra[30];
-
- static const WCHAR column_fmt[] = {'`','%','s','`',' ','%','s','%','s','%','s','%','s',' ',0};
- static const WCHAR size_fmt[] = {'(','%','s',')',0};
- static const WCHAR type_char[] = {'C','H','A','R',0};
- static const WCHAR type_int[] = {'I','N','T',0};
- static const WCHAR type_long[] = {'L','O','N','G',0};
- static const WCHAR type_object[] = {'O','B','J','E','C','T',0};
- static const WCHAR type_notnull[] = {' ','N','O','T',' ','N','U','L','L',0};
- static const WCHAR localizable[] = {' ','L','O','C','A','L','I','Z','A','B','L','E',0};
-
- columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
+ char expanded[128], *ptr;
+ char size[10], comma[2], extra[30];
+
+ static const char column_fmt[] = "`%s` %s%s%s%s ";
+ static const char size_fmt[] = "(%s)";
+ static const char type_char[] = "CHAR";
+ static const char type_int[] = "INT";
+ static const char type_long[] = "LONG";
+ static const char type_object[] = "OBJECT";
+ static const char type_notnull[] = " NOT NULL";
+ static const char localizable[] = " LOCALIZABLE";
+
+ columns = msi_alloc_zero(sql_size * sizeof(char));
if (!columns)
return NULL;
@@ -926,28 +830,28 @@ static WCHAR *msi_build_createsql_columns(WCHAR **columns_data, WCHAR **types, u
comma[0] = ',';
ptr = &types[i][1];
- len = atolW(ptr);
+ len = atol(ptr);
extra[0] = '\0';
switch (types[i][0])
{
case 'l':
- strcpyW(extra, type_notnull);
+ strcpy(extra, type_notnull);
/* fall through */
case 'L':
- strcatW(extra, localizable);
+ strcat(extra, localizable);
type = type_char;
- sprintfW(size, size_fmt, ptr);
+ sprintf(size, size_fmt, ptr);
break;
case 's':
- strcpyW(extra, type_notnull);
+ strcpy(extra, type_notnull);
/* fall through */
case 'S':
type = type_char;
- sprintfW(size, size_fmt, ptr);
+ sprintf(size, size_fmt, ptr);
break;
case 'i':
- strcpyW(extra, type_notnull);
+ strcpy(extra, type_notnull);
/* fall through */
case 'I':
if (len <= 2)
@@ -962,7 +866,7 @@ static WCHAR *msi_build_createsql_columns(WCHAR **columns_data, WCHAR **types, u
}
break;
case 'v':
- strcpyW(extra, type_notnull);
+ strcpy(extra, type_notnull);
/* fall through */
case 'V':
type = type_object;
@@ -973,10 +877,10 @@ static WCHAR *msi_build_createsql_columns(WCHAR **columns_data, WCHAR **types, u
return NULL;
}
- sprintfW(expanded, column_fmt, columns_data[i], type, size, extra, comma);
- sql_size += strlenW(expanded);
+ sprintf(expanded, column_fmt, columns_data[i], type, size, extra, comma);
+ sql_size += strlen(expanded);
- p = msi_realloc(columns, sql_size * sizeof(WCHAR));
+ p = msi_realloc(columns, sql_size * sizeof(char));
if (!p)
{
msi_free(columns);
@@ -984,60 +888,60 @@ static WCHAR *msi_build_createsql_columns(WCHAR **columns_data, WCHAR **types, u
}
columns = p;
- strcatW(columns, expanded);
+ strcat(columns, expanded);
}
return columns;
}
-static WCHAR *msi_build_createsql_postlude(WCHAR **primary_keys, unsigned num_keys)
+static char *msi_build_createsql_postlude(char **primary_keys, unsigned num_keys)
{
- WCHAR *postlude;
- WCHAR *keys;
- WCHAR *ptr;
+ char *postlude;
+ char *keys;
+ char *ptr;
unsigned size, key_size, i;
- static const WCHAR key_fmt[] = {'`','%','s','`',',',' ',0};
- static const WCHAR postlude_fmt[] = {'P','R','I','M','A','R','Y',' ','K','E','Y',' ','%','s',')',0};
+ static const char key_fmt[] = "`%s`, ";
+ static const char postlude_fmt[] = "PRIMARY KEY %s)";
for (i = 0, size = 1; i < num_keys; i++)
- size += strlenW(key_fmt) + strlenW(primary_keys[i]) - 2;
+ size += strlen(key_fmt) + strlen(primary_keys[i]) - 2;
- keys = msi_alloc(size * sizeof(WCHAR));
+ keys = msi_alloc(size * sizeof(char));
if (!keys)
return NULL;
for (i = 0, ptr = keys; i < num_keys; i++)
{
- key_size = strlenW(key_fmt) + strlenW(primary_keys[i]) -2;
- sprintfW(ptr, key_fmt, primary_keys[i]);
+ key_size = strlen(key_fmt) + strlen(primary_keys[i]) -2;
+ sprintf(ptr, key_fmt, primary_keys[i]);
ptr += key_size;
}
/* remove final ', ' */
*(ptr - 2) = '\0';
- size = strlenW(postlude_fmt) + size - 1;
- postlude = msi_alloc(size * sizeof(WCHAR));
+ size = strlen(postlude_fmt) + size - 1;
+ postlude = msi_alloc(size * sizeof(char));
if (!postlude)
goto done;
- sprintfW(postlude, postlude_fmt, keys);
+ sprintf(postlude, postlude_fmt, keys);
done:
msi_free(keys);
return postlude;
}
-static unsigned msi_add_table_to_db(LibmsiDatabase *db, WCHAR **columns, WCHAR **types, WCHAR **labels, unsigned num_labels, unsigned num_columns)
+static unsigned msi_add_table_to_db(LibmsiDatabase *db, char **columns, char **types, char **labels, unsigned num_labels, unsigned num_columns)
{
unsigned r = LIBMSI_RESULT_OUTOFMEMORY;
unsigned size;
LibmsiQuery *view;
- WCHAR *create_sql = NULL;
- WCHAR *prelude;
- WCHAR *columns_sql;
- WCHAR *postlude;
+ char *create_sql = NULL;
+ char *prelude;
+ char *columns_sql;
+ char *postlude;
prelude = msi_build_createsql_prelude(labels[0]);
columns_sql = msi_build_createsql_columns(columns, types, num_columns);
@@ -1046,14 +950,14 @@ static unsigned msi_add_table_to_db(LibmsiDatabase *db, WCHAR **columns, WCHAR *
if (!prelude || !columns_sql || !postlude)
goto done;
- size = strlenW(prelude) + strlenW(columns_sql) + strlenW(postlude) + 1;
- create_sql = msi_alloc(size * sizeof(WCHAR));
+ size = strlen(prelude) + strlen(columns_sql) + strlen(postlude) + 1;
+ create_sql = msi_alloc(size * sizeof(char));
if (!create_sql)
goto done;
- strcpyW(create_sql, prelude);
- strcatW(create_sql, columns_sql);
- strcatW(create_sql, postlude);
+ strcpy(create_sql, prelude);
+ strcat(create_sql, columns_sql);
+ strcat(create_sql, postlude);
r = _libmsi_database_open_query( db, create_sql, &view );
if (r != LIBMSI_RESULT_SUCCESS)
@@ -1071,14 +975,13 @@ done:
return r;
}
-static char *msi_import_stream_filename(const char *path, const WCHAR *name)
+static char *msi_import_stream_filename(const char *path, const char *name)
{
unsigned len;
- char *ascii_name = strdupWtoA(name);
char *fullname;
char *ptr;
- len = strlen(path) + strlen(ascii_name) + 1;
+ len = strlen(path) + strlen(name) + 1;
fullname = msi_alloc(len);
if (!fullname)
return NULL;
@@ -1092,14 +995,13 @@ static char *msi_import_stream_filename(const char *path, const WCHAR *name)
msi_free (fullname);
return NULL;
}
- *ptr++ = '\\';
- strcpy( ptr, ascii_name );
- msi_free( ascii_name );
+ strcpy( ptr, G_DIR_SEPARATOR_S );
+ strcat( ptr, name );
return fullname;
}
-static unsigned construct_record(unsigned num_columns, WCHAR **types,
- WCHAR **data, const char *path, LibmsiRecord **rec)
+static unsigned construct_record(unsigned num_columns, char **types,
+ char **data, const char *path, LibmsiRecord **rec)
{
unsigned i;
@@ -1112,11 +1014,11 @@ static unsigned construct_record(unsigned num_columns, WCHAR **types,
switch (types[i][0])
{
case 'L': case 'l': case 'S': case 's':
- _libmsi_record_set_stringW(*rec, i + 1, data[i]);
+ libmsi_record_set_string(*rec, i + 1, data[i]);
break;
case 'I': case 'i':
if (*data[i])
- libmsi_record_set_int(*rec, i + 1, atoiW(data[i]));
+ libmsi_record_set_int(*rec, i + 1, atoi(data[i]));
break;
case 'V': case 'v':
if (*data[i])
@@ -1142,8 +1044,8 @@ static unsigned construct_record(unsigned num_columns, WCHAR **types,
return LIBMSI_RESULT_SUCCESS;
}
-static unsigned msi_add_records_to_table(LibmsiDatabase *db, WCHAR **columns, WCHAR **types,
- WCHAR **labels, WCHAR ***records,
+static unsigned msi_add_records_to_table(LibmsiDatabase *db, char **columns, char **types,
+ char **labels, char ***records,
int num_columns, int num_records,
const char *path)
{
@@ -1197,18 +1099,16 @@ static unsigned _libmsi_database_import(LibmsiDatabase *db, const char *folder,
unsigned num_columns = 0;
unsigned num_records = 0;
char *path = NULL;
- WCHAR **columns = NULL;
- WCHAR **types = NULL;
- WCHAR **labels = NULL;
- WCHAR *ptr;
- WCHAR *data = NULL;
- WCHAR ***records = NULL;
- WCHAR ***temp_records;
-
- static const WCHAR suminfo[] =
- {'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
- static const WCHAR forcecodepage[] =
- {'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0};
+ char **columns = NULL;
+ char **types = NULL;
+ char **labels = NULL;
+ char *ptr;
+ char *data = NULL;
+ char ***records = NULL;
+ char ***temp_records;
+
+ static const char suminfo[] = "_SummaryInformation";
+ static const char forcecodepage[] = "_ForceCodepage";
TRACE("%p %s %s\n", db, debugstr_a(folder), debugstr_a(file) );
@@ -1221,7 +1121,7 @@ static unsigned _libmsi_database_import(LibmsiDatabase *db, const char *folder,
return LIBMSI_RESULT_OUTOFMEMORY;
strcpy( path, folder );
- strcat( path, "\\" );
+ strcat( path, G_DIR_SEPARATOR_S );
strcat( path, file );
data = msi_read_text_archive( path, &len );
@@ -1234,9 +1134,9 @@ static unsigned _libmsi_database_import(LibmsiDatabase *db, const char *folder,
msi_parse_line( &ptr, &labels, &num_labels, &len );
if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] &&
- num_types == 2 && !strcmpW( types[1], forcecodepage ))
+ num_types == 2 && !strcmp( types[1], forcecodepage ))
{
- r = msi_set_string_table_codepage( db->strings, atoiW( types[0] ) );
+ r = msi_set_string_table_codepage( db->strings, atoi( types[0] ) );
goto done;
}
@@ -1246,7 +1146,7 @@ static unsigned _libmsi_database_import(LibmsiDatabase *db, const char *folder,
goto done;
}
- records = msi_alloc(sizeof(WCHAR **));
+ records = msi_alloc(sizeof(char **));
if (!records)
{
r = LIBMSI_RESULT_OUTOFMEMORY;
@@ -1259,7 +1159,7 @@ static unsigned _libmsi_database_import(LibmsiDatabase *db, const char *folder,
msi_parse_line( &ptr, &records[num_records], NULL, &len );
num_records++;
- temp_records = msi_realloc(records, (num_records + 1) * sizeof(WCHAR **));
+ temp_records = msi_realloc(records, (num_records + 1) * sizeof(char **));
if (!temp_records)
{
r = LIBMSI_RESULT_OUTOFMEMORY;
@@ -1268,7 +1168,7 @@ static unsigned _libmsi_database_import(LibmsiDatabase *db, const char *folder,
records = temp_records;
}
- if (!strcmpW(labels[0], suminfo))
+ if (!strcmp(labels[0], suminfo))
{
r = msi_add_suminfo( db, records, num_records, num_columns );
if (r != LIBMSI_RESULT_SUCCESS)
@@ -1390,20 +1290,18 @@ static unsigned msi_export_forcecodepage( int fd, unsigned codepage )
return LIBMSI_RESULT_SUCCESS;
}
-static unsigned _libmsi_database_export( LibmsiDatabase *db, const WCHAR *table,
+static unsigned _libmsi_database_export( LibmsiDatabase *db, const char *table,
int fd)
{
- static const WCHAR query[] = {
- 's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 };
- static const WCHAR forcecodepage[] = {
- '_','F','o','r','c','e','C','o','d','e','p','a','g','e',0 };
+ static const char query[] = "select * from %s";
+ static const char forcecodepage[] = "_ForceCodepage";
LibmsiRecord *rec = NULL;
LibmsiQuery *view = NULL;
unsigned r;
- TRACE("%p %s %d\n", db, debugstr_w(table), fd );
+ TRACE("%p %s %d\n", db, debugstr_a(table), fd );
- if (!strcmpW( table, forcecodepage ))
+ if (!strcmp( table, forcecodepage ))
{
unsigned codepage = msi_get_string_table_codepage( db->strings );
r = msi_export_forcecodepage( fd, codepage );
@@ -1433,7 +1331,7 @@ static unsigned _libmsi_database_export( LibmsiDatabase *db, const WCHAR *table,
r = _libmsi_database_get_primary_keys( db, table, &rec );
if (r == LIBMSI_RESULT_SUCCESS)
{
- _libmsi_record_set_stringW( rec, 0, table );
+ libmsi_record_set_string( rec, 0, table );
msi_export_record( fd, rec, 0 );
g_object_unref(rec);
}
@@ -1448,7 +1346,7 @@ done:
}
/***********************************************************************
- * MsiExportDatabaseW [MSI.@]
+ * MsiExportDatabase [MSI.@]
*
* Writes a file containing the table data as tab separated ASCII.
*
@@ -1465,27 +1363,16 @@ done:
LibmsiResult libmsi_database_export( LibmsiDatabase *db, const char *szTable,
int fd )
{
- WCHAR *table = NULL;
unsigned r = LIBMSI_RESULT_OUTOFMEMORY;
TRACE("%x %s %d\n", db, debugstr_a(szTable), fd);
- if( szTable )
- {
- table = strdupAtoW( szTable );
- if( !table )
- goto end;
- }
-
if( !db )
return LIBMSI_RESULT_INVALID_HANDLE;
g_object_ref(db);
- r = _libmsi_database_export( db, table, fd );
+ r = _libmsi_database_export( db, szTable, fd );
g_object_unref(db);
-
-end:
- msi_free(table);
return r;
}
@@ -1493,13 +1380,13 @@ typedef struct _tagMERGETABLE
{
struct list entry;
struct list rows;
- WCHAR *name;
+ char *name;
unsigned numconflicts;
- WCHAR **columns;
+ char **columns;
unsigned numcolumns;
- WCHAR **types;
+ char **types;
unsigned numtypes;
- WCHAR **labels;
+ char **labels;
unsigned numlabels;
} MERGETABLE;
@@ -1518,7 +1405,7 @@ typedef struct _tagMERGEDATA
struct list *tabledata;
} MERGEDATA;
-static bool merge_type_match(const WCHAR *type1, const WCHAR *type2)
+static bool merge_type_match(const char *type1, const char *type2)
{
if (((type1[0] == 'l') || (type1[0] == 's')) &&
((type2[0] == 'l') || (type2[0] == 's')))
@@ -1528,7 +1415,7 @@ static bool merge_type_match(const WCHAR *type1, const WCHAR *type2)
((type2[0] == 'L') || (type2[0] == 'S')))
return true;
- return !strcmpW( type1, type2 );
+ return !strcmp( type1, type2 );
}
static unsigned merge_verify_colnames(LibmsiQuery *dbview, LibmsiQuery *mergeview)
@@ -1550,7 +1437,7 @@ static unsigned merge_verify_colnames(LibmsiQuery *dbview, LibmsiQuery *mergevie
if (!_libmsi_record_get_string_raw(mergerec, i))
break;
- if (strcmpW( _libmsi_record_get_string_raw( dbrec, i ), _libmsi_record_get_string_raw( mergerec, i ) ))
+ if (strcmp( _libmsi_record_get_string_raw( dbrec, i ), _libmsi_record_get_string_raw( mergerec, i ) ))
{
r = LIBMSI_RESULT_DATATYPE_MISMATCH;
goto done;
@@ -1591,7 +1478,7 @@ done:
}
static unsigned merge_verify_primary_keys(LibmsiDatabase *db, LibmsiDatabase *mergedb,
- const WCHAR *table)
+ const char *table)
{
LibmsiRecord *dbrec, *mergerec = NULL;
unsigned r, i, count;
@@ -1613,7 +1500,7 @@ static unsigned merge_verify_primary_keys(LibmsiDatabase *db, LibmsiDatabase *me
for (i = 1; i <= count; i++)
{
- if (strcmpW( _libmsi_record_get_string_raw( dbrec, i ), _libmsi_record_get_string_raw( mergerec, i ) ))
+ if (strcmp( _libmsi_record_get_string_raw( dbrec, i ), _libmsi_record_get_string_raw( mergerec, i ) ))
{
r = LIBMSI_RESULT_DATATYPE_MISMATCH;
goto done;
@@ -1627,11 +1514,11 @@ done:
return r;
}
-static WCHAR *get_key_value(LibmsiQuery *view, const WCHAR *key, LibmsiRecord *rec)
+static char *get_key_value(LibmsiQuery *view, const char *key, LibmsiRecord *rec)
{
LibmsiRecord *colnames;
- WCHAR *str;
- WCHAR *val;
+ char *str;
+ char *val;
unsigned r, i = 0, sz = 0;
int cmp;
@@ -1642,13 +1529,13 @@ static WCHAR *get_key_value(LibmsiQuery *view, const WCHAR *key, LibmsiRecord *r
do
{
str = msi_dup_record_field(colnames, ++i);
- cmp = strcmpW( key, str );
+ cmp = strcmp( key, str );
msi_free(str);
} while (cmp);
g_object_unref(colnames);
- r = _libmsi_record_get_stringW(rec, i, NULL, &sz);
+ r = _libmsi_record_get_string(rec, i, NULL, &sz);
if (r != LIBMSI_RESULT_SUCCESS)
return NULL;
sz++;
@@ -1656,24 +1543,24 @@ static WCHAR *get_key_value(LibmsiQuery *view, const WCHAR *key, LibmsiRecord *r
if (_libmsi_record_get_string_raw(rec, i)) /* check record field is a string */
{
/* quote string record fields */
- const WCHAR szQuote[] = {'\'', 0};
+ const char szQuote[] = "'";
sz += 2;
- val = msi_alloc(sz*sizeof(WCHAR));
+ val = msi_alloc(sz*sizeof(char));
if (!val)
return NULL;
- strcpyW(val, szQuote);
- r = _libmsi_record_get_stringW(rec, i, val+1, &sz);
- strcpyW(val+1+sz, szQuote);
+ strcpy(val, szQuote);
+ r = _libmsi_record_get_string(rec, i, val+1, &sz);
+ strcpy(val+1+sz, szQuote);
}
else
{
/* do not quote integer record fields */
- val = msi_alloc(sz*sizeof(WCHAR));
+ val = msi_alloc(sz*sizeof(char));
if (!val)
return NULL;
- r = _libmsi_record_get_stringW(rec, i, val, &sz);
+ r = _libmsi_record_get_string(rec, i, val, &sz);
}
if (r != LIBMSI_RESULT_SUCCESS)
@@ -1686,31 +1573,27 @@ static WCHAR *get_key_value(LibmsiQuery *view, const WCHAR *key, LibmsiRecord *r
return val;
}
-static WCHAR *create_diff_row_query(LibmsiDatabase *merge, LibmsiQuery *view,
- WCHAR *table, LibmsiRecord *rec)
+static char *create_diff_row_query(LibmsiDatabase *merge, LibmsiQuery *view,
+ char *table, LibmsiRecord *rec)
{
- WCHAR *query = NULL;
- WCHAR *clause = NULL;
- WCHAR *val;
- const WCHAR *setptr;
- const WCHAR *key;
+ char *query = NULL;
+ char *clause = NULL;
+ char *val;
+ const char *setptr;
+ const char *key;
unsigned size, oldsize;
LibmsiRecord *keys;
unsigned r, i, count;
- static const WCHAR keyset[] = {
- '`','%','s','`',' ','=',' ','%','s',' ','A','N','D',' ',0};
- static const WCHAR lastkeyset[] = {
- '`','%','s','`',' ','=',' ','%','s',' ',0};
- static const WCHAR fmt[] = {'S','E','L','E','C','T',' ','*',' ',
- 'F','R','O','M',' ','`','%','s','`',' ',
- 'W','H','E','R','E',' ','%','s',0};
+ static const char keyset[] = "`%s` = %s AND";
+ static const char lastkeyset[] = "`%s` = %s ";
+ static const char fmt[] = "SELECT * FROM %s WHERE %s";
r = _libmsi_database_get_primary_keys(merge, table, &keys);
if (r != LIBMSI_RESULT_SUCCESS)
return NULL;
- clause = msi_alloc_zero(sizeof(WCHAR));
+ clause = msi_alloc_zero(sizeof(char));
if (!clause)
goto done;
@@ -1727,24 +1610,24 @@ static WCHAR *create_diff_row_query(LibmsiDatabase *merge, LibmsiQuery *view,
setptr = keyset;
oldsize = size;
- size += strlenW(setptr) + strlenW(key) + strlenW(val) - 4;
- clause = msi_realloc(clause, size * sizeof (WCHAR));
+ size += strlen(setptr) + strlen(key) + strlen(val) - 4;
+ clause = msi_realloc(clause, size * sizeof (char));
if (!clause)
{
msi_free(val);
goto done;
}
- sprintfW(clause + oldsize - 1, setptr, key, val);
+ sprintf(clause + oldsize - 1, setptr, key, val);
msi_free(val);
}
- size = strlenW(fmt) + strlenW(table) + strlenW(clause) + 1;
- query = msi_alloc(size * sizeof(WCHAR));
+ size = strlen(fmt) + strlen(table) + strlen(clause) + 1;
+ query = msi_alloc(size * sizeof(char));
if (!query)
goto done;
- sprintfW(query, fmt, table, clause);
+ sprintf(query, fmt, table, clause);
done:
msi_free(clause);
@@ -1759,7 +1642,7 @@ static unsigned merge_diff_row(LibmsiRecord *rec, void *param)
MERGEROW *mergerow;
LibmsiQuery *dbview = NULL;
LibmsiRecord *row = NULL;
- WCHAR *query = NULL;
+ char *query = NULL;
unsigned r = LIBMSI_RESULT_SUCCESS;
if (table_view_exists(data->db, table->name))
@@ -1812,7 +1695,7 @@ done:
return r;
}
-static unsigned msi_get_table_labels(LibmsiDatabase *db, const WCHAR *table, WCHAR ***labels, unsigned *numlabels)
+static unsigned msi_get_table_labels(LibmsiDatabase *db, const char *table, char ***labels, unsigned *numlabels)
{
unsigned r, i, count;
LibmsiRecord *prec = NULL;
@@ -1823,17 +1706,17 @@ static unsigned msi_get_table_labels(LibmsiDatabase *db, const WCHAR *table, WCH
count = libmsi_record_get_field_count(prec);
*numlabels = count + 1;
- *labels = msi_alloc((*numlabels)*sizeof(WCHAR *));
+ *labels = msi_alloc((*numlabels)*sizeof(char *));
if (!*labels)
{
r = LIBMSI_RESULT_OUTOFMEMORY;
goto end;
}
- (*labels)[0] = strdupW(table);
+ (*labels)[0] = strdup(table);
for (i=1; i<=count; i++ )
{
- (*labels)[i] = strdupW(_libmsi_record_get_string_raw(prec, i));
+ (*labels)[i] = strdup(_libmsi_record_get_string_raw(prec, i));
}
end:
@@ -1841,7 +1724,7 @@ end:
return r;
}
-static unsigned msi_get_query_columns(LibmsiQuery *query, WCHAR ***columns, unsigned *numcolumns)
+static unsigned msi_get_query_columns(LibmsiQuery *query, char ***columns, unsigned *numcolumns)
{
unsigned r, i, count;
LibmsiRecord *prec = NULL;
@@ -1851,7 +1734,7 @@ static unsigned msi_get_query_columns(LibmsiQuery *query, WCHAR ***columns, unsi
return r;
count = libmsi_record_get_field_count(prec);
- *columns = msi_alloc(count*sizeof(WCHAR *));
+ *columns = msi_alloc(count*sizeof(char *));
if (!*columns)
{
r = LIBMSI_RESULT_OUTOFMEMORY;
@@ -1860,7 +1743,7 @@ static unsigned msi_get_query_columns(LibmsiQuery *query, WCHAR ***columns, unsi
for (i=1; i<=count; i++ )
{
- (*columns)[i-1] = strdupW(_libmsi_record_get_string_raw(prec, i));
+ (*columns)[i-1] = strdup(_libmsi_record_get_string_raw(prec, i));
}
*numcolumns = count;
@@ -1870,7 +1753,7 @@ end:
return r;
}
-static unsigned msi_get_query_types(LibmsiQuery *query, WCHAR ***types, unsigned *numtypes)
+static unsigned msi_get_query_types(LibmsiQuery *query, char ***types, unsigned *numtypes)
{
unsigned r, i, count;
LibmsiRecord *prec = NULL;
@@ -1880,7 +1763,7 @@ static unsigned msi_get_query_types(LibmsiQuery *query, WCHAR ***types, unsigned
return r;
count = libmsi_record_get_field_count(prec);
- *types = msi_alloc(count*sizeof(WCHAR *));
+ *types = msi_alloc(count*sizeof(char *));
if (!*types)
{
r = LIBMSI_RESULT_OUTOFMEMORY;
@@ -1890,7 +1773,7 @@ static unsigned msi_get_query_types(LibmsiQuery *query, WCHAR ***types, unsigned
*numtypes = count;
for (i=1; i<=count; i++ )
{
- (*types)[i-1] = strdupW(_libmsi_record_get_string_raw(prec, i));
+ (*types)[i-1] = strdup(_libmsi_record_get_string_raw(prec, i));
}
end:
@@ -1946,14 +1829,13 @@ static void free_merge_table(MERGETABLE *table)
msi_free(table);
}
-static unsigned msi_get_merge_table (LibmsiDatabase *db, const WCHAR *name, MERGETABLE **ptable)
+static unsigned msi_get_merge_table (LibmsiDatabase *db, const char *name, MERGETABLE **ptable)
{
unsigned r;
MERGETABLE *table;
LibmsiQuery *mergeview = NULL;
- static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
- 'F','R','O','M',' ','`','%','s','`',0};
+ static const char query[] = "SELECT * FROM %s";
table = msi_alloc_zero(sizeof(MERGETABLE));
if (!table)
@@ -1980,7 +1862,7 @@ static unsigned msi_get_merge_table (LibmsiDatabase *db, const WCHAR *name, MERG
list_init(&table->rows);
- table->name = strdupW(name);
+ table->name = strdup(name);
table->numconflicts = 0;
g_object_unref(mergeview);
@@ -2000,11 +1882,10 @@ static unsigned merge_diff_tables(LibmsiRecord *rec, void *param)
MERGETABLE *table;
LibmsiQuery *dbview = NULL;
LibmsiQuery *mergeview = NULL;
- const WCHAR *name;
+ const char *name;
unsigned r;
- static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
- 'F','R','O','M',' ','`','%','s','`',0};
+ static const char query[] = "SELECT * FROM %s";
name = _libmsi_record_get_string_raw(rec, 1);
@@ -2051,9 +1932,7 @@ done:
static unsigned gather_merge_data(LibmsiDatabase *db, LibmsiDatabase *merge,
struct list *tabledata)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','_','T','a','b','l','e','s','`',0};
+ static const char query[] = "SELECT * FROM _Tables";
LibmsiQuery *view;
MERGEDATA data;
unsigned r;
@@ -2100,26 +1979,17 @@ static unsigned merge_table(LibmsiDatabase *db, MERGETABLE *table)
return LIBMSI_RESULT_SUCCESS;
}
-static unsigned update_merge_errors(LibmsiDatabase *db, const WCHAR *error,
- WCHAR *table, unsigned numconflicts)
+static unsigned update_merge_errors(LibmsiDatabase *db, const char *error,
+ char *table, unsigned numconflicts)
{
unsigned r;
LibmsiQuery *view;
- static const WCHAR create[] = {
- 'C','R','E','A','T','E',' ','T','A','B','L','E',' ',
- '`','%','s','`',' ','(','`','T','a','b','l','e','`',' ',
- 'C','H','A','R','(','2','5','5',')',' ','N','O','T',' ',
- 'N','U','L','L',',',' ','`','N','u','m','R','o','w','M','e','r','g','e',
- 'C','o','n','f','l','i','c','t','s','`',' ','S','H','O','R','T',' ',
- 'N','O','T',' ','N','U','L','L',' ','P','R','I','M','A','R','Y',' ',
- 'K','E','Y',' ','`','T','a','b','l','e','`',')',0};
- static const WCHAR insert[] = {
- 'I','N','S','E','R','T',' ','I','N','T','O',' ',
- '`','%','s','`',' ','(','`','T','a','b','l','e','`',',',' ',
- '`','N','u','m','R','o','w','M','e','r','g','e',
- 'C','o','n','f','l','i','c','t','s','`',')',' ','V','A','L','U','E','S',
- ' ','(','\'','%','s','\'',',',' ','%','d',')',0};
+ static const char create[] =
+ "CREATE TABLE `%s` (`Table` CHAR(255) NOT NULL, "
+ "`NumRowMergeConflicts` SHORT NOT NULL PRIMARY KEY `Table`)";
+ static const char insert[] =
+ "INSERT INTO `%s` (`Table`, `NumRowMergeConflicts`) VALUES ('%s', %d)";
if (!table_view_exists(db, error))
{
@@ -2147,7 +2017,6 @@ LibmsiResult libmsi_database_merge(LibmsiDatabase *db, LibmsiDatabase *merge,
{
struct list tabledata = LIST_INIT(tabledata);
struct list *item, *cursor;
- WCHAR *szwTableName;
MERGETABLE *table;
bool conflicts;
unsigned r;
@@ -2161,7 +2030,6 @@ LibmsiResult libmsi_database_merge(LibmsiDatabase *db, LibmsiDatabase *merge,
if (!db || !merge)
return LIBMSI_RESULT_INVALID_HANDLE;
- szwTableName = strdupAtoW(szTableName);
g_object_ref(db);
g_object_ref(merge);
r = gather_merge_data(db, merge, &tabledata);
@@ -2175,7 +2043,7 @@ LibmsiResult libmsi_database_merge(LibmsiDatabase *db, LibmsiDatabase *merge,
{
conflicts = true;
- r = update_merge_errors(db, szwTableName, table->name,
+ r = update_merge_errors(db, szTableName, table->name,
table->numconflicts);
if (r != LIBMSI_RESULT_SUCCESS)
break;
@@ -2223,105 +2091,90 @@ LibmsiDBState libmsi_database_get_state( LibmsiDatabase *db )
static void cache_infile_structure( LibmsiDatabase *db )
{
- IEnumSTATSTG *stgenum = NULL;
- STATSTG stat;
- IStream *stream;
- HRESULT hr;
- unsigned r, size;
- WCHAR decname[0x40];
+ int i, n;
+ char decname[0x40];
+ unsigned r;
- hr = IStorage_EnumElements(db->infile, 0, NULL, 0, &stgenum);
- if (FAILED(hr))
- return;
+ n = gsf_infile_num_children(db->infile);
/* TODO: error handling */
- while (true)
+ for (i = 0; i < n; i++)
{
- size = 0;
- hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &size);
- if (FAILED(hr) || !size)
- break;
+ GsfInput *in = gsf_infile_child_by_index(db->infile, i);
+ const uint8_t *name = (const uint8_t *) gsf_input_name(in);
/* table streams are not in the _Streams table */
- if (stat.type == STGTY_STREAM) {
- if (*stat.pwcsName == 0x4840)
+ if (!GSF_IS_INFILE(in) || gsf_infile_num_children(GSF_INFILE(in)) == -1) {
+ /* UTF-8 encoding of 0x4840. */
+ if (name[0] == 0xe4 && name[1] == 0xa1 && name[2] == 0x80)
{
- decode_streamname( stat.pwcsName + 1, decname );
- if ( !strcmpW( decname, szStringPool ) ||
- !strcmpW( decname, szStringData ) )
- {
- CoTaskMemFree(stat.pwcsName);
+ decode_streamname( name + 3, decname );
+ if ( !strcmp( decname, szStringPool ) ||
+ !strcmp( decname, szStringData ) )
continue;
- }
r = _libmsi_open_table( db, decname, false );
}
else
{
- hr = IStorage_OpenStream( db->infile, stat.pwcsName, NULL,
- STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream );
- if ( SUCCEEDED(hr) ) {
- r = msi_alloc_stream(db, stat.pwcsName, stream);
- IStream_Release(stream);
- }
+ r = msi_alloc_stream(db, name, GSF_INPUT(in));
+ g_object_unref(G_OBJECT(in));
}
} else {
- msi_open_storage(db, stat.pwcsName);
+ msi_open_storage(db, name);
}
- CoTaskMemFree(stat.pwcsName);
}
-
- IEnumSTATSTG_Release(stgenum);
}
LibmsiResult _libmsi_database_open(LibmsiDatabase *db)
{
- WCHAR *szwDBPath;
- HRESULT hr;
- STATSTG stat;
- IStorage *stg;
+ GsfInput *in;
+ GsfInfile *stg;
+ uint8_t uuid[16];
unsigned ret = LIBMSI_RESULT_OPEN_FAILED;
TRACE("%p %s\n", db, db->path);
- szwDBPath = strdupAtoW(db->path);
- hr = StgOpenStorage( szwDBPath, NULL,
- STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
- msi_free(szwDBPath);
-
- if( FAILED( hr ) )
+ in = gsf_input_stdio_new(db->path, NULL);
+ if (!in)
{
- WARN("open failed hr = %08x for %s\n", hr, debugstr_a(db->path));
+ WARN("open file failed for %s\n", debugstr_a(db->path));
+ return LIBMSI_RESULT_OPEN_FAILED;
+ }
+ stg = gsf_infile_msole_new( in, NULL );
+ g_object_unref(G_OBJECT(in));
+ if( !stg )
+ {
+ WARN("open failed for %s\n", debugstr_a(db->path));
return LIBMSI_RESULT_OPEN_FAILED;
}
- hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
- if( FAILED( hr ) )
+ 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_database, 16 ) != 0 &&
- memcmp( &stat.clsid, &clsid_msi_patch, 16 ) != 0 &&
- memcmp( &stat.clsid, &clsid_msi_transform, 16 ) != 0 )
+ if ( memcmp( uuid, clsid_msi_database, 16 ) != 0 &&
+ memcmp( uuid, clsid_msi_patch, 16 ) != 0 &&
+ memcmp( uuid, clsid_msi_transform, 16 ) != 0 )
{
ERR("storage GUID is not a MSI database GUID %s\n",
- debugstr_guid(&stat.clsid) );
+ debugstr_guid(uuid) );
goto end;
}
- if ( db->patch && memcmp( &stat.clsid, &clsid_msi_patch, 16 ) != 0 )
+ if ( db->patch && memcmp( uuid, clsid_msi_patch, 16 ) != 0 )
{
ERR("storage GUID is not the MSI patch GUID %s\n",
- debugstr_guid(&stat.clsid) );
+ debugstr_guid(uuid) );
goto end;
}
db->infile = stg;
- IStorage_AddRef( db->infile );
+ g_object_ref(G_OBJECT(db->infile));
cache_infile_structure( db );
@@ -2333,39 +2186,38 @@ LibmsiResult _libmsi_database_open(LibmsiDatabase *db)
end:
if (ret) {
if (db->infile)
- IStorage_Release( db->infile );
+ g_object_unref(G_OBJECT(db->infile));
db->infile = NULL;
}
- IStorage_Release( stg );
+ g_object_unref(G_OBJECT(stg));
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;
+ 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 ) )
@@ -2374,8 +2226,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;
}
@@ -2393,65 +2244,79 @@ 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 char *name, GsfInfile *stg, void *opaque)
{
LibmsiDatabase *db = opaque;
- IStorage *outstg;
+ GsfOutfile *outstg;
unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
- HRESULT r;
- TRACE("%s %p %p\n", debugstr_w(name), stg, opaque);
+ TRACE("%s %p %p\n", debugstr_a(name), stg, opaque);
- r = IStorage_CreateStorage( db->outfile, name,
- STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &outstg);
- if ( FAILED(r) )
+ outstg = GSF_OUTFILE(gsf_outfile_new_child( db->outfile, name, true ));
+ 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 char *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 decname[0x40];
decode_streamname(name, decname);
- TRACE("%s(%s) %p %p\n", debugstr_w(name), debugstr_w(decname), stm, opaque);
+ TRACE("%s(%s) %p %p\n", debugstr_a(name), debugstr_a(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) )
+ outstm = gsf_outfile_new_child( db->outfile, name, false );
+ 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;
}
@@ -2459,7 +2324,6 @@ LibmsiResult libmsi_database_commit( LibmsiDatabase *db )
{
unsigned r = LIBMSI_RESULT_SUCCESS;
unsigned bytes_per_strref;
- HRESULT hr;
TRACE("%d\n", db);
@@ -2504,14 +2368,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);
db->mode = LIBMSI_DB_OPEN_TRANSACT;
_libmsi_database_open(db);
@@ -2532,8 +2388,8 @@ struct msi_primary_key_record_info
static unsigned msi_primary_key_iterator( LibmsiRecord *rec, void *param )
{
struct msi_primary_key_record_info *info = param;
- const WCHAR *name;
- const WCHAR *table;
+ const char *name;
+ const char *table;
unsigned type;
type = libmsi_record_get_integer( rec, 4 );
@@ -2545,11 +2401,11 @@ static unsigned msi_primary_key_iterator( LibmsiRecord *rec, void *param )
if ( info->n == 1 )
{
table = _libmsi_record_get_string_raw( rec, 1 );
- _libmsi_record_set_stringW( info->rec, 0, table);
+ libmsi_record_set_string( info->rec, 0, table);
}
name = _libmsi_record_get_string_raw( rec, 3 );
- _libmsi_record_set_stringW( info->rec, info->n, name );
+ libmsi_record_set_string( info->rec, info->n, name );
}
}
@@ -2557,13 +2413,9 @@ static unsigned msi_primary_key_iterator( LibmsiRecord *rec, void *param )
}
unsigned _libmsi_database_get_primary_keys( LibmsiDatabase *db,
- const WCHAR *table, LibmsiRecord **prec )
+ const char *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 };
+ static const char sql[] = "select * from `_Columns` where `Table` = '%s'";
struct msi_primary_key_record_info info;
LibmsiQuery *query = NULL;
unsigned r;
@@ -2600,25 +2452,16 @@ unsigned _libmsi_database_get_primary_keys( LibmsiDatabase *db,
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;
g_object_ref(db);
- r = _libmsi_database_get_primary_keys( db, szwTable, prec );
+ r = _libmsi_database_get_primary_keys( db, table, prec );
g_object_unref(db);
- msi_free( szwTable );
return r;
}
@@ -2626,26 +2469,17 @@ LibmsiResult libmsi_database_get_primary_keys(LibmsiDatabase *db,
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;
- }
-
g_object_ref(db);
if( !db )
return LIBMSI_CONDITION_ERROR;
- r = _libmsi_database_is_table_persistent( db, szwTableName );
+ r = _libmsi_database_is_table_persistent( db, szTableName );
g_object_unref(db);
- msi_free( szwTableName );
return r;
}