Commit 24e9a344 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Fetch binary streams at the table level.

parent d784600d
...@@ -79,7 +79,7 @@ typedef struct tagMSICOMPONENT ...@@ -79,7 +79,7 @@ typedef struct tagMSICOMPONENT
BOOL FeatureState; BOOL FeatureState;
BOOL Enabled; BOOL Enabled;
INT Cost; INT Cost;
}MSICOMPONENT; } MSICOMPONENT;
typedef struct tagMSIFOLDER typedef struct tagMSIFOLDER
{ {
...@@ -89,7 +89,7 @@ typedef struct tagMSIFOLDER ...@@ -89,7 +89,7 @@ typedef struct tagMSIFOLDER
WCHAR ResolvedTarget[MAX_PATH]; WCHAR ResolvedTarget[MAX_PATH];
WCHAR ResolvedSource[MAX_PATH]; WCHAR ResolvedSource[MAX_PATH];
WCHAR Property[MAX_PATH]; /* initialy set property */ WCHAR Property[MAX_PATH]; /* initially set property */
INT ParentIndex; INT ParentIndex;
INT State; INT State;
/* 0 = uninitialized */ /* 0 = uninitialized */
...@@ -821,7 +821,7 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action) ...@@ -821,7 +821,7 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
ui_actionstart(hPackage, action); ui_actionstart(hPackage, action);
ui_progress(hPackage,2,1,0,0); ui_progress(hPackage,2,1,0,0);
/* pre install, setup and configureation block */ /* pre install, setup and configuration block */
if (strcmpW(action,szLaunchConditions)==0) if (strcmpW(action,szLaunchConditions)==0)
rc = ACTION_LaunchConditions(hPackage); rc = ACTION_LaunchConditions(hPackage);
else if (strcmpW(action,szCostInitialize)==0) else if (strcmpW(action,szCostInitialize)==0)
...@@ -854,7 +854,7 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action) ...@@ -854,7 +854,7 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
rc = ACTION_RegisterProgIdInfo(hPackage); rc = ACTION_RegisterProgIdInfo(hPackage);
/* /*
Current called during itunes but unimplemented and seem important Called during itunes but unimplemented and seem important
ResolveSource (sets SourceDir) ResolveSource (sets SourceDir)
CreateShortcuts (would be nice to have soon) CreateShortcuts (would be nice to have soon)
...@@ -931,7 +931,7 @@ static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action) ...@@ -931,7 +931,7 @@ static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action)
case 1: /* DLL file stored in a Binary table stream */ case 1: /* DLL file stored in a Binary table stream */
rc = HANDLE_CustomType1(hPackage,source,target,type); rc = HANDLE_CustomType1(hPackage,source,target,type);
break; 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); rc = HANDLE_CustomType2(hPackage,source,target,type);
break; break;
case 35: /* Directory set with formatted text. */ case 35: /* Directory set with formatted text. */
...@@ -1431,7 +1431,7 @@ static void load_feature(MSIPACKAGE* package, MSIHANDLE row) ...@@ -1431,7 +1431,7 @@ static void load_feature(MSIPACKAGE* package, MSIHANDLE row)
* The native MSI does ALOT of modification to tables here. Mostly adding alot * The native MSI does ALOT of modification to tables here. Mostly adding alot
* of temporary columns to the Feature and Component tables. * 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 * track the long ones. Also looking at this directory table
* it appears that the directory table does not get the parents * it appears that the directory table does not get the parents
* resolved base on property only based on their entrys in the * resolved base on property only based on their entrys in the
......
...@@ -224,6 +224,7 @@ MSIVIEWOPS create_ops = ...@@ -224,6 +224,7 @@ MSIVIEWOPS create_ops =
CREATE_fetch_int, CREATE_fetch_int,
NULL, NULL,
NULL, NULL,
NULL,
CREATE_execute, CREATE_execute,
CREATE_close, CREATE_close,
CREATE_get_dimensions, CREATE_get_dimensions,
......
...@@ -252,6 +252,7 @@ MSIVIEWOPS distinct_ops = ...@@ -252,6 +252,7 @@ MSIVIEWOPS distinct_ops =
DISTINCT_fetch_int, DISTINCT_fetch_int,
NULL, NULL,
NULL, NULL,
NULL,
DISTINCT_execute, DISTINCT_execute,
DISTINCT_close, DISTINCT_close,
DISTINCT_get_dimensions, DISTINCT_get_dimensions,
......
...@@ -190,6 +190,7 @@ MSIVIEWOPS insert_ops = ...@@ -190,6 +190,7 @@ MSIVIEWOPS insert_ops =
INSERT_fetch_int, INSERT_fetch_int,
NULL, NULL,
NULL, NULL,
NULL,
INSERT_execute, INSERT_execute,
INSERT_close, INSERT_close,
INSERT_get_dimensions, INSERT_get_dimensions,
......
...@@ -67,6 +67,14 @@ typedef struct tagMSIVIEWOPS ...@@ -67,6 +67,14 @@ typedef struct tagMSIVIEWOPS
UINT (*fetch_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT *val ); 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 * get_int - sets one integer at {row,col} in the table
* *
* Similar semantics to fetch_int * Similar semantics to fetch_int
......
...@@ -194,63 +194,49 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record) ...@@ -194,63 +194,49 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
ERR("Error getting column type for %d\n", i ); ERR("Error getting column type for %d\n", i );
continue; continue;
} }
ret = view->ops->fetch_int( view, query->row, i, &ival ); if( type != MSITYPE_BINARY)
if( ret )
{ {
ERR("Error fetching data for %d\n", i ); ret = view->ops->fetch_int( view, query->row, i, &ival );
continue; if( ret )
} {
if( ! (type & MSITYPE_VALID ) ) ERR("Error fetching data for %d\n", i );
ERR("Invalid type!\n"); continue;
}
/* check if it's nul (0) - if so, don't set anything */ if( ! (type & MSITYPE_VALID ) )
if( !ival ) ERR("Invalid type!\n");
continue;
if( type & MSITYPE_STRING ) /* check if it's nul (0) - if so, don't set anything */
{ if( !ival )
LPWSTR sval; continue;
if( type != MSITYPE_BINARY) if( type & MSITYPE_STRING )
{ {
LPWSTR sval;
sval = MSI_makestring( query->db, ival ); sval = MSI_makestring( query->db, ival );
MsiRecordSetStringW( handle, i, sval ); MsiRecordSetStringW( handle, i, sval );
HeapFree( GetProcessHeap(), 0, sval ); HeapFree( GetProcessHeap(), 0, sval );
} }
else else
{ {
UINT refcol = 0; if( (type & MSI_DATASIZEMASK) == 2 )
IStream *stm = NULL; MsiRecordSetInteger( handle, i, ival - (1<<15) );
WCHAR full_name[0x40]; else
static const WCHAR szBinary[] = { 'B','i','n','a','r','y','.', 0}; MsiRecordSetInteger( handle, i, ival - (1<<31) );
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 );
}
} }
} }
else else
{ {
if( (type & MSI_DATASIZEMASK) == 2 ) IStream *stm;
MsiRecordSetInteger( handle, i, ival - (1<<15) );
ret = view->ops->fetch_stream( view, query->row, i, &stm );
if( ( ret == ERROR_SUCCESS ) && stm )
{
MSI_RecordSetIStream( handle, i, stm );
IStream_Release( stm );
}
else else
MsiRecordSetInteger( handle, i, ival - (1<<31) ); ERR("failed to get stream\n");
} }
} }
query->row ++; query->row ++;
......
...@@ -255,6 +255,7 @@ MSIVIEWOPS order_ops = ...@@ -255,6 +255,7 @@ MSIVIEWOPS order_ops =
ORDER_fetch_int, ORDER_fetch_int,
NULL, NULL,
NULL, NULL,
NULL,
ORDER_execute, ORDER_execute,
ORDER_close, ORDER_close,
ORDER_get_dimensions, ORDER_get_dimensions,
......
...@@ -65,6 +65,23 @@ static UINT SELECT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT ...@@ -65,6 +65,23 @@ static UINT SELECT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT
return sv->table->ops->fetch_int( sv->table, row, col, val ); 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 ) static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
{ {
MSISELECTVIEW *sv = (MSISELECTVIEW*)view; MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
...@@ -181,6 +198,7 @@ static UINT SELECT_delete( struct tagMSIVIEW *view ) ...@@ -181,6 +198,7 @@ static UINT SELECT_delete( struct tagMSIVIEW *view )
MSIVIEWOPS select_ops = MSIVIEWOPS select_ops =
{ {
SELECT_fetch_int, SELECT_fetch_int,
SELECT_fetch_stream,
SELECT_set_int, SELECT_set_int,
SELECT_insert_row, SELECT_insert_row,
SELECT_execute, SELECT_execute,
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "msipriv.h" #include "msipriv.h"
#include "winnls.h" #include "winnls.h"
#include "wine/unicode.h"
#include "query.h" #include "query.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
...@@ -1090,6 +1092,64 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * ...@@ -1090,6 +1092,64 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
return ERROR_SUCCESS; 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 ) static UINT TABLE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
{ {
MSITABLEVIEW *tv = (MSITABLEVIEW*)view; MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
...@@ -1268,6 +1328,7 @@ static UINT TABLE_delete( struct tagMSIVIEW *view ) ...@@ -1268,6 +1328,7 @@ static UINT TABLE_delete( struct tagMSIVIEW *view )
MSIVIEWOPS table_ops = MSIVIEWOPS table_ops =
{ {
TABLE_fetch_int, TABLE_fetch_int,
TABLE_fetch_stream,
TABLE_set_int, TABLE_set_int,
TABLE_insert_row, TABLE_insert_row,
TABLE_execute, TABLE_execute,
......
...@@ -182,6 +182,7 @@ static MSIVIEWOPS update_ops = ...@@ -182,6 +182,7 @@ static MSIVIEWOPS update_ops =
UPDATE_fetch_int, UPDATE_fetch_int,
NULL, NULL,
NULL, NULL,
NULL,
UPDATE_execute, UPDATE_execute,
UPDATE_close, UPDATE_close,
UPDATE_get_dimensions, UPDATE_get_dimensions,
......
...@@ -66,6 +66,23 @@ static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * ...@@ -66,6 +66,23 @@ static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
return wv->table->ops->fetch_int( wv->table, row, col, val ); 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 ) static UINT WHERE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
{ {
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
...@@ -328,6 +345,7 @@ static UINT WHERE_delete( struct tagMSIVIEW *view ) ...@@ -328,6 +345,7 @@ static UINT WHERE_delete( struct tagMSIVIEW *view )
MSIVIEWOPS where_ops = MSIVIEWOPS where_ops =
{ {
WHERE_fetch_int, WHERE_fetch_int,
WHERE_fetch_stream,
WHERE_set_int, WHERE_set_int,
NULL, NULL,
WHERE_execute, WHERE_execute,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment