Commit 7d677fc3 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Delay creating local installer and patch packages until the product is registered.

parent 791fe136
......@@ -4088,13 +4088,18 @@ static UINT msi_publish_patches( MSIPACKAGE *package )
if (r != ERROR_SUCCESS)
goto done;
res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ,
(const BYTE *)patch->localfile,
(strlenW(patch->localfile) + 1) * sizeof(WCHAR) );
res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ, (const BYTE *)patch->localfile,
(strlenW( patch->localfile ) + 1) * sizeof(WCHAR) );
RegCloseKey( patch_key );
if (res != ERROR_SUCCESS)
goto done;
if (patch->filename && !CopyFileW( patch->filename, patch->localfile, FALSE ))
{
res = GetLastError();
ERR("Unable to copy patch package %d\n", res);
goto done;
}
res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL );
if (res != ERROR_SUCCESS)
goto done;
......@@ -4898,14 +4903,22 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS)
return rc;
rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context,
NULL, &props, TRUE);
rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context, NULL, &props, TRUE);
if (rc != ERROR_SUCCESS)
goto done;
msi_reg_set_val_str( props, INSTALLPROPERTY_LOCALPACKAGEW, package->db->localfile );
msi_free( package->db->localfile );
package->db->localfile = NULL;
if (!msi_get_property_int( package->db, szInstalled, 0 ))
{
msi_reg_set_val_str( props, INSTALLPROPERTY_LOCALPACKAGEW, package->localfile );
if (!CopyFileW( package->PackagePath, package->localfile, FALSE ))
{
rc = GetLastError();
ERR("Unable to copy package %u\n", rc);
goto done;
}
}
msi_free( package->localfile );
package->localfile = NULL;
rc = msi_publish_install_properties(package, hkey);
if (rc != ERROR_SUCCESS)
......@@ -4986,8 +4999,14 @@ static UINT msi_unpublish_product( MSIPACKAGE *package, const WCHAR *remove )
LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry)
{
MSIREG_DeleteUserDataPatchKey(patch->patchcode, package->Context);
/* FIXME: remove local patch package if this is the last product */
}
TRACE("removing local package %s\n", debugstr_w(package->localfile));
DeleteFileW( package->localfile );
msi_free( package->localfile );
package->localfile = NULL;
return ERROR_SUCCESS;
}
......@@ -7435,6 +7454,15 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
msi_adjust_privilege_properties( package );
msi_set_context( package );
if (msi_get_property_int( package->db, szInstalled, 0 ))
{
HKEY hkey;
DeleteFileW( package->localfile );
msi_free( package->localfile );
MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE );
package->localfile = msi_reg_get_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW );
RegCloseKey( hkey );
}
if (msi_get_property_int( package->db, szDisableRollback, 0 ))
{
TRACE("disabling rollback\n");
......
......@@ -257,11 +257,6 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
DeleteFileW( db->deletefile );
msi_free( db->deletefile );
}
if (db->localfile)
{
DeleteFileW( db->localfile );
msi_free( db->localfile );
}
}
static HRESULT db_initialize( IStorage *stg, const GUID *clsid )
......
......@@ -86,7 +86,6 @@ typedef struct tagMSIDATABASE
UINT bytes_per_strref;
LPWSTR path;
LPWSTR deletefile;
LPWSTR localfile;
LPCWSTR mode;
UINT media_transform_offset;
UINT media_transform_disk_id;
......@@ -172,6 +171,7 @@ typedef struct tagMSIPATCHINFO
struct list entry;
LPWSTR patchcode;
LPWSTR transforms;
LPWSTR filename;
LPWSTR localfile;
MSIPATCHSTATE state;
} MSIPATCHINFO;
......@@ -383,6 +383,7 @@ typedef struct tagMSIPACKAGE
LPWSTR BaseURL;
LPWSTR PackagePath;
LPWSTR ProductCode;
LPWSTR localfile;
UINT CurrentInstallState;
msi_dialog *dialog;
......@@ -770,6 +771,7 @@ extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si
extern UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ) DECLSPEC_HIDDEN;
extern UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch ) DECLSPEC_HIDDEN;
extern UINT msi_apply_patches( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
extern UINT msi_apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code ) DECLSPEC_HIDDEN;
/* action internals */
extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN;
......
......@@ -157,8 +157,6 @@ static void free_package_structures( MSIPACKAGE *package )
INT i;
struct list *item, *cursor;
TRACE("Freeing package action data\n");
LIST_FOR_EACH_SAFE( item, cursor, &package->features )
{
MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
......@@ -303,6 +301,7 @@ static void free_package_structures( MSIPACKAGE *package )
msi_free( patch->patchcode );
msi_free( patch->transforms );
msi_free( patch->localfile );
msi_free( patch->filename );
msi_free( patch );
}
......@@ -358,6 +357,12 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
for (i = 0; i < CLR_VERSION_MAX; i++)
if (package->cache_net[i]) IAssemblyCache_Release( package->cache_net[i] );
if (package->cache_sxs) IAssemblyCache_Release( package->cache_sxs );
if (package->localfile)
{
DeleteFileW( package->localfile );
msi_free( package->localfile );
}
}
static UINT create_temp_property_table(MSIPACKAGE *package)
......@@ -1291,67 +1296,6 @@ UINT msi_get_local_package_name( LPWSTR path, LPCWSTR suffix )
return ERROR_SUCCESS;
}
static UINT apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code )
{
UINT r;
DWORD len;
WCHAR patch_file[MAX_PATH];
MSIDATABASE *patch_db;
MSIPATCHINFO *patch_info;
MSISUMMARYINFO *si;
len = sizeof(patch_file) / sizeof(WCHAR);
r = MsiGetPatchInfoExW( patch_code, package->ProductCode, NULL, package->Context,
INSTALLPROPERTY_LOCALPACKAGEW, patch_file, &len );
if (r != ERROR_SUCCESS)
{
ERR("failed to get patch filename %u\n", r);
return r;
}
r = MSI_OpenDatabaseW( patch_file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db );
if (r != ERROR_SUCCESS)
{
ERR("failed to open patch database %s\n", debugstr_w( patch_file ));
return r;
}
si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
if (!si)
{
msiobj_release( &patch_db->hdr );
return ERROR_FUNCTION_FAILED;
}
r = msi_parse_patch_summary( si, &patch_info );
msiobj_release( &si->hdr );
if (r != ERROR_SUCCESS)
{
ERR("failed to parse patch summary %u\n", r);
msiobj_release( &patch_db->hdr );
return r;
}
patch_info->localfile = strdupW( patch_file );
if (!patch_info->localfile)
{
msiobj_release( &patch_db->hdr );
return ERROR_OUTOFMEMORY;
}
r = msi_apply_patch_db( package, patch_db, patch_info );
msiobj_release( &patch_db->hdr );
if (r != ERROR_SUCCESS)
{
ERR("failed to apply patch %u\n", r);
msi_free( patch_info->patchcode );
msi_free( patch_info->transforms );
msi_free( patch_info->localfile );
msi_free( patch_info );
}
return r;
}
static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
{
WCHAR *template, *p, *q;
......@@ -1531,20 +1475,6 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
file = temppath;
}
r = msi_get_local_package_name( localfile, dotmsi );
if (r != ERROR_SUCCESS)
return r;
TRACE("Copying to local package %s\n", debugstr_w(localfile));
if (!CopyFileW( file, localfile, FALSE ))
{
ERR("Unable to copy package (%s -> %s) (error %u)\n",
debugstr_w(file), debugstr_w(localfile), GetLastError());
return GetLastError();
}
TRACE("Opening relocated package %s\n", debugstr_w( file ));
/* transforms that add binary streams require that we open the database
......@@ -1562,10 +1492,12 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
return r;
}
db->localfile = strdupW( localfile );
}
r = msi_get_local_package_name( localfile, dotmsi );
if (r != ERROR_SUCCESS)
return r;
package = MSI_CreatePackage( db, base_url );
msi_free( base_url );
msiobj_release( &db->hdr );
......@@ -1576,9 +1508,8 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
return ERROR_INSTALL_PACKAGE_INVALID;
}
if( file != szPackage )
msi_track_tempfile( package, file );
if (file != szPackage) msi_track_tempfile( package, file );
package->localfile = strdupW( localfile );
si = MSI_GetSummaryInformationW( db->storage, 0 );
if (!si)
......@@ -1629,7 +1560,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
TRACE("found registered patch %s\n", debugstr_w(patch_code));
r = apply_registered_patch( package, patch_code );
r = msi_apply_registered_patch( package, patch_code );
if (r != ERROR_SUCCESS)
{
ERR("registered patch failed to apply %u\n", r);
......
......@@ -630,16 +630,9 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, const WCHAR *file )
if ( r != ERROR_SUCCESS )
goto done;
TRACE("copying to local package %s\n", debugstr_w(localfile));
if (!CopyFileW( file, localfile, FALSE ))
{
ERR("Unable to copy package (%s -> %s) (error %u)\n",
debugstr_w(file), debugstr_w(localfile), GetLastError());
r = GetLastError();
goto done;
}
patch->localfile = strdupW( localfile );
r = ERROR_OUTOFMEMORY;
if (!(patch->filename = strdupW( file ))) goto done;
if (!(patch->localfile = strdupW( localfile ))) goto done;
r = msi_apply_patch_db( package, patch_db, patch );
if (r != ERROR_SUCCESS) WARN("patch failed to apply %u\n", r);
......@@ -649,9 +642,9 @@ done:
msiobj_release( &patch_db->hdr );
if (patch && r != ERROR_SUCCESS)
{
if (patch->localfile) DeleteFileW( patch->localfile );
msi_free( patch->patchcode );
msi_free( patch->transforms );
msi_free( patch->filename );
msi_free( patch->localfile );
msi_free( patch );
}
......@@ -717,3 +710,59 @@ UINT msi_apply_transforms( MSIPACKAGE *package )
msi_free( xform_list );
return r;
}
UINT msi_apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code )
{
UINT r;
DWORD len;
WCHAR patch_file[MAX_PATH];
MSIDATABASE *patch_db;
MSIPATCHINFO *patch_info;
MSISUMMARYINFO *si;
len = sizeof(patch_file) / sizeof(WCHAR);
r = MsiGetPatchInfoExW( patch_code, package->ProductCode, NULL, package->Context,
INSTALLPROPERTY_LOCALPACKAGEW, patch_file, &len );
if (r != ERROR_SUCCESS)
{
ERR("failed to get patch filename %u\n", r);
return r;
}
r = MSI_OpenDatabaseW( patch_file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db );
if (r != ERROR_SUCCESS)
{
ERR("failed to open patch database %s\n", debugstr_w( patch_file ));
return r;
}
si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
if (!si)
{
msiobj_release( &patch_db->hdr );
return ERROR_FUNCTION_FAILED;
}
r = msi_parse_patch_summary( si, &patch_info );
msiobj_release( &si->hdr );
if (r != ERROR_SUCCESS)
{
ERR("failed to parse patch summary %u\n", r);
msiobj_release( &patch_db->hdr );
return r;
}
patch_info->localfile = strdupW( patch_file );
if (!patch_info->localfile)
{
msiobj_release( &patch_db->hdr );
return ERROR_OUTOFMEMORY;
}
r = msi_apply_patch_db( package, patch_db, patch_info );
msiobj_release( &patch_db->hdr );
if (r != ERROR_SUCCESS)
{
ERR("failed to apply patch %u\n", r);
msi_free( patch_info->patchcode );
msi_free( patch_info->transforms );
msi_free( patch_info->localfile );
msi_free( patch_info );
}
return r;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment