~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/msi/cond.y

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 %{
  2 
  3 /*
  4  * Implementation of the Microsoft Installer (msi.dll)
  5  *
  6  * Copyright 2003 Mike McCormack for CodeWeavers
  7  *
  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.
 12  *
 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.
 17  *
 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  */
 22 
 23 #define COBJMACROS
 24 
 25 #include "config.h"
 26 
 27 #include <stdarg.h>
 28 #include <stdio.h>
 29 #include <stdlib.h>
 30 
 31 #include "windef.h"
 32 #include "winbase.h"
 33 #include "winuser.h"
 34 #include "msi.h"
 35 #include "msiquery.h"
 36 #include "objbase.h"
 37 #include "oleauto.h"
 38 
 39 #include "msipriv.h"
 40 #include "msiserver.h"
 41 #include "wine/debug.h"
 42 #include "wine/unicode.h"
 43 
 44 #define YYLEX_PARAM info
 45 #define YYPARSE_PARAM info
 46 
 47 static int cond_error(const char *str);
 48 
 49 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 50 
 51 typedef struct tag_yyinput
 52 {
 53     MSIPACKAGE *package;
 54     LPCWSTR str;
 55     INT    n;
 56     MSICONDITION result;
 57 } COND_input;
 58 
 59 struct cond_str {
 60     LPCWSTR data;
 61     INT len;
 62 };
 63 
 64 static LPWSTR COND_GetString( const struct cond_str *str );
 65 static LPWSTR COND_GetLiteral( const struct cond_str *str );
 66 static int cond_lex( void *COND_lval, COND_input *info);
 67 
 68 static INT compare_int( INT a, INT operator, INT b );
 69 static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert );
 70 
 71 static INT compare_and_free_strings( LPWSTR a, INT op, LPWSTR b, BOOL convert )
 72 {
 73     INT r;
 74 
 75     r = compare_string( a, op, b, convert );
 76     msi_free( a );
 77     msi_free( b );
 78     return r;
 79 }
 80 
 81 static BOOL num_from_prop( LPCWSTR p, INT *val )
 82 {
 83     INT ret = 0, sign = 1;
 84 
 85     if (!p)
 86         return FALSE;
 87     if (*p == '-')
 88     {
 89         sign = -1;
 90         p++;
 91     }
 92     if (!*p)
 93         return FALSE;
 94     while (*p)
 95     {
 96         if( *p < '0' || *p > '9' )
 97             return FALSE;
 98         ret = ret*10 + (*p - '0');
 99         p++;
100     }
101     *val = ret*sign;
102     return TRUE;
103 }
104 
105 %}
106 
107 %pure-parser
108 
109 %union
110 {
111     struct cond_str str;
112     LPWSTR    string;
113     INT       value;
114 }
115 
116 %token COND_SPACE COND_EOF
117 %token COND_OR COND_AND COND_NOT COND_XOR COND_IMP COND_EQV
118 %token COND_LT COND_GT COND_EQ COND_NE COND_GE COND_LE
119 %token COND_ILT COND_IGT COND_IEQ COND_INE COND_IGE COND_ILE
120 %token COND_LPAR COND_RPAR COND_TILDA COND_SS COND_ISS
121 %token COND_ILHS COND_IRHS COND_LHS COND_RHS
122 %token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
123 %token <str> COND_IDENT <str> COND_NUMBER <str> COND_LITER
124 
125 %nonassoc COND_ERROR COND_EOF
126 
127 %type <value> expression boolean_term boolean_factor 
128 %type <value> value_i integer operator
129 %type <string> identifier symbol_s value_s literal
130 
131 %%
132 
133 condition:
134     expression 
135         {
136             COND_input* cond = (COND_input*) info;
137             cond->result = $1;
138         }
139   | /* empty */
140         {
141             COND_input* cond = (COND_input*) info;
142             cond->result = MSICONDITION_NONE;
143         }
144     ;
145 
146 expression:
147     boolean_term 
148         {
149             $$ = $1;
150         }
151   | expression COND_OR boolean_term
152         {
153             $$ = $1 || $3;
154         }
155   | expression COND_IMP boolean_term
156         {
157             $$ = !$1 || $3;
158         }
159   | expression COND_XOR boolean_term
160         {
161             $$ = ( $1 || $3 ) && !( $1 && $3 );
162         }
163   | expression COND_EQV boolean_term
164         {
165             $$ = ( $1 && $3 ) || ( !$1 && !$3 );
166         }
167     ;
168 
169 boolean_term:
170     boolean_factor
171         {
172             $$ = $1;
173         }
174   | boolean_term COND_AND boolean_factor
175         {
176             $$ = $1 && $3;
177         }
178     ;
179 
180 boolean_factor:
181     COND_NOT boolean_factor
182         {
183             $$ = $2 ? 0 : 1;
184         }
185   | value_i
186         {
187             $$ = $1 ? 1 : 0;
188         }
189   | value_s
190         {
191             $$ = ($1 && $1[0]) ? 1 : 0;
192             msi_free($1);
193         }
194   | value_i operator value_i
195         {
196             $$ = compare_int( $1, $2, $3 );
197         }
198   | symbol_s operator value_i
199         {
200             int num;
201             if (num_from_prop( $1, &num ))
202                 $$ = compare_int( num, $2, $3 );
203             else 
204                 $$ = ($2 == COND_NE || $2 == COND_INE );
205             msi_free($1);
206         }
207   | value_i operator symbol_s
208         {
209             int num;
210             if (num_from_prop( $3, &num ))
211                 $$ = compare_int( $1, $2, num );
212             else 
213                 $$ = ($2 == COND_NE || $2 == COND_INE );
214             msi_free($3);
215         }
216   | symbol_s operator symbol_s
217         {
218             $$ = compare_and_free_strings( $1, $2, $3, TRUE );
219         }
220   | symbol_s operator literal
221         {
222             $$ = compare_and_free_strings( $1, $2, $3, TRUE );
223         }
224   | literal operator symbol_s
225         {
226             $$ = compare_and_free_strings( $1, $2, $3, TRUE );
227         }
228   | literal operator literal
229         {
230             $$ = compare_and_free_strings( $1, $2, $3, FALSE );
231         }
232   | literal operator value_i
233         {
234             $$ = 0;
235             msi_free($1);
236         }
237   | value_i operator literal
238         {
239             $$ = 0;
240             msi_free($3);
241         }
242   | COND_LPAR expression COND_RPAR
243         {
244             $$ = $2;
245         }
246     ;
247 
248 operator:
249     /* common functions */
250     COND_EQ { $$ = COND_EQ; }
251   | COND_NE { $$ = COND_NE; }
252   | COND_LT { $$ = COND_LT; }
253   | COND_GT { $$ = COND_GT; }
254   | COND_LE { $$ = COND_LE; }
255   | COND_GE { $$ = COND_GE; }
256   | COND_SS { $$ = COND_SS; }
257   | COND_IEQ { $$ = COND_IEQ; }
258   | COND_INE { $$ = COND_INE; }
259   | COND_ILT { $$ = COND_ILT; }
260   | COND_IGT { $$ = COND_IGT; }
261   | COND_ILE { $$ = COND_ILE; }
262   | COND_IGE { $$ = COND_IGE; }
263   | COND_ISS { $$ = COND_ISS; }
264   | COND_LHS { $$ = COND_LHS; }
265   | COND_RHS { $$ = COND_RHS; }
266   | COND_ILHS { $$ = COND_ILHS; }
267   | COND_IRHS { $$ = COND_IRHS; }
268     ;
269 
270 value_s:
271     symbol_s
272     {
273         $$ = $1;
274     } 
275   | literal
276     {
277         $$ = $1;
278     }
279     ;
280 
281 literal:
282     COND_LITER
283         {
284             $$ = COND_GetLiteral(&$1);
285             if( !$$ )
286                 YYABORT;
287         }
288     ;
289 
290 value_i:
291     integer
292         {
293             $$ = $1;
294         }
295   | COND_DOLLARS identifier
296         {
297             COND_input* cond = (COND_input*) info;
298             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
299       
300             MSI_GetComponentStateW(cond->package, $2, &install, &action );
301             $$ = action;
302             msi_free( $2 );
303         }
304   | COND_QUESTION identifier
305         {
306             COND_input* cond = (COND_input*) info;
307             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
308       
309             MSI_GetComponentStateW(cond->package, $2, &install, &action );
310             $$ = install;
311             msi_free( $2 );
312         }
313   | COND_AMPER identifier
314         {
315             COND_input* cond = (COND_input*) info;
316             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
317       
318             MSI_GetFeatureStateW(cond->package, $2, &install, &action );
319             if (action == INSTALLSTATE_UNKNOWN)
320                 $$ = MSICONDITION_FALSE;
321             else
322                 $$ = action;
323 
324             msi_free( $2 );
325         }
326   | COND_EXCLAM identifier
327         {
328             COND_input* cond = (COND_input*) info;
329             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
330       
331             MSI_GetFeatureStateW(cond->package, $2, &install, &action );
332             $$ = install;
333             msi_free( $2 );
334         }
335     ;
336 
337 symbol_s:
338     identifier
339         {
340             COND_input* cond = (COND_input*) info;
341 
342             $$ = msi_dup_property( cond->package, $1 );
343             msi_free( $1 );
344         }
345     | COND_PERCENT identifier
346         {
347             UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
348             $$ = NULL;
349             if (len++)
350             {
351                 $$ = msi_alloc( len*sizeof (WCHAR) );
352                 GetEnvironmentVariableW( $2, $$, len );
353             }
354             msi_free( $2 );
355         }
356     ;
357 
358 identifier:
359     COND_IDENT
360         {
361             $$ = COND_GetString(&$1);
362             if( !$$ )
363                 YYABORT;
364         }
365     ;
366 
367 integer:
368     COND_NUMBER
369         {
370             LPWSTR szNum = COND_GetString(&$1);
371             if( !szNum )
372                 YYABORT;
373             $$ = atoiW( szNum );
374             msi_free( szNum );
375         }
376     ;
377 
378 %%
379 
380 
381 static int COND_IsAlpha( WCHAR x )
382 {
383     return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
384             ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
385             ( ( x == '_' ) ) );
386 }
387 
388 static int COND_IsNumber( WCHAR x )
389 {
390     return( (( x >= '0' ) && ( x <= '9' ))  || (x =='-') || (x =='.') );
391 }
392 
393 static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub )
394 {
395     LPWSTR strlower, sublower, r;
396     strlower = CharLowerW( strdupW( str ) );
397     sublower = CharLowerW( strdupW( sub ) );
398     r = strstrW( strlower, sublower );
399     if (r)
400         r = (LPWSTR)str + (r - strlower);
401     msi_free( strlower );
402     msi_free( sublower );
403     return r;
404 }
405 
406 static BOOL str_is_number( LPCWSTR str )
407 {
408     int i;
409 
410     if (!*str)
411         return FALSE;
412 
413     for (i = 0; i < lstrlenW( str ); i++)
414         if (!isdigitW(str[i]))
415             return FALSE;
416 
417     return TRUE;
418 }
419 
420 static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
421 {
422     int lhs, rhs;
423 
424     /* substring operators return 0 if LHS is missing */
425     if (!a || !*a)
426         return 0;
427 
428     /* substring operators return 1 if RHS is missing */
429     if (!b || !*b)
430         return 1;
431 
432     /* if both strings contain only numbers, use integer comparison */
433     lhs = atoiW(a);
434     rhs = atoiW(b);
435     if (str_is_number(a) && str_is_number(b))
436         return compare_int( lhs, operator, rhs );
437 
438     switch (operator)
439     {
440     case COND_SS:
441         return strstrW( a, b ) ? 1 : 0;
442     case COND_ISS:
443         return strstriW( a, b ) ? 1 : 0;
444     case COND_LHS:
445         return 0 == strncmpW( a, b, lstrlenW( b ) );
446     case COND_RHS:
447         return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b );
448     case COND_ILHS:
449         return 0 == strncmpiW( a, b, lstrlenW( b ) );
450     case COND_IRHS:
451         return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b );
452     default:
453         ERR("invalid substring operator\n");
454         return 0;
455     }
456     return 0;
457 }
458 
459 static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert )
460 {
461     if (operator >= COND_SS && operator <= COND_RHS)
462         return compare_substring( a, operator, b );
463         
464     /* null and empty string are equivalent */
465     if (!a) a = szEmpty;
466     if (!b) b = szEmpty;
467 
468     if (convert && str_is_number(a) && str_is_number(b))
469         return compare_int( atoiW(a), operator, atoiW(b) );
470 
471     /* a or b may be NULL */
472     switch (operator)
473     {
474     case COND_LT:
475         return -1 == lstrcmpW( a, b );
476     case COND_GT:
477         return  1 == lstrcmpW( a, b );
478     case COND_EQ:
479         return  0 == lstrcmpW( a, b );
480     case COND_NE:
481         return  0 != lstrcmpW( a, b );
482     case COND_GE:
483         return -1 != lstrcmpW( a, b );
484     case COND_LE:
485         return  1 != lstrcmpW( a, b );
486     case COND_ILT:
487         return -1 == lstrcmpiW( a, b );
488     case COND_IGT:
489         return  1 == lstrcmpiW( a, b );
490     case COND_IEQ:
491         return  0 == lstrcmpiW( a, b );
492     case COND_INE:
493         return  0 != lstrcmpiW( a, b );
494     case COND_IGE:
495         return -1 != lstrcmpiW( a, b );
496     case COND_ILE:
497         return  1 != lstrcmpiW( a, b );
498     default:
499         ERR("invalid string operator\n");
500         return 0;
501     }
502     return 0;
503 }
504 
505 
506 static INT compare_int( INT a, INT operator, INT b )
507 {
508     switch (operator)
509     {
510     case COND_LT:
511     case COND_ILT:
512         return a < b;
513     case COND_GT:
514     case COND_IGT:
515         return a > b;
516     case COND_EQ:
517     case COND_IEQ:
518         return a == b;
519     case COND_NE:
520     case COND_INE:
521         return a != b;
522     case COND_GE:
523     case COND_IGE:
524         return a >= b;
525     case COND_LE:
526     case COND_ILE:
527         return a <= b;
528     case COND_SS:
529     case COND_ISS:
530         return ( a & b ) ? 1 : 0;
531     case COND_RHS:
532         return ( ( a & 0xffff ) == b ) ? 1 : 0;
533     case COND_LHS:
534         return ( ( (a>>16) & 0xffff ) == b ) ? 1 : 0;
535     default:
536         ERR("invalid integer operator\n");
537         return 0;
538     }
539     return 0;
540 }
541 
542 
543 static int COND_IsIdent( WCHAR x )
544 {
545     return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) 
546             || ( x == '#' ) || (x == '.') );
547 }
548 
549 static int COND_GetOperator( COND_input *cond )
550 {
551     static const struct {
552         const WCHAR str[4];
553         int id;
554     } table[] = {
555         { {'~','<','=',0}, COND_ILE },
556         { {'~','>','<',0}, COND_ISS },
557         { {'~','>','>',0}, COND_IRHS },
558         { {'~','<','>',0}, COND_INE },
559         { {'~','>','=',0}, COND_IGE },
560         { {'~','<','<',0}, COND_ILHS },
561         { {'~','=',0},     COND_IEQ },
562         { {'~','<',0},     COND_ILT },
563         { {'~','>',0},     COND_IGT },
564         { {'>','=',0},     COND_GE  },
565         { {'>','<',0},     COND_SS  },
566         { {'<','<',0},     COND_LHS },
567         { {'<','>',0},     COND_NE  },
568         { {'<','=',0},     COND_LE  },
569         { {'>','>',0},     COND_RHS },
570         { {'>',0},         COND_GT  },
571         { {'<',0},         COND_LT  },
572         { {0},             0        }
573     };
574     LPCWSTR p = &cond->str[cond->n];
575     int i = 0, len;
576 
577     while ( 1 )
578     {
579         len = lstrlenW( table[i].str );
580         if ( !len || 0 == strncmpW( table[i].str, p, len ) )
581             break;
582         i++;
583     }
584     cond->n += len;
585     return table[i].id;
586 }
587 
588 static int COND_GetOne( struct cond_str *str, COND_input *cond )
589 {
590     int rc, len = 1;
591     WCHAR ch;
592 
593     str->data = &cond->str[cond->n];
594 
595     ch = str->data[0];
596 
597     switch( ch )
598     {
599     case 0: return 0;
600     case '(': rc = COND_LPAR; break;
601     case ')': rc = COND_RPAR; break;
602     case '&': rc = COND_AMPER; break;
603     case '!': rc = COND_EXCLAM; break;
604     case '$': rc = COND_DOLLARS; break;
605     case '?': rc = COND_QUESTION; break;
606     case '%': rc = COND_PERCENT; break;
607     case ' ': rc = COND_SPACE; break;
608     case '=': rc = COND_EQ; break;
609 
610     case '~':
611     case '<':
612     case '>':
613         rc = COND_GetOperator( cond );
614         if (!rc)
615             rc = COND_ERROR;
616         return rc;
617     default:
618         rc = 0;
619     }
620 
621     if ( rc )
622     {
623         cond->n += len;
624         return rc;
625     }
626 
627     if (ch == '"' )
628     {
629         LPCWSTR p = strchrW( str->data + 1, '"' );
630         if (!p)
631             return COND_ERROR;
632         len = p - str->data + 1;
633         rc = COND_LITER;
634     }
635     else if( COND_IsAlpha( ch ) )
636     {
637         static const WCHAR szNot[] = {'N','O','T',0};
638         static const WCHAR szAnd[] = {'A','N','D',0};
639         static const WCHAR szXor[] = {'X','O','R',0};
640         static const WCHAR szEqv[] = {'E','Q','V',0};
641         static const WCHAR szImp[] = {'I','M','P',0};
642         static const WCHAR szOr[] = {'O','R',0};
643 
644         while( COND_IsIdent( str->data[len] ) )
645             len++;
646         rc = COND_IDENT;
647 
648         if ( len == 3 )
649         {
650             if ( !strncmpiW( str->data, szNot, len ) )
651                 rc = COND_NOT;
652             else if( !strncmpiW( str->data, szAnd, len ) )
653                 rc = COND_AND;
654             else if( !strncmpiW( str->data, szXor, len ) )
655                 rc = COND_XOR;
656             else if( !strncmpiW( str->data, szEqv, len ) )
657                 rc = COND_EQV;
658             else if( !strncmpiW( str->data, szImp, len ) )
659                 rc = COND_IMP;
660         }
661         else if( (len == 2) && !strncmpiW( str->data, szOr, len ) )
662             rc = COND_OR;
663     }
664     else if( COND_IsNumber( ch ) )
665     {
666         while( COND_IsNumber( str->data[len] ) )
667             len++;
668         rc = COND_NUMBER;
669     }
670     else
671     {
672         ERR("Got unknown character %c(%x)\n",ch,ch);
673         return COND_ERROR;
674     }
675 
676     cond->n += len;
677     str->len = len;
678 
679     return rc;
680 }
681 
682 static int cond_lex( void *COND_lval, COND_input *cond )
683 {
684     int rc;
685     struct cond_str *str = COND_lval;
686 
687     do {
688         rc = COND_GetOne( str, cond );
689     } while (rc == COND_SPACE);
690     
691     return rc;
692 }
693 
694 static LPWSTR COND_GetString( const struct cond_str *str )
695 {
696     LPWSTR ret;
697 
698     ret = msi_alloc( (str->len+1) * sizeof (WCHAR) );
699     if( ret )
700     {
701         memcpy( ret, str->data, str->len * sizeof(WCHAR));
702         ret[str->len]=0;
703     }
704     TRACE("Got identifier %s\n",debugstr_w(ret));
705     return ret;
706 }
707 
708 static LPWSTR COND_GetLiteral( const struct cond_str *str )
709 {
710     LPWSTR ret;
711 
712     ret = msi_alloc( (str->len-1) * sizeof (WCHAR) );
713     if( ret )
714     {
715         memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
716         ret[str->len - 2]=0;
717     }
718     TRACE("Got literal %s\n",debugstr_w(ret));
719     return ret;
720 }
721 
722 static int cond_error(const char *str)
723 {
724     TRACE("%s\n", str );
725     return 0;
726 }
727 
728 MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
729 {
730     COND_input cond;
731     MSICONDITION r;
732 
733     TRACE("%s\n", debugstr_w( szCondition ) );
734 
735     if ( szCondition == NULL )
736         return MSICONDITION_NONE;
737 
738     cond.package = package;
739     cond.str   = szCondition;
740     cond.n     = 0;
741     cond.result = MSICONDITION_ERROR;
742     
743     if ( !cond_parse( &cond ) )
744         r = cond.result;
745     else
746         r = MSICONDITION_ERROR;
747 
748     TRACE("%i <- %s\n", r, debugstr_w(szCondition));
749     return r;
750 }
751 
752 MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
753 {
754     MSIPACKAGE *package;
755     UINT ret;
756 
757     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
758     if( !package )
759     {
760         HRESULT hr;
761         BSTR condition;
762         IWineMsiRemotePackage *remote_package;
763 
764         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
765         if (!remote_package)
766             return MSICONDITION_ERROR;
767 
768         condition = SysAllocString( szCondition );
769         if (!condition)
770         {
771             IWineMsiRemotePackage_Release( remote_package );
772             return ERROR_OUTOFMEMORY;
773         }
774 
775         hr = IWineMsiRemotePackage_EvaluateCondition( remote_package, condition );
776 
777         SysFreeString( condition );
778         IWineMsiRemotePackage_Release( remote_package );
779 
780         if (FAILED(hr))
781         {
782             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
783                 return HRESULT_CODE(hr);
784 
785             return ERROR_FUNCTION_FAILED;
786         }
787 
788         return ERROR_SUCCESS;
789     }
790 
791     ret = MSI_EvaluateConditionW( package, szCondition );
792     msiobj_release( &package->hdr );
793     return ret;
794 }
795 
796 MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
797 {
798     LPWSTR szwCond = NULL;
799     MSICONDITION r;
800 
801     szwCond = strdupAtoW( szCondition );
802     if( szCondition && !szwCond )
803         return MSICONDITION_ERROR;
804 
805     r = MsiEvaluateConditionW( hInstall, szwCond );
806     msi_free( szwCond );
807     return r;
808 }

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.