msi: Make a local copy of patch packages.
This commit is contained in:
parent
28cc401295
commit
23eabb44c8
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue