diff --git a/src/ext/Util/ca/TouchFile.cpp b/src/ext/Util/ca/TouchFile.cpp index 2c3918afe..4a3b57b44 100644 --- a/src/ext/Util/ca/TouchFile.cpp +++ b/src/ext/Util/ca/TouchFile.cpp @@ -23,6 +23,7 @@ static HRESULT SetExistingFileModifiedTime( ) { HRESULT hr = S_OK; +#ifndef _WIN64 BOOL fReenableFileSystemRedirection = FALSE; if (f64Bit) @@ -32,14 +33,20 @@ static HRESULT SetExistingFileModifiedTime( fReenableFileSystemRedirection = TRUE; } +#else + UNREFERENCED_PARAMETER(wzId); + UNREFERENCED_PARAMETER(f64Bit); +#endif hr = FileSetTime(wzPath, NULL, NULL, pftModified); +#ifndef _WIN64 LExit: if (fReenableFileSystemRedirection) { WcaRevertWow64FSRedirection(); } +#endif return hr; } @@ -83,6 +90,7 @@ static BOOL TryGetExistingFileModifiedTime( ) { HRESULT hr = S_OK; +#ifndef _WIN64 BOOL fReenableFileSystemRedirection = FALSE; if (f64Bit) @@ -92,6 +100,10 @@ static BOOL TryGetExistingFileModifiedTime( fReenableFileSystemRedirection = TRUE; } +#else + UNREFERENCED_PARAMETER(wzId); + UNREFERENCED_PARAMETER(f64Bit); +#endif hr = FileGetTime(wzPath, NULL, NULL, pftModified); if (E_PATHNOTFOUND == hr || E_FILENOTFOUND == hr) @@ -104,11 +116,13 @@ static BOOL TryGetExistingFileModifiedTime( WcaLog(LOGMSG_STANDARD, "Cannot access modified timestamp for file: '%ls' due to error: 0x%x. Continuing with out rollback for: %ls", wzPath, hr, wzId); } +#ifndef _WIN64 LExit: if (fReenableFileSystemRedirection) { WcaRevertWow64FSRedirection(); } +#endif return SUCCEEDED(hr); } @@ -217,9 +231,17 @@ extern "C" UINT WINAPI WixTouchFileDuringInstall( hr = WcaInitialize(hInstall, "WixTouchFileDuringInstall"); ExitOnFailure(hr, "Failed to initialize WixTouchFileDuringInstall."); +#ifndef _WIN64 + WcaInitializeWow64(); +#endif + hr = ProcessTouchFileTable(TRUE); LExit: +#ifndef _WIN64 + WcaFinalizeWow64(); +#endif + DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); } @@ -236,9 +258,17 @@ extern "C" UINT WINAPI WixTouchFileDuringUninstall( hr = WcaInitialize(hInstall, "WixTouchFileDuringUninstall"); ExitOnFailure(hr, "Failed to initialize WixTouchFileDuringUninstall."); +#ifndef _WIN64 + WcaInitializeWow64(); +#endif + hr = ProcessTouchFileTable(FALSE); LExit: +#ifndef _WIN64 + WcaFinalizeWow64(); +#endif + DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); } @@ -261,6 +291,10 @@ extern "C" UINT WINAPI WixExecuteTouchFile( hr = WcaInitialize(hInstall, "WixExecuteTouchFile"); ExitOnFailure(hr, "Failed to initialize WixExecuteTouchFile."); +#ifndef _WIN64 + WcaInitializeWow64(); +#endif + hr = WcaGetProperty(L"CustomActionData", &sczData); ExitOnFailure(hr, "Failed to get custom action data for WixExecuteTouchFile."); @@ -299,6 +333,10 @@ extern "C" UINT WINAPI WixExecuteTouchFile( } LExit: +#ifndef _WIN64 + WcaFinalizeWow64(); +#endif + ReleaseStr(sczPath); ReleaseStr(sczId); ReleaseStr(sczData); diff --git a/src/test/msi/TestData/TouchFileTests/TouchFile/Package.wxs b/src/test/msi/TestData/TouchFileTests/TouchFile/Package.wxs new file mode 100644 index 000000000..23bd195b0 --- /dev/null +++ b/src/test/msi/TestData/TouchFileTests/TouchFile/Package.wxs @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/test/msi/TestData/TouchFileTests/TouchFile/TouchFile.wixproj b/src/test/msi/TestData/TouchFileTests/TouchFile/TouchFile.wixproj new file mode 100644 index 000000000..58321e7ea --- /dev/null +++ b/src/test/msi/TestData/TouchFileTests/TouchFile/TouchFile.wixproj @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/test/msi/WixToolsetTest.MsiE2E/TouchFileTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/TouchFileTests.cs new file mode 100644 index 000000000..f7666825e --- /dev/null +++ b/src/test/msi/WixToolsetTest.MsiE2E/TouchFileTests.cs @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolsetTest.MsiE2E; + +using System; +using System.IO; +using WixTestTools; +using Xunit; +using Xunit.Abstractions; + +public class TouchFileTests : MsiE2ETests +{ + public TouchFileTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + } + + [RuntimeFact] + public void CanValidateTouchFile() + { + var touchFileTestPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "touch-file-test.txt"); + + try + { + var touchFileTime = new DateTime(2004, 4, 5, 0, 0, 0, DateTimeKind.Utc); + + File.WriteAllText(touchFileTestPath, "This file exists to test CanValidateTouchFile()"); + File.SetCreationTimeUtc(touchFileTestPath, touchFileTime); + File.SetLastAccessTimeUtc(touchFileTestPath, touchFileTime); + File.SetLastWriteTimeUtc(touchFileTestPath, touchFileTime); + + var product = this.CreatePackageInstaller("TouchFile"); + + var justBeforeInstall = DateTime.UtcNow; + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + var touchFile = new FileInfo(touchFileTestPath); + Assert.Equal(touchFileTime, touchFile.CreationTimeUtc); + Assert.Equal(touchFileTime, touchFile.LastAccessTimeUtc); + Assert.True(touchFile.LastWriteTimeUtc >= justBeforeInstall, $"Touch file {touchFileTestPath} last write time: {touchFile.LastWriteTimeUtc} of file should have been updated to at least: {justBeforeInstall}"); + + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + } + finally + { + File.Delete(touchFileTestPath); + } + } +}