--- trunk/reactos/lib/msi/action.c 2005-08-03 21:34:01 UTC (rev 17033)
+++ trunk/reactos/lib/msi/action.c 2005-08-03 22:12:15 UTC (rev 17034)
@@ -1,7 +1,7 @@
/*
* Implementation of the Microsoft Installer (msi.dll)
*
- * Copyright 2004 Aric Stewart for CodeWeavers
+ * Copyright 2004,2005 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
@@ -27,7 +27,6 @@
*/
#include <stdarg.h>
-#include <stdio.h>
#define COBJMACROS
@@ -36,15 +35,8 @@
#include "winerror.h"
#include "winreg.h"
#include "wine/debug.h"
-#include "fdi.h"
-#include "msi.h"
-#include "msiquery.h"
#include "msidefs.h"
-#include "fcntl.h"
-#include "objbase.h"
-#include "objidl.h"
#include "msipriv.h"
-#include "winnls.h"
#include "winuser.h"
#include "shlobj.h"
#include "wine/unicode.h"
@@ -62,8 +54,6 @@
static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran);
static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq, BOOL UI);
-static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
- LPWSTR *FilePath);
/*
* action handlers
@@ -75,17 +65,11 @@
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_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_RegisterExtensionInfo(MSIPACKAGE *package);
-static UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
static UINT ACTION_RegisterUser(MSIPACKAGE *package);
static UINT ACTION_CreateShortcuts(MSIPACKAGE *package);
static UINT ACTION_PublishProduct(MSIPACKAGE *package);
@@ -101,26 +85,18 @@
static UINT ACTION_RegisterFonts(MSIPACKAGE *package);
static UINT ACTION_PublishComponents(MSIPACKAGE *package);
-
/*
* 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_colon[] = {'C',':','\\',0};
-static const WCHAR szProductCode[]=
- {'P','r','o','d','u','c','t','C','o','d','e',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[] =
+const WCHAR szInstallFiles[] =
{'I','n','s','t','a','l','l','F','i','l','e','s',0};
-const static WCHAR szDuplicateFiles[] =
+const 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',
@@ -140,9 +116,9 @@
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[] =
+const WCHAR szRegisterClassInfo[] =
{'R','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};
-const static WCHAR szRegisterProgIdInfo[] =
+const 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};
@@ -167,7 +143,7 @@
{'F','o','r','c','e','R','e','b','o','o','t',0};
const static WCHAR szResolveSource[] =
{'R','e','s','o','l','v','e','S','o','u','r','c','e',0};
-const static WCHAR szAppSearch[] =
+const WCHAR szAppSearch[] =
{'A','p','p','S','e','a','r','c','h',0};
const static WCHAR szAllocateRegistrySpace[] =
{'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y',
@@ -182,7 +158,7 @@
{'D','i','s','a','b','l','e','R','o','l','l','b','a','c','k',0};
const static WCHAR szExecuteAction[] =
{'E','x','e','c','u','t','e','A','c','t','i','o','n',0};
-const static WCHAR szFindRelatedProducts[] =
+const WCHAR szFindRelatedProducts[] =
{'F','i','n','d','R','e','l','a','t','e','d',
'P','r','o','d','u','c','t','s',0};
const static WCHAR szInstallAdminPackage[] =
@@ -193,10 +169,10 @@
'F','i','l','e',0};
const static WCHAR szIsolateComponents[] =
{'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0};
-const static WCHAR szMigrateFeatureStates[] =
+const WCHAR szMigrateFeatureStates[] =
{'M','i','g','r','a','t','e','F','e','a','t','u','r','e',
'S','t','a','t','e','s',0};
-const static WCHAR szMoveFiles[] =
+const WCHAR szMoveFiles[] =
{'M','o','v','e','F','i','l','e','s',0};
const static WCHAR szMsiPublishAssemblies[] =
{'M','s','i','P','u','b','l','i','s','h',
@@ -208,31 +184,31 @@
{'I','n','s','t','a','l','l','O','D','B','C',0};
const static WCHAR szInstallServices[] =
{'I','n','s','t','a','l','l','S','e','r','v','i','c','e','s',0};
-const static WCHAR szPatchFiles[] =
+const WCHAR szPatchFiles[] =
{'P','a','t','c','h','F','i','l','e','s',0};
const static WCHAR szPublishComponents[] =
{'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0};
const static WCHAR szRegisterComPlus[] =
{'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
-const static WCHAR szRegisterExtensionInfo[] =
+const WCHAR szRegisterExtensionInfo[] =
{'R','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n',
'I','n','f','o',0};
const static WCHAR szRegisterFonts[] =
{'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
-const static WCHAR szRegisterMIMEInfo[] =
+const WCHAR szRegisterMIMEInfo[] =
{'R','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
const static WCHAR szRegisterUser[] =
{'R','e','g','i','s','t','e','r','U','s','e','r',0};
-const static WCHAR szRemoveDuplicateFiles[] =
+const WCHAR szRemoveDuplicateFiles[] =
{'R','e','m','o','v','e','D','u','p','l','i','c','a','t','e',
'F','i','l','e','s',0};
const static WCHAR szRemoveEnvironmentStrings[] =
{'R','e','m','o','v','e','E','n','v','i','r','o','n','m','e','n','t',
'S','t','r','i','n','g','s',0};
-const static WCHAR szRemoveExistingProducts[] =
+const WCHAR szRemoveExistingProducts[] =
{'R','e','m','o','v','e','E','x','i','s','t','i','n','g',
'P','r','o','d','u','c','t','s',0};
-const static WCHAR szRemoveFiles[] =
+const WCHAR szRemoveFiles[] =
{'R','e','m','o','v','e','F','i','l','e','s',0};
const static WCHAR szRemoveFolders[] =
{'R','e','m','o','v','e','F','o','l','d','e','r','s',0};
@@ -262,19 +238,19 @@
'C','o','m','p','o','n','e','n','t','s',0};
const static WCHAR szUnpublishFeatures[] =
{'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
-const static WCHAR szUnregisterClassInfo[] =
+const WCHAR szUnregisterClassInfo[] =
{'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s',
'I','n','f','o',0};
const static WCHAR szUnregisterComPlus[] =
{'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
-const static WCHAR szUnregisterExtensionInfo[] =
+const WCHAR szUnregisterExtensionInfo[] =
{'U','n','r','e','g','i','s','t','e','r',
'E','x','t','e','n','s','i','o','n','I','n','f','o',0};
const static WCHAR szUnregisterFonts[] =
{'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};
-const static WCHAR szUnregisterMIMEInfo[] =
+const WCHAR szUnregisterMIMEInfo[] =
{'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
-const static WCHAR szUnregisterProgIdInfo[] =
+const WCHAR szUnregisterProgIdInfo[] =
{'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d',
'I','n','f','o',0};
const static WCHAR szUnregisterTypeLibraries[] =
@@ -305,7 +281,7 @@
{ szDuplicateFiles, ACTION_DuplicateFiles },
{ szExecuteAction, ACTION_ExecuteAction },
{ szFileCost, ACTION_FileCost },
- { szFindRelatedProducts, NULL},
+ { szFindRelatedProducts, ACTION_FindRelatedProducts },
{ szForceReboot, ACTION_ForceReboot },
{ szInstallAdminPackage, NULL},
{ szInstallExecute, ACTION_InstallExecute },
@@ -371,343 +347,22 @@
};
-/********************************************************
- * helper functions to get around current HACKS and such
+/********************************************************
+ * helper functions
********************************************************/
-inline static void reduce_to_longfilename(WCHAR* filename)
-{
- LPWSTR p = strchrW(filename,'|');
- if (p)
- memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
-}
-inline static void reduce_to_shortfilename(WCHAR* filename)
+static void ce_actiontext(MSIPACKAGE* package, LPCWSTR action)
{
- LPWSTR p = strchrW(filename,'|');
- if (p)
- *p = 0;
-}
+ static const WCHAR szActionText[] =
+ {'A','c','t','i','o','n','T','e','x','t',0};
+ MSIRECORD *row;
-WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
-{
- UINT rc;
- DWORD sz;
- LPWSTR ret;
-
- sz = 0;
- if (MSI_RecordIsNull(row,index))
- return NULL;
-
- rc = MSI_RecordGetStringW(row,index,NULL,&sz);
-
- /* having an empty string is different than NULL */
- if (sz == 0)
- {
- ret = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR));
- ret[0] = 0;
- return ret;
- }
-
- sz ++;
- ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
- rc = MSI_RecordGetStringW(row,index,ret,&sz);
- if (rc!=ERROR_SUCCESS)
- {
- ERR("Unable to load dynamic string\n");
- HeapFree(GetProcessHeap(), 0, ret);
- ret = NULL;
- }
- return ret;
-}
-
-LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc)
-{
- DWORD sz = 0;
- LPWSTR str;
- UINT r;
-
- r = MSI_GetPropertyW(package, prop, NULL, &sz);
- if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
- {
- if (rc)
- *rc = r;
- return NULL;
- }
- sz++;
- str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
- r = MSI_GetPropertyW(package, prop, str, &sz);
- if (r != ERROR_SUCCESS)
- {
- HeapFree(GetProcessHeap(),0,str);
- str = NULL;
- }
- if (rc)
- *rc = r;
- return str;
-}
-
-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;
-}
-
-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;
-}
-
-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;
-}
-
-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));
-
- package->files[index].File = strdupW(name);
- package->files[index].TargetPath = strdupW(path);
- package->files[index].Temporary = TRUE;
-
- TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));
-
- return 0;
-}
-
-static void remove_tracked_tempfiles(MSIPACKAGE* package)
-{
- DWORD i;
-
- if (!package)
- return;
-
- for (i = 0; i < package->loaded_files; i++)
- {
- if (package->files[i].Temporary)
- {
- TRACE("Cleaning up %s\n",debugstr_w(package->files[i].TargetPath));
- DeleteFileW(package->files[i].TargetPath);
- }
-
- }
-}
-
-/* wrapper to resist a need for a full rewrite right now */
-DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data )
-{
- if (ptr)
- {
- MSIRECORD *rec = MSI_CreateRecord(1);
- DWORD size = 0;
-
- MSI_RecordSetStringW(rec,0,ptr);
- MSI_FormatRecordW(package,rec,NULL,&size);
- if (size >= 0)
- {
- size++;
- *data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
- if (size > 1)
- MSI_FormatRecordW(package,rec,*data,&size);
- else
- *data[0] = 0;
- msiobj_release( &rec->hdr );
- return sizeof(WCHAR)*size;
- }
- msiobj_release( &rec->hdr );
- }
-
- *data = NULL;
- return 0;
-}
-
-/* Called when the package is being closed */
-void ACTION_free_package_structures( MSIPACKAGE* package)
-{
- INT i;
-
- TRACE("Freeing package action data\n");
-
- remove_tracked_tempfiles(package);
-
- /* No dynamic buffers in features */
- if (package->features && package->loaded_features > 0)
- HeapFree(GetProcessHeap(),0,package->features);
-
- for (i = 0; i < package->loaded_folders; i++)
- {
- HeapFree(GetProcessHeap(),0,package->folders[i].Directory);
- HeapFree(GetProcessHeap(),0,package->folders[i].TargetDefault);
- HeapFree(GetProcessHeap(),0,package->folders[i].SourceDefault);
- HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
- HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedSource);
- HeapFree(GetProcessHeap(),0,package->folders[i].Property);
- }
- if (package->folders && package->loaded_folders > 0)
- HeapFree(GetProcessHeap(),0,package->folders);
-
- for (i = 0; i < package->loaded_components; i++)
- HeapFree(GetProcessHeap(),0,package->components[i].FullKeypath);
-
- if (package->components && package->loaded_components > 0)
- HeapFree(GetProcessHeap(),0,package->components);
-
- for (i = 0; i < package->loaded_files; i++)
- {
- HeapFree(GetProcessHeap(),0,package->files[i].File);
- HeapFree(GetProcessHeap(),0,package->files[i].FileName);
- HeapFree(GetProcessHeap(),0,package->files[i].ShortName);
- HeapFree(GetProcessHeap(),0,package->files[i].Version);
- HeapFree(GetProcessHeap(),0,package->files[i].Language);
- HeapFree(GetProcessHeap(),0,package->files[i].SourcePath);
- HeapFree(GetProcessHeap(),0,package->files[i].TargetPath);
- }
-
- if (package->files && package->loaded_files > 0)
- HeapFree(GetProcessHeap(),0,package->files);
-
- for (i = 0; i < package->DeferredActionCount; i++)
- HeapFree(GetProcessHeap(),0,package->DeferredAction[i]);
- HeapFree(GetProcessHeap(),0,package->DeferredAction);
-
- for (i = 0; i < package->CommitActionCount; i++)
- HeapFree(GetProcessHeap(),0,package->CommitAction[i]);
- HeapFree(GetProcessHeap(),0,package->CommitAction);
-
- HeapFree(GetProcessHeap(),0,package->PackagePath);
-}
-
-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);
-
- msi_dialog_check_messages(NULL);
-}
-
-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;
- DWORD size;
-
- if (!package->LastAction || strcmpW(package->LastAction,action))
- {
- rc = MSI_OpenQuery(package->db, &view, Query_t, action);
- 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;
- }
-
- if (MSI_RecordIsNull(row,3))
- {
- msiobj_release(&row->hdr);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- return;
- }
-
- /* update the cached actionformat */
- HeapFree(GetProcessHeap(),0,package->ActionFormat);
- package->ActionFormat = load_dynamic_stringW(row,3);
-
- HeapFree(GetProcessHeap(),0,package->LastAction);
- package->LastAction = strdupW(action);
-
- msiobj_release(&row->hdr);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- }
-
- MSI_RecordSetStringW(record,0,package->ActionFormat);
- size = 1024;
- MSI_FormatRecordW(package,record,message,&size);
-
row = MSI_CreateRecord(1);
- MSI_RecordSetStringW(row,1,message);
-
- MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);
+ MSI_RecordSetStringW(row,1,action);
+ ControlEvent_FireSubscribedEvent(package,szActionText, row);
msiobj_release(&row->hdr);
}
-
static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action)
{
static const WCHAR template_s[]=
@@ -722,44 +377,25 @@
' ','\'','%','s','\'',0};
WCHAR message[1024];
WCHAR timet[0x100];
- UINT rc;
- MSIQUERY * view;
MSIRECORD * row = 0;
- WCHAR *ActionText=NULL;
+ LPCWSTR ActionText;
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
- rc = MSI_OpenQuery(package->db, &view, Query_t, action);
- if (rc != ERROR_SUCCESS)
+ row = MSI_QueryGetRecord( package->db, Query_t, action );
+ if (!row)
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);
+ ActionText = MSI_RecordGetString(row,2);
sprintfW(message,template_s,timet,action,ActionText);
+ msiobj_release(&row->hdr);
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,
@@ -791,82 +427,6 @@
msiobj_release(&row->hdr);
}
-/*
- * build_directory_name()
- *
- * This function is to save messing round with directory names
- * It handles adding backslashes between path segments,
- * and can add \ at the end of the directory name if told to.
- *
- * It takes a variable number of arguments.
- * It always allocates a new string for the result, so make sure
- * to free the return value when finished with it.
- *
- * The first arg is the number of path segments that follow.
- * The arguments following count are a list of path segments.
- * A path segment may be NULL.
- *
- * Path segments will be added with a \ separating them.
- * A \ will not be added after the last segment, however if the
- * last segment is NULL, then the last character will be a \
- *
- */
-static LPWSTR build_directory_name(DWORD count, ...)
-{
- DWORD sz = 1, i;
- LPWSTR dir;
- va_list va;
-
- va_start(va,count);
- for(i=0; i<count; i++)
- {
- LPCWSTR str = va_arg(va,LPCWSTR);
- if (str)
- sz += strlenW(str) + 1;
- }
- va_end(va);
-
- dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
- dir[0]=0;
-
- va_start(va,count);
- for(i=0; i<count; i++)
- {
- LPCWSTR str = va_arg(va,LPCWSTR);
- if (!str)
- continue;
- strcatW(dir, str);
- if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
- strcatW(dir, cszbs);
- }
- return dir;
-}
-
-static BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, INT index,
- INSTALLSTATE check )
-{
- if (package->components[index].Installed == check)
- return FALSE;
-
- if (package->components[index].ActionRequest == check)
- return TRUE;
- else
- return FALSE;
-}
-
-static BOOL ACTION_VerifyFeatureForAction(MSIPACKAGE* package, INT index,
- INSTALLSTATE check )
-{
- if (package->features[index].Installed == check)
- return FALSE;
-
- if (package->features[index].ActionRequest == check)
- return TRUE;
- else
- return FALSE;
-}
-
-
/****************************************************
* TOP level entry points
*****************************************************/
@@ -883,8 +443,10 @@
static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
MSI_SetPropertyW(package, szAction, szInstall);
- package->ExecuteSequenceRun = FALSE;
+ package->script = HeapAlloc(GetProcessHeap(),0,sizeof(MSISCRIPT));
+ memset(package->script,0,sizeof(MSISCRIPT));
+
if (szPackagePath)
{
LPWSTR p, check, path;
@@ -993,15 +555,17 @@
rc = ERROR_SUCCESS;
}
+ package->script->CurrentlyScripting= FALSE;
+
/* process the ending type action */
if (rc == ERROR_SUCCESS)
ACTION_PerformActionSequence(package,-1,ui);
else if (rc == ERROR_INSTALL_USEREXIT)
ACTION_PerformActionSequence(package,-2,ui);
- else if (rc == ERROR_FUNCTION_FAILED)
- ACTION_PerformActionSequence(package,-3,ui);
else if (rc == ERROR_INSTALL_SUSPEND)
ACTION_PerformActionSequence(package,-4,ui);
+ else /* failed */
+ ACTION_PerformActionSequence(package,-3,ui);
/* finish up running custom actions */
ACTION_FinishCustomActions(package);
@@ -1011,10 +575,7 @@
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq, BOOL UI)
{
- MSIQUERY * view;
- UINT rc;
- WCHAR buffer[0x100];
- DWORD sz = 0x100;
+ UINT rc = ERROR_SUCCESS;
MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
@@ -1029,67 +590,39 @@
' ', '=',' ','%','i',0};
if (UI)
- rc = MSI_OpenQuery(package->db, &view, UISeqQuery, seq);
+ row = MSI_QueryGetRecord(package->db, UISeqQuery, seq);
else
- rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
+ row = MSI_QueryGetRecord(package->db, ExecSeqQuery, seq);
- if (rc == ERROR_SUCCESS)
+ if (row)
{
- rc = MSI_ViewExecute(view, 0);
+ LPCWSTR action, cond;
- if (rc != ERROR_SUCCESS)
- {
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- goto end;
- }
-
TRACE("Running the actions\n");
- rc = MSI_ViewFetch(view,&row);
- if (rc != ERROR_SUCCESS)
- {
- rc = ERROR_SUCCESS;
- goto end;
- }
-
/* check conditions */
- if (!MSI_RecordIsNull(row,2))
+ cond = MSI_RecordGetString(row,2);
+ if (cond)
{
- 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);
- goto end;
- }
- else
- HeapFree(GetProcessHeap(),0,cond);
- }
+ /* this is a hack to skip errors in the condition code */
+ if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
+ goto end;
}
- sz=0x100;
- rc = MSI_RecordGetStringW(row,1,buffer,&sz);
- if (rc != ERROR_SUCCESS)
+ action = MSI_RecordGetString(row,1);
+ if (!action)
{
- ERR("Error is %x\n",rc);
- msiobj_release(&row->hdr);
+ ERR("failed to fetch action\n");
+ rc = ERROR_FUNCTION_FAILED;
goto end;
}
if (UI)
- rc = ACTION_PerformUIAction(package,buffer);
+ rc = ACTION_PerformUIAction(package,action);
else
- rc = ACTION_PerformAction(package,buffer);
- msiobj_release(&row->hdr);
+ rc = ACTION_PerformAction(package,action,FALSE);
end:
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
+ msiobj_release(&row->hdr);
}
else
rc = ERROR_SUCCESS;
@@ -1097,6 +630,51 @@
return rc;
}
+typedef struct {
+ MSIPACKAGE* package;
+ BOOL UI;
+} iterate_action_param;
+
+static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
+{
+ iterate_action_param *iap= (iterate_action_param*)param;
+ UINT rc;
+ LPCWSTR cond, action;
+
+ action = MSI_RecordGetString(row,1);
+ if (!action)
+ {
+ ERR("Error is retrieving action name\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ /* check conditions */
+ cond = MSI_RecordGetString(row,2);
+ if (cond)
+ {
+ /* this is a hack to skip errors in the condition code */
+ if (MSI_EvaluateConditionW(iap->package, cond) == MSICONDITION_FALSE)
+ {
+ TRACE("Skipping action: %s (condition is false)\n",
+ debugstr_w(action));
+ return ERROR_SUCCESS;
+ }
+ }
+
+ if (iap->UI)
+ rc = ACTION_PerformUIAction(iap->package,action);
+ else
+ rc = ACTION_PerformAction(iap->package,action,FALSE);
+
+ if (rc == ERROR_FUNCTION_NOT_CALLED)
+ rc = ERROR_SUCCESS;
+
+ if (rc != ERROR_SUCCESS)
+ ERR("Execution halted due to error (%i)\n",rc);
+
+ return rc;
+}
+
static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran)
{
MSIQUERY * view;
@@ -1117,122 +695,41 @@
' ','\'', 'I','n','s','t','a','l','l',
'V','a','l','i','d','a','t','e','\'', 0};
INT seq = 0;
+ iterate_action_param iap;
+ iap.package = package;
+ iap.UI = FALSE;
- if (package->ExecuteSequenceRun)
+ if (package->script->ExecuteSequenceRun)
{
TRACE("Execute Sequence already Run\n");
return ERROR_SUCCESS;
}
- package->ExecuteSequenceRun = TRUE;
-
+ package->script->ExecuteSequenceRun = TRUE;
+
/* get the sequence number */
if (UIran)
{
- 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;
- }
+ row = MSI_QueryGetRecord(package->db, IVQuery);
+ if( !row )
+ return ERROR_FUNCTION_FAILED;
seq = MSI_RecordGetInteger(row,1);
msiobj_release(&row->hdr);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
}
rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
if (rc == ERROR_SUCCESS)
{
- rc = MSI_ViewExecute(view, 0);
+ TRACE("Running the actions\n");
- if (rc != ERROR_SUCCESS)
- {
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- goto end;
- }
-
- TRACE("Running the actions\n");
-
- while (1)
- {
[truncated at 1000 lines; 11128 more skipped]