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]