From 8dd3d389b02a6477e78aa9af1ccc310fa3a562a9 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 20 Oct 2009 14:09:53 +0200 Subject: [PATCH] msi: Create the local copy before opening the database. --- dlls/msi/action.c | 61 +++------------------------------------------ dlls/msi/database.c | 5 ++++ dlls/msi/msipriv.h | 1 + dlls/msi/package.c | 49 +++++++++++++++++++++++++++++++++++- 4 files changed, 57 insertions(+), 59 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index e10870133c4..b9b819995cd 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -3802,63 +3802,6 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package) return ERROR_SUCCESS; } -static UINT msi_get_local_package_name( LPWSTR path ) -{ - 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; - HANDLE handle; - - time = GetTickCount(); - GetWindowsDirectoryW( path, MAX_PATH ); - lstrcatW( path, szInstaller ); - CreateDirectoryW( path, NULL ); - - len = lstrlenW(path); - for (i=0; i<0x10000; i++) - { - snprintfW( &path[len], MAX_PATH - len, fmt, (time+i)&0xffff ); - handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, - CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); - if (handle != INVALID_HANDLE_VALUE) - { - CloseHandle(handle); - break; - } - if (GetLastError() != ERROR_FILE_EXISTS && - GetLastError() != ERROR_SHARING_VIOLATION) - return ERROR_FUNCTION_FAILED; - } - - return ERROR_SUCCESS; -} - -static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) -{ - WCHAR packagefile[MAX_PATH]; - UINT r; - - r = msi_get_local_package_name( packagefile ); - if (r != ERROR_SUCCESS) - return r; - - TRACE("Copying to local package %s\n",debugstr_w(packagefile)); - - r = CopyFileW( package->db->path, packagefile, FALSE); - - if (!r) - { - ERR("Unable to copy package (%s -> %s) (error %d)\n", - debugstr_w(package->db->path), debugstr_w(packagefile), GetLastError()); - return ERROR_FUNCTION_FAILED; - } - - msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile ); - - return ERROR_SUCCESS; -} - static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) { LPWSTR prop, val, key; @@ -3990,7 +3933,9 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) if (rc != ERROR_SUCCESS) goto done; - msi_make_package_local(package, props); + msi_reg_set_val_str( props, INSTALLPROPERTY_LOCALPACKAGEW, package->db->localfile ); + msi_free( package->db->localfile ); + package->db->localfile = NULL; rc = msi_publish_install_properties(package, hkey); if (rc != ERROR_SUCCESS) diff --git a/dlls/msi/database.c b/dlls/msi/database.c index 8d0ee42ea02..a75b8a8204e 100644 --- a/dlls/msi/database.c +++ b/dlls/msi/database.c @@ -65,6 +65,11 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg ) DeleteFileW( db->deletefile ); msi_free( db->deletefile ); } + if (db->localfile) + { + DeleteFileW( db->localfile ); + msi_free( db->localfile ); + } } UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 296e87d69ae..9692b64e14a 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -76,6 +76,7 @@ typedef struct tagMSIDATABASE UINT bytes_per_strref; LPWSTR path; LPWSTR deletefile; + LPWSTR localfile; LPCWSTR mode; struct list tables; struct list transforms; diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 1d34770916d..1ab2afd1774 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -870,6 +870,38 @@ LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename ) return filename; } +static UINT msi_get_local_package_name( LPWSTR path ) +{ + 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; + HANDLE handle; + + time = GetTickCount(); + GetWindowsDirectoryW( path, MAX_PATH ); + strcatW( path, szInstaller ); + CreateDirectoryW( path, NULL ); + + len = strlenW(path); + for (i = 0; i < 0x10000; i++) + { + snprintfW( &path[len], MAX_PATH - len, fmt, (time + i)&0xffff ); + handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, + CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); + if (handle != INVALID_HANDLE_VALUE) + { + CloseHandle(handle); + break; + } + if (GetLastError() != ERROR_FILE_EXISTS && + GetLastError() != ERROR_SHARING_VIOLATION) + return ERROR_FUNCTION_FAILED; + } + + return ERROR_SUCCESS; +} + UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) { static const WCHAR OriginalDatabase[] = @@ -880,7 +912,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) MSIHANDLE handle; LPWSTR ptr, base_url = NULL; UINT r; - WCHAR temppath[MAX_PATH]; + WCHAR temppath[MAX_PATH], localfile[MAX_PATH]; LPCWSTR file = szPackage; TRACE("%s %p\n", debugstr_w(szPackage), pPackage); @@ -921,6 +953,19 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) else file = copy_package_to_temp( szPackage, temppath ); + r = msi_get_local_package_name( localfile ); + 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(); + } + r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &db ); if( r != ERROR_SUCCESS ) { @@ -932,6 +977,8 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) return r; } + + db->localfile = strdupW( localfile ); } package = MSI_CreatePackage( db, base_url );