From f1b52aef96a14d6a59cbfc23c83cae08129d89ad Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Tue, 28 Jun 2005 19:14:30 +0000 Subject: [PATCH] Relocate the msi file to prevent cd locking, corrected to properly not try to relocated #nnnn handles as files. --- dlls/msi/action.c | 11 +++++------ dlls/msi/helpers.c | 1 + dlls/msi/msi.c | 24 +++++++++++++++++++++--- dlls/msi/msipriv.h | 3 ++- dlls/msi/package.c | 24 +++++++++++++++++++++++- 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 2b033e808a6..1dafcef1170 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -432,7 +432,7 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, *****************************************************/ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath, - LPCWSTR szCommandLine) + LPCWSTR szCommandLine, LPCWSTR msiFilePath) { DWORD sz; WCHAR buffer[10]; @@ -447,6 +447,8 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath, package->script = HeapAlloc(GetProcessHeap(),0,sizeof(MSISCRIPT)); memset(package->script,0,sizeof(MSISCRIPT)); + package->msiFilePath= strdupW(msiFilePath); + if (szPackagePath) { LPWSTR p, check, path; @@ -1371,9 +1373,6 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir) if (targetdir[0] == '.' && targetdir[1] == 0) targetdir = NULL; - if (srcdir && srcdir[0] == '.' && srcdir[1] == 0) - srcdir = NULL; - if (targetdir) { TRACE(" TargetDefault = %s\n",debugstr_w(targetdir)); @@ -3574,9 +3573,9 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) snprintfW(path,sizeof(path)/sizeof(path[0]),installerPathFmt,windir); create_full_pathW(path); TRACE("Copying to local package %s\n",debugstr_w(packagefile)); - if (!CopyFileW(package->PackagePath,packagefile,FALSE)) + if (!CopyFileW(package->msiFilePath,packagefile,FALSE)) ERR("Unable to copy package (%s -> %s) (error %ld)\n", - debugstr_w(package->PackagePath), debugstr_w(packagefile), + debugstr_w(package->msiFilePath), debugstr_w(packagefile), GetLastError()); size = strlenW(packagefile)*sizeof(WCHAR); RegSetValueExW(hkey,szLocalPackage,0,REG_SZ,(LPSTR)packagefile,size); diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c index e9e12f12214..e67e16f7133 100644 --- a/dlls/msi/helpers.c +++ b/dlls/msi/helpers.c @@ -580,6 +580,7 @@ void ACTION_free_package_structures( MSIPACKAGE* package) } HeapFree(GetProcessHeap(),0,package->PackagePath); + HeapFree(GetProcessHeap(),0,package->msiFilePath); /* cleanup control event subscriptions */ ControlEvent_CleanupSubscriptions(package); diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index bec3ccbf05a..2d6f196993f 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -202,6 +202,9 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine) MSIPACKAGE *package = NULL; UINT r; MSIHANDLE handle; + WCHAR path[MAX_PATH]; + WCHAR filename[MAX_PATH]; + static const WCHAR szMSI[] = {'M','S','I',0}; FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine)); @@ -209,16 +212,31 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine) if (r != ERROR_SUCCESS) return r; - r = MSI_OpenPackageW(szPackagePath,&package); + /* copy the msi file to a temp file to pervent locking a CD + * with a multi disc install + */ + GetTempPathW(MAX_PATH, path); + GetTempFileNameW(path, szMSI, 0, filename); + + CopyFileW(szPackagePath, filename, FALSE); + + TRACE("Opening relocated package %s\n",debugstr_w(filename)); + r = MSI_OpenPackageW(filename, &package); if (r != ERROR_SUCCESS) + { + DeleteFileW(filename); return r; + } handle = alloc_msihandle( &package->hdr ); - r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine); + r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine, + filename); MsiCloseHandle(handle); msiobj_release( &package->hdr ); + + DeleteFileW(filename); return r; } @@ -324,7 +342,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN) lstrcatW(commandline,szInstalled); - rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline); + rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath); msiobj_release( &package->hdr ); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index dde612992fe..4aa39ceb1b5 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -216,6 +216,7 @@ typedef struct tagMSIPACKAGE UINT RunningActionCount; LPWSTR PackagePath; + LPWSTR msiFilePath; UINT CurrentInstallState; msi_dialog *dialog; @@ -307,7 +308,7 @@ extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname, USHORT **pdata, UINT *psz ); /* action internals */ -extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR ); +extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR, LPCWSTR ); extern void ACTION_free_package_structures( MSIPACKAGE* ); extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR); diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 54a692452eb..5bbfe850b72 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -454,18 +454,40 @@ UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phP { MSIPACKAGE *package = NULL; UINT ret; + WCHAR path[MAX_PATH]; + WCHAR filename[MAX_PATH]; + static const WCHAR szMSI[] = {'M','S','I',0}; TRACE("%s %08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage); + /* copy the msi file to a temp file to pervent locking a CD + * with a multi disc install + */ + if( szPackage[0] == '#' ) + strcpyW(filename,szPackage); + else + { + GetTempPathW(MAX_PATH, path); + GetTempFileNameW(path, szMSI, 0, filename); + + CopyFileW(szPackage, filename, FALSE); + + TRACE("Opening relocated package %s\n",debugstr_w(filename)); + } + if( dwOptions ) FIXME("dwOptions %08lx not supported\n", dwOptions); - ret = MSI_OpenPackageW( szPackage, &package); + ret = MSI_OpenPackageW( filename, &package); if( ret == ERROR_SUCCESS ) { *phPackage = alloc_msihandle( &package->hdr ); msiobj_release( &package->hdr ); } + + if( szPackage[0] != '#' ) + DeleteFileW(filename); + return ret; }