4 * Implementation of the Microsoft Installer (msi.dll)
6 * Copyright 2003 Mike McCormack for CodeWeavers
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
37 #define YYLEX_PARAM info
38 #define YYPARSE_PARAM info
40 static int COND_error(char *str);
42 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 typedef struct tag_yyinput
53 static LPWSTR COND_GetString( COND_input *info );
54 static int COND_lex( void *COND_lval, COND_input *info);
56 typedef INT (*comp_int)(INT a, INT b);
58 static INT comp_lt(INT a, INT b);
59 static INT comp_gt(INT a, INT b);
60 static INT comp_le(INT a, INT b);
61 static INT comp_ge(INT a, INT b);
62 static INT comp_eq(INT a, INT b);
63 static INT comp_ne(INT a, INT b);
76 %token COND_SPACE COND_EOF COND_SPACE
77 %token COND_OR COND_AND COND_NOT
78 %token COND_LT COND_GT COND_LE COND_GE COND_EQ COND_NE
79 %token COND_LPAR COND_RPAR
80 %token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
81 %token COND_IDENT COND_NUMBER
83 %nonassoc COND_EOF COND_ERROR
85 %type <value> expression boolean_term boolean_factor term value symbol integer
86 %type <string> identifier
87 %type <fn_comp_int> comparison_op
94 COND_input* cond = (COND_input*) info;
104 | boolean_term COND_OR expression
115 | boolean_factor COND_AND term
137 | value comparison_op value
141 | COND_LPAR expression COND_RPAR
186 COND_DOLLARS identifier
188 COND_input* cond = (COND_input*) info;
189 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
191 MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
194 | COND_QUESTION identifier
196 COND_input* cond = (COND_input*) info;
197 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
199 MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
202 | COND_AMPER identifier
204 COND_input* cond = (COND_input*) info;
205 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
207 MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
210 | COND_EXCLAM identifier
212 COND_input* cond = (COND_input*) info;
213 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
215 MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
223 COND_input* cond = (COND_input*) info;
224 $$ = COND_GetString(cond);
228 | COND_PERCENT identifier
230 UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
233 $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
235 GetEnvironmentVariableW( $2, $$, len );
237 HeapFree( GetProcessHeap(), 0, $2 );
244 COND_input* cond = (COND_input*) info;
245 LPWSTR szNum = COND_GetString(cond);
249 HeapFree( GetProcessHeap(), 0, szNum );
255 static INT comp_lt(INT a, INT b)
260 static INT comp_gt(INT a, INT b)
265 static INT comp_le(INT a, INT b)
270 static INT comp_ge(INT a, INT b)
275 static INT comp_eq(INT a, INT b)
280 static INT comp_ne(INT a, INT b)
286 static int COND_IsAlpha( WCHAR x )
288 return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
289 ( ( x >= 'a' ) && ( x <= 'z' ) ) );
292 static int COND_IsNumber( WCHAR x )
294 return( ( x >= '0' ) && ( x <= '9' ) );
297 static int COND_IsIdent( WCHAR x )
299 return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) );
302 static int COND_lex( void *COND_lval, COND_input *cond )
306 cond->start = cond->n;
307 ch = cond->str[cond->n];
314 case '(': return COND_LPAR;
315 case ')': return COND_RPAR;
316 case '&': return COND_AMPER;
317 case '!': return COND_EXCLAM;
318 case '$': return COND_DOLLARS;
319 case '?': return COND_QUESTION;
320 case '%': return COND_PERCENT;
321 case ' ': return COND_SPACE;
324 if( COND_IsAlpha( ch ) )
326 ch = cond->str[cond->n];
327 while( COND_IsIdent( ch ) )
328 ch = cond->str[cond->n++];
332 if( COND_IsNumber( ch ) )
334 ch = cond->str[cond->n];
335 while( COND_IsNumber( ch ) )
336 ch = cond->str[cond->n++];
343 static LPWSTR COND_GetString( COND_input *cond )
348 len = cond->n - cond->start;
349 str = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof (WCHAR) );
351 strncpyW( str, &cond->str[cond->start], len );
355 static int COND_error(char *str)
360 MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
365 cond.hInstall = hInstall;
366 cond.str = szCondition;
369 cond.result = MSICONDITION_ERROR;
371 if( !COND_parse( &cond ) )
374 r = MSICONDITION_ERROR;
379 MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
381 LPWSTR szwCond = NULL;
386 UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
387 szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
388 MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
391 r = MsiEvaluateConditionW( hInstall, szwCond );
394 HeapFree( GetProcessHeap(), 0, szwCond );