Sync to Wine-20050628: Mike McCormack mike@codeweavers.com - Repaint the area behind the "transparent" text control when it changes. - Implement transparency in the text control. - Make the MSI icon control work. - Make tabs work in msi dialogs. - Added support for the MSI MaskEdit control. - Use a richedit control for license text. - Fix radio button groups. Don't add the WS_GROUP style to every window. - Use standard lists in the event subscription code. - Take the dialog frame into account when calculating the dialog size. - Use MSI_QueryGetRecord in one more place. - Create a helper function to fetch a single record from a query. - More -Wmissing-declarations and -Wwrite-strings warning fixes. - Get rid of some redundant parser types. - Use the new helper function MSI_QueryGetRecord. - Use MSI_RecordGetString in more actions. - Use MSI_RecordGetString where possible. - Fixes for -Wmissing-declarations and -Wwrite-strings warnings. - Remove some unused code. - Add and correct some function declarations. - Improve number parsing and avoid unicode.h. - avoid unicode.h - add a missing function prototype - Create a stub implementation for MsiViewGetError. - Remove more types from the parser. - Test and fix the size of stream fields in a record. - Clean up headers and make some functions static. Marcus Meissner meissner@suse.de - Use a simpler expression for the "RichEdit20W" string to workaround compiler bug. - Remove cszbs from msi/action.h. Aric Stewart aric@codeweavers.com Mike McCormack mike@codeweavers.com - Allow dialog controls to subscribe to installer events. - Fix handling of checkbox properties. - Implement dialog events and hook up the dialog code. Aric Stewart aric@codeweavers.com - Break out all the file related actions and helper functions into files.c - Break out all the top level apis into install.c. - Break out all the class registration actions into classes.c. This includes RegisterClassInfo, RegisterProgIds, RegisterExtensions and RegisterMIMETypes. - Break out all the helper functions into helpers.c. - Added module upgrade.c and implemented FindRelatedProducts. - A long overdue fix to MSI_SetTargetPath. This should fix an error with some installers that where unable to change the target path. - Add functions to add the User UpgradeCodes. - A simple cleanup to only track the temp file if we need to have it laying around because the action is going on asynchronously. Otherwise clean up the temp file as the action finishes. - Introduce really basic scripting of actions. This is primarily to get the order of execution of the action correct since some custom actions can be scripted and others are run during the script building phase. - Perform ExecuteAction at UILevel 2. - Rework CreateShortcuts to use MSI_IterateRecords. - Properly handle -1 as a registry key root. - Rework SelfRegModules to use MSI_IterateRecords. - Rework component, feature and file loading to use MSI_IterateRecords. - Rework RegisterFonts to use MSI_IterateRecords. - Rework WriteIniValues to use MSI_IterateRecords. - Rework PublishProduct to use MSI_IterateRecords. - Rework RegisterTypeLibraries to use MSI_IterateR - Rework LaunchConditions to use MSI_IterateRecord - Rework CostFinalize to use MSI_IterateRecords. - Rework WriteRegistryValues to use MSI_IterateRecords. - Rework CreateFolders to use MSI_IterateRecords. - Use MSI_IterateRecords for processing actions. Some whitespace cleanup and replace a comment block I did not want to remove. - Flesh out the remaining keys in RegisterProduct. - Extending upon Mike McCormack's cleanup to use MSI_RecordGetString. - Register the Product Version also. Also help plug some memory leaks pointed out by Mike McCormack. - Avoid a loop where a parent's parent refers to itself as its parent. - Added module upgrade.c and implemented FindRelatedProducts. - Set the Preselected property if appropriate (relevant to MigrateFeatureStates when implemented). - Write out Product Language and Product Icon to the registry. - Write out UpgradeCodes to the registry to allow for future upgrades. - Don't get caught in loops on parent progids. - Since multiple progids can refer to 1 class we need to check if that class is isntalled instead of just relying on having it set the InstallMe variable. - Add install_on_demand for Extension servers also. currently defaulting to TRUE. - Extension need to have 1 verb to mark the given progid to be installed. - Do not loop if a ProgId's Parent Index it itself. - Add a VersionIndIndex for tracking version independent fields for the ProgIds properly. - Print a message for skipped actions in ProcessExecSequence like in the UISequence. - Do not change a features state to Advertise if it explicitly disallows it. - For typelibs index 1 do not add \1 to the path. This cleans up registry diffs with native MSI. - Register the FileType and correct short vs long path problems with InprocServer32. Also add install_on_demand boolean for future expansion. - First pass at writing out CurVer keys for ProgIds. Also print a message for the actions we skip. Lines up with native MSI output logs for ease of comparison. - A big rewrite of the whole RegisterClass, RegisterProgId, RegisterExtension and RegisterMIME actions. We now handle verbs properly, handle dependancies and such properly and keep track of what we need to register and what we do not properly. - Allow control events to return codes to halt the processing of event. Needed for the SetTargetPath Event. - Fix situations where TARGETDIR is set to a non \ terminated path. Fixes a few installers. - Redo how we extract files from a cabinet in order to dramatically improve performance, especially if picking and choosing files out of the cabinet. - Duplicate files should not fail if unable to get Destination Directory. - Use MSI_IterateRecords for DuplicateFiles. - Add UI messages to FindRelatedProducts. - Reduce unneeded includes. - A "1" is returned not a 1 for AssignmentType. Also as a bit more to the FIXME message. - Add Language to the values we can query with MsiGetProductInfo. - Correct a crash if the length buffer is NULL. - Locate where a buffer size is not being set and correctly handle the buffer size conversion from W to A (with help from Robert Shearman). - Make sure the TRACE statements do not spew garbage by using debugstr_wn. - Restrict deformating of nested index keys [[1]]. - Introduce the beginning of group deformating {}. - Implement the [!file] format to produce the short filename. Stefan Huehner stefan@huehner.org - Fix more -Wstrict-prototypes warnings. Francois Gouget fgouget@free.fr - Assorted spelling fixes. Dmitry Timoshkov dmitry@codeweavers.com - Make more of the OLE interface vtables const. Added: trunk/reactos/include/wine/msvcrt/ Added: trunk/reactos/include/wine/msvcrt/fcntl.h Modified: trunk/reactos/lib/msi/Makefile.in Modified: trunk/reactos/lib/msi/action.c Modified: trunk/reactos/lib/msi/action.h Added: trunk/reactos/lib/msi/classes.c Modified: trunk/reactos/lib/msi/cond.tab.c Modified: trunk/reactos/lib/msi/cond.tab.h Modified: trunk/reactos/lib/msi/cond.y Modified: trunk/reactos/lib/msi/create.c Modified: trunk/reactos/lib/msi/custom.c Modified: trunk/reactos/lib/msi/database.c Modified: trunk/reactos/lib/msi/dialog.c Added: trunk/reactos/lib/msi/events.c Added: trunk/reactos/lib/msi/files.c Modified: trunk/reactos/lib/msi/format.c Added: trunk/reactos/lib/msi/helpers.c Modified: trunk/reactos/lib/msi/insert.c Added: trunk/reactos/lib/msi/install.c Modified: trunk/reactos/lib/msi/msi.c Modified: trunk/reactos/lib/msi/msi.spec Modified: trunk/reactos/lib/msi/msi.xml Modified: trunk/reactos/lib/msi/msipriv.h Modified: trunk/reactos/lib/msi/msiquery.c Modified: trunk/reactos/lib/msi/order.c Modified: trunk/reactos/lib/msi/package.c Modified: trunk/reactos/lib/msi/preview.c Modified: trunk/reactos/lib/msi/query.h Modified: trunk/reactos/lib/msi/record.c Modified: trunk/reactos/lib/msi/registry.c Modified: trunk/reactos/lib/msi/select.c Modified: trunk/reactos/lib/msi/sql.tab.c Modified: trunk/reactos/lib/msi/sql.tab.h Modified: trunk/reactos/lib/msi/sql.y Modified: trunk/reactos/lib/msi/suminfo.c Modified: trunk/reactos/lib/msi/table.c Modified: trunk/reactos/lib/msi/tokenize.c Modified: trunk/reactos/lib/msi/update.c Added: trunk/reactos/lib/msi/upgrade.c Modified: trunk/reactos/lib/msi/where.c Modified: trunk/reactos/w32api/include/msi.h Modified: trunk/reactos/w32api/include/msidefs.h Modified: trunk/reactos/w32api/include/msiquery.h _____
Added: trunk/reactos/include/wine/msvcrt/fcntl.h --- trunk/reactos/include/wine/msvcrt/fcntl.h 2005-08-03 21:34:01 UTC (rev 17033) +++ trunk/reactos/include/wine/msvcrt/fcntl.h 2005-08-03 22:12:15 UTC (rev 17034) @@ -0,0 +1,10 @@
+#ifndef __WINE_MSVCRT_FCNTL_H +#define __WINE_MSVCRT_FCNTL_H + +/* + * Compatibility header + */ + +#include <fcntl.h> + +#endif /* __WINE_MSVCRT_FCNTL_H */ Property changes on: trunk/reactos/include/wine/msvcrt/fcntl.h ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native _____
Modified: trunk/reactos/lib/msi/Makefile.in --- trunk/reactos/lib/msi/Makefile.in 2005-08-03 21:34:01 UTC (rev 17033) +++ trunk/reactos/lib/msi/Makefile.in 2005-08-03 22:12:15 UTC (rev 17034) @@ -4,21 +4,26 @@
VPATH = @srcdir@ MODULE = msi.dll IMPORTLIB = libmsi.$(IMPLIBEXT) -IMPORTS = shell32 cabinet oleaut32 ole32 version user32 gdi32 advapi32 kernel32 +IMPORTS = shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 kernel32 EXTRALIBS = -luuid $(LIBUNICODE)
C_SRCS = \ action.c \ appsearch.c \ + classes.c \ create.c \ custom.c \ database.c \ delete.c \ dialog.c \ distinct.c \ + events.c \ + files.c \ format.c \ handle.c \ + helpers.c \ insert.c \ + install.c \ msi.c \ msiquery.c \ order.c \ @@ -33,6 +38,7 @@ table.c \ tokenize.c \ update.c \ + upgrade.c \ where.c
RC_SRCS = msi.rc _____
Modified: trunk/reactos/lib/msi/action.c --- 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]