msi: Make a local copy of patch packages.

This commit is contained in:
Hans Leidekker 2010-05-04 09:06:42 +02:00 committed by Alexandre Julliard
parent 28cc401295
commit 23eabb44c8
3 changed files with 44 additions and 15 deletions

View File

@ -497,7 +497,7 @@ static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
MSIPATCHINFO *pi; MSIPATCHINFO *pi;
UINT r = ERROR_SUCCESS; UINT r = ERROR_SUCCESS;
pi = msi_alloc( sizeof(MSIPATCHINFO) ); pi = msi_alloc_zero( sizeof(MSIPATCHINFO) );
if (!pi) if (!pi)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -522,11 +522,13 @@ static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file ) static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
{ {
static const WCHAR dotmsp[] = {'.','m','s','p',0};
MSIDATABASE *patch_db = NULL; MSIDATABASE *patch_db = NULL;
WCHAR localfile[MAX_PATH];
LPWSTR *substorage; LPWSTR *substorage;
MSISUMMARYINFO *si; MSISUMMARYINFO *si;
MSIPATCHINFO *patch; MSIPATCHINFO *patch = NULL;
UINT i, r; UINT i, r = ERROR_SUCCESS;
TRACE("%p %s\n", package, debugstr_w( file ) ); TRACE("%p %s\n", package, debugstr_w( file ) );
@ -548,18 +550,28 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{ {
TRACE("patch not applicable\n"); TRACE("patch not applicable\n");
msiobj_release( &si->hdr ); r = ERROR_SUCCESS;
msiobj_release( &patch_db->hdr ); goto done;
return ERROR_SUCCESS;
} }
r = msi_parse_patch_summary( si, &patch ); r = msi_parse_patch_summary( si, &patch );
if ( r != ERROR_SUCCESS ) if ( r != ERROR_SUCCESS )
goto done;
r = msi_get_local_package_name( localfile, dotmsp );
if ( r != ERROR_SUCCESS )
goto done;
TRACE("copying to local package %s\n", debugstr_w(localfile));
if (!CopyFileW( file, localfile, FALSE ))
{ {
msiobj_release( &si->hdr ); ERR("Unable to copy package (%s -> %s) (error %u)\n",
msiobj_release( &patch_db->hdr ); debugstr_w(file), debugstr_w(localfile), GetLastError());
return r; r = GetLastError();
goto done;
} }
patch->localfile = strdupW( localfile );
/* apply substorage transforms */ /* apply substorage transforms */
substorage = msi_split_string( patch->transforms, ';' ); substorage = msi_split_string( patch->transforms, ';' );
@ -567,6 +579,8 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
r = msi_apply_substorage_transform( package, patch_db, substorage[i] ); r = msi_apply_substorage_transform( package, patch_db, substorage[i] );
msi_free( substorage ); msi_free( substorage );
if (r != ERROR_SUCCESS)
goto done;
msi_set_media_source_prop( package ); msi_set_media_source_prop( package );
/* /*
@ -577,10 +591,20 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
list_add_tail( &package->patches, &patch->entry ); list_add_tail( &package->patches, &patch->entry );
done:
msiobj_release( &si->hdr ); msiobj_release( &si->hdr );
msiobj_release( &patch_db->hdr ); msiobj_release( &patch_db->hdr );
if (patch && r != ERROR_SUCCESS)
{
if (patch->localfile)
DeleteFileW( patch->localfile );
return ERROR_SUCCESS; msi_free( patch->patchcode );
msi_free( patch->transforms );
msi_free( patch->localfile );
msi_free( patch );
}
return r;
} }
/* get the PATCH property, and apply all the patches it specifies */ /* get the PATCH property, and apply all the patches it specifies */

View File

@ -151,6 +151,7 @@ typedef struct tagMSIPATCHINFO
struct list entry; struct list entry;
LPWSTR patchcode; LPWSTR patchcode;
LPWSTR transforms; LPWSTR transforms;
LPWSTR localfile;
} MSIPATCHINFO; } MSIPATCHINFO;
typedef struct _column_info typedef struct _column_info
@ -996,6 +997,7 @@ extern WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... );
extern UINT msi_create_component_directories( MSIPACKAGE *package ); extern UINT msi_create_component_directories( MSIPACKAGE *package );
extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value); MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value);
extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix);
/* media */ /* media */

View File

@ -271,6 +271,7 @@ static void free_package_structures( MSIPACKAGE *package )
list_remove( &patch->entry ); list_remove( &patch->entry );
msi_free( patch->patchcode ); msi_free( patch->patchcode );
msi_free( patch->transforms ); msi_free( patch->transforms );
msi_free( patch->localfile );
msi_free( patch ); msi_free( patch );
} }
@ -1133,12 +1134,12 @@ UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT msi_get_local_package_name( LPWSTR path ) UINT msi_get_local_package_name( LPWSTR path, LPCWSTR suffix )
{ {
static const WCHAR szInstaller[] = { static const WCHAR szInstaller[] = {
'\\','I','n','s','t','a','l','l','e','r','\\',0}; '\\','I','n','s','t','a','l','l','e','r','\\',0};
static const WCHAR fmt[] = { '%','x','.','m','s','i',0}; static const WCHAR fmt[] = {'%','x',0};
DWORD time, len, i; DWORD time, len, i, offset;
HANDLE handle; HANDLE handle;
time = GetTickCount(); time = GetTickCount();
@ -1149,7 +1150,8 @@ static UINT msi_get_local_package_name( LPWSTR path )
len = strlenW(path); len = strlenW(path);
for (i = 0; i < 0x10000; i++) for (i = 0; i < 0x10000; i++)
{ {
snprintfW( &path[len], MAX_PATH - len, fmt, (time + i)&0xffff ); offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff );
memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) );
handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, handle = CreateFileW( path, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
if (handle != INVALID_HANDLE_VALUE) if (handle != INVALID_HANDLE_VALUE)
@ -1170,6 +1172,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
static const WCHAR OriginalDatabase[] = static const WCHAR OriginalDatabase[] =
{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
static const WCHAR Database[] = {'D','A','T','A','B','A','S','E',0}; static const WCHAR Database[] = {'D','A','T','A','B','A','S','E',0};
static const WCHAR dotmsi[] = {'.','m','s','i',0};
MSIDATABASE *db = NULL; MSIDATABASE *db = NULL;
MSIPACKAGE *package; MSIPACKAGE *package;
MSIHANDLE handle; MSIHANDLE handle;
@ -1228,7 +1231,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
file = temppath; file = temppath;
} }
r = msi_get_local_package_name( localfile ); r = msi_get_local_package_name( localfile, dotmsi );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;