summaryrefslogtreecommitdiffstats
path: root/libmsi/libmsi-record.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmsi/libmsi-record.c')
-rw-r--r--libmsi/libmsi-record.c250
1 files changed, 93 insertions, 157 deletions
diff --git a/libmsi/libmsi-record.c b/libmsi/libmsi-record.c
index 78b0e21..848ba61 100644
--- a/libmsi/libmsi-record.c
+++ b/libmsi/libmsi-record.c
@@ -20,24 +20,11 @@
#include <stdarg.h>
-#define COBJMACROS
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-
#include "libmsi-record.h"
#include "debug.h"
-#include "unicode.h"
#include "libmsi.h"
#include "msipriv.h"
-#include "objidl.h"
-#include "winnls.h"
-#include "ole2.h"
-
-#include "shlwapi.h"
-
#include "query.h"
enum
@@ -51,7 +38,7 @@ G_DEFINE_TYPE (LibmsiRecord, libmsi_record, G_TYPE_OBJECT);
#define LIBMSI_FIELD_TYPE_NULL 0
#define LIBMSI_FIELD_TYPE_INT 1
-#define LIBMSI_FIELD_TYPE_WSTR 3
+#define LIBMSI_FIELD_TYPE_STR 3
#define LIBMSI_FIELD_TYPE_STREAM 4
static void
@@ -66,11 +53,11 @@ _libmsi_free_field (LibmsiField *field )
case LIBMSI_FIELD_TYPE_NULL:
case LIBMSI_FIELD_TYPE_INT:
break;
- case LIBMSI_FIELD_TYPE_WSTR:
- msi_free( field->u.szwVal);
+ case LIBMSI_FIELD_TYPE_STR:
+ msi_free (field->u.szVal);
break;
case LIBMSI_FIELD_TYPE_STREAM:
- IStream_Release( field->u.stream );
+ g_object_unref (G_OBJECT (field->u.stream));
break;
default:
ERR ("Invalid field type %d\n", field->type);
@@ -159,10 +146,10 @@ unsigned libmsi_record_get_field_count( const LibmsiRecord *rec )
return rec->count;
}
-static bool expr_int_from_string( const WCHAR *str, int *out )
+static bool expr_int_from_string( const char *str, int *out )
{
int x = 0;
- const WCHAR *p = str;
+ const char *p = str;
if( *p == '-' ) /* skip the minus sign */
p++;
@@ -191,7 +178,7 @@ unsigned _libmsi_record_copy_field( LibmsiRecord *in_rec, unsigned in_n,
r = LIBMSI_RESULT_FUNCTION_FAILED;
else if ( in_rec != out_rec || in_n != out_n )
{
- WCHAR *str;
+ char *str;
LibmsiField *in, *out;
in = &in_rec->fields[in_n];
@@ -204,15 +191,15 @@ unsigned _libmsi_record_copy_field( LibmsiRecord *in_rec, unsigned in_n,
case LIBMSI_FIELD_TYPE_INT:
out->u.iVal = in->u.iVal;
break;
- case LIBMSI_FIELD_TYPE_WSTR:
- str = strdupW( in->u.szwVal );
+ case LIBMSI_FIELD_TYPE_STR:
+ str = strdup( in->u.szVal );
if ( !str )
r = LIBMSI_RESULT_OUTOFMEMORY;
else
- out->u.szwVal = str;
+ out->u.szVal = str;
break;
case LIBMSI_FIELD_TYPE_STREAM:
- IStream_AddRef( in->u.stream );
+ g_object_ref(G_OBJECT(in->u.stream));
out->u.stream = in->u.stream;
break;
default:
@@ -241,8 +228,8 @@ int libmsi_record_get_integer( const LibmsiRecord *rec, unsigned iField)
{
case LIBMSI_FIELD_TYPE_INT:
return rec->fields[iField].u.iVal;
- case LIBMSI_FIELD_TYPE_WSTR:
- if( expr_int_from_string( rec->fields[iField].u.szwVal, &ret ) )
+ case LIBMSI_FIELD_TYPE_STR:
+ if( expr_int_from_string( rec->fields[iField].u.szVal, &ret ) )
return ret;
return MSI_NULL_INTEGER;
default:
@@ -329,21 +316,15 @@ LibmsiResult libmsi_record_get_string(const LibmsiRecord *rec, unsigned iField,
switch( rec->fields[iField].type )
{
case LIBMSI_FIELD_TYPE_INT:
- wsprintfA(buffer, "%d", rec->fields[iField].u.iVal);
+ sprintf(buffer, "%d", rec->fields[iField].u.iVal);
len = strlen( buffer );
if (szValue)
- strcpynA(szValue, buffer, *pcchValue);
+ strcpyn(szValue, buffer, *pcchValue);
break;
- case LIBMSI_FIELD_TYPE_WSTR:
- len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
- NULL, 0 , NULL, NULL);
+ case LIBMSI_FIELD_TYPE_STR:
+ len = strlen( rec->fields[iField].u.szVal );
if (szValue)
- WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
- szValue, *pcchValue, NULL, NULL);
- if( szValue && *pcchValue && len>*pcchValue )
- szValue[*pcchValue-1] = 0;
- if( len )
- len--;
+ strcpyn(szValue, rec->fields[iField].u.szVal, *pcchValue );
break;
case LIBMSI_FIELD_TYPE_NULL:
if( szValue && *pcchValue > 0 )
@@ -361,23 +342,23 @@ LibmsiResult libmsi_record_get_string(const LibmsiRecord *rec, unsigned iField,
return ret;
}
-const WCHAR *_libmsi_record_get_string_raw( const LibmsiRecord *rec, unsigned iField )
+const char *_libmsi_record_get_string_raw( const LibmsiRecord *rec, unsigned iField )
{
if( iField > rec->count )
return NULL;
- if( rec->fields[iField].type != LIBMSI_FIELD_TYPE_WSTR )
+ if( rec->fields[iField].type != LIBMSI_FIELD_TYPE_STR )
return NULL;
- return rec->fields[iField].u.szwVal;
+ return rec->fields[iField].u.szVal;
}
-unsigned _libmsi_record_get_stringW(const LibmsiRecord *rec, unsigned iField,
- WCHAR *szValue, unsigned *pcchValue)
+unsigned _libmsi_record_get_string(const LibmsiRecord *rec, unsigned iField,
+ char *szValue, unsigned *pcchValue)
{
unsigned len=0, ret;
- WCHAR buffer[16];
- static const WCHAR szFormat[] = { '%','d',0 };
+ char buffer[16];
+ static const char szFormat[] = "%d";
TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
@@ -394,15 +375,15 @@ unsigned _libmsi_record_get_stringW(const LibmsiRecord *rec, unsigned iField,
switch( rec->fields[iField].type )
{
case LIBMSI_FIELD_TYPE_INT:
- wsprintfW(buffer, szFormat, rec->fields[iField].u.iVal);
- len = strlenW( buffer );
+ sprintf(buffer, szFormat, rec->fields[iField].u.iVal);
+ len = strlen( buffer );
if (szValue)
- strcpynW(szValue, buffer, *pcchValue);
+ strcpyn(szValue, buffer, *pcchValue);
break;
- case LIBMSI_FIELD_TYPE_WSTR:
- len = strlenW( rec->fields[iField].u.szwVal );
+ case LIBMSI_FIELD_TYPE_STR:
+ len = strlen( rec->fields[iField].u.szVal );
if (szValue)
- strcpynW(szValue, rec->fields[iField].u.szwVal, *pcchValue);
+ strcpyn(szValue, rec->fields[iField].u.szVal, *pcchValue);
break;
case LIBMSI_FIELD_TYPE_NULL:
if( szValue && *pcchValue > 0 )
@@ -419,17 +400,6 @@ unsigned _libmsi_record_get_stringW(const LibmsiRecord *rec, unsigned iField,
return ret;
}
-static unsigned msi_get_stream_size( IStream *stm )
-{
- STATSTG stat;
- HRESULT r;
-
- r = IStream_Stat( stm, &stat, STATFLAG_NONAME );
- if( FAILED(r) )
- return 0;
- return stat.cbSize.QuadPart;
-}
-
unsigned libmsi_record_get_field_size(const LibmsiRecord *rec, unsigned iField)
{
TRACE("%p %d\n", rec, iField);
@@ -444,35 +414,25 @@ unsigned libmsi_record_get_field_size(const LibmsiRecord *rec, unsigned iField)
{
case LIBMSI_FIELD_TYPE_INT:
return sizeof (int);
- case LIBMSI_FIELD_TYPE_WSTR:
- return strlenW( rec->fields[iField].u.szwVal );
+ case LIBMSI_FIELD_TYPE_STR:
+ return strlen( rec->fields[iField].u.szVal );
case LIBMSI_FIELD_TYPE_NULL:
break;
case LIBMSI_FIELD_TYPE_STREAM:
- return msi_get_stream_size( rec->fields[iField].u.stream );
+ return gsf_input_size( rec->fields[iField].u.stream );
}
return 0;
}
LibmsiResult libmsi_record_set_string( LibmsiRecord *rec, unsigned iField, const char *szValue )
{
- WCHAR *str;
+ char *str;
TRACE("%d %d %s\n", rec, iField, debugstr_a(szValue));
if( !rec )
return LIBMSI_RESULT_INVALID_HANDLE;
- str = strdupAtoW( szValue );
- return _libmsi_record_set_stringW( rec, iField, str );
-}
-
-unsigned _libmsi_record_set_stringW( LibmsiRecord *rec, unsigned iField, const WCHAR *szValue )
-{
- WCHAR *str;
-
- TRACE("%p %d %s\n", rec, iField, debugstr_w(szValue));
-
if( iField > rec->count )
return LIBMSI_RESULT_INVALID_FIELD;
@@ -480,70 +440,60 @@ unsigned _libmsi_record_set_stringW( LibmsiRecord *rec, unsigned iField, const W
if( szValue && szValue[0] )
{
- str = strdupW( szValue );
- rec->fields[iField].type = LIBMSI_FIELD_TYPE_WSTR;
- rec->fields[iField].u.szwVal = str;
+ str = strdup( szValue );
+ rec->fields[iField].type = LIBMSI_FIELD_TYPE_STR;
+ rec->fields[iField].u.szVal = str;
}
else
{
rec->fields[iField].type = LIBMSI_FIELD_TYPE_NULL;
- rec->fields[iField].u.szwVal = NULL;
+ rec->fields[iField].u.szVal = NULL;
}
return 0;
}
-/* read the data in a file into an IStream */
-static unsigned _libmsi_addstream_from_file(const char *szFile, IStream **pstm)
+/* read the data in a file into a memory-backed GsfInput */
+static unsigned _libmsi_addstream_from_file(const char *szFile, GsfInput **pstm)
{
- unsigned sz, szHighWord = 0, read;
- HANDLE handle;
- HGLOBAL hGlob = 0;
- HRESULT hr;
- ULARGE_INTEGER ulSize;
+ GsfInput *stm;
+ char *data;
+ off_t sz;
- TRACE("reading %s\n", debugstr_a(szFile));
-
- /* read the file into memory */
- handle = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if( handle == INVALID_HANDLE_VALUE )
- return GetLastError();
- sz = GetFileSize(handle, &szHighWord);
- if( sz != INVALID_FILE_SIZE && szHighWord == 0 )
+ stm = gsf_input_stdio_new(szFile, NULL);
+ if (!stm)
{
- hGlob = GlobalAlloc(GMEM_FIXED, sz);
- if( hGlob )
- {
- bool r = ReadFile(handle, hGlob, sz, &read, NULL);
- if( !r )
- {
- GlobalFree(hGlob);
- hGlob = 0;
- }
- }
+ WARN("open file failed for %s\n", debugstr_a(szFile));
+ return LIBMSI_RESULT_OPEN_FAILED;
}
- CloseHandle(handle);
- if( !hGlob )
- return LIBMSI_RESULT_FUNCTION_FAILED;
- /* make a stream out of it, and set the correct file size */
- hr = CreateStreamOnHGlobal(hGlob, true, pstm);
- if( FAILED( hr ) )
+ sz = gsf_input_size(stm);
+ if (sz == 0)
{
- GlobalFree(hGlob);
- return LIBMSI_RESULT_FUNCTION_FAILED;
+ data = g_malloc(1);
}
+ else
+ {
+ data = g_try_malloc(sz);
+ if (!data)
+ return LIBMSI_RESULT_NOT_ENOUGH_MEMORY;
- /* set the correct size - CreateStreamOnHGlobal screws it up */
- ulSize.QuadPart = sz;
- IStream_SetSize(*pstm, ulSize);
+ if (!gsf_input_read(stm, sz, data))
+ {
+ g_object_unref(G_OBJECT(stm));
+ return LIBMSI_RESULT_FUNCTION_FAILED;
+ }
+ }
+
+ g_object_unref(G_OBJECT(stm));
+ *pstm = gsf_input_memory_new(data, sz, true);
- TRACE("read %s, %d bytes into IStream %p\n", debugstr_a(szFile), sz, *pstm);
+ TRACE("read %s, %d bytes into GsfInput %p\n", debugstr_a(szFile), sz, *pstm);
return LIBMSI_RESULT_SUCCESS;
}
-unsigned _libmsi_record_load_stream(LibmsiRecord *rec, unsigned iField, IStream *stream)
+unsigned _libmsi_record_load_stream(LibmsiRecord *rec, unsigned iField, GsfInput *stream)
{
if ( (iField == 0) || (iField > rec->count) )
return LIBMSI_RESULT_INVALID_PARAMETER;
@@ -557,8 +507,8 @@ unsigned _libmsi_record_load_stream(LibmsiRecord *rec, unsigned iField, IStream
unsigned _libmsi_record_load_stream_from_file(LibmsiRecord *rec, unsigned iField, const char *szFilename)
{
- IStream *stm = NULL;
- HRESULT r;
+ GsfInput *stm;
+ unsigned r;
if( (iField == 0) || (iField > rec->count) )
return LIBMSI_RESULT_INVALID_PARAMETER;
@@ -566,9 +516,6 @@ unsigned _libmsi_record_load_stream_from_file(LibmsiRecord *rec, unsigned iField
/* no filename means we should seek back to the start of the stream */
if( !szFilename )
{
- LARGE_INTEGER ofs;
- ULARGE_INTEGER cur;
-
if( rec->fields[iField].type != LIBMSI_FIELD_TYPE_STREAM )
return LIBMSI_RESULT_INVALID_FIELD;
@@ -576,10 +523,7 @@ unsigned _libmsi_record_load_stream_from_file(LibmsiRecord *rec, unsigned iField
if( !stm )
return LIBMSI_RESULT_INVALID_FIELD;
- ofs.QuadPart = 0;
- r = IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
- if( FAILED( r ) )
- return LIBMSI_RESULT_FUNCTION_FAILED;
+ gsf_input_seek( stm, 0, G_SEEK_SET );
}
else
{
@@ -613,9 +557,8 @@ LibmsiResult libmsi_record_load_stream(LibmsiRecord *rec, unsigned iField, const
unsigned _libmsi_record_save_stream(const LibmsiRecord *rec, unsigned iField, char *buf, unsigned *sz)
{
- unsigned count;
- HRESULT r;
- IStream *stm;
+ uint64_t left;
+ GsfInput *stm;
TRACE("%p %d %p %p\n", rec, iField, buf, sz);
@@ -638,34 +581,26 @@ unsigned _libmsi_record_save_stream(const LibmsiRecord *rec, unsigned iField, ch
if( !stm )
return LIBMSI_RESULT_INVALID_PARAMETER;
+ left = gsf_input_size(stm) - gsf_input_tell(stm);
+
/* if there's no buffer pointer, calculate the length to the end */
if( !buf )
{
- LARGE_INTEGER ofs;
- ULARGE_INTEGER end, cur;
-
- ofs.QuadPart = cur.QuadPart = 0;
- end.QuadPart = 0;
- IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
- IStream_Seek( stm, ofs, STREAM_SEEK_END, &end );
- ofs.QuadPart = cur.QuadPart;
- IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
- *sz = end.QuadPart - cur.QuadPart;
+ *sz = left;
return LIBMSI_RESULT_SUCCESS;
}
/* read the data */
- count = 0;
- r = IStream_Read( stm, buf, *sz, &count );
- if( FAILED( r ) )
+ if (*sz > left)
+ *sz = left;
+
+ if (*sz > 0 && !gsf_input_read( stm, *sz, buf ))
{
*sz = 0;
return LIBMSI_RESULT_FUNCTION_FAILED;
}
- *sz = count;
-
return LIBMSI_RESULT_SUCCESS;
}
@@ -685,7 +620,7 @@ LibmsiResult libmsi_record_save_stream(LibmsiRecord *rec, unsigned iField, char
return ret;
}
-unsigned _libmsi_record_set_IStream( LibmsiRecord *rec, unsigned iField, IStream *stm )
+unsigned _libmsi_record_set_gsf_input( LibmsiRecord *rec, unsigned iField, GsfInput *stm )
{
TRACE("%p %d %p\n", rec, iField, stm);
@@ -696,12 +631,12 @@ unsigned _libmsi_record_set_IStream( LibmsiRecord *rec, unsigned iField, IStream
rec->fields[iField].type = LIBMSI_FIELD_TYPE_STREAM;
rec->fields[iField].u.stream = stm;
- IStream_AddRef( stm );
+ g_object_ref(G_OBJECT(stm));
return LIBMSI_RESULT_SUCCESS;
}
-unsigned _libmsi_record_get_IStream( const LibmsiRecord *rec, unsigned iField, IStream **pstm)
+unsigned _libmsi_record_get_gsf_input( const LibmsiRecord *rec, unsigned iField, GsfInput **pstm)
{
TRACE("%p %d %p\n", rec, iField, pstm);
@@ -712,7 +647,7 @@ unsigned _libmsi_record_get_IStream( const LibmsiRecord *rec, unsigned iField, I
return LIBMSI_RESULT_INVALID_FIELD;
*pstm = rec->fields[iField].u.stream;
- IStream_AddRef( *pstm );
+ g_object_ref(G_OBJECT(*pstm));
return LIBMSI_RESULT_SUCCESS;
}
@@ -731,12 +666,13 @@ LibmsiRecord *_libmsi_record_clone(LibmsiRecord *rec)
{
if (rec->fields[i].type == LIBMSI_FIELD_TYPE_STREAM)
{
- if (FAILED(IStream_Clone(rec->fields[i].u.stream,
- &clone->fields[i].u.stream)))
+ GsfInput *stm = gsf_input_dup(rec->fields[i].u.stream, NULL);
+ if (!stm)
{
g_object_unref(clone);
return NULL;
}
+ clone->fields[i].u.stream = stm;
clone->fields[i].type = LIBMSI_FIELD_TYPE_STREAM;
}
else
@@ -768,8 +704,8 @@ bool _libmsi_record_compare_fields(const LibmsiRecord *a, const LibmsiRecord *b,
return false;
break;
- case LIBMSI_FIELD_TYPE_WSTR:
- if (strcmpW(a->fields[field].u.szwVal, b->fields[field].u.szwVal))
+ case LIBMSI_FIELD_TYPE_STR:
+ if (strcmp(a->fields[field].u.szVal, b->fields[field].u.szVal))
return false;
break;
@@ -797,23 +733,23 @@ bool _libmsi_record_compare(const LibmsiRecord *a, const LibmsiRecord *b)
return true;
}
-WCHAR *msi_dup_record_field( LibmsiRecord *rec, int field )
+char *msi_dup_record_field( LibmsiRecord *rec, int field )
{
unsigned sz = 0;
- WCHAR *str;
+ char *str;
unsigned r;
if (libmsi_record_is_null( rec, field )) return NULL;
- r = _libmsi_record_get_stringW( rec, field, NULL, &sz );
+ r = _libmsi_record_get_string( rec, field, NULL, &sz );
if (r != LIBMSI_RESULT_SUCCESS)
return NULL;
sz++;
- str = msi_alloc( sz * sizeof(WCHAR) );
+ str = msi_alloc( sz * sizeof(char) );
if (!str) return NULL;
str[0] = 0;
- r = _libmsi_record_get_stringW( rec, field, str, &sz );
+ r = _libmsi_record_get_string( rec, field, str, &sz );
if (r != LIBMSI_RESULT_SUCCESS)
{
ERR("failed to get string!\n");