sync msi to wine 1.1.31

svn path=/trunk/; revision=43546
This commit is contained in:
Christoph von Wittich 2009-10-17 21:16:57 +00:00
parent 72a954c01c
commit 002073c923
11 changed files with 227 additions and 41 deletions

View file

@ -501,7 +501,7 @@ static UINT msi_apply_substorage_transform( MSIPACKAGE *package,
return ERROR_SUCCESS;
}
static UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
{
static const WCHAR szProdCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 };
LPWSTR guid_list, *guids, product_code;
@ -789,6 +789,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
static const WCHAR szAll[] = {'A','L','L',0};
MSI_SetPropertyW(package, szAction, szInstall);
@ -837,6 +840,12 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
msi_apply_transforms( package );
msi_apply_patches( package );
if (!szCommandLine && msi_get_property_int( package, szInstalled, 0 ))
{
TRACE("setting reinstall property\n");
MSI_SetPropertyW( package, szReinstall, szAll );
}
/* properties may have been added by a transform */
msi_clone_properties( package );
msi_set_context( package );
@ -871,6 +880,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
/* finish up running custom actions */
ACTION_FinishCustomActions(package);
if (rc == ERROR_SUCCESS && package->need_reboot)
return ERROR_SUCCESS_REBOOT_REQUIRED;
return rc;
}
@ -3378,16 +3390,12 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
return ERROR_SUCCESS;
res = CoInitialize( NULL );
if (FAILED (res))
{
ERR("CoInitialize failed\n");
return ERROR_FUNCTION_FAILED;
}
rc = MSI_IterateRecords(view, NULL, ITERATE_CreateShortcuts, package);
msiobj_release(&view->hdr);
CoUninitialize();
if (SUCCEEDED(res))
CoUninitialize();
return rc;
}
@ -5308,8 +5316,7 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
}
}
if (!*flags ||
check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
if (check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) ||
check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETALWAYS) ||
check_flag_combo(*flags, ENV_ACT_SETABSENT | ENV_MOD_MASK))
@ -5318,6 +5325,9 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
return ERROR_FUNCTION_FAILED;
}
if (!*flags)
*flags = ENV_ACT_SETALWAYS | ENV_ACT_REMOVE;
return ERROR_SUCCESS;
}
@ -5345,6 +5355,8 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
name = MSI_RecordGetString(rec, 2);
value = MSI_RecordGetString(rec, 3);
TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
res = env_set_flags(&name, &value, &flags);
if (res != ERROR_SUCCESS)
goto done;

View file

@ -679,7 +679,7 @@ static DWORD ACTION_CallDllFunction( const GUID *guid )
hModule = LoadLibraryW( dll );
if (!hModule)
{
ERR("failed to load dll %s\n", debugstr_w( dll ) );
ERR("failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() );
return r;
}
@ -1046,15 +1046,16 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
if( row )
{
LPCWSTR error = MSI_RecordGetString( row, 1 );
MessageBoxW( NULL, error, NULL, MB_OK );
if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
MessageBoxW( NULL, error, NULL, MB_OK );
msiobj_release( &row->hdr );
}
else
else if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
MessageBoxW( NULL, deformated, NULL, MB_OK );
msi_free( deformated );
return ERROR_FUNCTION_FAILED;
return ERROR_INSTALL_FAILURE;
}
static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,

View file

@ -139,7 +139,7 @@ static UINT copy_file(MSIFILE *file, LPWSTR source)
return ERROR_SUCCESS;
}
static UINT copy_install_file(MSIFILE *file, LPWSTR source)
static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
{
UINT gle;
@ -153,7 +153,7 @@ static UINT copy_install_file(MSIFILE *file, LPWSTR source)
if (gle == ERROR_ALREADY_EXISTS && file->state == msifs_overwrite)
{
TRACE("overwriting existing file\n");
gle = ERROR_SUCCESS;
return ERROR_SUCCESS;
}
else if (gle == ERROR_ACCESS_DENIED)
{
@ -162,6 +162,39 @@ static UINT copy_install_file(MSIFILE *file, LPWSTR source)
gle = copy_file(file, source);
TRACE("Overwriting existing file: %d\n", gle);
}
if (gle == ERROR_SHARING_VIOLATION)
{
static const WCHAR msiW[] = {'m','s','i',0};
static const WCHAR slashW[] = {'\\',0};
WCHAR tmpfileW[MAX_PATH], *pathW, *p;
DWORD len;
TRACE("file in use, scheduling rename operation\n");
GetTempFileNameW(slashW, msiW, 0, tmpfileW);
len = strlenW(file->TargetPath) + strlenW(tmpfileW) + 1;
if (!(pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
return ERROR_OUTOFMEMORY;
strcpyW(pathW, file->TargetPath);
if ((p = strrchrW(pathW, '\\'))) *p = 0;
strcatW(pathW, tmpfileW);
if (CopyFileW(source, pathW, FALSE) &&
MoveFileExW(file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) &&
MoveFileExW(pathW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT))
{
file->state = msifs_installed;
package->need_reboot = 1;
gle = ERROR_SUCCESS;
}
else
{
gle = GetLastError();
WARN("failed to schedule rename operation: %d)\n", gle);
}
HeapFree(GetProcessHeap(), 0, pathW);
}
return gle;
}
@ -296,7 +329,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
debugstr_w(file->TargetPath));
msi_file_update_ui(package, file, szInstallFiles);
rc = copy_install_file(file, source);
rc = copy_install_file(package, file, source);
if (rc != ERROR_SUCCESS)
{
ERR("Failed to copy %s to %s (%d)\n", debugstr_w(source),

View file

@ -49,11 +49,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
#define _O_TEXT 0x4000
#define _O_BINARY 0x8000
static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPWSTR source_root)
static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
{
WCHAR volume_name[MAX_PATH + 1];
WCHAR root[MAX_PATH + 1];
if (!GetVolumeInformationW(source_root, volume_name, MAX_PATH + 1,
strcpyW(root, source_root);
PathStripToRootW(root);
PathAddBackslashW(root);
if (!GetVolumeInformationW(root, volume_name, MAX_PATH + 1,
NULL, NULL, NULL, NULL, 0))
{
ERR("Failed to get volume information\n");
@ -80,7 +85,6 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
error = generate_error_string(package, 1302, 1, mi->disk_prompt);
error_dialog = msi_dup_property(package, error_prop);
source_dir = msi_dup_property(package, cszSourceDir);
PathStripToRootW(source_dir);
while (r == ERROR_SUCCESS &&
!source_matches_volume(mi, source_dir))
@ -333,11 +337,56 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
NULL, CREATE_ALWAYS, attrs, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
ERR("failed to create %s (error %d)\n",
debugstr_w(path), GetLastError());
DWORD err = GetLastError();
DWORD attrs2 = GetFileAttributesW(path);
goto done;
if (attrs2 == INVALID_FILE_ATTRIBUTES)
{
ERR("failed to create %s (error %d)\n", debugstr_w(path), err);
goto done;
}
else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY))
{
TRACE("removing read-only attribute on %s\n", debugstr_w(path));
SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY );
handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs2, NULL);
if (handle != INVALID_HANDLE_VALUE) goto done;
err = GetLastError();
}
if (err == ERROR_SHARING_VIOLATION)
{
static const WCHAR msiW[] = {'m','s','i',0};
static const WCHAR slashW[] = {'\\',0};
WCHAR tmpfileW[MAX_PATH], *tmppathW, *p;
DWORD len;
TRACE("file in use, scheduling rename operation\n");
GetTempFileNameW(slashW, msiW, 0, tmpfileW);
len = strlenW(path) + strlenW(tmpfileW) + 1;
if (!(tmppathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
return ERROR_OUTOFMEMORY;
strcpyW(tmppathW, path);
if ((p = strrchrW(tmppathW, '\\'))) *p = 0;
strcatW(tmppathW, tmpfileW);
handle = CreateFileW(tmppathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
if (handle != INVALID_HANDLE_VALUE &&
MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) &&
MoveFileExW(tmppathW, path, MOVEFILE_DELAY_UNTIL_REBOOT))
{
data->package->need_reboot = 1;
}
else
WARN("failed to schedule rename operation %s (error %d)\n", debugstr_w(path), GetLastError());
HeapFree(GetProcessHeap(), 0, tmppathW);
}
else
WARN("failed to create %s (error %d)\n", debugstr_w(path), err);
}
done:
@ -455,6 +504,17 @@ void msi_free_media_info(MSIMEDIAINFO *mi)
msi_free(mi);
}
static UINT get_drive_type(const WCHAR *path)
{
WCHAR root[MAX_PATH + 1];
strcpyW(root, path);
PathStripToRootW(root);
PathAddBackslashW(root);
return GetDriveTypeW(root);
}
static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
{
MSIRECORD *row;
@ -494,9 +554,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO
source_dir = msi_dup_property(package, cszSourceDir);
lstrcpyW(mi->source, source_dir);
PathStripToRootW(source_dir);
mi->type = GetDriveTypeW(source_dir);
mi->type = get_drive_type(source_dir);
if (file->IsCompressed && mi->cabinet)
{
@ -576,7 +634,6 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
{
/* FIXME: what about SourceDir */
lstrcpyW(mi->source, source);
lstrcatW(mi->source, mi->cabinet);
return ERROR_SUCCESS;
}
}

View file

@ -489,13 +489,86 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
return ERROR_CALL_NOT_IMPLEMENTED;
}
static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
{
MSISUMMARYINFO *si;
MSIDATABASE *patch_db;
UINT r = ERROR_SUCCESS;
r = MSI_OpenDatabaseW( patch, MSIDBOPEN_READONLY, &patch_db );
if (r != ERROR_SUCCESS)
{
WARN("failed to open patch file %s\n", debugstr_w(patch));
return r;
}
si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
if (!si)
{
r = ERROR_FUNCTION_FAILED;
goto done;
}
r = msi_check_patch_applicable( package, si );
if (r != ERROR_SUCCESS)
TRACE("patch not applicable\n");
done:
msiobj_release( &patch_db->hdr );
msiobj_release( &si->hdr );
return r;
}
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
{
FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
cPatchInfo, pPatchInfo);
UINT i, r, ret = ERROR_FUNCTION_FAILED;
MSIPACKAGE *package;
return ERROR_CALL_NOT_IMPLEMENTED;
TRACE("(%s, %d, %p)\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
r = MSI_OpenPackageW( szProductPackagePath, &package );
if (r != ERROR_SUCCESS)
{
ERR("failed to open package %u\n", r);
return r;
}
for (i = 0; i < cPatchInfo; i++)
{
switch (pPatchInfo[i].ePatchDataType)
{
case MSIPATCH_DATATYPE_PATCHFILE:
{
FIXME("patch ordering not supported\n");
r = MSI_ApplicablePatchW( package, pPatchInfo[i].szPatchData );
if (r != ERROR_SUCCESS)
{
pPatchInfo[i].dwOrder = ~0u;
pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
}
else
{
pPatchInfo[i].dwOrder = i;
pPatchInfo[i].uStatus = ret = ERROR_SUCCESS;
}
break;
}
default:
{
FIXME("patch data type %u not supported\n", pPatchInfo[i].ePatchDataType);
pPatchInfo[i].dwOrder = ~0u;
pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
break;
}
}
TRACE(" szPatchData: %s\n", debugstr_w(pPatchInfo[i].szPatchData));
TRACE("ePatchDataType: %u\n", pPatchInfo[i].ePatchDataType);
TRACE(" dwOrder: %u\n", pPatchInfo[i].dwOrder);
TRACE(" uStatus: %u\n", pPatchInfo[i].uStatus);
}
return ret;
}
UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
@ -620,9 +693,6 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
if (szCommandLine)
lstrcpyW(commandline,szCommandLine);
if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
lstrcatW(commandline,szInstalled);
if (eInstallState == INSTALLSTATE_ABSENT)
lstrcatW(commandline, szRemoveAll);

View file

@ -340,6 +340,7 @@ typedef struct tagMSIPACKAGE
unsigned char scheduled_action_running : 1;
unsigned char commit_action_running : 1;
unsigned char rollback_action_running : 1;
unsigned char need_reboot : 1;
} MSIPACKAGE;
typedef struct tagMSIPREVIEW
@ -683,6 +684,8 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
LPCWSTR szTransformFile, int iErrorCond );
extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg );
extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si );
/* action internals */
extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern void ACTION_free_package_structures( MSIPACKAGE* );

View file

@ -424,4 +424,4 @@ library WindowsInstaller
properties:
methods:
}
}
}

View file

@ -453,13 +453,14 @@ static VOID set_installer_properties(MSIPACKAGE *package)
static const WCHAR szTime[] = {'T','i','m','e',0};
static const WCHAR szUserLangID[] = {'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0};
static const WCHAR szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0};
static const WCHAR szProductState[] = {'P','r','o','d','u','c','t','S','t','a','t','e',0};
/*
* Other things that probably should be set:
*
* ComputerName LogonUser VirtualMemory
* ShellAdvSupport DefaultUIFont PackagecodeChanging
* ProductState CaptionHeight BorderTop BorderSide TextHeight
* CaptionHeight BorderTop BorderSide TextHeight
* RedirectedDllSupport
*/
@ -658,6 +659,9 @@ static VOID set_installer_properties(MSIPACKAGE *package)
sprintfW(bufstr, szIntFormat, langid);
MSI_SetPropertyW( package, szSystemLangID, bufstr );
sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode));
MSI_SetPropertyW( package, szProductState, bufstr );
}
static UINT msi_load_summary_properties( MSIPACKAGE *package )
@ -804,12 +808,14 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
create_temp_property_table( package );
msi_clone_properties( package );
set_installer_properties(package);
sprintfW(uilevel,szpi,gUILevel);
MSI_SetPropertyW(package, szLevel, uilevel);
package->ProductCode = msi_dup_property( package, szProductCode );
set_installed_prop( package );
set_installer_properties( package );
sprintfW(uilevel,szpi,gUILevel);
MSI_SetPropertyW(package, szLevel, uilevel);
r = msi_load_summary_properties( package );
if (r != ERROR_SUCCESS)
{

View file

@ -475,7 +475,9 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
if( szDatabase )
{
ret = MSI_OpenDatabaseW( szDatabase, NULL, &db );
LPCWSTR persist = uiUpdateCount ? MSIDBOPEN_TRANSACT : MSIDBOPEN_READONLY;
ret = MSI_OpenDatabaseW( szDatabase, persist, &db );
if( ret != ERROR_SUCCESS )
return ret;
}

View file

@ -2777,7 +2777,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
r = TABLE_insert_row( &tv->view, rec, -1, FALSE );
if (r != ERROR_SUCCESS)
ERR("insert row failed\n");
WARN("insert row failed\n");
if ( number != MSI_NULL_INTEGER && !lstrcmpW(name, szColumns) )
msi_update_table_columns( db, table );
@ -2788,7 +2788,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
r = msi_table_find_row( tv, rec, &row );
if (r != ERROR_SUCCESS)
ERR("no matching row to transform\n");
WARN("no matching row to transform\n");
else if ( mask )
{
TRACE("modifying row [%d]:\n", row);

View file

@ -237,6 +237,8 @@ typedef struct tagMSIPATCHSEQUENCEINFOW
#define MAX_FEATURE_CHARS 38
#define ERROR_PATCH_TARGET_NOT_FOUND 1642
/* Strings defined in msi.h */
/* Advertised Information */