Wine-20041201 vendor drop Added: vendor/wine/dlls/msi/ Added: vendor/wine/dlls/msi/current/ Added: vendor/wine/dlls/msi/current/Makefile.in Added: vendor/wine/dlls/msi/current/action.c Added: vendor/wine/dlls/msi/current/cond.y Added: vendor/wine/dlls/msi/current/create.c Added: vendor/wine/dlls/msi/current/distinct.c Added: vendor/wine/dlls/msi/current/handle.c Added: vendor/wine/dlls/msi/current/insert.c Added: vendor/wine/dlls/msi/current/msi.c Added: vendor/wine/dlls/msi/current/msi.spec Added: vendor/wine/dlls/msi/current/msipriv.h Added: vendor/wine/dlls/msi/current/msiquery.c Added: vendor/wine/dlls/msi/current/order.c Added: vendor/wine/dlls/msi/current/package.c Added: vendor/wine/dlls/msi/current/query.h Added: vendor/wine/dlls/msi/current/record.c Added: vendor/wine/dlls/msi/current/regsvr.c Added: vendor/wine/dlls/msi/current/select.c Added: vendor/wine/dlls/msi/current/sql.y Added: vendor/wine/dlls/msi/current/string.c Added: vendor/wine/dlls/msi/current/suminfo.c Added: vendor/wine/dlls/msi/current/table.c Added: vendor/wine/dlls/msi/current/tokenize.c Added: vendor/wine/dlls/msi/current/update.c Added: vendor/wine/dlls/msi/current/version.rc Added: vendor/wine/dlls/msi/current/where.c _____
Added: vendor/wine/dlls/msi/current/Makefile.in --- vendor/wine/dlls/msi/current/Makefile.in 2004-12-31 15:08:50 UTC (rev 12559) +++ vendor/wine/dlls/msi/current/Makefile.in 2004-12-31 15:08:54 UTC (rev 12560) @@ -0,0 +1,50 @@
+TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = msi.dll +IMPORTS = shell32 cabinet oleaut32 ole32 version user32 advapi32 kernel32 +EXTRALIBS = -luuid $(LIBUNICODE) + +C_SRCS = \ + action.c \ + create.c \ + distinct.c \ + handle.c \ + insert.c \ + msi.c \ + msiquery.c \ + order.c \ + package.c \ + record.c \ + regsvr.c \ + select.c \ + string.c \ + suminfo.c \ + table.c \ + tokenize.c \ + update.c \ + where.c + +RC_SRCS = version.rc + +EXTRA_SRCS = sql.y cond.y +EXTRA_OBJS = sql.tab.o cond.tab.o + +@MAKE_DLL_RULES@ + +sql.tab.c sql.tab.h: sql.y + $(BISON) -p SQL_ -d $(SRCDIR)/sql.y -o sql.tab.c + +cond.tab.c cond.tab.h: cond.y + $(BISON) -p COND_ -d $(SRCDIR)/cond.y -o cond.tab.c + +# hack to allow parallel make +sql.tab.h: sql.tab.c +sql.tab.o: sql.tab.h +cond.tab.h: cond.tab.c +cond.tab.o: cond.tab.h + +tokenize.o: sql.tab.h + +### Dependencies: _____
Added: vendor/wine/dlls/msi/current/action.c --- vendor/wine/dlls/msi/current/action.c 2004-12-31 15:08:50 UTC (rev 12559) +++ vendor/wine/dlls/msi/current/action.c 2004-12-31 15:08:54 UTC (rev 12560) @@ -0,0 +1,4877 @@
+/* + * Implementation of the Microsoft Installer (msi.dll) + * + * Copyright 2004 Aric Stewart for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Pages I need + * +http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/se tup/installexecutesequence_table.asp + +http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/se tup/standard_actions_reference.asp + */ + +#include <stdarg.h> +#include <stdio.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "wine/debug.h" +#include "fdi.h" +#include "msi.h" +#include "msiquery.h" +#include "msvcrt/fcntl.h" +#include "objbase.h" +#include "objidl.h" +#include "msipriv.h" +#include "winnls.h" +#include "winuser.h" +#include "shlobj.h" +#include "wine/unicode.h" +#include "ver.h" + +#define CUSTOM_ACTION_TYPE_MASK 0x3F + +WINE_DEFAULT_DEBUG_CHANNEL(msi); + +typedef struct tagMSIFEATURE +{ + WCHAR Feature[96]; + WCHAR Feature_Parent[96]; + WCHAR Title[0x100]; + WCHAR Description[0x100]; + INT Display; + INT Level; + WCHAR Directory[96]; + INT Attributes; + + INSTALLSTATE State; + BOOL Enabled; + INT ComponentCount; + INT Components[1024]; /* yes hardcoded limit.... I am bad */ + INT Cost; +} MSIFEATURE; + +typedef struct tagMSICOMPONENT +{ + WCHAR Component[96]; + WCHAR ComponentId[96]; + WCHAR Directory[96]; + INT Attributes; + WCHAR Condition[0x100]; + WCHAR KeyPath[96]; + + INSTALLSTATE State; + BOOL FeatureState; + BOOL Enabled; + INT Cost; +} MSICOMPONENT; + +typedef struct tagMSIFOLDER +{ + WCHAR Directory[96]; + WCHAR TargetDefault[96]; + WCHAR SourceDefault[96]; + + WCHAR ResolvedTarget[MAX_PATH]; + WCHAR ResolvedSource[MAX_PATH]; + WCHAR Property[MAX_PATH]; /* initially set property */ + INT ParentIndex; + INT State; + /* 0 = uninitialized */ + /* 1 = existing */ + /* 2 = created remove if empty */ + /* 3 = created persist if empty */ + INT Cost; + INT Space; +}MSIFOLDER; + +typedef struct tagMSIFILE +{ + WCHAR File[72]; + INT ComponentIndex; + WCHAR FileName[MAX_PATH]; + INT FileSize; + WCHAR Version[72]; + WCHAR Language[20]; + INT Attributes; + INT Sequence; + + INT State; + /* 0 = uninitialize */ + /* 1 = not present */ + /* 2 = present but replace */ + /* 3 = present do not replace */ + /* 4 = Installed */ + WCHAR SourcePath[MAX_PATH]; + WCHAR TargetPath[MAX_PATH]; + BOOL Temporary; +}MSIFILE; + +/* + * Prototypes + */ +static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran); +static UINT ACTION_ProcessUISequence(MSIPACKAGE *package); + +UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action); + +static UINT ACTION_LaunchConditions(MSIPACKAGE *package); +static UINT ACTION_CostInitialize(MSIPACKAGE *package); +static UINT ACTION_CreateFolders(MSIPACKAGE *package); +static UINT ACTION_CostFinalize(MSIPACKAGE *package); +static UINT ACTION_FileCost(MSIPACKAGE *package); +static UINT ACTION_InstallFiles(MSIPACKAGE *package); +static UINT ACTION_DuplicateFiles(MSIPACKAGE *package); +static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package); +static UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action); +static UINT ACTION_InstallInitialize(MSIPACKAGE *package); +static UINT ACTION_InstallValidate(MSIPACKAGE *package); +static UINT ACTION_ProcessComponents(MSIPACKAGE *package); +static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package); +static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package); +static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package); +static UINT ACTION_CreateShortcuts(MSIPACKAGE *package); +static UINT ACTION_PublishProduct(MSIPACKAGE *package); + +static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source, + const LPWSTR target, const INT type); +static UINT HANDLE_CustomType2(MSIPACKAGE *package, const LPWSTR source, + const LPWSTR target, const INT type); +static UINT HANDLE_CustomType18(MSIPACKAGE *package, const LPWSTR source, + const LPWSTR target, const INT type); +static UINT HANDLE_CustomType50(MSIPACKAGE *package, const LPWSTR source, + const LPWSTR target, const INT type); +static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source, + const LPWSTR target, const INT type); + +static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data); +static UINT resolve_folder(MSIPACKAGE *package, LPCWSTR name, LPWSTR path, + BOOL source, BOOL set_prop, MSIFOLDER **folder); + +static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path); + +/* + * consts and values used + */ +static const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0}; +static const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0}; +static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0}; +static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0}; +static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0}; +static const WCHAR c_collen[] = {'C',':','\',0}; + +static const WCHAR cszlsb[]={'[',0}; +static const WCHAR cszrsb[]={']',0}; +static const WCHAR cszbs[]={'\',0}; + +const static WCHAR szCreateFolders[] = + {'C','r','e','a','t','e','F','o','l','d','e','r','s',0}; +const static WCHAR szCostFinalize[] = + {'C','o','s','t','F','i','n','a','l','i','z','e',0}; +const static WCHAR szInstallFiles[] = + {'I','n','s','t','a','l','l','F','i','l','e','s',0}; +const static WCHAR szDuplicateFiles[] = + {'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0}; +const static WCHAR szWriteRegistryValues[] = +{'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e ','s',0}; +const static WCHAR szCostInitialize[] = + {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0}; +const static WCHAR szFileCost[] = {'F','i','l','e','C','o','s','t',0}; +const static WCHAR szInstallInitialize[] = + {'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0}; +const static WCHAR szInstallValidate[] = + {'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0}; +const static WCHAR szLaunchConditions[] = + {'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0}; +const static WCHAR szProcessComponents[] = + {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0}; +const static WCHAR szRegisterTypeLibraries[] = +{'R','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r ', +'i','e','s',0}; +const static WCHAR szRegisterClassInfo[] = +{'R','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0} ; +const static WCHAR szRegisterProgIdInfo[] = +{'R','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o ',0}; +const static WCHAR szCreateShortcuts[] = +{'C','r','e','a','t','e','S','h','o','r','t','c','u','t','s',0}; +const static WCHAR szPublishProduct[] = +{'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0}; + +/******************************************************** + * helper functions to get around current HACKS and such + ********************************************************/ +inline static void reduce_to_longfilename(WCHAR* filename) +{ + if (strchrW(filename,'|')) + { + WCHAR newname[MAX_PATH]; + strcpyW(newname,strchrW(filename,'|')+1); + strcpyW(filename,newname); + } +} + +inline static char *strdupWtoA( const WCHAR *str ) +{ + char *ret = NULL; + if (str) + { + DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL +); + if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) + WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL ); + } + return ret; +} + +inline static WCHAR *strdupAtoW( const char *str ) +{ + WCHAR *ret = NULL; + if (str) + { + DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len ); + } + return ret; +} + +inline static WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index) +{ + UINT rc; + DWORD sz; + LPWSTR ret; + + sz = 0; + rc = MSI_RecordGetStringW(row,index,NULL,&sz); + if (sz <= 0) + return NULL; + + sz ++; + ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR)); + rc = MSI_RecordGetStringW(row,index,ret,&sz); + return ret; +} + +inline static int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component ) +{ + int rc = -1; + DWORD i; + + for (i = 0; i < package->loaded_components; i++) + { + if (strcmpW(Component,package->components[i].Component)==0) + { + rc = i; + break; + } + } + return rc; +} + +inline static int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature ) +{ + int rc = -1; + DWORD i; + + for (i = 0; i < package->loaded_features; i++) + { + if (strcmpW(Feature,package->features[i].Feature)==0) + { + rc = i; + break; + } + } + return rc; +} + +inline static int get_loaded_file(MSIPACKAGE* package, LPCWSTR file) +{ + int rc = -1; + DWORD i; + + for (i = 0; i < package->loaded_files; i++) + { + if (strcmpW(file,package->files[i].File)==0) + { + rc = i; + break; + } + } + return rc; +} + +static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path) +{ + DWORD i; + DWORD index; + + if (!package) + return -2; + + for (i=0; i < package->loaded_files; i++) + if (strcmpW(package->files[i].File,name)==0) + return -1; + + index = package->loaded_files; + package->loaded_files++; + if (package->loaded_files== 1) + package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE)); + else + package->files = HeapReAlloc(GetProcessHeap(),0, + package->files , package->loaded_files * sizeof(MSIFILE)); + + memset(&package->files[index],0,sizeof(MSIFILE)); + + strcpyW(package->files[index].File,name); + strcpyW(package->files[index].TargetPath,path); + package->files[index].Temporary = TRUE; + + TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File)); + + return 0; +} + +void ACTION_remove_tracked_tempfiles(MSIPACKAGE* package) +{ + DWORD i; + + if (!package) + return; + + for (i = 0; i < package->loaded_files; i++) + { + if (package->files[i].Temporary) + DeleteFileW(package->files[i].TargetPath); + + } +} + +static void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d ) +{ + MSIRECORD * row; + + row = MSI_CreateRecord(4); + MSI_RecordSetInteger(row,1,a); + MSI_RecordSetInteger(row,2,b); + MSI_RecordSetInteger(row,3,c); + MSI_RecordSetInteger(row,4,d); + MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row); + msiobj_release(&row->hdr); +} + +static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record) +{ + static const WCHAR Query_t[] = +{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o', +'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=', +' ',''','%','s',''',0}; + WCHAR message[1024]; + UINT rc; + MSIQUERY * view; + MSIRECORD * row = 0; + static WCHAR *ActionFormat=NULL; + static WCHAR LastAction[0x100] = {0}; + WCHAR Query[1024]; + LPWSTR ptr; + + if (strcmpW(LastAction,action)!=0) + { + sprintfW(Query,Query_t,action); + rc = MSI_DatabaseOpenViewW(package->db, Query, &view); + if (rc != ERROR_SUCCESS) + return; + rc = MSI_ViewExecute(view, 0); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + return; + } + rc = MSI_ViewFetch(view,&row); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + return; + } + + if (MSI_RecordIsNull(row,3)) + { + msiobj_release(&row->hdr); + MSI_ViewClose(view); + msiobj_release(&view->hdr); + return; + } + + if (ActionFormat) + HeapFree(GetProcessHeap(),0,ActionFormat); + + ActionFormat = load_dynamic_stringW(row,3); + strcpyW(LastAction,action); + msiobj_release(&row->hdr); + MSI_ViewClose(view); + msiobj_release(&view->hdr); + } + + message[0]=0; + ptr = ActionFormat; + while (*ptr) + { + LPWSTR ptr2; + LPWSTR data=NULL; + WCHAR tmp[1023]; + INT field; + + ptr2 = strchrW(ptr,'['); + if (ptr2) + { + strncpyW(tmp,ptr,ptr2-ptr); + tmp[ptr2-ptr]=0; + strcatW(message,tmp); + ptr2++; + field = atoiW(ptr2); + data = load_dynamic_stringW(record,field); + if (data) + { + strcatW(message,data); + HeapFree(GetProcessHeap(),0,data); + } + ptr=strchrW(ptr2,']'); + ptr++; + } + else + { + strcatW(message,ptr); + break; + } + } + + row = MSI_CreateRecord(1); + MSI_RecordSetStringW(row,1,message); + + MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row); + msiobj_release(&row->hdr); +} + + +static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action) +{ + static const WCHAR template_s[]= +{'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ','%','s','.',0}; + static const WCHAR format[] = +{'H','H',''',':',''','m','m',''',':',''','s','s',0}; + static const WCHAR Query_t[] = +{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o', +'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=', +' ',''','%','s',''',0}; + WCHAR message[1024]; + WCHAR timet[0x100]; + UINT rc; + MSIQUERY * view; + MSIRECORD * row = 0; + WCHAR *ActionText=NULL; + WCHAR Query[1024]; + + GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100); + + sprintfW(Query,Query_t,action); + rc = MSI_DatabaseOpenViewW(package->db, Query, &view); + if (rc != ERROR_SUCCESS) + return; + rc = MSI_ViewExecute(view, 0); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + return; + } + rc = MSI_ViewFetch(view,&row); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + return; + } + + ActionText = load_dynamic_stringW(row,2); + msiobj_release(&row->hdr); + MSI_ViewClose(view); + msiobj_release(&view->hdr); + + sprintfW(message,template_s,timet,action,ActionText); + + row = MSI_CreateRecord(1); + MSI_RecordSetStringW(row,1,message); + + MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row); + msiobj_release(&row->hdr); + HeapFree(GetProcessHeap(),0,ActionText); +} + +static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, + UINT rc) +{ + MSIRECORD * row; + static const WCHAR template_s[]= +{'A','c','t','i','o','n',' ','s','t','a','r','t',' ','%','s',':',' ','%','s', +'.',0}; + static const WCHAR template_e[]= +{'A','c','t','i','o','n',' ','e','n','d','e','d',' ','%','s',':',' ','%','s', +'.',' ','R','e','t','u','r','n',' ','v','a','l','u','e',' ','%','i','.',0}; + static const WCHAR format[] = +{'H','H',''',':',''','m','m',''',':',''','s','s',0}; + WCHAR message[1024]; + WCHAR timet[0x100]; + + GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100); + if (start) + sprintfW(message,template_s,timet,action); + else + sprintfW(message,template_e,timet,action,rc); + + row = MSI_CreateRecord(1); + MSI_RecordSetStringW(row,1,message); + + MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row); + msiobj_release(&row->hdr); +} + +/**************************************************** + * TOP level entry points + *****************************************************/ + +UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath, + LPCWSTR szCommandLine) +{ + DWORD sz; + WCHAR buffer[10]; + UINT rc; + static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; + + if (szPackagePath) + { + LPWSTR p; + WCHAR check[MAX_PATH]; + WCHAR pth[MAX_PATH]; + DWORD size; + + strcpyW(pth,szPackagePath); + p = strrchrW(pth,'\'); + if (p) + { + p++; + *p=0; + } + + size = MAX_PATH; + if (MSI_GetPropertyW(package,cszSourceDir,check,&size) + != ERROR_SUCCESS ) + MSI_SetPropertyW(package, cszSourceDir, pth); + } + + if (szCommandLine) + { + LPWSTR ptr,ptr2; + ptr = (LPWSTR)szCommandLine; + + while (*ptr) + { + WCHAR prop[0x100]; + WCHAR val[0x100]; + + TRACE("Looking at %s\n",debugstr_w(ptr)); + + ptr2 = strchrW(ptr,'='); + if (ptr2) + { + BOOL quote=FALSE; + DWORD len = 0; + + while (*ptr == ' ') ptr++; + strncpyW(prop,ptr,ptr2-ptr); + prop[ptr2-ptr]=0; + ptr2++; + + ptr = ptr2; + while (*ptr && (quote || (!quote && *ptr!=' '))) + { + if (*ptr == '"') + quote = !quote; + ptr++; + len++; + } + + if (*ptr2=='"') + { + ptr2++; + len -= 2; + } + strncpyW(val,ptr2,len); + val[len]=0; + + if (strlenW(prop) > 0) + { + TRACE("Found commandline property (%s) = (%s)\n", debugstr_w(prop), debugstr_w(val)); + MSI_SetPropertyW(package,prop,val); + } + } + ptr++; + } + } + + sz = 10; + if (MSI_GetPropertyW(package,szUILevel,buffer,&sz) == ERROR_SUCCESS) + { + if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED) + { + rc = ACTION_ProcessUISequence(package); + if (rc == ERROR_SUCCESS) + rc = ACTION_ProcessExecSequence(package,TRUE); + } + else + rc = ACTION_ProcessExecSequence(package,FALSE); + } + else + rc = ACTION_ProcessExecSequence(package,FALSE); + + return rc; +} + + +static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran) +{ + MSIQUERY * view; + UINT rc; + static const WCHAR ExecSeqQuery[] = { + 's','e','l','e','c','t',' ','*',' ', + 'f','r','o','m',' ', + 'I','n','s','t','a','l','l','E','x','e','c','u','t','e', + 'S','e','q','u','e','n','c','e',' ', + 'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ', + '>',' ','%','i',' ','o','r','d','e','r',' ', + 'b','y',' ','S','e','q','u','e','n','c','e',0 }; + WCHAR Query[1024]; + MSIRECORD * row = 0; + static const WCHAR IVQuery[] = { + 's','e','l','e','c','t',' ','S','e','q','u','e','n','c','e',' ', + 'f','r','o','m',' ','I','n','s','t','a','l','l', + 'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e',' ', + 'w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',' ', + '`','I','n','s','t','a','l','l','V','a','l','i','d','a','t','e','`', + 0}; + + if (UIran) + { + INT seq = 0; + + rc = MSI_DatabaseOpenViewW(package->db, IVQuery, &view); + if (rc != ERROR_SUCCESS) + return rc; + rc = MSI_ViewExecute(view, 0); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + return rc; + } + rc = MSI_ViewFetch(view,&row); + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + return rc; + } + seq = MSI_RecordGetInteger(row,1); + msiobj_release(&row->hdr); + MSI_ViewClose(view); + msiobj_release(&view->hdr); + sprintfW(Query,ExecSeqQuery,seq); + } + else + sprintfW(Query,ExecSeqQuery,0); + + rc = MSI_DatabaseOpenViewW(package->db, Query, &view); + if (rc == ERROR_SUCCESS) + { + rc = MSI_ViewExecute(view, 0); + + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + goto end; + } + + TRACE("Running the actions \n"); + + while (1) + { + WCHAR buffer[0x100]; + DWORD sz = 0x100; + + rc = MSI_ViewFetch(view,&row); + if (rc != ERROR_SUCCESS) + { + rc = ERROR_SUCCESS; + break; + } + + /* check conditions */ + if (!MSI_RecordIsNull(row,2)) + { + LPWSTR cond = NULL; + cond = load_dynamic_stringW(row,2); + + if (cond) + { + /* this is a hack to skip errors in the condition code */ + if (MSI_EvaluateConditionW(package, cond) == + MSICONDITION_FALSE) + { + HeapFree(GetProcessHeap(),0,cond); + msiobj_release(&row->hdr); + continue; + } + else + HeapFree(GetProcessHeap(),0,cond); + } + } + + sz=0x100; + rc = MSI_RecordGetStringW(row,1,buffer,&sz); + if (rc != ERROR_SUCCESS) + { + ERR("Error is %x\n",rc); + msiobj_release(&row->hdr); + break; + } + + rc = ACTION_PerformAction(package,buffer); + + if (rc == ERROR_FUNCTION_NOT_CALLED) + rc = ERROR_SUCCESS; + + if (rc != ERROR_SUCCESS) + { + ERR("Execution halted due to error (%i)\n",rc); + msiobj_release(&row->hdr); + break; + } + + msiobj_release(&row->hdr); + } + + MSI_ViewClose(view); + msiobj_release(&view->hdr); + } + +end: + return rc; +} + + +static UINT ACTION_ProcessUISequence(MSIPACKAGE *package) +{ + MSIQUERY * view; + UINT rc; + static const WCHAR ExecSeqQuery [] = { + 's','e','l','e','c','t',' ','*',' ', + 'f','r','o','m',' ','I','n','s','t','a','l','l', + 'U','I','S','e','q','u','e','n','c','e',' ', + 'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ', '>',' ','0',' ', + 'o','r','d','e','r',' ','b','y',' ','S','e','q','u','e','n','c','e',0}; + + rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view); + + if (rc == ERROR_SUCCESS) + { + rc = MSI_ViewExecute(view, 0); + + if (rc != ERROR_SUCCESS) + { + MSI_ViewClose(view); + msiobj_release(&view->hdr); + goto end; + } + + TRACE("Running the actions \n"); + + while (1) + { + WCHAR buffer[0x100]; + DWORD sz = 0x100; + MSIRECORD * row = 0; + + rc = MSI_ViewFetch(view,&row); + if (rc != ERROR_SUCCESS) + { + rc = ERROR_SUCCESS; + break; + } + + /* check conditions */ + if (!MSI_RecordIsNull(row,2)) + { + LPWSTR cond = NULL; + cond = load_dynamic_stringW(row,2); + + if (cond) + { + /* this is a hack to skip errors in the condition code */ + if (MSI_EvaluateConditionW(package, cond) == + MSICONDITION_FALSE) + { + HeapFree(GetProcessHeap(),0,cond); + msiobj_release(&row->hdr); + continue; + } + else + HeapFree(GetProcessHeap(),0,cond); + } + } + + sz=0x100; + rc = MSI_RecordGetStringW(row,1,buffer,&sz); + if (rc != ERROR_SUCCESS) + { + ERR("Error is %x\n",rc); + msiobj_release(&row->hdr); + break; + } + + rc = ACTION_PerformAction(package,buffer); + + if (rc == ERROR_FUNCTION_NOT_CALLED) + rc = ERROR_SUCCESS; + + if (rc != ERROR_SUCCESS) + { + ERR("Execution halted due to error (%i)\n",rc); + msiobj_release(&row->hdr); + break; + } + + msiobj_release(&row->hdr); + } + + MSI_ViewClose(view); + msiobj_release(&view->hdr); + } + +end: + return rc; +} + +/******************************************************** + * ACTION helper functions and functions that perform the actions + *******************************************************/ + +/* + * Alot of actions are really important even if they don't do anything + * explicit.. Lots of properties are set at the beginning of the installation + * CostFinalize does a bunch of work to translated the directories and such + * + * But until I get write access to the database that is hard, so I am going to + * hack it to see if I can get something to run. + */ +UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action) +{ + UINT rc = ERROR_SUCCESS; + + TRACE("Performing action (%s)\n",debugstr_w(action)); + ui_actioninfo(package, action, TRUE, 0); + ui_actionstart(package, action); + ui_progress(package,2,1,0,0); + + /* pre install, setup and configuration block */ + if (strcmpW(action,szLaunchConditions)==0) + rc = ACTION_LaunchConditions(package); + else if (strcmpW(action,szCostInitialize)==0) + rc = ACTION_CostInitialize(package); + else if (strcmpW(action,szFileCost)==0) + rc = ACTION_FileCost(package); + else if (strcmpW(action,szCostFinalize)==0) + rc = ACTION_CostFinalize(package); + else if (strcmpW(action,szInstallValidate)==0) + rc = ACTION_InstallValidate(package); + + /* install block */ + else if (strcmpW(action,szProcessComponents)==0) + rc = ACTION_ProcessComponents(package); + else if (strcmpW(action,szInstallInitialize)==0) + rc = ACTION_InstallInitialize(package); + else if (strcmpW(action,szCreateFolders)==0) + rc = ACTION_CreateFolders(package); + else if (strcmpW(action,szInstallFiles)==0) + rc = ACTION_InstallFiles(package); + else if (strcmpW(action,szDuplicateFiles)==0) + rc = ACTION_DuplicateFiles(package); + else if (strcmpW(action,szWriteRegistryValues)==0) + rc = ACTION_WriteRegistryValues(package); + else if (strcmpW(action,szRegisterTypeLibraries)==0) + rc = ACTION_RegisterTypeLibraries(package); + else if (strcmpW(action,szRegisterClassInfo)==0) + rc = ACTION_RegisterClassInfo(package); + else if (strcmpW(action,szRegisterProgIdInfo)==0) + rc = ACTION_RegisterProgIdInfo(package); + else if (strcmpW(action,szCreateShortcuts)==0) + rc = ACTION_CreateShortcuts(package); + else if (strcmpW(action,szPublishProduct)==0) + rc = ACTION_PublishProduct(package); + + /* [truncated at 1000 lines; 15340 more skipped]