Sync to Wine-20050310: Ulrich Czekalla ulrich@codeweavers.com - Add support for radio buttons. - Allocate space for terminating null. - Fix a memory leak. - Prevent accessing freed memory in failure case. Mike McCormack mike@codeweavers.com - Add a border to the edit control, add some more controls. - Implement SQL delete query. - Move product, feature and component enumeration functions to registry.c. - Make sure strings are null terminated. - Fix up the summary information code a little. - Allow MsiViewExecute to be called twice on the same query. - Implement MsiDatabaseGetPrimaryKeys. - MsiGetComponentPath should allow null pointers for pcchBuf and lpPathBuf. - Remove const declaration from non-const function. Jose Manuel Ferrer Ortiz jmfo1982@yahoo.es - Added MSI Spanish resources. Juan Lang juan_lang@yahoo.com - Implement MsiEnumRelatedProducts. - make sure msihandle2msiinfo is correctly matched with msiobj_release - don't do redundant NULL checks - Don't hardcode windows or system directories, correct a typo. - Fix a regression in AppSearch. Jonathan Ernst Jonathan@ErnstFamily.ch - Add French resources. Henning Gerhardt henning.gerhardt@web.de - Add/updated German resources. Marcelo Duarte wine-devel@bol.com.br - Update the resources for Portuguese. Francois Gouget fgouget@free.fr - Assorted spelling fixes. Alexandre Julliard julliard@winehq.org - Avoid spaces before preprocessor directives, that's not portable. Aric Stewart aric@codeweavers.com - Text reformatting patch to clean up all the static strings. - Implement the action RegisterFonts. - Add the ExecuteAction handler. - Store the keypath, and do refcounting and registration of SharedDLLs. - Fix a bug with handing dword values in the registry. - Fix bugs with writing registry keys where value == NULL. - Make use of msidefs.h. - Lay some groundwork for uninstalls. - Update the installed state for components during CostFinalize. Laying groundwork to be able to start processing uninstall logic as well. - Fixed problems with my code for finding the PackageCode. - Stubs for MsiUseFeature. - Do some basic work with registry component paths. - Make sure formats like [\]] and [\[] work properly. Steven Edwards steven@codeweavers.com - Correct typo. Marcus Meissner marcus@jet.franken.de - Output some more informations. - Mark one global variable static. Modified: trunk/reactos/lib/msi/Makefile.in Modified: trunk/reactos/lib/msi/action.c Deleted: trunk/reactos/lib/msi/action.h Added: trunk/reactos/lib/msi/action.h Deleted: trunk/reactos/lib/msi/appsearch.c Added: trunk/reactos/lib/msi/appsearch.c Deleted: trunk/reactos/lib/msi/custom.c Added: trunk/reactos/lib/msi/custom.c Added: trunk/reactos/lib/msi/delete.c Deleted: trunk/reactos/lib/msi/dialog.c Added: trunk/reactos/lib/msi/dialog.c Deleted: trunk/reactos/lib/msi/format.c Added: trunk/reactos/lib/msi/format.c Modified: trunk/reactos/lib/msi/msi.c Deleted: trunk/reactos/lib/msi/msi.rc Added: trunk/reactos/lib/msi/msi.rc Modified: trunk/reactos/lib/msi/msi.spec Added: trunk/reactos/lib/msi/msi_De.rc Deleted: trunk/reactos/lib/msi/msi_En.rc Added: trunk/reactos/lib/msi/msi_En.rc Added: trunk/reactos/lib/msi/msi_Es.rc Added: trunk/reactos/lib/msi/msi_Fr.rc Added: trunk/reactos/lib/msi/msi_Pt.rc Modified: trunk/reactos/lib/msi/msipriv.h Modified: trunk/reactos/lib/msi/msiquery.c Modified: trunk/reactos/lib/msi/package.c Deleted: trunk/reactos/lib/msi/preview.c Added: trunk/reactos/lib/msi/preview.c Modified: trunk/reactos/lib/msi/query.h Modified: trunk/reactos/lib/msi/record.c Deleted: trunk/reactos/lib/msi/registry.c Added: trunk/reactos/lib/msi/registry.c Modified: trunk/reactos/lib/msi/sql.tab.c 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/where.c _____
Modified: trunk/reactos/lib/msi/Makefile.in --- trunk/reactos/lib/msi/Makefile.in 2005-03-14 22:38:12 UTC (rev 14080) +++ trunk/reactos/lib/msi/Makefile.in 2005-03-14 22:54:57 UTC (rev 14081) @@ -11,6 +11,7 @@
appsearch.c \ create.c \ custom.c \ + delete.c \ dialog.c \ distinct.c \ format.c \ _____
Modified: trunk/reactos/lib/msi/action.c --- trunk/reactos/lib/msi/action.c 2005-03-14 22:38:12 UTC (rev 14080) +++ trunk/reactos/lib/msi/action.c 2005-03-14 22:54:57 UTC (rev 14081) @@ -1,6127 +1,6715 @@
-/* - * 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> - -#include <fcntl.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" -#include "action.h" - -#define REG_PROGRESS_VALUE 13200 -#define COMPONENT_PROGRESS_VALUE 24000 - -WINE_DEFAULT_DEBUG_CHANNEL(msi); - -/* - * Prototypes - */ -static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran); -static UINT ACTION_ProcessUISequence(MSIPACKAGE *package); -static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq); -static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, - LPWSTR *FilePath); - -/* - * action handlers - */ -typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*); - -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_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); -static UINT ACTION_WriteIniValues(MSIPACKAGE *package); -static UINT ACTION_SelfRegModules(MSIPACKAGE *package); -static UINT ACTION_PublishFeatures(MSIPACKAGE *package); -static UINT ACTION_RegisterProduct(MSIPACKAGE *package); -static UINT ACTION_InstallExecute(MSIPACKAGE *package); -static UINT ACTION_InstallFinalize(MSIPACKAGE *package); -static UINT ACTION_ForceReboot(MSIPACKAGE *package); -static UINT ACTION_ResolveSource(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_collen[] = {'C',':','\',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}; -const static WCHAR szWriteIniValues[] = -{'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0}; -const static WCHAR szSelfRegModules[] = -{'S','e','l','f','R','e','g','M','o','d','u','l','e','s',0}; -const static WCHAR szPublishFeatures[] = -{'P','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0}; -const static WCHAR szRegisterProduct[] = -{'R','e','g','i','s','t','e','r','P','r','o','d','u','c','t',0}; -const static WCHAR szInstallExecute[] = -{'I','n','s','t','a','l','l','E','x','e','c','u','t','e',0}; -const static WCHAR szInstallExecuteAgain[] = -{'I','n','s','t','a','l','l','E','x','e','c','u','t','e','A','g','a','i ','n',0}; -const static WCHAR szInstallFinalize[] = -{'I','n','s','t','a','l','l','F','i','n','a','l','i','z','e',0}; -const static WCHAR szForceReboot[] = -{'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[] = -{'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','S','p ','a','c','e',0}; -const static WCHAR szBindImage[] = -{'B','i','n','d','I','m','a','g','e',0}; -const static WCHAR szCCPSearch[] = -{'C','C','P','S','e','a','r','c','h',0}; -const static WCHAR szDeleteServices[] = -{'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0}; -const static WCHAR szDisableRollback[] = -{'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[] = -{'F','i','n','d','R','e','l','a','t','e','d','P','r','o','d','u','c','t ','s',0}; -const static WCHAR szInstallAdminPackage[] = -{'I','n','s','t','a','l','l','A','d','m','i','n','P','a','c','k','a','g ','e',0}; -const static WCHAR szInstallSFPCatalogFile[] = -{'I','n','s','t','a','l','l','S','F','P','C','a','t','a','l','o','g','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[] = -{'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[] = -{'M','o','v','e','F','i','l','e','s',0}; -const static WCHAR szMsiPublishAssemblies[] = -{'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i ','e','s',0}; -const static WCHAR szMsiUnpublishAssemblies[] = -{'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b ','l','i','e','s',0}; -const static WCHAR szInstallODBC[] = -{'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[] = -{'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[] = -{'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[] = -{'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[] = -{'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[] = -{'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[] = -{'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}; -const static WCHAR szRemoveIniValues[] = -{'R','e','m','o','v','e','I','n','i','V','a','l','u','e','s',0}; -const static WCHAR szRemoveODBC[] = -{'R','e','m','o','v','e','O','D','B','C',0}; -const static WCHAR szRemoveRegistryValues[] = -{'R','e','m','o','v','e','R','e','g','i','s','t','r','y','V','a','l','u ','e','s',0}; -const static WCHAR szRemoveShortcuts[] = -{'R','e','m','o','v','e','S','h','o','r','t','c','u','t','s',0}; -const static WCHAR szRMCCPSearch[] = -{'R','M','C','C','P','S','e','a','r','c','h',0}; -const static WCHAR szScheduleReboot[] = -{'S','c','h','e','d','u','l','e','R','e','b','o','o','t',0}; -const static WCHAR szSelfUnregModules[] = -{'S','e','l','f','U','n','r','e','g','M','o','d','u','l','e','s',0}; -const static WCHAR szSetODBCFolders[] = -{'S','e','t','O','D','B','C','F','o','l','d','e','r','s',0}; -const static WCHAR szStartServices[] = -{'S','t','a','r','t','S','e','r','v','i','c','e','s',0}; -const static WCHAR szStopServices[] = -{'S','t','o','p','S','e','r','v','i','c','e','s',0}; -const static WCHAR szUnpublishComponents[] = -{'U','n','p','u','b','l','i','s','h','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[] = -{'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[] = -{'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[] = -{'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o ',0}; -const static 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[] = -{'U','n','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 szValidateProductID[] = -{'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0} ; -const static WCHAR szWriteEnvironmentStrings[] = -{'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t ','r','i','n','g','s',0}; - -struct _actions { - LPCWSTR action; - STANDARDACTIONHANDLER handler; -}; - -struct _actions StandardActions[] = { - { szAllocateRegistrySpace, NULL}, - { szAppSearch, ACTION_AppSearch }, - { szBindImage, NULL}, - { szCCPSearch, NULL}, - { szCostFinalize, ACTION_CostFinalize }, - { szCostInitialize, ACTION_CostInitialize }, - { szCreateFolders, ACTION_CreateFolders }, - { szCreateShortcuts, ACTION_CreateShortcuts }, - { szDeleteServices, NULL}, - { szDisableRollback, NULL}, - { szDuplicateFiles, ACTION_DuplicateFiles}, - { szExecuteAction, NULL}, - { szFileCost, ACTION_FileCost }, - { szFindRelatedProducts, NULL}, - { szForceReboot, ACTION_ForceReboot }, - { szInstallAdminPackage, NULL}, - { szInstallExecute, ACTION_InstallExecute }, - { szInstallExecuteAgain, ACTION_InstallExecute }, - { szInstallFiles, ACTION_InstallFiles}, - { szInstallFinalize, ACTION_InstallFinalize }, - { szInstallInitialize, ACTION_InstallInitialize }, - { szInstallSFPCatalogFile, NULL}, - { szInstallValidate, ACTION_InstallValidate }, - { szIsolateComponents, NULL}, - { szLaunchConditions, ACTION_LaunchConditions }, - { szMigrateFeatureStates, NULL}, - { szMoveFiles, NULL}, - { szMsiPublishAssemblies, NULL}, - { szMsiUnpublishAssemblies, NULL}, - { szInstallODBC, NULL}, - { szInstallServices, NULL}, - { szPatchFiles, NULL}, - { szProcessComponents, ACTION_ProcessComponents }, - { szPublishComponents, NULL}, - { szPublishFeatures, ACTION_PublishFeatures }, - { szPublishProduct, ACTION_PublishProduct }, - { szRegisterClassInfo, ACTION_RegisterClassInfo }, - { szRegisterComPlus, NULL}, - { szRegisterExtensionInfo, ACTION_RegisterExtensionInfo }, - { szRegisterFonts, NULL}, - { szRegisterMIMEInfo, ACTION_RegisterMIMEInfo }, - { szRegisterProduct, ACTION_RegisterProduct }, - { szRegisterProgIdInfo, ACTION_RegisterProgIdInfo }, - { szRegisterTypeLibraries, ACTION_RegisterTypeLibraries }, - { szRegisterUser, ACTION_RegisterUser}, - { szRemoveDuplicateFiles, NULL}, - { szRemoveEnvironmentStrings, NULL}, - { szRemoveExistingProducts, NULL}, - { szRemoveFiles, NULL}, - { szRemoveFolders, NULL}, - { szRemoveIniValues, NULL}, - { szRemoveODBC, NULL}, - { szRemoveRegistryValues, NULL}, - { szRemoveShortcuts, NULL}, - { szResolveSource, ACTION_ResolveSource}, - { szRMCCPSearch, NULL}, - { szScheduleReboot, NULL}, - { szSelfRegModules, ACTION_SelfRegModules }, - { szSelfUnregModules, NULL}, - { szSetODBCFolders, NULL}, - { szStartServices, NULL}, - { szStopServices, NULL}, - { szUnpublishComponents, NULL}, - { szUnpublishFeatures, NULL}, - { szUnregisterClassInfo, NULL}, - { szUnregisterComPlus, NULL}, - { szUnregisterExtensionInfo, NULL}, - { szUnregisterFonts, NULL}, - { szUnregisterMIMEInfo, NULL}, - { szUnregisterProgIdInfo, NULL}, - { szUnregisterTypeLibraries, NULL}, - { szValidateProductID, NULL}, - { szWriteEnvironmentStrings, NULL}, - { szWriteIniValues, ACTION_WriteIniValues }, - { szWriteRegistryValues, ACTION_WriteRegistryValues}, - { NULL, NULL}, -}; - - -/******************************************************** - * helper functions to get around current HACKS and such - ********************************************************/ -inline static void reduce_to_longfilename(WCHAR* filename) -{ - LPWSTR p = strchrW(filename,'|'); - if (p) - memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR)); -} - -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 = dupstrW(name); - package->files[index].TargetPath = dupstrW(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); - - /* no dynamic buffers in components */ - 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].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(package->dialog, 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); - 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; - } - - /* update the cached actionformat */ - HeapFree(GetProcessHeap(),0,package->ActionFormat); - package->ActionFormat = load_dynamic_stringW(row,3); - - HeapFree(GetProcessHeap(),0,package->LastAction); - package->LastAction = dupstrW(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); - 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; - - GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100); - - 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; - } - - 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); -} - -/* - * 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; -} - - -/**************************************************** - * 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}; - static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; - static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0}; - - MSI_SetPropertyW(package, szAction, szInstall); - - if (szPackagePath) - { - LPWSTR p, check, path; - - package->PackagePath = dupstrW(szPackagePath); - path = dupstrW(szPackagePath); - p = strrchrW(path,'\'); - if (p) - { - p++; - *p=0; - } - else - { - HeapFree(GetProcessHeap(),0,path); - path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR)); - GetCurrentDirectoryW(MAX_PATH,path); - strcatW(path,cszbs); - } - - check = load_dynamic_property(package, cszSourceDir,NULL); - if (!check) - MSI_SetPropertyW(package, cszSourceDir, path); - else - HeapFree(GetProcessHeap(), 0, check); - - HeapFree(GetProcessHeap(), 0, path); - } - - if (szCommandLine) - { - LPWSTR ptr,ptr2; - ptr = (LPWSTR)szCommandLine; - - while (*ptr) - { - WCHAR *prop = NULL; - WCHAR *val = NULL; - - TRACE("Looking at %s\n",debugstr_w(ptr)); - - ptr2 = strchrW(ptr,'='); - if (ptr2) - { - BOOL quote=FALSE; - DWORD len = 0; - - while (*ptr == ' ') ptr++; - len = ptr2-ptr; - prop = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR)); - strncpyW(prop,ptr,len); - prop[len]=0; - ptr2++; - - len = 0; - ptr = ptr2; - while (*ptr && (quote || (!quote && *ptr!=' '))) - { - if (*ptr == '"') - quote = !quote; - ptr++; - len++; - } - - if (*ptr2=='"') - { - ptr2++; - len -= 2; - } - val = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR)); - 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); - } - HeapFree(GetProcessHeap(),0,val); - HeapFree(GetProcessHeap(),0,prop); - } - 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); - - if (rc == -1) - { - /* install was halted but should be considered a success */ - rc = ERROR_SUCCESS; - } - - /* process the ending type action */ - if (rc == ERROR_SUCCESS) - ACTION_PerformActionSequence(package,-1); - else if (rc == ERROR_INSTALL_USEREXIT) - ACTION_PerformActionSequence(package,-2); - else if (rc == ERROR_FUNCTION_FAILED) - ACTION_PerformActionSequence(package,-3); - else if (rc == ERROR_INSTALL_SUSPEND) - ACTION_PerformActionSequence(package,-4); - - /* finish up running custom actions */ - ACTION_FinishCustomActions(package); - - return rc; -} - -static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq) -{ - MSIQUERY * view; - UINT rc; - WCHAR buffer[0x100]; - DWORD sz = 0x100; - MSIRECORD * row = 0; - 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',0}; - - rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq); - - 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"); - - rc = MSI_ViewFetch(view,&row); - if (rc != ERROR_SUCCESS) - { - rc = ERROR_SUCCESS; - goto end; - } - - /* check conditions */ [truncated at 1000 lines; 19371 more skipped]