@joebigelow / wix / commits / 8fb5d579

Initialize WOW64 in TouchFile custom action

Fixes 8638

Rob Mensching committed Jul 17, 2024 at 11:09 UTC 8fb5d579e8cf5eb0f93d07a73bf318a8969c6b10
4 files changed +100
src/ext/Util/ca/TouchFile.cpp
+38
@@ -23,6 +23,7 @@ static HRESULT SetExistingFileModifiedTime(
23 )
24 {
25 HRESULT hr = S_OK;
26 +#ifndef _WIN64
27 BOOL fReenableFileSystemRedirection = FALSE;
28
29 if (f64Bit)
@@ -32,14 +33,20 @@ static HRESULT SetExistingFileModifiedTime(
33
34 fReenableFileSystemRedirection = TRUE;
35 }
36 +#else
37 + UNREFERENCED_PARAMETER(wzId);
38 + UNREFERENCED_PARAMETER(f64Bit);
39 +#endif
40
41 hr = FileSetTime(wzPath, NULL, NULL, pftModified);
42
43 +#ifndef _WIN64
44 LExit:
45 if (fReenableFileSystemRedirection)
46 {
47 WcaRevertWow64FSRedirection();
48 }
49 +#endif
50
51 return hr;
52 }
@@ -83,6 +90,7 @@ static BOOL TryGetExistingFileModifiedTime(
90 )
91 {
92 HRESULT hr = S_OK;
93 +#ifndef _WIN64
94 BOOL fReenableFileSystemRedirection = FALSE;
95
96 if (f64Bit)
@@ -92,6 +100,10 @@ static BOOL TryGetExistingFileModifiedTime(
100
101 fReenableFileSystemRedirection = TRUE;
102 }
103 +#else
104 + UNREFERENCED_PARAMETER(wzId);
105 + UNREFERENCED_PARAMETER(f64Bit);
106 +#endif
107
108 hr = FileGetTime(wzPath, NULL, NULL, pftModified);
109 if (E_PATHNOTFOUND == hr || E_FILENOTFOUND == hr)
@@ -104,11 +116,13 @@ static BOOL TryGetExistingFileModifiedTime(
116 WcaLog(LOGMSG_STANDARD, "Cannot access modified timestamp for file: '%ls' due to error: 0x%x. Continuing with out rollback for: %ls", wzPath, hr, wzId);
117 }
118
119 +#ifndef _WIN64
120 LExit:
121 if (fReenableFileSystemRedirection)
122 {
123 WcaRevertWow64FSRedirection();
124 }
125 +#endif
126
127 return SUCCEEDED(hr);
128 }
@@ -217,9 +231,17 @@ extern "C" UINT WINAPI WixTouchFileDuringInstall(
231 hr = WcaInitialize(hInstall, "WixTouchFileDuringInstall");
232 ExitOnFailure(hr, "Failed to initialize WixTouchFileDuringInstall.");
233
234 +#ifndef _WIN64
235 + WcaInitializeWow64();
236 +#endif
237 +
238 hr = ProcessTouchFileTable(TRUE);
239
240 LExit:
241 +#ifndef _WIN64
242 + WcaFinalizeWow64();
243 +#endif
244 +
245 DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
246 return WcaFinalize(er);
247 }
@@ -236,9 +258,17 @@ extern "C" UINT WINAPI WixTouchFileDuringUninstall(
258 hr = WcaInitialize(hInstall, "WixTouchFileDuringUninstall");
259 ExitOnFailure(hr, "Failed to initialize WixTouchFileDuringUninstall.");
260
261 +#ifndef _WIN64
262 + WcaInitializeWow64();
263 +#endif
264 +
265 hr = ProcessTouchFileTable(FALSE);
266
267 LExit:
268 +#ifndef _WIN64
269 + WcaFinalizeWow64();
270 +#endif
271 +
272 DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
273 return WcaFinalize(er);
274 }
@@ -261,6 +291,10 @@ extern "C" UINT WINAPI WixExecuteTouchFile(
291 hr = WcaInitialize(hInstall, "WixExecuteTouchFile");
292 ExitOnFailure(hr, "Failed to initialize WixExecuteTouchFile.");
293
294 +#ifndef _WIN64
295 + WcaInitializeWow64();
296 +#endif
297 +
298 hr = WcaGetProperty(L"CustomActionData", &sczData);
299 ExitOnFailure(hr, "Failed to get custom action data for WixExecuteTouchFile.");
300
@@ -299,6 +333,10 @@ extern "C" UINT WINAPI WixExecuteTouchFile(
333 }
334
335 LExit:
336 +#ifndef _WIN64
337 + WcaFinalizeWow64();
338 +#endif
339 +
340 ReleaseStr(sczPath);
341 ReleaseStr(sczId);
342 ReleaseStr(sczData);
src/test/msi/TestData/TouchFileTests/TouchFile/Package.wxs new
+8
@@ -0,0 +1,8 @@
1 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
2 + <Package Name="~TouchFile" Version="1.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3 + <Component>
4 + <File Source="$(sys.SOURCEFILEPATH)" />
5 + <util:TouchFile Path="[LocalAppDataFolder]touch-file-test.txt" />
6 + </Component>
7 + </Package>
8 +</Wix>
src/test/msi/TestData/TouchFileTests/TouchFile/TouchFile.wixproj new
+6
@@ -0,0 +1,6 @@
1 +<!-- 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. -->
2 +<Project Sdk="WixToolset.Sdk">
3 + <ItemGroup>
4 + <PackageReference Include="WixToolset.Util.wixext" />
5 + </ItemGroup>
6 +</Project>
\ No newline at end of file
src/test/msi/WixToolsetTest.MsiE2E/TouchFileTests.cs new
+48
@@ -0,0 +1,48 @@
1 +// 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.
2 +
3 +namespace WixToolsetTest.MsiE2E;
4 +
5 +using System;
6 +using System.IO;
7 +using WixTestTools;
8 +using Xunit;
9 +using Xunit.Abstractions;
10 +
11 +public class TouchFileTests : MsiE2ETests
12 +{
13 + public TouchFileTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
14 + {
15 + }
16 +
17 + [RuntimeFact]
18 + public void CanValidateTouchFile()
19 + {
20 + var touchFileTestPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "touch-file-test.txt");
21 +
22 + try
23 + {
24 + var touchFileTime = new DateTime(2004, 4, 5, 0, 0, 0, DateTimeKind.Utc);
25 +
26 + File.WriteAllText(touchFileTestPath, "This file exists to test CanValidateTouchFile()");
27 + File.SetCreationTimeUtc(touchFileTestPath, touchFileTime);
28 + File.SetLastAccessTimeUtc(touchFileTestPath, touchFileTime);
29 + File.SetLastWriteTimeUtc(touchFileTestPath, touchFileTime);
30 +
31 + var product = this.CreatePackageInstaller("TouchFile");
32 +
33 + var justBeforeInstall = DateTime.UtcNow;
34 + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
35 +
36 + var touchFile = new FileInfo(touchFileTestPath);
37 + Assert.Equal(touchFileTime, touchFile.CreationTimeUtc);
38 + Assert.Equal(touchFileTime, touchFile.LastAccessTimeUtc);
39 + Assert.True(touchFile.LastWriteTimeUtc >= justBeforeInstall, $"Touch file {touchFileTestPath} last write time: {touchFile.LastWriteTimeUtc} of file should have been updated to at least: {justBeforeInstall}");
40 +
41 + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
42 + }
43 + finally
44 + {
45 + File.Delete(touchFileTestPath);
46 + }
47 + }
48 +}