From 681da11cfc9a266304b47b88843cb8a365015c63 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 27 Apr 2022 16:54:28 -0500 Subject: Add ability to disable file system redirection for File/DirectorySearch Fixes 5476 --- .../WixToolset.Data/Symbols/WixFileSearchSymbol.cs | 17 +++ src/burn/engine/search.cpp | 114 ++++++++++++++++++++- src/burn/engine/search.h | 1 + src/burn/test/BurnUnitTest/SearchTest.cpp | 12 +++ .../TestData/BundleWithSearches/Bundle.wxs | 5 + .../WixToolsetTest.Util/UtilExtensionFixture.cs | 26 ++--- src/ext/Util/wixext/UtilCompiler.cs | 12 +++ .../Bind/LegacySearchFacade.cs | 5 + 8 files changed, 179 insertions(+), 13 deletions(-) diff --git a/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs index 4f8a370e..9c8e0843 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs @@ -54,6 +54,7 @@ namespace WixToolset.Data.Symbols MaxSizeInclusive = 0x010, MinDateInclusive = 0x020, MaxDateInclusive = 0x040, + DisableFileRedirection = 0x080, } public enum WixFileSearchType @@ -246,5 +247,21 @@ namespace WixToolset.Data.Symbols } } } + + public bool DisableFileRedirection + { + get { return this.Attributes.HasFlag(WixFileSearchAttributes.DisableFileRedirection); } + set + { + if (value) + { + this.Attributes |= WixFileSearchAttributes.DisableFileRedirection; + } + else + { + this.Attributes &= ~WixFileSearchAttributes.DisableFileRedirection; + } + } + } } } diff --git a/src/burn/engine/search.cpp b/src/burn/engine/search.cpp index a57e703e..f521cdbd 100644 --- a/src/burn/engine/search.cpp +++ b/src/burn/engine/search.cpp @@ -139,6 +139,10 @@ extern "C" HRESULT SearchesParseFromXml( hr = XmlGetAttributeEx(pixnNode, L"Path", &pSearch->FileSearch.sczPath); ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Path."); + // @DisableFileRedirection + hr = XmlGetYesNoAttribute(pixnNode, L"DisableFileRedirection", &pSearch->FileSearch.fDisableFileRedirection); + ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get DisableFileRedirection attribute."); + // @Type hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); @@ -557,6 +561,49 @@ extern "C" void SearchesUninitialize( // internal function definitions +#if !defined(_WIN64) + +typedef struct _BURN_FILE_SEARCH +{ + BURN_SEARCH* pSearch; + PROC_FILESYSTEMREDIRECTION pfsr; +} BURN_FILE_SEARCH; + +static HRESULT FileSystemSearchStart( + __in BURN_FILE_SEARCH* pFileSearch + ) +{ + HRESULT hr = S_OK; + + if (pFileSearch->pSearch->FileSearch.fDisableFileRedirection) + { + hr = ProcDisableWowFileSystemRedirection(&pFileSearch->pfsr); + if (hr == E_NOTIMPL) + { + hr = S_FALSE; + } + ExitOnFailure(hr, "Failed to disable file system redirection."); + } + +LExit: + return hr; +} + +static void FileSystemSearchEnd( + __in BURN_FILE_SEARCH* pFileSearch + ) +{ + HRESULT hr = S_OK; + + hr = ProcRevertWowFileSystemRedirection(&pFileSearch->pfsr); + ExitOnFailure(hr, "Failed to revert file system redirection."); + +LExit: + return; +} + +#endif + static HRESULT DirectorySearchExists( __in BURN_SEARCH* pSearch, __in BURN_VARIABLES* pVariables @@ -566,6 +613,15 @@ static HRESULT DirectorySearchExists( LPWSTR sczPath = NULL; BOOL fExists = FALSE; +#if !defined(_WIN64) + BURN_FILE_SEARCH bfs = { }; + + bfs.pSearch = pSearch; + + hr = FileSystemSearchStart(&bfs); + ExitOnFailure(hr, "Failed to initialize file search."); +#endif + // format path hr = VariableFormatString(pVariables, pSearch->DirectorySearch.sczPath, &sczPath, NULL); ExitOnFailure(hr, "Failed to format variable string."); @@ -593,6 +649,10 @@ static HRESULT DirectorySearchExists( ExitOnFailure(hr, "Failed to set variable."); LExit: +#if !defined(_WIN64) + FileSystemSearchEnd(&bfs); +#endif + StrSecureZeroFreeString(sczPath); return hr; @@ -606,6 +666,15 @@ static HRESULT DirectorySearchPath( HRESULT hr = S_OK; LPWSTR sczPath = NULL; +#if !defined(_WIN64) + BURN_FILE_SEARCH bfs = { }; + + bfs.pSearch = pSearch; + + hr = FileSystemSearchStart(&bfs); + ExitOnFailure(hr, "Failed to initialize file search."); +#endif + // format path hr = VariableFormatString(pVariables, pSearch->DirectorySearch.sczPath, &sczPath, NULL); ExitOnFailure(hr, "Failed to format variable string."); @@ -634,6 +703,10 @@ static HRESULT DirectorySearchPath( ExitOnFailure(hr, "Failed while searching directory search: %ls, for path: %ls", pSearch->sczKey, sczPath); LExit: +#if !defined(_WIN64) + FileSystemSearchEnd(&bfs); +#endif + StrSecureZeroFreeString(sczPath); return hr; @@ -649,6 +722,15 @@ static HRESULT FileSearchExists( LPWSTR sczPath = NULL; BOOL fExists = FALSE; +#if !defined(_WIN64) + BURN_FILE_SEARCH bfs = { }; + + bfs.pSearch = pSearch; + + hr = FileSystemSearchStart(&bfs); + ExitOnFailure(hr, "Failed to initialize file search."); +#endif + // format path hr = VariableFormatString(pVariables, pSearch->FileSearch.sczPath, &sczPath, NULL); ExitOnFailure(hr, "Failed to format variable string."); @@ -665,7 +747,7 @@ static HRESULT FileSearchExists( } else { - ExitOnWin32Error(er, hr, "Failed get to file attributes. '%ls'", pSearch->DirectorySearch.sczPath); + ExitOnWin32Error(er, hr, "Failed get to file attributes. '%ls'", pSearch->FileSearch.sczPath); } } else if (FILE_ATTRIBUTE_DIRECTORY != (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)) @@ -678,6 +760,10 @@ static HRESULT FileSearchExists( ExitOnFailure(hr, "Failed to set variable."); LExit: +#if !defined(_WIN64) + FileSystemSearchEnd(&bfs); +#endif + StrSecureZeroFreeString(sczPath); return hr; } @@ -692,6 +778,15 @@ static HRESULT FileSearchVersion( LPWSTR sczPath = NULL; VERUTIL_VERSION* pVersion = NULL; +#if !defined(_WIN64) + BURN_FILE_SEARCH bfs = { }; + + bfs.pSearch = pSearch; + + hr = FileSystemSearchStart(&bfs); + ExitOnFailure(hr, "Failed to initialize file search."); +#endif + // format path hr = VariableFormatString(pVariables, pSearch->FileSearch.sczPath, &sczPath, NULL); ExitOnFailure(hr, "Failed to format path string."); @@ -714,6 +809,10 @@ static HRESULT FileSearchVersion( ExitOnFailure(hr, "Failed to set variable."); LExit: +#if !defined(_WIN64) + FileSystemSearchEnd(&bfs); +#endif + StrSecureZeroFreeString(sczPath); ReleaseVerutilVersion(pVersion); return hr; @@ -727,6 +826,15 @@ static HRESULT FileSearchPath( HRESULT hr = S_OK; LPWSTR sczPath = NULL; +#if !defined(_WIN64) + BURN_FILE_SEARCH bfs = { }; + + bfs.pSearch = pSearch; + + hr = FileSystemSearchStart(&bfs); + ExitOnFailure(hr, "Failed to initialize file search."); +#endif + // format path hr = VariableFormatString(pVariables, pSearch->FileSearch.sczPath, &sczPath, NULL); ExitOnFailure(hr, "Failed to format variable string."); @@ -755,6 +863,10 @@ static HRESULT FileSearchPath( ExitOnFailure(hr, "Failed while searching file search: %ls, for path: %ls", pSearch->sczKey, sczPath); LExit: +#if !defined(_WIN64) + FileSystemSearchEnd(&bfs); +#endif + StrSecureZeroFreeString(sczPath); return hr; diff --git a/src/burn/engine/search.h b/src/burn/engine/search.h index bc53f197..341fe1aa 100644 --- a/src/burn/engine/search.h +++ b/src/burn/engine/search.h @@ -88,6 +88,7 @@ typedef struct _BURN_SEARCH { BURN_FILE_SEARCH_TYPE Type; LPWSTR sczPath; + BOOL fDisableFileRedirection; } FileSearch; struct { diff --git a/src/burn/test/BurnUnitTest/SearchTest.cpp b/src/burn/test/BurnUnitTest/SearchTest.cpp index 7efbca2d..a8e397c2 100644 --- a/src/burn/test/BurnUnitTest/SearchTest.cpp +++ b/src/burn/test/BurnUnitTest/SearchTest.cpp @@ -129,6 +129,9 @@ namespace Bootstrapper L" " L" " L" " + L" " + L" " + L" " L""; // load XML document @@ -145,6 +148,15 @@ namespace Bootstrapper Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable1")); Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable2")); Assert::Equal(gcnew String(pVersion->sczVersion), VariableGetVersionHelper(&variables, L"Variable3")); + + // Assume that consent.exe continues to only exist in 64-bit system folder. + Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable4")); +#if !defined(_WIN64) + Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable5")); +#else + Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5")); +#endif + Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable6")); } finally { diff --git a/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs b/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs index 7fef0725..45147066 100644 --- a/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs +++ b/src/ext/Util/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs @@ -7,6 +7,7 @@ + @@ -42,6 +43,10 @@ + + + + diff --git a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs index 32d18e9c..c7b7efb1 100644 --- a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs +++ b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs @@ -4,6 +4,7 @@ namespace WixToolsetTest.Util { using System.IO; using System.Linq; + using System.Xml; using WixBuildTools.TestSupport; using WixToolset.Core.TestPackage; using WixToolset.Util; @@ -279,18 +280,19 @@ namespace WixToolsetTest.Util "" + "", bundleExtensionDatas[0].GetTestXml()); - var utilSearches = extractResult.SelectManifestNodes("/burn:BurnManifest/*[self::burn:ExtensionSearch or self::burn:FileSearch or self::burn:MsiProductSearch or self::burn:RegistrySearch]"); - Assert.Equal(5, utilSearches.Count); - Assert.Equal("", utilSearches[0].GetTestXml()); - Assert.Equal("", utilSearches[1].GetTestXml()); - Assert.Equal("", utilSearches[2].GetTestXml()); - Assert.Equal("", utilSearches[3].GetTestXml()); - Assert.Equal("", utilSearches[4].GetTestXml()); + var utilSearches = extractResult.SelectManifestNodes("/burn:BurnManifest/*[self::burn:ExtensionSearch or self::burn:DirectorySearch or self::burn:FileSearch or self::burn:MsiProductSearch or self::burn:RegistrySearch]") + .Cast() + .Select(e => e.GetTestXml()) + .ToArray(); + WixAssert.CompareLineByLine(new[] + { + @"", + @"", + @"", + @"", + @"", + @"" + }, utilSearches); } } diff --git a/src/ext/Util/wixext/UtilCompiler.cs b/src/ext/Util/wixext/UtilCompiler.cs index 323e0f6a..d770555f 100644 --- a/src/ext/Util/wixext/UtilCompiler.cs +++ b/src/ext/Util/wixext/UtilCompiler.cs @@ -999,6 +999,12 @@ namespace WixToolset.Util case "After": this.ParseCommonSearchAttributes(sourceLineNumbers, attrib, ref id, ref variable, ref condition, ref after); break; + case "DisableFileRedirection": + if (this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes) + { + attributes |= WixFileSearchAttributes.DisableFileRedirection; + } + break; case "Path": path = this.ParseHelper.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true); break; @@ -1104,6 +1110,12 @@ namespace WixToolset.Util case "After": this.ParseCommonSearchAttributes(sourceLineNumbers, attrib, ref id, ref variable, ref condition, ref after); break; + case "DisableFileRedirection": + if (this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes) + { + attributes |= WixFileSearchAttributes.DisableFileRedirection; + } + break; case "Path": path = this.ParseHelper.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true); break; diff --git a/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs b/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs index c6b6e7ee..c9301fdc 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs @@ -98,6 +98,11 @@ namespace WixToolset.Core.Burn throw new NotImplementedException(); } + if (searchSymbol.DisableFileRedirection) + { + writer.WriteAttributeString("DisableFileRedirection", "yes"); + } + writer.WriteEndElement(); } -- cgit v1.2.3-55-g6feb