Module: wine Branch: master Commit: 23eabb44c894ebccb01cb0d4457b809127ed93a4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=23eabb44c894ebccb01cb0d445...
Author: Hans Leidekker hans@codeweavers.com Date: Tue May 4 09:06:42 2010 +0200
msi: Make a local copy of patch packages.
---
dlls/msi/action.c | 44 ++++++++++++++++++++++++++++++++++---------- dlls/msi/msipriv.h | 2 ++ dlls/msi/package.c | 13 ++++++++----- 3 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 5ca786d..e744973 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -497,7 +497,7 @@ static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ) MSIPATCHINFO *pi; UINT r = ERROR_SUCCESS;
- pi = msi_alloc( sizeof(MSIPATCHINFO) ); + pi = msi_alloc_zero( sizeof(MSIPATCHINFO) ); if (!pi) 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 const WCHAR dotmsp[] = {'.','m','s','p',0}; MSIDATABASE *patch_db = NULL; + WCHAR localfile[MAX_PATH]; LPWSTR *substorage; MSISUMMARYINFO *si; - MSIPATCHINFO *patch; - UINT i, r; + MSIPATCHINFO *patch = NULL; + UINT i, r = ERROR_SUCCESS;
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) { TRACE("patch not applicable\n"); - msiobj_release( &si->hdr ); - msiobj_release( &patch_db->hdr ); - return ERROR_SUCCESS; + r = ERROR_SUCCESS; + goto done; }
r = msi_parse_patch_summary( si, &patch ); 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 ); - msiobj_release( &patch_db->hdr ); - return r; + 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 );
/* apply substorage 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] );
msi_free( substorage ); + if (r != ERROR_SUCCESS) + goto done; 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 );
+done: msiobj_release( &si->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 */ diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index c339ea9..a8594a8 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -151,6 +151,7 @@ typedef struct tagMSIPATCHINFO struct list entry; LPWSTR patchcode; LPWSTR transforms; + LPWSTR localfile; } MSIPATCHINFO;
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_set_last_used_source(LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value); +extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix);
/* media */
diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 45b4dc9..2ffd66e 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -271,6 +271,7 @@ static void free_package_structures( MSIPACKAGE *package ) list_remove( &patch->entry ); msi_free( patch->patchcode ); msi_free( patch->transforms ); + msi_free( patch->localfile ); msi_free( patch ); }
@@ -1133,12 +1134,12 @@ UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ) 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[] = { '\','I','n','s','t','a','l','l','e','r','\',0}; - static const WCHAR fmt[] = { '%','x','.','m','s','i',0}; - DWORD time, len, i; + static const WCHAR fmt[] = {'%','x',0}; + DWORD time, len, i, offset; HANDLE handle;
time = GetTickCount(); @@ -1149,7 +1150,8 @@ static UINT msi_get_local_package_name( LPWSTR path ) len = strlenW(path); 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, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); if (handle != INVALID_HANDLE_VALUE) @@ -1170,6 +1172,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) static const WCHAR OriginalDatabase[] = {'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 dotmsi[] = {'.','m','s','i',0}; MSIDATABASE *db = NULL; MSIPACKAGE *package; MSIHANDLE handle; @@ -1228,7 +1231,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) file = temppath; }
- r = msi_get_local_package_name( localfile ); + r = msi_get_local_package_name( localfile, dotmsi ); if (r != ERROR_SUCCESS) return r;