Author: cwittich Date: Sat Oct 17 23:16:57 2009 New Revision: 43546
URL: http://svn.reactos.org/svn/reactos?rev=43546&view=rev Log: sync msi to wine 1.1.31
Modified: trunk/reactos/dll/win32/msi/action.c trunk/reactos/dll/win32/msi/custom.c trunk/reactos/dll/win32/msi/files.c trunk/reactos/dll/win32/msi/media.c trunk/reactos/dll/win32/msi/msi.c trunk/reactos/dll/win32/msi/msipriv.h trunk/reactos/dll/win32/msi/msiserver.idl trunk/reactos/dll/win32/msi/package.c trunk/reactos/dll/win32/msi/suminfo.c trunk/reactos/dll/win32/msi/table.c trunk/reactos/include/psdk/msi.h
Modified: trunk/reactos/dll/win32/msi/action.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/action.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msi/action.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/action.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -501,7 +501,7 @@ 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 @@ 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);
@@ -836,6 +839,12 @@
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 ); @@ -871,6 +880,9 @@ /* 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 @@ 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 @@ } }
- 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)) @@ -5317,6 +5324,9 @@ ERR("Invalid flags: %08x\n", *flags); return ERROR_FUNCTION_FAILED; } + + if (!*flags) + *flags = ENV_ACT_SETALWAYS | ENV_ACT_REMOVE;
return ERROR_SUCCESS; } @@ -5344,6 +5354,8 @@
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)
Modified: trunk/reactos/dll/win32/msi/custom.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/custom.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -679,7 +679,7 @@ 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 @@ 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,
Modified: trunk/reactos/dll/win32/msi/files.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/files.c?rev=4... ============================================================================== --- trunk/reactos/dll/win32/msi/files.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/files.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -139,7 +139,7 @@ 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 @@ 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) { @@ -161,6 +161,39 @@
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 @@ 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),
Modified: trunk/reactos/dll/win32/msi/media.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/media.c?rev=4... ============================================================================== --- trunk/reactos/dll/win32/msi/media.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/media.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -49,11 +49,16 @@ #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]; - - if (!GetVolumeInformationW(source_root, volume_name, MAX_PATH + 1, + WCHAR root[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 @@ 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 @@ 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()); - - goto done; + DWORD err = GetLastError(); + DWORD attrs2 = GetFileAttributesW(path); + + 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: @@ -453,6 +502,17 @@ msi_free(mi->volume_label); msi_free(mi->first_volume); 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) @@ -494,9 +554,7 @@
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 @@ { /* FIXME: what about SourceDir */ lstrcpyW(mi->source, source); - lstrcatW(mi->source, mi->cabinet); return ERROR_SUCCESS; } }
Modified: trunk/reactos/dll/win32/msi/msi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.c?rev=435... ============================================================================== --- trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -489,13 +489,86 @@ 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); - - return ERROR_CALL_NOT_IMPLEMENTED; + UINT i, r, ret = ERROR_FUNCTION_FAILED; + MSIPACKAGE *package; + + 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, @@ -619,9 +692,6 @@ commandline[0] = 0; if (szCommandLine) lstrcpyW(commandline,szCommandLine); - - if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN) - lstrcatW(commandline,szInstalled);
if (eInstallState == INSTALLSTATE_ABSENT) lstrcatW(commandline, szRemoveAll);
Modified: trunk/reactos/dll/win32/msi/msipriv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msipriv.h?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -340,6 +340,7 @@ 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 @@ -682,6 +683,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 );
Modified: trunk/reactos/dll/win32/msi/msiserver.idl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msiserver.idl... ============================================================================== --- trunk/reactos/dll/win32/msi/msiserver.idl [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msiserver.idl [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -424,4 +424,4 @@ properties: methods: } -} +}
Modified: trunk/reactos/dll/win32/msi/package.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/package.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/package.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/package.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -453,13 +453,14 @@ 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 @@ 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 @@
create_temp_property_table( package ); msi_clone_properties( package ); - set_installer_properties(package); + + package->ProductCode = msi_dup_property( package, szProductCode ); + set_installed_prop( 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 ); r = msi_load_summary_properties( package ); if (r != ERROR_SUCCESS) {
Modified: trunk/reactos/dll/win32/msi/suminfo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/suminfo.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -475,7 +475,9 @@
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; }
Modified: trunk/reactos/dll/win32/msi/table.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/table.c?rev=4... ============================================================================== --- trunk/reactos/dll/win32/msi/table.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/table.c [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -2777,7 +2777,7 @@
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 @@
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);
Modified: trunk/reactos/include/psdk/msi.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/msi.h?rev=4354... ============================================================================== --- trunk/reactos/include/psdk/msi.h [iso-8859-1] (original) +++ trunk/reactos/include/psdk/msi.h [iso-8859-1] Sat Oct 17 23:16:57 2009 @@ -237,6 +237,8 @@
#define MAX_FEATURE_CHARS 38
+#define ERROR_PATCH_TARGET_NOT_FOUND 1642 + /* Strings defined in msi.h */ /* Advertised Information */