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