msi: Delay creating local installer and patch packages until the product is registered.
This commit is contained in:
parent
791fe136a9
commit
7d677fc327
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue