Start implementing actions.

This commit is contained in:
Aric Stewart 2004-06-28 20:34:35 +00:00 committed by Alexandre Julliard
parent c390bb2aea
commit 401bd3f772
9 changed files with 2277 additions and 156 deletions

View file

@ -3,10 +3,11 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = msi.dll
IMPORTS = ole32 user32 advapi32 kernel32
IMPORTS = shell32 cabinet ole32 user32 advapi32 kernel32
EXTRALIBS = -luuid $(LIBUNICODE)
C_SRCS = \
action.c \
create.c \
distinct.c \
handle.c \

1562
dlls/msi/action.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -52,15 +52,46 @@ typedef struct tag_yyinput
static LPWSTR COND_GetString( COND_input *info );
static int COND_lex( void *COND_lval, COND_input *info);
UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, WCHAR* value);
typedef INT (*comp_int)(INT a, INT b);
typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
typedef INT (*comp_m1)(LPWSTR a,int b);
typedef INT (*comp_m2)(int a,LPWSTR b);
static INT comp_lt(INT a, INT b);
static INT comp_gt(INT a, INT b);
static INT comp_le(INT a, INT b);
static INT comp_ge(INT a, INT b);
static INT comp_eq(INT a, INT b);
static INT comp_ne(INT a, INT b);
static INT comp_lt_i(INT a, INT b);
static INT comp_gt_i(INT a, INT b);
static INT comp_le_i(INT a, INT b);
static INT comp_ge_i(INT a, INT b);
static INT comp_eq_i(INT a, INT b);
static INT comp_ne_i(INT a, INT b);
static INT comp_bitand(INT a, INT b);
static INT comp_highcomp(INT a, INT b);
static INT comp_lowcomp(INT a, INT b);
static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);
static INT comp_eq_m1(LPWSTR a, INT b);
static INT comp_ne_m1(LPWSTR a, INT b);
static INT comp_lt_m1(LPWSTR a, INT b);
static INT comp_gt_m1(LPWSTR a, INT b);
static INT comp_le_m1(LPWSTR a, INT b);
static INT comp_ge_m1(LPWSTR a, INT b);
static INT comp_eq_m2(INT a, LPWSTR b);
static INT comp_ne_m2(INT a, LPWSTR b);
static INT comp_lt_m2(INT a, LPWSTR b);
static INT comp_gt_m2(INT a, LPWSTR b);
static INT comp_le_m2(INT a, LPWSTR b);
static INT comp_ge_m2(INT a, LPWSTR b);
%}
@ -71,20 +102,27 @@ static INT comp_ne(INT a, INT b);
LPWSTR string;
INT value;
comp_int fn_comp_int;
comp_str fn_comp_str;
comp_m1 fn_comp_m1;
comp_m2 fn_comp_m2;
}
%token COND_SPACE COND_EOF COND_SPACE
%token COND_OR COND_AND COND_NOT
%token COND_LT COND_GT COND_LE COND_GE COND_EQ COND_NE
%token COND_LPAR COND_RPAR
%token COND_LT COND_GT COND_EQ
%token COND_LPAR COND_RPAR COND_DBLQ COND_TILDA
%token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
%token COND_IDENT COND_NUMBER
%nonassoc COND_EOF COND_ERROR
%type <value> expression boolean_term boolean_factor term value symbol integer
%type <string> identifier
%type <fn_comp_int> comparison_op
%type <value> expression boolean_term boolean_factor
%type <value> term value_i symbol_i integer
%type <string> identifier value_s symbol_s literal
%type <fn_comp_int> comp_op_i
%type <fn_comp_str> comp_op_s
%type <fn_comp_m1> comp_op_m1
%type <fn_comp_m2> comp_op_m2
%%
@ -112,7 +150,7 @@ boolean_term:
{
$$ = $1;
}
| boolean_factor COND_AND term
| boolean_term COND_AND boolean_factor
{
$$ = $1 && $3;
}
@ -129,12 +167,33 @@ boolean_factor:
}
;
term:
value
value_i
{
$$ = $1;
}
| value comparison_op value
| value_s
{
$$ = atoiW($1);
}
| value_i comp_op_i value_i
{
$$ = $2( $1, $3 );
}
| value_s comp_op_s value_s
{
$$ = $2( $1, $3, FALSE );
}
| value_s COND_TILDA comp_op_s value_s
{
$$ = $3( $1, $4, TRUE );
}
| value_s comp_op_m1 value_i
{
$$ = $2( $1, $3 );
}
| value_i comp_op_m2 value_s
{
$$ = $2( $1, $3 );
}
@ -144,35 +203,172 @@ term:
}
;
comparison_op:
COND_LT
comp_op_i:
/* common functions */
COND_EQ
{
$$ = comp_lt;
$$ = comp_eq_i;
}
| COND_LT COND_GT
{
$$ = comp_ne_i;
}
| COND_LT
{
$$ = comp_lt_i;
}
| COND_GT
{
$$ = comp_gt;
$$ = comp_gt_i;
}
| COND_LE
| COND_LT COND_EQ
{
$$ = comp_le;
$$ = comp_le_i;
}
| COND_GE
| COND_GT COND_EQ
{
$$ = comp_ge;
$$ = comp_ge_i;
}
| COND_EQ
/*Int only*/
| COND_GT COND_LT
{
$$ = comp_eq;
$$ = comp_bitand;
}
| COND_NE
| COND_LT COND_LT
{
$$ = comp_ne;
$$ = comp_highcomp;
}
| COND_GT COND_GT
{
$$ = comp_lowcomp;
}
;
value:
symbol
comp_op_s:
/* common functions */
COND_EQ
{
$$ = comp_eq_s;
}
| COND_LT COND_GT
{
$$ = comp_ne_s;
}
| COND_LT
{
$$ = comp_lt_s;
}
| COND_GT
{
$$ = comp_gt_s;
}
| COND_LT COND_EQ
{
$$ = comp_le_s;
}
| COND_GT COND_EQ
{
$$ = comp_ge_s;
}
/*string only*/
| COND_GT COND_LT
{
$$ = comp_substring;
}
| COND_LT COND_LT
{
$$ = comp_start;
}
| COND_GT COND_GT
{
$$ = comp_end;
}
;
comp_op_m1:
/* common functions */
COND_EQ
{
$$ = comp_eq_m1;
}
| COND_LT COND_GT
{
$$ = comp_ne_m1;
}
| COND_LT
{
$$ = comp_lt_m1;
}
| COND_GT
{
$$ = comp_gt_m1;
}
| COND_LT COND_EQ
{
$$ = comp_le_m1;
}
| COND_GT COND_EQ
{
$$ = comp_ge_m1;
}
/*Not valid for mixed compares*/
| COND_GT COND_LT
{
$$ = 0;
}
| COND_LT COND_LT
{
$$ = 0;
}
| COND_GT COND_GT
{
$$ = 0;
}
;
comp_op_m2:
/* common functions */
COND_EQ
{
$$ = comp_eq_m2;
}
| COND_LT COND_GT
{
$$ = comp_ne_m2;
}
| COND_LT
{
$$ = comp_lt_m2;
}
| COND_GT
{
$$ = comp_gt_m2;
}
| COND_LT COND_EQ
{
$$ = comp_le_m2;
}
| COND_GT COND_EQ
{
$$ = comp_ge_m2;
}
/*Not valid for mixed compares*/
| COND_GT COND_LT
{
$$ = 0;
}
| COND_LT COND_LT
{
$$ = 0;
}
| COND_GT COND_GT
{
$$ = 0;
}
;
value_i:
symbol_i
{
$$ = $1;
}
@ -182,7 +378,25 @@ value:
}
;
symbol:
value_s:
symbol_s
{
$$ = $1;
}
| literal
{
$$ = $1;
}
;
literal:
COND_DBLQ identifier COND_DBLQ
{
$$ = $2;
}
;
symbol_i:
COND_DOLLARS identifier
{
COND_input* cond = (COND_input*) info;
@ -217,15 +431,22 @@ symbol:
}
;
identifier:
COND_IDENT
symbol_s:
identifier
{
COND_input* cond = (COND_input*) info;
$$ = COND_GetString(cond);
if( !$$ )
YYABORT;
$$ = HeapAlloc( GetProcessHeap(), 0, 0x100*sizeof (WCHAR) );
/* Lookup the identifier */
/* This will not really work until we have write access to the table*/
/* HACK ALERT HACK ALERT... */
if (get_property(cond->hInstall,$1,$$) != ERROR_SUCCESS)
{
$$[0]=0;
}
}
| COND_PERCENT identifier
| COND_PERCENT identifier
{
UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
if( len++ )
@ -238,6 +459,16 @@ identifier:
}
;
identifier:
COND_IDENT
{
COND_input* cond = (COND_input*) info;
$$ = COND_GetString(cond);
if( !$$ )
YYABORT;
}
;
integer:
COND_NUMBER
{
@ -252,35 +483,82 @@ integer:
%%
static INT comp_lt(INT a, INT b)
{
return (a < b);
/* the mess of comparison functions */
static INT comp_lt_i(INT a, INT b)
{ return (a < b); }
static INT comp_gt_i(INT a, INT b)
{ return (a > b); }
static INT comp_le_i(INT a, INT b)
{ return (a <= b); }
static INT comp_ge_i(INT a, INT b)
{ return (a >= b); }
static INT comp_eq_i(INT a, INT b)
{ return (a == b); }
static INT comp_ne_i(INT a, INT b)
{ return (a != b); }
static INT comp_bitand(INT a, INT b)
{ return a & b;}
static INT comp_highcomp(INT a, INT b)
{ return HIWORD(a)==b; }
static INT comp_lowcomp(INT a, INT b)
{ return LOWORD(a)==b; }
static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);}
static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);}
static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;}
static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;}
static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;}
static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;}
static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless)
/* ERROR NOT WORKING REWRITE */
{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;}
static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless)
{ if (casless) return strncmpiW(a,b,strlenW(b))==0;
else return strncmpW(a,b,strlenW(b))==0;}
static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless)
{
int i = strlenW(a);
int j = strlenW(b);
if (j>i)
return 0;
if (casless) return (!strcmpiW(&a[i-j-1],b));
else return (!strcmpW(&a[i-j-1],b));
}
static INT comp_gt(INT a, INT b)
{
return (a > b);
}
static INT comp_le(INT a, INT b)
{
return (a <= b);
}
static INT comp_eq_m1(LPWSTR a, INT b)
{ return atoiW(a)==b; }
static INT comp_ne_m1(LPWSTR a, INT b)
{ return atoiW(a)!=b; }
static INT comp_lt_m1(LPWSTR a, INT b)
{ return atoiW(a)<b; }
static INT comp_gt_m1(LPWSTR a, INT b)
{ return atoiW(a)>b; }
static INT comp_le_m1(LPWSTR a, INT b)
{ return atoiW(a)<=b; }
static INT comp_ge_m1(LPWSTR a, INT b)
{ return atoiW(a)>=b; }
static INT comp_ge(INT a, INT b)
{
return (a >= b);
}
static INT comp_eq(INT a, INT b)
{
return (a == b);
}
static INT comp_ne(INT a, INT b)
{
return (a != b);
}
static INT comp_eq_m2(INT a, LPWSTR b)
{ return a == atoiW(b); }
static INT comp_ne_m2(INT a, LPWSTR b)
{ return a != atoiW(b); }
static INT comp_lt_m2(INT a, LPWSTR b)
{ return a < atoiW(b); }
static INT comp_gt_m2(INT a, LPWSTR b)
{ return a > atoiW(b); }
static INT comp_le_m2(INT a, LPWSTR b)
{ return a <= atoiW(b); }
static INT comp_ge_m2(INT a, LPWSTR b)
{ return a >= atoiW(b); }
static int COND_IsAlpha( WCHAR x )
@ -296,48 +574,95 @@ static int COND_IsNumber( WCHAR x )
static int COND_IsIdent( WCHAR x )
{
return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) );
return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' )
|| ( x == '#' ) || (x == '.') );
}
static int COND_lex( void *COND_lval, COND_input *cond )
{
WCHAR ch;
/* grammer */
static const WCHAR NOT[] = {'O','T',' ',0};
static const WCHAR AND[] = {'N','D',' ',0};
static const WCHAR OR[] = {'R',' ',0};
int rc = COND_SPACE;
while (rc == COND_SPACE)
{
cond->start = cond->n;
ch = cond->str[cond->n];
if( !ch )
return COND_EOF;
if( ch == 0 )
return 0;
cond->n++;
switch( ch )
{
case '(': return COND_LPAR;
case ')': return COND_RPAR;
case '&': return COND_AMPER;
case '!': return COND_EXCLAM;
case '$': return COND_DOLLARS;
case '?': return COND_QUESTION;
case '%': return COND_PERCENT;
case ' ': return COND_SPACE;
}
case '(': rc = COND_LPAR; break;
case ')': rc = COND_RPAR; break;
case '&': rc = COND_AMPER; break;
case '!': rc = COND_EXCLAM; break;
case '$': rc = COND_DOLLARS; break;
case '?': rc = COND_QUESTION; break;
case '%': rc = COND_PERCENT; break;
case ' ': rc = COND_SPACE; break;
case '=': rc = COND_EQ; break;
case '"': rc = COND_DBLQ; break;
case '~': rc = COND_TILDA; break;
case '<': rc = COND_LT; break;
case '>': rc = COND_GT; break;
case 'N':
case 'n':
if (strncmpiW(&cond->str[cond->n],NOT,3)==0)
{
cond->n+=3;
rc = COND_NOT;
}
break;
case 'A':
case 'a':
if (strncmpiW(&cond->str[cond->n],AND,3)==0)
{
cond->n+=3;
rc = COND_AND;
}
break;
case 'O':
case 'o':
if (strncmpiW(&cond->str[cond->n],OR,2)==0)
{
cond->n+=2;
rc = COND_OR;
}
break;
default:
if( COND_IsAlpha( ch ) )
{
ch = cond->str[cond->n];
while( COND_IsIdent( ch ) )
ch = cond->str[cond->n++];
cond->n--;
rc = COND_IDENT;
break;
}
if( COND_IsAlpha( ch ) )
{
ch = cond->str[cond->n];
while( COND_IsIdent( ch ) )
ch = cond->str[cond->n++];
return COND_IDENT;
}
if( COND_IsNumber( ch ) )
{
ch = cond->str[cond->n];
while( COND_IsNumber( ch ) )
ch = cond->str[cond->n++];
rc = COND_NUMBER;
break;
}
if( COND_IsNumber( ch ) )
{
ch = cond->str[cond->n];
while( COND_IsNumber( ch ) )
ch = cond->str[cond->n++];
return COND_NUMBER;
ERR("Got unknown character %c(%x)\n",ch,ch);
rc = COND_ERROR;
break;
}
return COND_ERROR;
}
return rc;
}
static LPWSTR COND_GetString( COND_input *cond )
@ -348,7 +673,11 @@ static LPWSTR COND_GetString( COND_input *cond )
len = cond->n - cond->start;
str = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof (WCHAR) );
if( str )
{
strncpyW( str, &cond->str[cond->start], len );
str[len]=0;
}
TRACE("Got identifier %s\n",debugstr_w(str));
return str;
}
@ -366,13 +695,16 @@ MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szConditi
cond.str = szCondition;
cond.n = 0;
cond.start = 0;
cond.result = MSICONDITION_ERROR;
cond.result = -1;
TRACE("Evaluating %s\n",debugstr_w(szCondition));
if( !COND_parse( &cond ) )
r = cond.result;
else
r = MSICONDITION_ERROR;
TRACE("Evaluates to %i\n",r);
return r;
}

View file

@ -54,6 +54,7 @@ MSIHANDLE alloc_msihandle(UINT type, UINT size, msihandledestructor destroy, voi
info->magic = MSIHANDLE_MAGIC;
info->type = type;
info->refcount = 1;
info->destructor = destroy;
msihandletable[i] = info;
@ -79,6 +80,26 @@ void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
return &msihandletable[handle][1];
}
void msihandle_addref(MSIHANDLE handle)
{
MSIHANDLEINFO *info = msihandle2msiinfo(handle, 0);
TRACE("%lx\n",handle);
if( !info )
return;
info--;
if( info->magic != MSIHANDLE_MAGIC )
{
ERR("Invalid handle!\n");
return;
}
info->refcount++;
}
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
{
MSIHANDLEINFO *info = msihandle2msiinfo(handle, 0);
@ -96,6 +117,10 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
return ERROR_INVALID_HANDLE;
}
info->refcount--;
if (info->refcount > 0)
return ERROR_SUCCESS;
if( info->destructor )
info->destructor( &info[1] );

View file

@ -33,6 +33,7 @@
#include "msipriv.h"
#include "objidl.h"
#include "wincrypt.h"
#include "wine/unicode.h"
#include "objbase.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@ -302,18 +303,24 @@ UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
if( r != ERROR_SUCCESS )
return r;
return ERROR_UNKNOWN_PRODUCT;
r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
/* find the size of the path */
type = count = 0;
r = RegQueryValueExW( hKeyProduct, szLocalPackage,
NULL, &type, NULL, &count );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
/* now alloc and fetch the path of the database to open */
path = HeapAlloc( GetProcessHeap(), 0, count );
@ -323,7 +330,10 @@ UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
r = RegQueryValueExW( hKeyProduct, szLocalPackage,
NULL, &type, (LPBYTE) path, &count );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
r = MsiOpenPackageW( path, phProduct );
@ -345,8 +355,10 @@ UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
{
UINT rc;
FIXME("%s %p\n",debugstr_w(szPackage), phPackage);
return ERROR_CALL_NOT_IMPLEMENTED;
rc = MsiOpenDatabaseW(szPackage,MSIDBOPEN_READONLY,phPackage);
return rc;
}
UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
@ -426,9 +438,23 @@ end:
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
MSIHANDLE dbhandle;
UINT rc = ERROR_SUCCESS;
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
return ERROR_CALL_NOT_IMPLEMENTED;
rc = MsiVerifyPackageW(szPackagePath);
if (rc != ERROR_SUCCESS)
return rc;
rc = MsiOpenDatabaseW(szPackagePath,MSIDBOPEN_READONLY,&dbhandle);
if (rc != ERROR_SUCCESS)
return rc;
ACTION_DoTopLevelINSTALL(dbhandle, szPackagePath, szCommandLine);
MsiCloseHandle(dbhandle);
return rc;
}
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
@ -511,66 +537,8 @@ UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
{
LPWSTR szwName = NULL, szwValueBuf = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
FIXME("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
if (NULL != szValueBuf && NULL == pchValueBuf) {
return ERROR_INVALID_PARAMETER;
}
if( szName )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwName )
goto end;
MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
} else {
return ERROR_INVALID_PARAMETER;
}
if( szValueBuf )
{
szwValueBuf = HeapAlloc( GetProcessHeap(), 0, (*pchValueBuf) * sizeof(WCHAR) );
if( !szwValueBuf )
goto end;
}
hr = MsiGetPropertyW( hInstall, szwName, szwValueBuf, pchValueBuf );
if( ERROR_SUCCESS == hr )
{
WideCharToMultiByte(CP_ACP, 0, szwValueBuf, -1, szValueBuf, *pchValueBuf, NULL, NULL);
}
end:
if( szwName )
HeapFree( GetProcessHeap(), 0, szwName );
if( szwValueBuf )
HeapFree( GetProcessHeap(), 0, szwValueBuf );
return hr;
}
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, LPWSTR szValueBuf, DWORD* pchValueBuf)
{
FIXME("%lu %s %lu\n", hInstall, debugstr_w(szName), *pchValueBuf);
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, DWORD *pcchValueBuf)
{
@ -715,6 +683,13 @@ INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
return dwUILevel;
}
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
DWORD dwMessageFilter, LPVOID pvContext)
{
FIXME("STUB\n");
return NULL;
}
UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax, DWORD e)
{
/*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
@ -1220,3 +1195,148 @@ BOOL WINAPI MSI_DllCanUnloadNow(void)
{
return S_FALSE;
}
/* property code */
UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
{
FIXME("STUB until write access is done: (%s %s)\n", szName,
szValue);
if (!hInstall)
return ERROR_INVALID_HANDLE;
return ERROR_SUCCESS;
}
UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
{
FIXME("STUB until write access is done: (%s %s)\n",debugstr_w(szName),
debugstr_w(szValue));
if (!hInstall)
return ERROR_INVALID_HANDLE;
return ERROR_SUCCESS;
}
UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
{
LPWSTR szwName = NULL, szwValueBuf = NULL;
UINT hr = ERROR_INSTALL_FAILURE;
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
FIXME("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
if (NULL != szValueBuf && NULL == pchValueBuf) {
return ERROR_INVALID_PARAMETER;
}
if( szName )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if( !szwName )
goto end;
MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
} else {
return ERROR_INVALID_PARAMETER;
}
if( szValueBuf )
{
szwValueBuf = HeapAlloc( GetProcessHeap(), 0, (*pchValueBuf) * sizeof(WCHAR) );
if( !szwValueBuf )
goto end;
}
hr = MsiGetPropertyW( hInstall, szwName, szwValueBuf, pchValueBuf );
if( ERROR_SUCCESS == hr )
{
WideCharToMultiByte(CP_ACP, 0, szwValueBuf, -1, szValueBuf, *pchValueBuf, NULL, NULL);
}
end:
if( szwName )
HeapFree( GetProcessHeap(), 0, szwName );
if( szwValueBuf )
HeapFree( GetProcessHeap(), 0, szwValueBuf );
return hr;
}
UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
LPWSTR szValueBuf, DWORD* pchValueBuf)
{
MSIHANDLE view,row;
UINT rc;
WCHAR Query[1024]=
{'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' '
,'P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' ','`'
,'P','r','o','p','e','r','t','y','`','=','`',0};
static const WCHAR szEnd[]={'`',0};
if (0 == hInstall) {
return ERROR_INVALID_HANDLE;
}
if (NULL == szName) {
return ERROR_INVALID_PARAMETER;
}
strcatW(Query,szName);
strcatW(Query,szEnd);
rc = MsiDatabaseOpenViewW(hInstall, Query, &view);
if (rc == ERROR_SUCCESS)
{
DWORD sz;
WCHAR value[0x100];
rc = MsiViewExecute(view, 0);
if (rc != ERROR_SUCCESS)
{
MsiViewClose(view);
MsiCloseHandle(view);
return rc;
}
rc = MsiViewFetch(view,&row);
if (rc == ERROR_SUCCESS)
{
sz=0x100;
rc = MsiRecordGetStringW(row,2,value,&sz);
strncpyW(szValueBuf,value,min(sz+1,*pchValueBuf));
*pchValueBuf = sz+1;
MsiCloseHandle(row);
}
MsiViewClose(view);
MsiCloseHandle(view);
}
if (rc == ERROR_SUCCESS)
TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
debugstr_w(szName));
return rc;
}
INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
MSIHANDLE hRecord)
{
FIXME("STUB: \n");
return ERROR_SUCCESS;
}
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
{
FIXME("Is this correct?\n");
msihandle_addref(hInstall);
return hInstall;
}

View file

@ -46,7 +46,7 @@
46 stdcall MsiEvaluateConditionA(long str)
47 stdcall MsiEvaluateConditionW(long wstr)
48 stub MsiGetLastErrorRecord
49 stub MsiGetActiveDatabase
49 stdcall MsiGetActiveDatabase(long)
50 stdcall MsiGetComponentStateA(long str ptr ptr)
51 stdcall MsiGetComponentStateW(long wstr ptr ptr)
52 stub MsiGetDatabaseState
@ -100,7 +100,7 @@
100 stub MsiPreviewDialogW
101 stub MsiProcessAdvertiseScriptA
102 stub MsiProcessAdvertiseScriptW
103 stub MsiProcessMessage
103 stdcall MsiProcessMessage(long long long)
104 stub MsiProvideComponentA
105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr)
106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr)
@ -133,7 +133,7 @@
133 stub MsiSequenceW
134 stub MsiSetComponentStateA
135 stub MsiSetComponentStateW
136 stub MsiSetExternalUIA
136 stdcall MsiSetExternalUIA(ptr long ptr)
137 stub MsiSetExternalUIW
138 stub MsiSetFeatureStateA
139 stub MsiSetFeatureStateW
@ -141,8 +141,8 @@
141 stdcall MsiSetInternalUI(long ptr)
142 stub MsiVerifyDiskSpace
143 stub MsiSetMode
144 stub MsiSetPropertyA
145 stub MsiSetPropertyW
144 stdcall MsiSetPropertyA(long str str)
145 stdcall MsiSetPropertyW(long wstr wstr)
146 stub MsiSetTargetPathA
147 stub MsiSetTargetPathW
148 stdcall MsiSummaryInfoGetPropertyA(long long ptr ptr ptr ptr ptr)

View file

@ -132,6 +132,7 @@ typedef struct tagMSIHANDLEINFO
{
UINT magic;
UINT type;
UINT refcount;
msihandledestructor destructor;
struct tagMSIHANDLEINFO *next;
struct tagMSIHANDLEINFO *prev;
@ -164,6 +165,7 @@ DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x0
extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
MSIHANDLE alloc_msihandle(UINT type, UINT extra, msihandledestructor destroy, void **out);
void msihandle_addref(MSIHANDLE handle);
/* add this table to the list of cached tables in the database */
extern void add_table(MSIDATABASE *db, MSITABLE *table);
@ -199,4 +201,9 @@ UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n );
extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name );
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
USHORT **pdata, UINT *psz );
UINT ACTION_DoTopLevelINSTALL(MSIHANDLE hPackage, LPCWSTR szPackagePath,
LPCWSTR szCommandLine);
#endif /* __WINE_MSI_PRIVATE__ */

View file

@ -571,7 +571,8 @@ LPWSTR SQL_getstring( struct sql_str *strdata)
LPWSTR str;
/* if there's quotes, remove them */
if( (p[0]=='`') && (p[len-1]=='`') )
if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
( (p[0]=='\'') && (p[len-1]=='\'') ) )
{
p++;
len -= 2;

View file

@ -1254,3 +1254,76 @@ UINT MSI_CommitTables( MSIDATABASE *db )
return ERROR_SUCCESS;
}
UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
USHORT **pdata, UINT *psz )
{
HRESULT r;
UINT ret = ERROR_FUNCTION_FAILED;
VOID *data;
ULONG sz, count;
IStream *stm = NULL;
IStorage *stg = NULL;
STATSTG stat;
WCHAR encname[0x20];
MSIDATABASE *db;
db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE );
if ( !db )
return ERROR_INVALID_HANDLE;
stg = db->storage;
encode_streamname(FALSE, stname, encname);
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
r = IStorage_OpenStream(stg, encname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
if( FAILED( r ) )
{
WARN("open stream failed r = %08lx - empty table?\n",r);
return ret;
}
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
if( FAILED( r ) )
{
ERR("open stream failed r = %08lx!\n",r);
goto end;
}
if( stat.cbSize.QuadPart >> 32 )
{
ERR("Too big!\n");
goto end;
}
sz = stat.cbSize.QuadPart;
data = HeapAlloc( GetProcessHeap(), 0, sz );
if( !data )
{
ERR("couldn't allocate memory r=%08lx!\n",r);
ret = ERROR_NOT_ENOUGH_MEMORY;
goto end;
}
r = IStream_Read(stm, data, sz, &count );
if( FAILED( r ) || ( count != sz ) )
{
HeapFree( GetProcessHeap(), 0, data );
ERR("read stream failed r = %08lx!\n",r);
goto end;
}
*pdata = data;
*psz = sz;
ret = ERROR_SUCCESS;
end:
IStream_Release( stm );
return ret;
}