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);
+ }
+ }
+}