* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-#define COBJMACROS
-
-#include <stdarg.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winnls.h"
-#include "shlwapi.h"
-#include "wingdi.h"
-#include "wine/debug.h"
-#include "msi.h"
-#include "msiquery.h"
-#include "objidl.h"
-#include "wincrypt.h"
-#include "winuser.h"
-#include "wininet.h"
-#include "winver.h"
-#include "urlmon.h"
-#include "shlobj.h"
-#include "wine/unicode.h"
-#include "objbase.h"
-#include "msidefs.h"
-#include "sddl.h"
-
#include "msipriv.h"
-#include "msiserver.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
-static void remove_tracked_tempfiles( MSIPACKAGE *package )
-{
- struct list *item, *cursor;
- LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles )
- {
- MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry );
+#include <wininet.h>
- list_remove( &temp->entry );
- TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
- DeleteFileW( temp->Path );
- msi_free( temp->Path );
- msi_free( temp );
- }
-}
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
static void free_feature( MSIFEATURE *feature )
{
static void free_package_structures( MSIPACKAGE *package )
{
- INT i;
struct list *item, *cursor;
LIST_FOR_EACH_SAFE( item, cursor, &package->features )
free_folder( folder );
}
+ LIST_FOR_EACH_SAFE( item, cursor, &package->files )
+ {
+ MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
+
+ list_remove( &file->entry );
+ msi_free( file->File );
+ msi_free( file->FileName );
+ msi_free( file->ShortName );
+ msi_free( file->LongName );
+ msi_free( file->Version );
+ msi_free( file->Language );
+ if (msi_is_global_assembly( file->Component )) DeleteFileW( file->TargetPath );
+ msi_free( file->TargetPath );
+ msi_free( file );
+ }
+
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
{
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
msi_free( comp );
}
- LIST_FOR_EACH_SAFE( item, cursor, &package->files )
+ LIST_FOR_EACH_SAFE( item, cursor, &package->filepatches )
{
- MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
+ MSIFILEPATCH *patch = LIST_ENTRY( item, MSIFILEPATCH, entry );
- list_remove( &file->entry );
- msi_free( file->File );
- msi_free( file->FileName );
- msi_free( file->ShortName );
- msi_free( file->LongName );
- msi_free( file->Version );
- msi_free( file->Language );
- msi_free( file->TargetPath );
- msi_free( file );
+ list_remove( &patch->entry );
+ msi_free( patch->path );
+ msi_free( patch );
}
/* clean up extension, progid, class and verb structures */
if (package->script)
{
+ INT i;
+ UINT j;
+
for (i = 0; i < SCRIPT_MAX; i++)
msi_free_action_script( package, i );
- for (i = 0; i < package->script->UniqueActionsCount; i++)
- msi_free( package->script->UniqueActions[i] );
+ for (j = 0; j < package->script->UniqueActionsCount; j++)
+ msi_free( package->script->UniqueActions[j] );
msi_free( package->script->UniqueActions );
msi_free( package->script );
msi_free( package->ProductCode );
msi_free( package->ActionFormat );
msi_free( package->LastAction );
+ msi_free( package->LastActionTemplate );
msi_free( package->langids );
- remove_tracked_tempfiles(package);
-
/* cleanup control event subscriptions */
- ControlEvent_CleanupSubscriptions( package );
+ msi_event_cleanup_all_subscriptions( package );
}
static void MSI_FreePackage( MSIOBJECTHDR *arg)
if (package->delete_on_close) DeleteFileW( package->localfile );
msi_free( package->localfile );
+ MSI_ProcessMessage(NULL, INSTALLMESSAGE_TERMINATE, 0);
}
static UINT create_temp_property_table(MSIPACKAGE *package)
return rc;
}
-UINT msi_clone_properties(MSIPACKAGE *package)
+UINT msi_clone_properties( MSIDATABASE *db )
{
static const WCHAR query_select[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
MSIQUERY *view_select;
UINT rc;
- rc = MSI_DatabaseOpenViewW( package->db, query_select, &view_select );
+ rc = MSI_DatabaseOpenViewW( db, query_select, &view_select );
if (rc != ERROR_SUCCESS)
return rc;
if (rc != ERROR_SUCCESS)
break;
- rc = MSI_DatabaseOpenViewW( package->db, query_insert, &view_insert );
+ rc = MSI_DatabaseOpenViewW( db, query_insert, &view_insert );
if (rc != ERROR_SUCCESS)
{
msiobj_release( &rec_select->hdr );
TRACE("insert failed, trying update\n");
- rc = MSI_DatabaseOpenViewW( package->db, query_update, &view_update );
+ rc = MSI_DatabaseOpenViewW( db, query_update, &view_update );
if (rc != ERROR_SUCCESS)
{
WARN("open view failed %u\n", rc);
if (r == ERROR_SUCCESS)
{
RegCloseKey( hkey );
- msi_set_property( package->db, szInstalled, szOne );
+ msi_set_property( package->db, szInstalled, szOne, -1 );
}
return r;
}
if (!ConvertSidToStringSidW( psid, &sid_str ))
goto done;
- r = msi_set_property( package->db, szUserSID, sid_str );
+ r = msi_set_property( package->db, szUserSID, sid_str, -1 );
done:
LocalFree( sid_str );
return;
size = GetFileVersionInfoSizeW(fusion, &handle);
- if (!size) return;
+ if (!size)
+ goto done;
version = msi_alloc(size);
- if (!version) return;
+ if (!version)
+ goto done;
if (!GetFileVersionInfoW(fusion, handle, size, version))
goto done;
if (!val_len || !verstr)
goto done;
- msi_set_property(package->db, netasm, verstr);
+ msi_set_property( package->db, netasm, verstr, -1 );
done:
msi_free(fusion);
HKEY hkey;
LPWSTR username, companyname;
SYSTEM_INFO sys_info;
- SYSTEMTIME systemtime;
LANGID langid;
static const WCHAR szCommonFilesFolder[] = {'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
};
static const WCHAR szUSERNAME[] = {'U','S','E','R','N','A','M','E',0};
static const WCHAR szCOMPANYNAME[] = {'C','O','M','P','A','N','Y','N','A','M','E',0};
- static const WCHAR szDate[] = {'D','a','t','e',0};
- static const WCHAR szTime[] = {'T','i','m','e',0};
static const WCHAR szUserLanguageID[] = {'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0};
static const WCHAR szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0};
static const WCHAR szProductState[] = {'P','r','o','d','u','c','t','S','t','a','t','e',0};
SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szCommonAppDataFolder, pth);
+ msi_set_property( package->db, szCommonAppDataFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szFavoritesFolder, pth);
+ msi_set_property( package->db, szFavoritesFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szFontsFolder, pth);
+ msi_set_property( package->db, szFontsFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_SENDTO, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szSendToFolder, pth);
+ msi_set_property( package->db, szSendToFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szStartMenuFolder, pth);
+ msi_set_property( package->db, szStartMenuFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szStartupFolder, pth);
+ msi_set_property( package->db, szStartupFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_TEMPLATES, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szTemplateFolder, pth);
+ msi_set_property( package->db, szTemplateFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szDesktopFolder, pth);
+ msi_set_property( package->db, szDesktopFolder, pth, -1 );
/* FIXME: set to AllUsers profile path if ALLUSERS is set */
SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szProgramMenuFolder, pth);
+ msi_set_property( package->db, szProgramMenuFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szAdminToolsFolder, pth);
+ msi_set_property( package->db, szAdminToolsFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szAppDataFolder, pth);
+ msi_set_property( package->db, szAppDataFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szSystemFolder, pth);
- msi_set_property(package->db, szSystem16Folder, pth);
+ msi_set_property( package->db, szSystemFolder, pth, -1 );
+ msi_set_property( package->db, szSystem16Folder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szLocalAppDataFolder, pth);
+ msi_set_property( package->db, szLocalAppDataFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szMyPicturesFolder, pth);
+ msi_set_property( package->db, szMyPicturesFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szPersonalFolder, pth);
+ msi_set_property( package->db, szPersonalFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szWindowsFolder, pth);
+ msi_set_property( package->db, szWindowsFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szPrintHoodFolder, pth);
+ msi_set_property( package->db, szPrintHoodFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szNetHoodFolder, pth);
+ msi_set_property( package->db, szNetHoodFolder, pth, -1 );
SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, szRecentFolder, pth);
+ msi_set_property( package->db, szRecentFolder, pth, -1 );
/* Physical Memory is specified in MB. Using total amount. */
msex.dwLength = sizeof(msex);
GlobalMemoryStatusEx( &msex );
- sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) );
- msi_set_property(package->db, szPhysicalMemory, bufstr);
+ len = sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) );
+ msi_set_property( package->db, szPhysicalMemory, bufstr, len );
SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
ptr = strchrW(pth,'\\');
if (ptr) *(ptr + 1) = 0;
- msi_set_property(package->db, szWindowsVolume, pth);
+ msi_set_property( package->db, szWindowsVolume, pth, -1 );
- GetTempPathW(MAX_PATH,pth);
- msi_set_property(package->db, szTempFolder, pth);
+ len = GetTempPathW(MAX_PATH, pth);
+ msi_set_property( package->db, szTempFolder, pth, len );
/* in a wine environment the user is always admin and privileged */
- msi_set_property(package->db, szAdminUser, szOne);
- msi_set_property(package->db, szPrivileged, szOne);
+ msi_set_property( package->db, szAdminUser, szOne, -1 );
+ msi_set_property( package->db, szPrivileged, szOne, -1 );
/* set the os things */
OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
GetVersionExW((OSVERSIONINFOW *)&OSVersion);
verval = OSVersion.dwMinorVersion + OSVersion.dwMajorVersion * 100;
- sprintfW(verstr, szFormat, verval);
+ len = sprintfW( verstr, szFormat, verval );
switch (OSVersion.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS:
- msi_set_property(package->db, szVersion9x, verstr);
+ msi_set_property( package->db, szVersion9x, verstr, len );
break;
case VER_PLATFORM_WIN32_NT:
- msi_set_property(package->db, szVersionNT, verstr);
- sprintfW(verstr, szFormat,OSVersion.wProductType);
- msi_set_property(package->db, szMsiNTProductType, verstr);
+ msi_set_property( package->db, szVersionNT, verstr, len );
+ len = sprintfW( bufstr, szFormat,OSVersion.wProductType );
+ msi_set_property( package->db, szMsiNTProductType, bufstr, len );
break;
}
- sprintfW(verstr, szFormat, OSVersion.dwBuildNumber);
- msi_set_property(package->db, szWindowsBuild, verstr);
- sprintfW(verstr, szFormat, OSVersion.wServicePackMajor);
- msi_set_property(package->db, szServicePackLevel, verstr);
+ len = sprintfW( bufstr, szFormat, OSVersion.dwBuildNumber );
+ msi_set_property( package->db, szWindowsBuild, bufstr, len );
+ len = sprintfW( bufstr, szFormat, OSVersion.wServicePackMajor );
+ msi_set_property( package->db, szServicePackLevel, bufstr, len );
- sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
- msi_set_property( package->db, szVersionMsi, bufstr );
- sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100);
- msi_set_property( package->db, szVersionDatabase, bufstr );
+ len = sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION );
+ msi_set_property( package->db, szVersionMsi, bufstr, len );
+ len = sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100 );
+ msi_set_property( package->db, szVersionDatabase, bufstr, len );
GetNativeSystemInfo( &sys_info );
- sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel );
- msi_set_property( package->db, szIntel, bufstr );
+ len = sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel );
+ msi_set_property( package->db, szIntel, bufstr, len );
if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
GetSystemDirectoryW( pth, MAX_PATH );
PathAddBackslashW( pth );
- msi_set_property( package->db, szSystemFolder, pth );
+ msi_set_property( package->db, szSystemFolder, pth, -1 );
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
PathAddBackslashW( pth );
- msi_set_property( package->db, szProgramFilesFolder, pth );
+ msi_set_property( package->db, szProgramFilesFolder, pth, -1 );
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
PathAddBackslashW( pth );
- msi_set_property( package->db, szCommonFilesFolder, pth );
+ msi_set_property( package->db, szCommonFilesFolder, pth, -1 );
}
else if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
{
- msi_set_property( package->db, szMsiAMD64, bufstr );
- msi_set_property( package->db, szMsix64, bufstr );
- msi_set_property( package->db, szVersionNT64, verstr );
+ msi_set_property( package->db, szMsiAMD64, bufstr, -1 );
+ msi_set_property( package->db, szMsix64, bufstr, -1 );
+ msi_set_property( package->db, szVersionNT64, verstr, -1 );
GetSystemDirectoryW( pth, MAX_PATH );
PathAddBackslashW( pth );
- msi_set_property( package->db, szSystem64Folder, pth );
+ msi_set_property( package->db, szSystem64Folder, pth, -1 );
GetSystemWow64DirectoryW( pth, MAX_PATH );
PathAddBackslashW( pth );
- msi_set_property( package->db, szSystemFolder, pth );
+ msi_set_property( package->db, szSystemFolder, pth, -1 );
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
PathAddBackslashW( pth );
- msi_set_property( package->db, szProgramFiles64Folder, pth );
+ msi_set_property( package->db, szProgramFiles64Folder, pth, -1 );
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth );
PathAddBackslashW( pth );
- msi_set_property( package->db, szProgramFilesFolder, pth );
+ msi_set_property( package->db, szProgramFilesFolder, pth, -1 );
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
PathAddBackslashW( pth );
- msi_set_property( package->db, szCommonFiles64Folder, pth );
+ msi_set_property( package->db, szCommonFiles64Folder, pth, -1 );
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth );
PathAddBackslashW( pth );
- msi_set_property( package->db, szCommonFilesFolder, pth );
+ msi_set_property( package->db, szCommonFilesFolder, pth, -1 );
}
/* Screen properties. */
dc = GetDC(0);
- sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, HORZRES ) );
- msi_set_property( package->db, szScreenX, bufstr );
- sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, VERTRES ));
- msi_set_property( package->db, szScreenY, bufstr );
- sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, BITSPIXEL ));
- msi_set_property( package->db, szColorBits, bufstr );
+ len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, HORZRES) );
+ msi_set_property( package->db, szScreenX, bufstr, len );
+ len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, VERTRES) );
+ msi_set_property( package->db, szScreenY, bufstr, len );
+ len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, BITSPIXEL) );
+ msi_set_property( package->db, szColorBits, bufstr, len );
ReleaseDC(0, dc);
/* USERNAME and COMPANYNAME */
{
if (!username &&
(username = msi_reg_get_val_str( hkey, szDefName )))
- msi_set_property( package->db, szUSERNAME, username );
+ msi_set_property( package->db, szUSERNAME, username, -1 );
if (!companyname &&
(companyname = msi_reg_get_val_str( hkey, szDefCompany )))
- msi_set_property( package->db, szCOMPANYNAME, companyname );
+ msi_set_property( package->db, szCOMPANYNAME, companyname, -1 );
CloseHandle( hkey );
}
if ((!username || !companyname) &&
{
if (!username &&
(username = msi_reg_get_val_str( hkey, szRegisteredUser )))
- msi_set_property( package->db, szUSERNAME, username );
+ msi_set_property( package->db, szUSERNAME, username, -1 );
if (!companyname &&
(companyname = msi_reg_get_val_str( hkey, szRegisteredOrganization )))
- msi_set_property( package->db, szCOMPANYNAME, companyname );
+ msi_set_property( package->db, szCOMPANYNAME, companyname, -1 );
CloseHandle( hkey );
}
msi_free( username );
if ( set_user_sid_prop( package ) != ERROR_SUCCESS)
ERR("Failed to set the UserSID property\n");
- /* Date and time properties */
- GetSystemTime( &systemtime );
- if (GetDateFormatW( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime,
- NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) ))
- msi_set_property( package->db, szDate, bufstr );
- else
- ERR("Couldn't set Date property: GetDateFormat failed with error %d\n", GetLastError());
-
- if (GetTimeFormatW( LOCALE_USER_DEFAULT,
- TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER,
- &systemtime, NULL, bufstr,
- sizeof(bufstr)/sizeof(bufstr[0]) ))
- msi_set_property( package->db, szTime, bufstr );
- else
- ERR("Couldn't set Time property: GetTimeFormat failed with error %d\n", GetLastError());
-
set_msi_assembly_prop( package );
langid = GetUserDefaultLangID();
- sprintfW(bufstr, szIntFormat, langid);
- msi_set_property( package->db, szUserLanguageID, bufstr );
+ len = sprintfW( bufstr, szIntFormat, langid );
+ msi_set_property( package->db, szUserLanguageID, bufstr, len );
langid = GetSystemDefaultLangID();
- sprintfW(bufstr, szIntFormat, langid);
- msi_set_property( package->db, szSystemLangID, bufstr );
+ len = sprintfW( bufstr, szIntFormat, langid );
+ msi_set_property( package->db, szSystemLangID, bufstr, len );
- sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode));
- msi_set_property( package->db, szProductState, bufstr );
+ len = sprintfW( bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode) );
+ msi_set_property( package->db, szProductState, bufstr, len );
len = 0;
if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
if ((username = msi_alloc( len * sizeof(WCHAR) )))
{
if (GetUserNameW( username, &len ))
- msi_set_property( package->db, szLogonUser, username );
+ msi_set_property( package->db, szLogonUser, username, len - 1 );
msi_free( username );
}
}
if ((computername = msi_alloc( len * sizeof(WCHAR) )))
{
if (GetComputerNameW( computername, &len ))
- msi_set_property( package->db, szComputerName, computername );
+ msi_set_property( package->db, szComputerName, computername, len );
msi_free( computername );
}
}
}
-static UINT msi_load_summary_properties( MSIPACKAGE *package )
-{
- UINT rc;
- MSIHANDLE suminfo;
- MSIHANDLE hdb = alloc_msihandle( &package->db->hdr );
- INT count;
- DWORD len;
- LPWSTR package_code;
- static const WCHAR szPackageCode[] = {
- 'P','a','c','k','a','g','e','C','o','d','e',0};
-
- if (!hdb) {
- ERR("Unable to allocate handle\n");
- return ERROR_OUTOFMEMORY;
- }
-
- rc = MsiGetSummaryInformationW( hdb, NULL, 0, &suminfo );
- MsiCloseHandle(hdb);
- if (rc != ERROR_SUCCESS)
- {
- ERR("Unable to open Summary Information\n");
- return rc;
- }
-
- rc = MsiSummaryInfoGetPropertyW( suminfo, PID_PAGECOUNT, NULL,
- &count, NULL, NULL, NULL );
- if (rc != ERROR_SUCCESS)
- {
- WARN("Unable to query page count: %d\n", rc);
- goto done;
- }
-
- /* load package code property */
- len = 0;
- rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL,
- NULL, NULL, NULL, &len );
- if (rc != ERROR_MORE_DATA)
- {
- WARN("Unable to query revision number: %d\n", rc);
- rc = ERROR_FUNCTION_FAILED;
- goto done;
- }
-
- len++;
- package_code = msi_alloc( len * sizeof(WCHAR) );
- rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL,
- NULL, NULL, package_code, &len );
- if (rc != ERROR_SUCCESS)
- {
- WARN("Unable to query rev number: %d\n", rc);
- goto done;
- }
-
- msi_set_property( package->db, szPackageCode, package_code );
- msi_free( package_code );
-
- /* load package attributes */
- count = 0;
- MsiSummaryInfoGetPropertyW( suminfo, PID_WORDCOUNT, NULL,
- &count, NULL, NULL, NULL );
- package->WordCount = count;
-
-done:
- MsiCloseHandle(suminfo);
- return rc;
-}
-
static MSIPACKAGE *msi_alloc_package( void )
{
MSIPACKAGE *package;
if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2)
{
TRACE("resetting ALLUSERS property from 2 to 1\n");
- msi_set_property( package->db, szAllUsers, szOne );
+ msi_set_property( package->db, szAllUsers, szOne, -1 );
}
- msi_set_property( package->db, szAdminUser, szOne );
+ msi_set_property( package->db, szAdminUser, szOne, -1 );
}
MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
static const WCHAR fmtW[] = {'%','u',0};
MSIPACKAGE *package;
WCHAR uilevel[11];
+ int len;
UINT r;
TRACE("%p\n", db);
msiobj_addref( &db->hdr );
package->db = db;
+ package->LastAction = NULL;
+ package->LastActionTemplate = NULL;
+ package->LastActionResult = MSI_NULL_INTEGER;
package->WordCount = 0;
package->PackagePath = strdupW( db->path );
package->BaseURL = strdupW( base_url );
create_temp_property_table( package );
- msi_clone_properties( package );
+ msi_clone_properties( package->db );
msi_adjust_privilege_properties( package );
package->ProductCode = msi_dup_property( package->db, szProductCode );
package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
- set_installed_prop( package );
set_installer_properties( package );
package->ui_level = gUILevel;
- sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK );
- msi_set_property(package->db, szUILevel, uilevel);
+ len = sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK );
+ msi_set_property( package->db, szUILevel, uilevel, len );
- r = msi_load_summary_properties( package );
+ r = msi_load_suminfo_properties( package );
if (r != ERROR_SUCCESS)
{
msiobj_release( &package->hdr );
return ERROR_SUCCESS;
}
-static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
+static enum platform parse_platform( const WCHAR *str )
{
- WCHAR *template, *p, *q;
+ if (!str[0] || !strcmpW( str, szIntel )) return PLATFORM_INTEL;
+ else if (!strcmpW( str, szIntel64 )) return PLATFORM_INTEL64;
+ else if (!strcmpW( str, szX64 ) || !strcmpW( str, szAMD64 )) return PLATFORM_X64;
+ else if (!strcmpW( str, szARM )) return PLATFORM_ARM;
+ return PLATFORM_UNKNOWN;
+}
+
+static UINT parse_suminfo( MSISUMMARYINFO *si, MSIPACKAGE *package )
+{
+ WCHAR *template, *p, *q, *platform;
DWORD i, count;
package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT );
return ERROR_PATCH_PACKAGE_INVALID;
}
*p = 0;
- if ((q = strchrW( template, ',' ))) *q = 0;
- if (!template[0] || !strcmpW( template, szIntel ))
- package->platform = PLATFORM_INTEL;
- else if (!strcmpW( template, szIntel64 ))
- package->platform = PLATFORM_INTEL64;
- else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 ))
- package->platform = PLATFORM_X64;
- else if (!strcmpW( template, szARM ))
- package->platform = PLATFORM_ARM;
- else
+ platform = template;
+ if ((q = strchrW( platform, ',' ))) *q = 0;
+ package->platform = parse_platform( platform );
+ while (package->platform == PLATFORM_UNKNOWN && q)
+ {
+ platform = q + 1;
+ if ((q = strchrW( platform, ',' ))) *q = 0;
+ package->platform = parse_platform( platform );
+ }
+ if (package->platform == PLATFORM_UNKNOWN)
{
WARN("unknown platform %s\n", debugstr_w(template));
msi_free( template );
return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
}
-int msi_track_tempfile( MSIPACKAGE *package, const WCHAR *path )
-{
- MSITEMPFILE *temp;
-
- TRACE("%s\n", debugstr_w(path));
-
- LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
- {
- if (!strcmpW( path, temp->Path )) return 0;
- }
- if (!(temp = msi_alloc_zero( sizeof (MSITEMPFILE) ))) return -1;
- list_add_head( &package->tempfiles, &temp->entry );
- temp->Path = strdupW( path );
- return 0;
-}
-
static WCHAR *get_product_code( MSIDATABASE *db )
{
static const WCHAR query[] = {
{
WCHAR *ret;
MSISUMMARYINFO *si;
+ UINT r;
- if (!(si = MSI_GetSummaryInformationW( db->storage, 0 )))
+ r = msi_get_suminfo( db->storage, 0, &si );
+ if (r != ERROR_SUCCESS)
{
- WARN("failed to load summary info\n");
- return NULL;
+ r = msi_get_db_suminfo( db, 0, &si );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("failed to load summary info %u\n", r);
+ return NULL;
+ }
}
ret = msi_suminfo_dup_string( si, PID_REVNUMBER );
msiobj_release( &si->hdr );
return r;
}
+UINT msi_set_original_database_property( MSIDATABASE *db, const WCHAR *package )
+{
+ UINT r;
+
+ if (UrlIsW( package, URLIS_URL ))
+ r = msi_set_property( db, szOriginalDatabase, package, -1 );
+ else if (package[0] == '#')
+ r = msi_set_property( db, szOriginalDatabase, db->path, -1 );
+ else
+ {
+ DWORD len;
+ WCHAR *path;
+
+ if (!(len = GetFullPathNameW( package, 0, NULL, NULL ))) return GetLastError();
+ if (!(path = msi_alloc( len * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
+ len = GetFullPathNameW( package, len, path, NULL );
+ r = msi_set_property( db, szOriginalDatabase, path, len );
+ msi_free( path );
+ }
+ return r;
+}
+
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{
static const WCHAR dotmsi[] = {'.','m','s','i',0};
MSIDATABASE *db;
MSIPACKAGE *package;
MSIHANDLE handle;
+ MSIRECORD *data_row, *info_row;
LPWSTR ptr, base_url = NULL;
UINT r;
WCHAR localfile[MAX_PATH], cachefile[MAX_PATH];
DWORD index = 0;
MSISUMMARYINFO *si;
BOOL delete_on_close = FALSE;
+ LPWSTR productname;
+ WCHAR *info_template;
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
+ MSI_ProcessMessage(NULL, INSTALLMESSAGE_INITIALIZE, 0);
+
localfile[0] = 0;
if( szPackage[0] == '#' )
{
{
r = msi_create_empty_local_file( localfile, dotmsi );
if (r != ERROR_SUCCESS)
+ {
+ msi_free ( base_url );
return r;
+ }
if (!CopyFileW( file, localfile, FALSE ))
{
r = GetLastError();
WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r);
DeleteFileW( localfile );
+ msi_free ( base_url );
return r;
}
delete_on_close = TRUE;
TRACE("opening package %s\n", debugstr_w( localfile ));
r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db );
if (r != ERROR_SUCCESS)
+ {
+ msi_free ( base_url );
return r;
+ }
}
package = MSI_CreatePackage( db, base_url );
msi_free( base_url );
package->localfile = strdupW( localfile );
package->delete_on_close = delete_on_close;
- si = MSI_GetSummaryInformationW( db->storage, 0 );
- if (!si)
+ r = msi_get_suminfo( db->storage, 0, &si );
+ if (r != ERROR_SUCCESS)
{
- WARN("failed to load summary info\n");
- msiobj_release( &package->hdr );
- return ERROR_INSTALL_PACKAGE_INVALID;
+ r = msi_get_db_suminfo( db, 0, &si );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("failed to load summary info\n");
+ msiobj_release( &package->hdr );
+ return ERROR_INSTALL_PACKAGE_INVALID;
+ }
}
- r = msi_parse_summary( si, package );
+ r = parse_suminfo( si, package );
msiobj_release( &si->hdr );
if (r != ERROR_SUCCESS)
{
msiobj_release( &package->hdr );
return r;
}
- msi_set_property( package->db, szDatabase, db->path );
-
- if( UrlIsW( szPackage, URLIS_URL ) )
- msi_set_property( package->db, szOriginalDatabase, szPackage );
- else if( szPackage[0] == '#' )
- msi_set_property( package->db, szOriginalDatabase, db->path );
- else
- {
- WCHAR fullpath[MAX_PATH];
-
- GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL );
- msi_set_property( package->db, szOriginalDatabase, fullpath );
- }
+ msi_set_property( package->db, szDatabase, db->path, -1 );
+ set_installed_prop( package );
msi_set_context( package );
while (1)
}
index++;
}
- if (index)
+ if (index) msi_adjust_privilege_properties( package );
+
+ r = msi_set_original_database_property( package->db, szPackage );
+ if (r != ERROR_SUCCESS)
{
- msi_clone_properties( package );
- msi_adjust_privilege_properties( package );
+ msiobj_release( &package->hdr );
+ return r;
}
if (gszLogFile)
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+
+ /* FIXME: when should these messages be sent? */
+ data_row = MSI_CreateRecord(3);
+ if (!data_row)
+ return ERROR_OUTOFMEMORY;
+ MSI_RecordSetStringW(data_row, 0, NULL);
+ MSI_RecordSetInteger(data_row, 1, 0);
+ MSI_RecordSetInteger(data_row, 2, package->num_langids ? package->langids[0] : 0);
+ MSI_RecordSetInteger(data_row, 3, msi_get_string_table_codepage(package->db->strings));
+ MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_COMMONDATA, data_row);
+
+ info_row = MSI_CreateRecord(0);
+ if (!info_row)
+ {
+ msiobj_release(&data_row->hdr);
+ return ERROR_OUTOFMEMORY;
+ }
+ info_template = msi_get_error_message(package->db, MSIERR_INFO_LOGGINGSTART);
+ MSI_RecordSetStringW(info_row, 0, info_template);
+ msi_free(info_template);
+ MSI_ProcessMessage(package, INSTALLMESSAGE_INFO|MB_ICONHAND, info_row);
+
+ MSI_ProcessMessage(package, INSTALLMESSAGE_COMMONDATA, data_row);
+
+ productname = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW);
+ MSI_RecordSetInteger(data_row, 1, 1);
+ MSI_RecordSetStringW(data_row, 2, productname);
+ MSI_RecordSetStringW(data_row, 3, NULL);
+ MSI_ProcessMessage(package, INSTALLMESSAGE_COMMONDATA, data_row);
+
+ msi_free(productname);
+ msiobj_release(&info_row->hdr);
+ msiobj_release(&data_row->hdr);
+
*pPackage = package;
return ERROR_SUCCESS;
}
ret = ERROR_NOT_ENOUGH_MEMORY;
msiobj_release( &package->hdr );
}
+ else
+ MSI_ProcessMessage(NULL, INSTALLMESSAGE_TERMINATE, 0);
return ret;
}
return handle;
}
-INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record )
+static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record, LPCWSTR message)
{
static const WCHAR szActionData[] = {'A','c','t','i','o','n','D','a','t','a',0};
- static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0};
static const WCHAR szActionText[] = {'A','c','t','i','o','n','T','e','x','t',0};
- MSIRECORD *uirow;
- LPWSTR deformated, message;
- DWORD i, len, total_len, log_type = 0;
+ static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0};
+ static const WCHAR szWindows_Installer[] =
+ {'W','i','n','d','o','w','s',' ','I','n','s','t','a','l','l','e','r',0};
+
+ if (!package || (package->ui_level & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE)
+ return 0;
+
+ /* todo: check if message needs additional styles (topmost/foreground/modality?) */
+
+ switch (eMessageType & 0xff000000)
+ {
+ case INSTALLMESSAGE_FATALEXIT:
+ case INSTALLMESSAGE_ERROR:
+ case INSTALLMESSAGE_OUTOFDISKSPACE:
+ if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
+ if (!(eMessageType & MB_ICONMASK))
+ eMessageType |= MB_ICONEXCLAMATION;
+ return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
+ case INSTALLMESSAGE_WARNING:
+ if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
+ if (!(eMessageType & MB_ICONMASK))
+ eMessageType |= MB_ICONASTERISK;
+ return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
+ case INSTALLMESSAGE_USER:
+ if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
+ if (!(eMessageType & MB_ICONMASK))
+ eMessageType |= MB_USERICON;
+ return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
+ case INSTALLMESSAGE_INFO:
+ case INSTALLMESSAGE_INITIALIZE:
+ case INSTALLMESSAGE_TERMINATE:
+ return 0;
+ case INSTALLMESSAGE_SHOWDIALOG:
+ {
+ LPWSTR dialog = msi_dup_record_field(record, 0);
+ INT rc = ACTION_DialogBox(package, dialog);
+ msi_free(dialog);
+ return rc;
+ }
+ case INSTALLMESSAGE_ACTIONSTART:
+ {
+ LPWSTR deformatted;
+ MSIRECORD *uirow = MSI_CreateRecord(1);
+ if (!uirow) return -1;
+ deformat_string(package, MSI_RecordGetString(record, 2), &deformatted);
+ MSI_RecordSetStringW(uirow, 1, deformatted);
+ msi_event_fire(package, szActionText, uirow);
+
+ msi_free(deformatted);
+ msiobj_release(&uirow->hdr);
+ return 1;
+ }
+ case INSTALLMESSAGE_ACTIONDATA:
+ {
+ MSIRECORD *uirow = MSI_CreateRecord(1);
+ if (!uirow) return -1;
+ MSI_RecordSetStringW(uirow, 1, message);
+ msi_event_fire(package, szActionData, uirow);
+ msiobj_release(&uirow->hdr);
+
+ if (package->action_progress_increment)
+ {
+ uirow = MSI_CreateRecord(2);
+ if (!uirow) return -1;
+ MSI_RecordSetInteger(uirow, 1, 2);
+ MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
+ msi_event_fire(package, szSetProgress, uirow);
+ msiobj_release(&uirow->hdr);
+ }
+ return 1;
+ }
+ case INSTALLMESSAGE_PROGRESS:
+ msi_event_fire(package, szSetProgress, record);
+ return 1;
+ case INSTALLMESSAGE_COMMONDATA:
+ switch (MSI_RecordGetInteger(record, 1))
+ {
+ case 0:
+ case 1:
+ /* do nothing */
+ return 0;
+ default:
+ /* fall through */
+ ;
+ }
+ default:
+ FIXME("internal UI not implemented for message 0x%08x (UI level = %x)\n", eMessageType, package->ui_level);
+ return 0;
+ }
+}
+
+static const WCHAR szActionNotFound[] = {'D','E','B','U','G',':',' ','E','r','r','o','r',' ','[','1',']',':',' ',' ','A','c','t','i','o','n',' ','n','o','t',' ','f','o','u','n','d',':',' ','[','2',']',0};
+
+static const struct
+{
+ int id;
+ const WCHAR *text;
+}
+internal_errors[] =
+{
+ {2726, szActionNotFound},
+ {0}
+};
+
+static LPCWSTR get_internal_error_message(int error)
+{
+ int i = 0;
+
+ while (internal_errors[i].id != 0)
+ {
+ if (internal_errors[i].id == error)
+ return internal_errors[i].text;
+ i++;
+ }
+
+ FIXME("missing error message %d\n", error);
+ return NULL;
+}
+
+/* Returned string must be freed */
+LPWSTR msi_get_error_message(MSIDATABASE *db, int error)
+{
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
+ 'F','R','O','M',' ','`','E','r','r','o','r','`',' ','W','H','E','R','E',' ',
+ '`','E','r','r','o','r','`',' ','=',' ','%','i',0};
+ MSIRECORD *record;
+ LPWSTR ret = NULL;
+
+ if ((record = MSI_QueryGetRecord(db, query, error)))
+ {
+ ret = msi_dup_record_field(record, 1);
+ msiobj_release(&record->hdr);
+ }
+ else if (error < 2000)
+ {
+ int len = LoadStringW(msi_hInstance, IDS_ERROR_BASE + error, (LPWSTR) &ret, 0);
+ if (len)
+ {
+ ret = msi_alloc((len + 1) * sizeof(WCHAR));
+ LoadStringW(msi_hInstance, IDS_ERROR_BASE + error, ret, len + 1);
+ }
+ else
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+INT MSI_ProcessMessageVerbatim(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record)
+{
+ LPWSTR message = {0};
+ DWORD len, log_type = 0;
+ UINT res;
INT rc = 0;
char *msg;
TRACE("%x\n", eMessageType);
+ if (TRACE_ON(msi)) dump_record(record);
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_FATALEXIT)
log_type |= INSTALLLOGMODE_FATALEXIT;
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_SHOWDIALOG)
log_type |= INSTALLLOGMODE_SHOWDIALOG;
- if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART)
- {
- static const WCHAR template_s[]=
- {'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ',0};
- static const WCHAR format[] =
- {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
- WCHAR timet[0x100];
- LPCWSTR action_text, action;
- LPWSTR deformatted = NULL;
-
- GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
-
- action = MSI_RecordGetString(record, 1);
- action_text = MSI_RecordGetString(record, 2);
-
- if (!action || !action_text)
- return IDOK;
-
- deformat_string(package, action_text, &deformatted);
-
- len = strlenW(timet) + strlenW(action) + strlenW(template_s);
- if (deformatted)
- len += strlenW(deformatted);
- message = msi_alloc(len*sizeof(WCHAR));
- sprintfW(message, template_s, timet, action);
- if (deformatted)
- strcatW(message, deformatted);
- msi_free(deformatted);
- }
- else
- {
- static const WCHAR format[] = {'%','u',':',' ',0};
- UINT count = MSI_RecordGetFieldCount( record );
- WCHAR *p;
-
- total_len = 1;
- for (i = 1; i <= count; i++)
- {
- len = 0;
- MSI_RecordGetStringW( record, i, NULL, &len );
- total_len += len + 13;
- }
- p = message = msi_alloc( total_len * sizeof(WCHAR) );
- if (!p) return ERROR_OUTOFMEMORY;
-
- for (i = 1; i <= count; i++)
- {
- if (count > 1)
- {
- len = sprintfW( p, format, i );
- total_len -= len;
- p += len;
- }
- len = total_len;
- MSI_RecordGetStringW( record, i, p, &len );
- total_len -= len;
- p += len;
- if (count > 1 && total_len)
- {
- *p++ = ' ';
- total_len--;
- }
- }
- p[0] = 0;
+ if (!package || !record)
+ message = NULL;
+ else {
+ res = MSI_FormatRecordW(package, record, message, &len);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
+ return res;
+ len++;
+ message = msi_alloc(len * sizeof(WCHAR));
+ if (!message) return ERROR_OUTOFMEMORY;
+ MSI_FormatRecordW(package, record, message, &len);
}
- TRACE("%p %p %p %x %x %s\n", gUIHandlerA, gUIHandlerW, gUIHandlerRecord,
- gUIFilter, log_type, debugstr_w(message));
-
/* convert it to ASCII */
len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL );
msg = msi_alloc( len );
WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL );
- if (gUIHandlerW && (gUIFilter & log_type))
+ if (gUIHandlerRecord && (gUIFilterRecord & log_type))
{
- rc = gUIHandlerW( gUIContext, eMessageType, message );
+ MSIHANDLE rec = alloc_msihandle(&record->hdr);
+ TRACE("Calling UI handler %p(pvContext=%p, iMessageType=%08x, hRecord=%u)\n",
+ gUIHandlerRecord, gUIContextRecord, eMessageType, rec);
+ rc = gUIHandlerRecord( gUIContextRecord, eMessageType, rec );
+ MsiCloseHandle( rec );
}
- else if (gUIHandlerA && (gUIFilter & log_type))
+ if (!rc && gUIHandlerW && (gUIFilter & log_type))
{
- rc = gUIHandlerA( gUIContext, eMessageType, msg );
+ TRACE("Calling UI handler %p(pvContext=%p, iMessageType=%08x, szMessage=%s)\n",
+ gUIHandlerW, gUIContext, eMessageType, debugstr_w(message));
+ rc = gUIHandlerW( gUIContext, eMessageType, message );
}
- else if (gUIHandlerRecord && (gUIFilter & log_type))
+ else if (!rc && gUIHandlerA && (gUIFilter & log_type))
{
- MSIHANDLE rec = MsiCreateRecord( 1 );
- MsiRecordSetStringW( rec, 0, message );
- rc = gUIHandlerRecord( gUIContext, eMessageType, rec );
- MsiCloseHandle( rec );
+ TRACE("Calling UI handler %p(pvContext=%p, iMessageType=%08x, szMessage=%s)\n",
+ gUIHandlerA, gUIContext, eMessageType, debugstr_a(msg));
+ rc = gUIHandlerA( gUIContext, eMessageType, msg );
}
- if (!rc && package->log_file != INVALID_HANDLE_VALUE &&
+ if (!rc)
+ rc = internal_ui_handler(package, eMessageType, record, message);
+
+ if (!rc && package && package->log_file != INVALID_HANDLE_VALUE &&
(eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS)
{
DWORD written;
msi_free( msg );
msi_free( message );
+ return rc;
+}
+
+INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record )
+{
switch (eMessageType & 0xff000000)
{
- case INSTALLMESSAGE_ACTIONDATA:
- deformat_string(package, MSI_RecordGetString(record, 2), &deformated);
- uirow = MSI_CreateRecord(1);
- MSI_RecordSetStringW(uirow, 1, deformated);
- msi_free(deformated);
+ case INSTALLMESSAGE_FATALEXIT:
+ case INSTALLMESSAGE_ERROR:
+ case INSTALLMESSAGE_WARNING:
+ case INSTALLMESSAGE_USER:
+ case INSTALLMESSAGE_INFO:
+ case INSTALLMESSAGE_OUTOFDISKSPACE:
+ if (MSI_RecordGetInteger(record, 1) != MSI_NULL_INTEGER)
+ {
+ /* error message */
- ControlEvent_FireSubscribedEvent(package, szActionData, uirow);
- msiobj_release(&uirow->hdr);
+ LPWSTR template;
+ LPWSTR template_rec = NULL, template_prefix = NULL;
+ int error = MSI_RecordGetInteger(record, 1);
- if (package->action_progress_increment)
- {
- uirow = MSI_CreateRecord(2);
- MSI_RecordSetInteger(uirow, 1, 2);
- MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
- ControlEvent_FireSubscribedEvent(package, szSetProgress, uirow);
- msiobj_release(&uirow->hdr);
- }
- break;
+ if (MSI_RecordIsNull(record, 0))
+ {
+ if (error >= 32)
+ {
+ template_rec = msi_get_error_message(package->db, error);
+
+ if (!template_rec && error >= 2000)
+ {
+ /* internal error, not localized */
+ if ((template_rec = (LPWSTR) get_internal_error_message(error)))
+ {
+ MSI_RecordSetStringW(record, 0, template_rec);
+ MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_INFO, record);
+ }
+ template_rec = msi_get_error_message(package->db, MSIERR_INSTALLERROR);
+ MSI_RecordSetStringW(record, 0, template_rec);
+ MSI_ProcessMessageVerbatim(package, eMessageType, record);
+ msi_free(template_rec);
+ return 0;
+ }
+ }
+ }
+ else
+ template_rec = msi_dup_record_field(record, 0);
- case INSTALLMESSAGE_ACTIONSTART:
- deformat_string(package, MSI_RecordGetString(record, 2), &deformated);
- uirow = MSI_CreateRecord(1);
- MSI_RecordSetStringW(uirow, 1, deformated);
- msi_free(deformated);
+ template_prefix = msi_get_error_message(package->db, eMessageType >> 24);
+ if (!template_prefix) template_prefix = strdupW(szEmpty);
- ControlEvent_FireSubscribedEvent(package, szActionText, uirow);
+ if (!template_rec)
+ {
+ /* always returns 0 */
+ MSI_RecordSetStringW(record, 0, template_prefix);
+ MSI_ProcessMessageVerbatim(package, eMessageType, record);
+ msi_free(template_prefix);
+ return 0;
+ }
- msiobj_release(&uirow->hdr);
+ template = msi_alloc((strlenW(template_rec) + strlenW(template_prefix) + 1) * sizeof(WCHAR));
+ if (!template) return ERROR_OUTOFMEMORY;
+
+ strcpyW(template, template_prefix);
+ strcatW(template, template_rec);
+ MSI_RecordSetStringW(record, 0, template);
+
+ msi_free(template_prefix);
+ msi_free(template_rec);
+ msi_free(template);
+ }
break;
+ case INSTALLMESSAGE_ACTIONSTART:
+ {
+ WCHAR *template = msi_get_error_message(package->db, MSIERR_ACTIONSTART);
+ MSI_RecordSetStringW(record, 0, template);
+ msi_free(template);
- case INSTALLMESSAGE_PROGRESS:
- ControlEvent_FireSubscribedEvent(package, szSetProgress, record);
+ msi_free(package->LastAction);
+ msi_free(package->LastActionTemplate);
+ package->LastAction = msi_dup_record_field(record, 1);
+ if (!package->LastAction) package->LastAction = strdupW(szEmpty);
+ package->LastActionTemplate = msi_dup_record_field(record, 3);
+ break;
+ }
+ case INSTALLMESSAGE_ACTIONDATA:
+ if (package->LastAction && package->LastActionTemplate)
+ {
+ static const WCHAR template_s[] =
+ {'{','{','%','s',':',' ','}','}','%','s',0};
+ WCHAR *template;
+
+ template = msi_alloc((strlenW(package->LastAction) + strlenW(package->LastActionTemplate) + 7) * sizeof(WCHAR));
+ if (!template) return ERROR_OUTOFMEMORY;
+ sprintfW(template, template_s, package->LastAction, package->LastActionTemplate);
+ MSI_RecordSetStringW(record, 0, template);
+ msi_free(template);
+ }
break;
+ case INSTALLMESSAGE_COMMONDATA:
+ {
+ WCHAR *template = msi_get_error_message(package->db, MSIERR_COMMONDATA);
+ MSI_RecordSetStringW(record, 0, template);
+ msi_free(template);
+ }
+ break;
}
- return ERROR_SUCCESS;
+ return MSI_ProcessMessageVerbatim(package, eMessageType, record);
}
INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
MSIPACKAGE *package = NULL;
MSIRECORD *record = NULL;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INITIALIZE ||
+ (eMessageType & 0xff000000) == INSTALLMESSAGE_TERMINATE)
+ return -1;
+
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA &&
+ MsiRecordGetInteger(hRecord, 1) != 2)
+ return -1;
+
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
if( !package )
{
}
}
-UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue )
+UINT msi_set_property( MSIDATABASE *db, const WCHAR *name, const WCHAR *value, int len )
{
static const WCHAR insert_query[] = {
'I','N','S','E','R','T',' ','I','N','T','O',' ',
WCHAR query[1024];
UINT rc;
- TRACE("%p %s %s\n", db, debugstr_w(szName), debugstr_w(szValue));
+ TRACE("%p %s %s %d\n", db, debugstr_w(name), debugstr_wn(value, len), len);
- if (!szName)
+ if (!name)
return ERROR_INVALID_PARAMETER;
/* this one is weird... */
- if (!szName[0])
- return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS;
+ if (!name[0])
+ return value ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS;
+
+ if (value && len < 0) len = strlenW( value );
- rc = msi_get_property(db, szName, 0, &sz);
- if (!szValue || !*szValue)
+ rc = msi_get_property( db, name, 0, &sz );
+ if (!value || (!*value && !len))
{
- sprintfW(query, delete_query, szName);
+ sprintfW( query, delete_query, name );
}
else if (rc == ERROR_MORE_DATA || rc == ERROR_SUCCESS)
{
- sprintfW(query, update_query, szName);
-
+ sprintfW( query, update_query, name );
row = MSI_CreateRecord(1);
- MSI_RecordSetStringW(row, 1, szValue);
+ msi_record_set_string( row, 1, value, len );
}
else
{
- strcpyW(query, insert_query);
-
+ strcpyW( query, insert_query );
row = MSI_CreateRecord(2);
- MSI_RecordSetStringW(row, 1, szName);
- MSI_RecordSetStringW(row, 2, szValue);
+ msi_record_set_string( row, 1, name, -1 );
+ msi_record_set_string( row, 2, value, len );
}
rc = MSI_DatabaseOpenViewW(db, query, &view);
return ERROR_SUCCESS;
}
- ret = msi_set_property( package->db, szName, szValue );
+ ret = msi_set_property( package->db, szName, szValue, -1 );
if (ret == ERROR_SUCCESS && !strcmpW( szName, szSourceDir ))
msi_reset_folders( package, TRUE );
MSIQUERY *view;
UINT r;
+ static const WCHAR szDate[] = {'D','a','t','e',0};
+ static const WCHAR szTime[] = {'T','i','m','e',0};
+ WCHAR *buffer;
+ int length;
+
if (!name || !*name)
return NULL;
+ if (!strcmpW(name, szDate))
+ {
+ length = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, NULL, 0);
+ if (!length)
+ return NULL;
+ buffer = msi_alloc(length * sizeof(WCHAR));
+ GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, buffer, length);
+
+ row = MSI_CreateRecord(1);
+ if (!row)
+ return NULL;
+ MSI_RecordSetStringW(row, 1, buffer);
+ msi_free(buffer);
+ return row;
+ }
+ else if (!strcmpW(name, szTime))
+ {
+ length = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER, NULL, NULL, NULL, 0);
+ if (!length)
+ return NULL;
+ buffer = msi_alloc(length * sizeof(WCHAR));
+ GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER, NULL, NULL, buffer, length);
+
+ row = MSI_CreateRecord(1);
+ if (!row)
+ return NULL;
+ MSI_RecordSetStringW(row, 1, buffer);
+ msi_free(buffer);
+ return row;
+ }
+
rec = MSI_CreateRecord(1);
if (!rec)
return NULL;
MSIRECORD *row;
UINT rc = ERROR_FUNCTION_FAILED;
+ TRACE("%p %s %p %p\n", db, debugstr_w(szName), szValueBuf, pchValueBuf);
+
row = msi_get_property_row( db, szName );
if (*pchValueBuf > 0)
}
if (rc == ERROR_SUCCESS)
- TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
+ TRACE("returning %s for property %s\n", debugstr_wn(szValueBuf, *pchValueBuf),
debugstr_w(szName));
else if (rc == ERROR_MORE_DATA)
TRACE("need %d sized buffer for %s\n", *pchValueBuf,
MSIRECORD *row = NULL;
UINT r = ERROR_FUNCTION_FAILED;
LPCWSTR val = NULL;
+ DWORD len = 0;
TRACE("%u %s %p %p\n", handle, debugstr_w(name),
szValueBuf->str.w, pchValueBuf );
IWineMsiRemotePackage *remote_package;
LPWSTR value = NULL;
BSTR bname;
- DWORD len;
remote_package = (IWineMsiRemotePackage *)msi_get_remote( handle );
if (!remote_package)
return ERROR_OUTOFMEMORY;
}
- len = 0;
hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, NULL, &len );
if (FAILED(hr))
goto done;
if (FAILED(hr))
goto done;
- r = msi_strcpy_to_awstring( value, szValueBuf, pchValueBuf );
+ r = msi_strcpy_to_awstring( value, len, szValueBuf, pchValueBuf );
/* Bug required by Adobe installers */
if (!szValueBuf->unicode && !szValueBuf->str.a)
row = msi_get_property_row( package->db, name );
if (row)
- val = MSI_RecordGetString( row, 1 );
+ val = msi_record_get_string( row, 1, (int *)&len );
if (!val)
val = szEmpty;
- r = msi_strcpy_to_awstring( val, szValueBuf, pchValueBuf );
+ r = msi_strcpy_to_awstring( val, len, szValueBuf, pchValueBuf );
if (row)
msiobj_release( &row->hdr );
This->package = 0;
This->refs = 1;
- *ppObj = This;
+ *ppObj = &This->IWineMsiRemotePackage_iface;
return S_OK;
}