MSI: Fetch binary streams at the table level
Mike McCormack
mike at codeweavers.com
Sat Jul 3 20:33:31 CDT 2004
ChangeLog:
* Fetch binary streams at the table level
-------------- next part --------------
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/action.c 2004-07-03 20:30:56.000000000 -0500
@@ -79,7 +79,7 @@
BOOL FeatureState;
BOOL Enabled;
INT Cost;
-}MSICOMPONENT;
+} MSICOMPONENT;
typedef struct tagMSIFOLDER
{
@@ -89,7 +89,7 @@
WCHAR ResolvedTarget[MAX_PATH];
WCHAR ResolvedSource[MAX_PATH];
- WCHAR Property[MAX_PATH]; /* initialy set property */
+ WCHAR Property[MAX_PATH]; /* initially set property */
INT ParentIndex;
INT State;
/* 0 = uninitialized */
@@ -821,7 +821,7 @@
ui_actionstart(hPackage, action);
ui_progress(hPackage,2,1,0,0);
- /* pre install, setup and configureation block */
+ /* pre install, setup and configuration block */
if (strcmpW(action,szLaunchConditions)==0)
rc = ACTION_LaunchConditions(hPackage);
else if (strcmpW(action,szCostInitialize)==0)
@@ -854,7 +854,7 @@
rc = ACTION_RegisterProgIdInfo(hPackage);
/*
- Current called during itunes but unimplemented and seem important
+ Called during itunes but unimplemented and seem important
ResolveSource (sets SourceDir)
CreateShortcuts (would be nice to have soon)
@@ -931,7 +931,7 @@
case 1: /* DLL file stored in a Binary table stream */
rc = HANDLE_CustomType1(hPackage,source,target,type);
break;
- case 2: /* Exe file stored in a Binary table strem */
+ case 2: /* EXE file stored in a Binary table strem */
rc = HANDLE_CustomType2(hPackage,source,target,type);
break;
case 35: /* Directory set with formatted text. */
@@ -1431,7 +1431,7 @@
* The native MSI does ALOT of modification to tables here. Mostly adding alot
* of temporary columns to the Feature and Component tables.
*
- * note: native msi also tracks the short filename. but i am only going to
+ * note: native msi also tracks the short filename. but I am only going to
* track the long ones. Also looking at this directory table
* it appears that the directory table does not get the parents
* resolved base on property only based on their entrys in the
diff -ur dlls/msi.old/create.c dlls/msi/create.c
--- dlls/msi.old/create.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/create.c 2004-07-03 20:30:56.000000000 -0500
@@ -224,6 +224,7 @@
CREATE_fetch_int,
NULL,
NULL,
+ NULL,
CREATE_execute,
CREATE_close,
CREATE_get_dimensions,
diff -ur dlls/msi.old/distinct.c dlls/msi/distinct.c
--- dlls/msi.old/distinct.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/distinct.c 2004-07-03 20:30:56.000000000 -0500
@@ -252,6 +252,7 @@
DISTINCT_fetch_int,
NULL,
NULL,
+ NULL,
DISTINCT_execute,
DISTINCT_close,
DISTINCT_get_dimensions,
diff -ur dlls/msi.old/insert.c dlls/msi/insert.c
--- dlls/msi.old/insert.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/insert.c 2004-07-03 20:30:56.000000000 -0500
@@ -190,6 +190,7 @@
INSERT_fetch_int,
NULL,
NULL,
+ NULL,
INSERT_execute,
INSERT_close,
INSERT_get_dimensions,
diff -ur dlls/msi.old/msipriv.h dlls/msi/msipriv.h
--- dlls/msi.old/msipriv.h 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/msipriv.h 2004-07-03 20:30:56.000000000 -0500
@@ -67,6 +67,14 @@
UINT (*fetch_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT *val );
/*
+ * fetch_int - reads one integer from {row,col} in the table
+ *
+ * This function is similar to fetch_int, except fetches a
+ * stream instead of an integer.
+ */
+ UINT (*fetch_stream)( struct tagMSIVIEW *, UINT row, UINT col, IStream **stm );
+
+ /*
* get_int - sets one integer at {row,col} in the table
*
* Similar semantics to fetch_int
diff -ur dlls/msi.old/msiquery.c dlls/msi/msiquery.c
--- dlls/msi.old/msiquery.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/msiquery.c 2004-07-03 20:30:56.000000000 -0500
@@ -194,63 +194,49 @@
ERR("Error getting column type for %d\n", i );
continue;
}
- ret = view->ops->fetch_int( view, query->row, i, &ival );
- if( ret )
+ if( type != MSITYPE_BINARY)
{
- ERR("Error fetching data for %d\n", i );
- continue;
- }
- if( ! (type & MSITYPE_VALID ) )
- ERR("Invalid type!\n");
+ ret = view->ops->fetch_int( view, query->row, i, &ival );
+ if( ret )
+ {
+ ERR("Error fetching data for %d\n", i );
+ continue;
+ }
+ if( ! (type & MSITYPE_VALID ) )
+ ERR("Invalid type!\n");
- /* check if it's nul (0) - if so, don't set anything */
- if( !ival )
- continue;
+ /* check if it's nul (0) - if so, don't set anything */
+ if( !ival )
+ continue;
- if( type & MSITYPE_STRING )
- {
- LPWSTR sval;
-
- if( type != MSITYPE_BINARY)
+ if( type & MSITYPE_STRING )
{
+ LPWSTR sval;
+
sval = MSI_makestring( query->db, ival );
MsiRecordSetStringW( handle, i, sval );
HeapFree( GetProcessHeap(), 0, sval );
}
else
{
- UINT refcol = 0;
- IStream *stm = NULL;
- WCHAR full_name[0x40];
- static const WCHAR szBinary[] = { 'B','i','n','a','r','y','.', 0};
- const int maxlen = (sizeof full_name - sizeof szBinary)/sizeof(WCHAR);
-
- ret = view->ops->fetch_int( view, query->row, ival, &refcol );
- sval = MSI_makestring( query->db, refcol );
-
- if( sval && ( strlenW( sval ) < maxlen ) )
- {
- strcpyW( full_name, szBinary );
- strcatW( full_name, sval );
-
- db_get_raw_stream( query->db, full_name, &stm );
- if( stm )
- {
- MSI_RecordSetIStream( handle, i, stm );
- IStream_Release( stm );
- }
- else
- ERR("failed to get stream\n");
- HeapFree( GetProcessHeap(), 0, sval );
- }
+ if( (type & MSI_DATASIZEMASK) == 2 )
+ MsiRecordSetInteger( handle, i, ival - (1<<15) );
+ else
+ MsiRecordSetInteger( handle, i, ival - (1<<31) );
}
}
else
{
- if( (type & MSI_DATASIZEMASK) == 2 )
- MsiRecordSetInteger( handle, i, ival - (1<<15) );
+ IStream *stm;
+
+ ret = view->ops->fetch_stream( view, query->row, i, &stm );
+ if( ( ret == ERROR_SUCCESS ) && stm )
+ {
+ MSI_RecordSetIStream( handle, i, stm );
+ IStream_Release( stm );
+ }
else
- MsiRecordSetInteger( handle, i, ival - (1<<31) );
+ ERR("failed to get stream\n");
}
}
query->row ++;
diff -ur dlls/msi.old/order.c dlls/msi/order.c
--- dlls/msi.old/order.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/order.c 2004-07-03 20:30:56.000000000 -0500
@@ -255,6 +255,7 @@
ORDER_fetch_int,
NULL,
NULL,
+ NULL,
ORDER_execute,
ORDER_close,
ORDER_get_dimensions,
diff -ur dlls/msi.old/select.c dlls/msi/select.c
--- dlls/msi.old/select.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/select.c 2004-07-03 20:30:56.000000000 -0500
@@ -65,6 +65,23 @@
return sv->table->ops->fetch_int( sv->table, row, col, val );
}
+static UINT SELECT_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %d %d %p\n", sv, row, col, stm );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( (col==0) || (col>sv->num_cols) )
+ return ERROR_FUNCTION_FAILED;
+
+ col = sv->cols[ col - 1 ];
+
+ return sv->table->ops->fetch_stream( sv->table, row, col, stm );
+}
+
static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
{
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
@@ -181,6 +198,7 @@
MSIVIEWOPS select_ops =
{
SELECT_fetch_int,
+ SELECT_fetch_stream,
SELECT_set_int,
SELECT_insert_row,
SELECT_execute,
diff -ur dlls/msi.old/table.c dlls/msi/table.c
--- dlls/msi.old/table.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/table.c 2004-07-03 20:30:56.000000000 -0500
@@ -34,6 +34,8 @@
#include "msipriv.h"
#include "winnls.h"
+#include "wine/unicode.h"
+
#include "query.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -1090,6 +1092,64 @@
return ERROR_SUCCESS;
}
+/*
+ * We need a special case for streams, as we need to reference column with
+ * the name of the stream in the same table, and the table name
+ * which may not be available at higher levels of the query
+ */
+static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm )
+{
+ MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
+ UINT ival = 0, refcol = 0, r;
+ LPWSTR sval;
+
+ if( !view->ops->fetch_int )
+ return ERROR_INVALID_PARAMETER;
+
+ /*
+ * The column marked with the type stream data seems to have a single number
+ * which references the column containing the name of the stream data
+ *
+ * Fetch the column to reference first.
+ */
+ r = view->ops->fetch_int( view, row, col, &ival );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* now get the column with the name of the stream */
+ r = view->ops->fetch_int( view, row, ival, &refcol );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* lookup the string value from the string table */
+ sval = MSI_makestring( tv->db, refcol );
+ if( !sval )
+ return ERROR_INVALID_PARAMETER;
+
+ if( ( strlenW( sval ) + strlenW( tv->name ) + 1 ) > MAX_STREAM_NAME )
+ {
+ ERR("Name of stream is too long %s.%s\n",
+ debugstr_w( tv->name ), debugstr_w( sval ) );
+ r = ERROR_INVALID_PARAMETER;
+ }
+ else
+ {
+ WCHAR full_name[0x40];
+ static const WCHAR szDot[] = { '.', 0 };
+
+ strcpyW( full_name, tv->name );
+ strcatW( full_name, szDot );
+ strcatW( full_name, sval );
+
+ r = db_get_raw_stream( tv->db, full_name, stm );
+ if( r )
+ ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
+ }
+ HeapFree( GetProcessHeap(), 0, sval );
+
+ return r;
+}
+
static UINT TABLE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
@@ -1268,6 +1328,7 @@
MSIVIEWOPS table_ops =
{
TABLE_fetch_int,
+ TABLE_fetch_stream,
TABLE_set_int,
TABLE_insert_row,
TABLE_execute,
diff -ur dlls/msi.old/update.c dlls/msi/update.c
--- dlls/msi.old/update.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/update.c 2004-07-03 20:30:56.000000000 -0500
@@ -182,6 +182,7 @@
UPDATE_fetch_int,
NULL,
NULL,
+ NULL,
UPDATE_execute,
UPDATE_close,
UPDATE_get_dimensions,
diff -ur dlls/msi.old/where.c dlls/msi/where.c
--- dlls/msi.old/where.c 2004-07-03 20:30:43.000000000 -0500
+++ dlls/msi/where.c 2004-07-03 20:30:56.000000000 -0500
@@ -66,6 +66,23 @@
return wv->table->ops->fetch_int( wv->table, row, col, val );
}
+static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %d %d %p\n", wv, row, col, stm );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( row > wv->row_count )
+ return ERROR_NO_MORE_ITEMS;
+
+ row = wv->reorder[ row ];
+
+ return wv->table->ops->fetch_stream( wv->table, row, col, stm );
+}
+
static UINT WHERE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
@@ -328,6 +345,7 @@
MSIVIEWOPS where_ops =
{
WHERE_fetch_int,
+ WHERE_fetch_stream,
WHERE_set_int,
NULL,
WHERE_execute,
More information about the wine-patches
mailing list