[7/8] msi: Delay creating local installer and patch packages until the product is registered.
Hans Leidekker
hans at codeweavers.com
Thu Jun 30 05:15:37 CDT 2011
---
dlls/msi/action.c | 44 +++++++++++++++++++----
dlls/msi/database.c | 5 ---
dlls/msi/msipriv.h | 4 ++-
dlls/msi/package.c | 97 +++++++-------------------------------------------
dlls/msi/patch.c | 71 +++++++++++++++++++++++++++++++------
5 files changed, 113 insertions(+), 108 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 4671f3e..9070b76 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -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");
diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index 9b5a894..2c45a7a 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -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 )
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index e2fb03e..5a264df 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -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;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 1cbb221..5d6523d 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -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);
diff --git a/dlls/msi/patch.c b/dlls/msi/patch.c
index 00281a8..a31802e 100644
--- a/dlls/msi/patch.c
+++ b/dlls/msi/patch.c
@@ -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;
+}
--
1.7.4.1
More information about the wine-patches
mailing list