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/setup/installexecutesequence_table.asp
-
-http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/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]