From 9337172498d263399b8c5e3795aca1897093d37b Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 10 Mar 2022 22:37:58 -0800 Subject: Use min DOS date/time when filetime not supported by cabinet Cabinets require files use DOS date/time. Since there are limits to DOS date/time, use the minimum date/time when a file's actual DOS date/time are out of bounds. Fixes 5296 --- src/libs/dutil/WixToolset.DUtil/cabcutil.cpp | 14 +++++-- .../WixToolsetTest.CoreIntegration/CabFixture.cs | 45 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp b/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp index 93a9b7e1..9cc45a83 100644 --- a/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/cabcutil.cpp @@ -1047,12 +1047,12 @@ static HRESULT UtcFileTimeToLocalDosDateTime( if (!::FileTimeToLocalFileTime(pFileTime, &ftLocal)) { - CabcExitWithLastError(hr, "Filed to convert file time to local file time."); + CabcExitWithLastError(hr, "Failed to convert file time to local file time."); } if (!::FileTimeToDosDateTime(&ftLocal, pDate, pTime)) { - CabcExitWithLastError(hr, "Filed to convert file time to DOS date time."); + CabcExitWithLastError(hr, "Failed to convert file time to DOS date time."); } LExit: @@ -1508,7 +1508,15 @@ static __callback INT_PTR DIAMONDAPI CabCGetOpenInfo( // found. This would create further problems if the file was written to the CAB without this value. Windows // Installer would then fail to extract the file. hr = UtcFileTimeToLocalDosDateTime(&fad.ftCreationTime, pdate, ptime); - CabcExitOnFailure(hr, "Filed to read a valid file time stucture on file '%s'.", pszName); + + // If we could not convert the ftLastWriteTime or ftCreationTime to a DOS time, then set the date/time to + // the smallest value that can be represented: midnight on 1/1/1980. + if (FAILED(hr)) + { + *pdate = 0; + *ptime = 0; + hr = S_OK; + } } iResult = CabCOpen(pszFilePlusMagic, _O_BINARY|_O_RDONLY, 0, err, pv); diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs index fdb3ff06..6fae3801 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs @@ -49,6 +49,51 @@ namespace WixToolsetTest.CoreIntegration } } + [Fact] + public void CanCabReallyOldFiles() + { + var folder = TestData.Get(@"TestData", "SingleFileCompressed"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(create: true); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var msiPath = Path.Combine(baseFolder, @"bin\test.msi"); + var cabPath = Path.Combine(baseFolder, @"bin\cab1.cab"); + + var old = new DateTime(1980, 1, 1, 0, 0, 0, DateTimeKind.Utc); + var oldTxt = Path.Combine(baseFolder, "test.txt"); + File.Copy(Path.Combine(folder, "data", "test.txt"), oldTxt); + File.SetCreationTime(oldTxt, old); + File.SetLastWriteTime(oldTxt, old); + File.SetLastAccessTime(oldTxt, old); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "Package.wxs"), + Path.Combine(folder, "PackageComponents.wxs"), + "-d", "MediaTemplateCompressionLevel", + "-loc", Path.Combine(folder, "Package.en-us.wxl"), + "-bindpath", baseFolder, + "-intermediateFolder", intermediateFolder, + "-o", msiPath + }); + + result.AssertSuccess(); + Assert.True(File.Exists(cabPath)); + + var fileTable = Query.QueryDatabase(msiPath, new[] { "File" }); + var fileRows = fileTable.Select(r => new FileRow(r)).OrderBy(f => f.Sequence).ToList(); + + Assert.Equal(new[] { 1 }, fileRows.Select(f => f.Sequence).ToArray()); + WixAssert.CompareLineByLine(new[] { "test.txt" }, fileRows.Select(f => f.Name).ToArray()); + + var files = Query.GetCabinetFiles(cabPath); + Assert.Equal(fileRows.Select(f => f.Id).ToArray(), files.Select(f => f.Name).ToArray()); + } + } + private class FileRow { public FileRow(string row) -- cgit v1.2.3-55-g6feb