diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2020-03-30 19:46:56 +1000 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2020-03-30 21:57:49 +1000 |
commit | 0afd76e4c5d46f237591d860e7d445e267522187 (patch) | |
tree | 9f3b648da7733464c83ba6e253a65a18d17f5583 | |
parent | d74e3dd4bcc573d0c4b1fb5c36c8bf0115cc21a1 (diff) | |
download | wix-0afd76e4c5d46f237591d860e7d445e267522187.tar.gz wix-0afd76e4c5d46f237591d860e7d445e267522187.tar.bz2 wix-0afd76e4c5d46f237591d860e7d445e267522187.zip |
Add DetectSHA2Support "search".
-rw-r--r-- | nuget.config | 2 | ||||
-rw-r--r-- | src/be/UtilBundleExtension.cpp | 87 | ||||
-rw-r--r-- | src/be/UtilBundleExtension.h | 16 | ||||
-rw-r--r-- | src/be/detectsha2support.cpp | 58 | ||||
-rw-r--r-- | src/be/detectsha2support.h | 8 | ||||
-rw-r--r-- | src/be/packages.config | 1 | ||||
-rw-r--r-- | src/be/precomp.h | 23 | ||||
-rw-r--r-- | src/be/utilbe.cpp | 28 | ||||
-rw-r--r-- | src/be/utilbe.vcxproj | 20 | ||||
-rw-r--r-- | src/be/utilsearch.cpp | 137 | ||||
-rw-r--r-- | src/be/utilsearch.h | 52 | ||||
-rw-r--r-- | src/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs | 5 | ||||
-rw-r--r-- | src/test/WixToolsetTest.Util/UtilExtensionFixture.cs | 55 | ||||
-rw-r--r-- | src/wixext/Tuples/UtilTupleDefinitions.cs | 10 | ||||
-rw-r--r-- | src/wixext/Tuples/WixDetectSHA2SupportTuple.cs | 33 | ||||
-rw-r--r-- | src/wixext/UtilBinder.cs | 347 | ||||
-rw-r--r-- | src/wixext/UtilCompiler.cs | 198 | ||||
-rw-r--r-- | src/wixext/UtilConstants.cs | 2 | ||||
-rw-r--r-- | src/wixext/UtilErrors.cs | 6 | ||||
-rw-r--r-- | src/wixext/util.xsd | 24 |
20 files changed, 611 insertions, 501 deletions
diff --git a/nuget.config b/nuget.config index aaee3228..80101d94 100644 --- a/nuget.config +++ b/nuget.config | |||
@@ -2,6 +2,8 @@ | |||
2 | <configuration> | 2 | <configuration> |
3 | <packageSources> | 3 | <packageSources> |
4 | <clear /> | 4 | <clear /> |
5 | <add key="wixtoolset-balutil" value="https://ci.appveyor.com/nuget/wixtoolset-balutil" /> | ||
6 | <add key="wixtoolset-bootstrappercore" value="https://ci.appveyor.com/nuget/wixtoolset-bootstrappercore" /> | ||
5 | <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" /> | 7 | <add key="wixtoolset-data" value="https://ci.appveyor.com/nuget/wixtoolset-data" /> |
6 | <add key="wixtoolset-extensibility" value="https://ci.appveyor.com/nuget/wixtoolset-extensibility" /> | 8 | <add key="wixtoolset-extensibility" value="https://ci.appveyor.com/nuget/wixtoolset-extensibility" /> |
7 | <add key="wixtoolset-core" value="https://ci.appveyor.com/nuget/wixtoolset-core" /> | 9 | <add key="wixtoolset-core" value="https://ci.appveyor.com/nuget/wixtoolset-core" /> |
diff --git a/src/be/UtilBundleExtension.cpp b/src/be/UtilBundleExtension.cpp new file mode 100644 index 00000000..2ac842a5 --- /dev/null +++ b/src/be/UtilBundleExtension.cpp | |||
@@ -0,0 +1,87 @@ | |||
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 | #include "precomp.h" | ||
4 | #include "BextBaseBundleExtension.h" | ||
5 | |||
6 | class CWixUtilBundleExtension : public CBextBaseBundleExtension | ||
7 | { | ||
8 | public: // IBundleExtension | ||
9 | virtual STDMETHODIMP Search( | ||
10 | __in LPCWSTR wzId, | ||
11 | __in LPCWSTR wzVariable | ||
12 | ) | ||
13 | { | ||
14 | HRESULT hr = S_OK; | ||
15 | |||
16 | hr = UtilSearchExecute(&m_searches, wzId, wzVariable, m_pEngine); | ||
17 | |||
18 | return hr; | ||
19 | } | ||
20 | |||
21 | public: //CBextBaseBundleExtension | ||
22 | virtual STDMETHODIMP Initialize( | ||
23 | __in const BUNDLE_EXTENSION_CREATE_ARGS* pCreateArgs | ||
24 | ) | ||
25 | { | ||
26 | HRESULT hr = S_OK; | ||
27 | IXMLDOMDocument* pixdManifest = NULL; | ||
28 | IXMLDOMNode* pixnBundleExtension = NULL; | ||
29 | |||
30 | hr = CBextBaseBundleExtension::Initialize(pCreateArgs); | ||
31 | ExitOnFailure(hr, "CBextBaseBundleExtension initialization failed."); | ||
32 | |||
33 | hr = XmlLoadDocumentFromFile(m_sczBundleExtensionDataPath, &pixdManifest); | ||
34 | ExitOnFailure(hr, "Failed to load bundle extension manifest from path: %ls", m_sczBundleExtensionDataPath); | ||
35 | |||
36 | hr = BextGetBundleExtensionDataNode(pixdManifest, UTIL_BUNDLE_EXTENSION_ID, &pixnBundleExtension); | ||
37 | ExitOnFailure(hr, "Failed to get BundleExtension '%ls'", UTIL_BUNDLE_EXTENSION_ID); | ||
38 | |||
39 | hr = UtilSearchParseFromXml(&m_searches, pixnBundleExtension); | ||
40 | ExitOnFailure(hr, "Failed to parse searches from bundle extension manifest."); | ||
41 | |||
42 | LExit: | ||
43 | ReleaseObject(pixnBundleExtension); | ||
44 | ReleaseObject(pixdManifest); | ||
45 | |||
46 | return hr; | ||
47 | } | ||
48 | |||
49 | public: | ||
50 | CWixUtilBundleExtension( | ||
51 | __in IBundleExtensionEngine* pEngine | ||
52 | ) : CBextBaseBundleExtension(pEngine) | ||
53 | { | ||
54 | m_searches = { }; | ||
55 | } | ||
56 | |||
57 | ~CWixUtilBundleExtension() | ||
58 | { | ||
59 | UtilSearchUninitialize(&m_searches); | ||
60 | } | ||
61 | |||
62 | private: | ||
63 | UTIL_SEARCHES m_searches; | ||
64 | }; | ||
65 | |||
66 | HRESULT UtilBundleExtensionCreate( | ||
67 | __in IBundleExtensionEngine* pEngine, | ||
68 | __in const BUNDLE_EXTENSION_CREATE_ARGS* pArgs, | ||
69 | __out IBundleExtension** ppBundleExtension | ||
70 | ) | ||
71 | { | ||
72 | HRESULT hr = S_OK; | ||
73 | CWixUtilBundleExtension* pExtension = NULL; | ||
74 | |||
75 | pExtension = new CWixUtilBundleExtension(pEngine); | ||
76 | ExitOnNull(pExtension, hr, E_OUTOFMEMORY, "Failed to create new CWixUtilBundleExtension."); | ||
77 | |||
78 | hr = pExtension->Initialize(pArgs); | ||
79 | ExitOnFailure(hr, "CWixUtilBundleExtension initialization failed"); | ||
80 | |||
81 | *ppBundleExtension = pExtension; | ||
82 | pExtension = NULL; | ||
83 | |||
84 | LExit: | ||
85 | ReleaseObject(pExtension); | ||
86 | return hr; | ||
87 | } | ||
diff --git a/src/be/UtilBundleExtension.h b/src/be/UtilBundleExtension.h new file mode 100644 index 00000000..16c5b346 --- /dev/null +++ b/src/be/UtilBundleExtension.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #pragma once | ||
2 | // 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. | ||
3 | |||
4 | |||
5 | // constants | ||
6 | |||
7 | #define UTIL_BUNDLE_EXTENSION_ID L"WixUtilBundleExtension" | ||
8 | |||
9 | |||
10 | // function declarations | ||
11 | |||
12 | HRESULT UtilBundleExtensionCreate( | ||
13 | __in IBundleExtensionEngine* pEngine, | ||
14 | __in const BUNDLE_EXTENSION_CREATE_ARGS* pArgs, | ||
15 | __out IBundleExtension** ppBundleExtension | ||
16 | ); | ||
diff --git a/src/be/detectsha2support.cpp b/src/be/detectsha2support.cpp new file mode 100644 index 00000000..f1f3637e --- /dev/null +++ b/src/be/detectsha2support.cpp | |||
@@ -0,0 +1,58 @@ | |||
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 | #include "precomp.h" | ||
4 | |||
5 | // https://gist.github.com/navossoc/7572c7d82243e9f818989e2765e7793a | ||
6 | HRESULT DetectSHA2Support( | ||
7 | __out BOOL* pfSupported | ||
8 | ) | ||
9 | { | ||
10 | HRESULT hr = S_OK; | ||
11 | HMODULE hModule = NULL; | ||
12 | FARPROC pfn = NULL; | ||
13 | DWORD er = ERROR_SUCCESS; | ||
14 | |||
15 | hr = LoadSystemLibrary(L"wintrust.dll", &hModule); | ||
16 | ExitOnFailure(hr, "Failed to load wintrust.dll"); | ||
17 | |||
18 | pfn = ::GetProcAddress(hModule, "CryptCATAdminAcquireContext2"); | ||
19 | if (pfn) | ||
20 | { | ||
21 | *pfSupported = TRUE; | ||
22 | ExitFunction1(hr = S_OK); | ||
23 | } | ||
24 | |||
25 | er = ::GetLastError(); | ||
26 | if (er == ERROR_PROC_NOT_FOUND) | ||
27 | { | ||
28 | *pfSupported = FALSE; | ||
29 | ExitFunction1(hr = S_OK); | ||
30 | } | ||
31 | |||
32 | hr = HRESULT_FROM_WIN32(er); | ||
33 | ExitOnFailure(hr, "Failed to probe for CryptCATAdminAcquireContext2 in wintrust.dll"); | ||
34 | |||
35 | LExit: | ||
36 | ::FreeLibrary(hModule); | ||
37 | |||
38 | return hr; | ||
39 | } | ||
40 | |||
41 | HRESULT UtilPerformDetectSHA2Support( | ||
42 | __in LPCWSTR wzVariable, | ||
43 | __in UTIL_SEARCH* /*pSearch*/, | ||
44 | __in IBundleExtensionEngine* pEngine | ||
45 | ) | ||
46 | { | ||
47 | HRESULT hr = S_OK; | ||
48 | BOOL fSupported = FALSE; | ||
49 | |||
50 | hr = DetectSHA2Support(&fSupported); | ||
51 | ExitOnFailure(hr, "DetectSHA2Support failed."); | ||
52 | |||
53 | hr = pEngine->SetVariableNumeric(wzVariable, fSupported ? 1 : 0); | ||
54 | ExitOnFailure(hr, "Failed to set variable '%ls'", wzVariable); | ||
55 | |||
56 | LExit: | ||
57 | return hr; | ||
58 | } | ||
diff --git a/src/be/detectsha2support.h b/src/be/detectsha2support.h new file mode 100644 index 00000000..7f1f6031 --- /dev/null +++ b/src/be/detectsha2support.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #pragma once | ||
2 | // 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. | ||
3 | |||
4 | HRESULT UtilPerformDetectSHA2Support( | ||
5 | __in LPCWSTR wzVariable, | ||
6 | __in UTIL_SEARCH* pSearch, | ||
7 | __in IBundleExtensionEngine* pEngine | ||
8 | ); \ No newline at end of file | ||
diff --git a/src/be/packages.config b/src/be/packages.config index f05546c5..ca23641f 100644 --- a/src/be/packages.config +++ b/src/be/packages.config | |||
@@ -1,5 +1,6 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | <packages> | 2 | <packages> |
3 | <package id="WixToolset.BextUtil" version="4.0.16" targetFramework="native" /> | ||
3 | <package id="WixToolset.BootstrapperCore.Native" version="4.0.13" targetFramework="native" /> | 4 | <package id="WixToolset.BootstrapperCore.Native" version="4.0.13" targetFramework="native" /> |
4 | <package id="WixToolset.DUtil" version="4.0.18" targetFramework="native" /> | 5 | <package id="WixToolset.DUtil" version="4.0.18" targetFramework="native" /> |
5 | </packages> \ No newline at end of file | 6 | </packages> \ No newline at end of file |
diff --git a/src/be/precomp.h b/src/be/precomp.h index 9dc3c468..a4ab7abf 100644 --- a/src/be/precomp.h +++ b/src/be/precomp.h | |||
@@ -17,9 +17,20 @@ | |||
17 | 17 | ||
18 | #define MAXUINT USHRT_MAX | 18 | #define MAXUINT USHRT_MAX |
19 | 19 | ||
20 | #include "dutil.h" | 20 | #include <dutil.h> |
21 | #include "memutil.h" | 21 | #include <memutil.h> |
22 | 22 | #include <strutil.h> | |
23 | #include "BootstrapperEngine.h" | 23 | #include <pathutil.h> |
24 | #include "BundleExtensionEngine.h" | 24 | #include <xmlutil.h> |
25 | #include "BundleExtension.h" | 25 | |
26 | #include <BundleExtensionEngine.h> | ||
27 | #include <BundleExtension.h> | ||
28 | |||
29 | #include <IBundleExtensionEngine.h> | ||
30 | #include <IBundleExtension.h> | ||
31 | #include <bextutil.h> | ||
32 | #include <BextBundleExtensionEngine.h> | ||
33 | |||
34 | #include "utilsearch.h" | ||
35 | #include "detectsha2support.h" | ||
36 | #include "UtilBundleExtension.h" | ||
diff --git a/src/be/utilbe.cpp b/src/be/utilbe.cpp index 370669dd..d9816dc7 100644 --- a/src/be/utilbe.cpp +++ b/src/be/utilbe.cpp | |||
@@ -1,19 +1,41 @@ | |||
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. | 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 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | #include "BextBaseBundleExtensionProc.h" | ||
5 | |||
6 | static IBundleExtension* vpBundleExtension = NULL; | ||
4 | 7 | ||
5 | // function definitions | 8 | // function definitions |
6 | 9 | ||
7 | extern "C" HRESULT WINAPI BundleExtensionCreate( | 10 | extern "C" HRESULT WINAPI BundleExtensionCreate( |
8 | __in const BUNDLE_EXTENSION_CREATE_ARGS* /*pArgs*/, | 11 | __in const BUNDLE_EXTENSION_CREATE_ARGS* pArgs, |
9 | __inout BUNDLE_EXTENSION_CREATE_RESULTS* /*pResults*/ | 12 | __inout BUNDLE_EXTENSION_CREATE_RESULTS* pResults |
10 | ) | 13 | ) |
11 | { | 14 | { |
12 | HRESULT hr = S_OK; | 15 | HRESULT hr = S_OK; |
16 | IBundleExtensionEngine* pEngine = NULL; | ||
17 | |||
18 | hr = XmlInitialize(); | ||
19 | ExitOnFailure(hr, "Failed to initialize XML."); | ||
20 | |||
21 | hr = BextInitializeFromCreateArgs(pArgs, &pEngine); | ||
22 | ExitOnFailure(hr, "Failed to initialize bext"); | ||
23 | |||
24 | hr = UtilBundleExtensionCreate(pEngine, pArgs, &vpBundleExtension); | ||
25 | BextExitOnFailure(hr, "Failed to create WixUtilBundleExtension"); | ||
26 | |||
27 | pResults->pfnBundleExtensionProc = BextBaseBundleExtensionProc; | ||
28 | pResults->pvBundleExtensionProcContext = vpBundleExtension; | ||
29 | |||
30 | LExit: | ||
31 | ReleaseObject(pEngine); | ||
13 | 32 | ||
14 | return hr; | 33 | return hr; |
15 | } | 34 | } |
16 | 35 | ||
17 | extern "C" void WINAPI BundleExtensionDestroy() | 36 | extern "C" void WINAPI BundleExtensionDestroy() |
18 | { | 37 | { |
38 | BextUninitialize(); | ||
39 | ReleaseNullObject(vpBundleExtension); | ||
40 | XmlUninitialize(); | ||
19 | } \ No newline at end of file | 41 | } \ No newline at end of file |
diff --git a/src/be/utilbe.vcxproj b/src/be/utilbe.vcxproj index 963eac7f..e64d113e 100644 --- a/src/be/utilbe.vcxproj +++ b/src/be/utilbe.vcxproj | |||
@@ -1,10 +1,9 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | <!-- 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 | <!-- 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. --> |
3 | |||
4 | <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | 3 | <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
4 | <Import Project="..\..\packages\WixToolset.BextUtil.4.0.16\build\WixToolset.BextUtil.props" Condition="Exists('..\..\packages\WixToolset.BextUtil.4.0.16\build\WixToolset.BextUtil.props')" /> | ||
5 | <Import Project="..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props" Condition="Exists('..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props')" /> | 5 | <Import Project="..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props" Condition="Exists('..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props')" /> |
6 | <Import Project="..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props')" /> | 6 | <Import Project="..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props')" /> |
7 | |||
8 | <ItemGroup Label="ProjectConfigurations"> | 7 | <ItemGroup Label="ProjectConfigurations"> |
9 | <ProjectConfiguration Include="Debug|Win32"> | 8 | <ProjectConfiguration Include="Debug|Win32"> |
10 | <Configuration>Debug</Configuration> | 9 | <Configuration>Debug</Configuration> |
@@ -15,7 +14,6 @@ | |||
15 | <Platform>Win32</Platform> | 14 | <Platform>Win32</Platform> |
16 | </ProjectConfiguration> | 15 | </ProjectConfiguration> |
17 | </ItemGroup> | 16 | </ItemGroup> |
18 | |||
19 | <PropertyGroup Label="Globals"> | 17 | <PropertyGroup Label="Globals"> |
20 | <ProjectGuid>{630C1EE7-2517-4A8C-83E3-DA1150308B58}</ProjectGuid> | 18 | <ProjectGuid>{630C1EE7-2517-4A8C-83E3-DA1150308B58}</ProjectGuid> |
21 | <ConfigurationType>DynamicLibrary</ConfigurationType> | 19 | <ConfigurationType>DynamicLibrary</ConfigurationType> |
@@ -25,37 +23,37 @@ | |||
25 | <ProjectModuleDefinitionFile>utilbe.def</ProjectModuleDefinitionFile> | 23 | <ProjectModuleDefinitionFile>utilbe.def</ProjectModuleDefinitionFile> |
26 | <Description>WiX Toolset Util BundleExtension</Description> | 24 | <Description>WiX Toolset Util BundleExtension</Description> |
27 | </PropertyGroup> | 25 | </PropertyGroup> |
28 | |||
29 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | 26 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
30 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | 27 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
31 | |||
32 | <PropertyGroup> | 28 | <PropertyGroup> |
33 | <ProjectAdditionalLinkLibraries>msi.lib</ProjectAdditionalLinkLibraries> | 29 | <ProjectAdditionalLinkLibraries>msi.lib</ProjectAdditionalLinkLibraries> |
34 | </PropertyGroup> | 30 | </PropertyGroup> |
35 | |||
36 | <ItemGroup> | 31 | <ItemGroup> |
32 | <ClCompile Include="detectsha2support.cpp" /> | ||
37 | <ClCompile Include="precomp.cpp"> | 33 | <ClCompile Include="precomp.cpp"> |
38 | <PrecompiledHeader>Create</PrecompiledHeader> | 34 | <PrecompiledHeader>Create</PrecompiledHeader> |
39 | </ClCompile> | 35 | </ClCompile> |
40 | <ClCompile Include="utilbe.cpp" /> | 36 | <ClCompile Include="utilbe.cpp" /> |
37 | <ClCompile Include="UtilBundleExtension.cpp" /> | ||
38 | <ClCompile Include="utilsearch.cpp" /> | ||
41 | </ItemGroup> | 39 | </ItemGroup> |
42 | |||
43 | <ItemGroup> | 40 | <ItemGroup> |
41 | <ClInclude Include="detectsha2support.h" /> | ||
44 | <ClInclude Include="precomp.h" /> | 42 | <ClInclude Include="precomp.h" /> |
43 | <ClInclude Include="UtilBundleExtension.h" /> | ||
44 | <ClInclude Include="utilsearch.h" /> | ||
45 | </ItemGroup> | 45 | </ItemGroup> |
46 | |||
47 | <ItemGroup> | 46 | <ItemGroup> |
48 | <None Include="packages.config" /> | 47 | <None Include="packages.config" /> |
49 | <None Include="utilbe.def" /> | 48 | <None Include="utilbe.def" /> |
50 | </ItemGroup> | 49 | </ItemGroup> |
51 | |||
52 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | 50 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
53 | |||
54 | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | 51 | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
55 | <PropertyGroup> | 52 | <PropertyGroup> |
56 | <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | 53 | <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> |
57 | </PropertyGroup> | 54 | </PropertyGroup> |
55 | <Error Condition="!Exists('..\..\packages\WixToolset.BextUtil.4.0.16\build\WixToolset.BextUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.BextUtil.4.0.16\build\WixToolset.BextUtil.props'))" /> | ||
58 | <Error Condition="!Exists('..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props'))" /> | 56 | <Error Condition="!Exists('..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.BootstrapperCore.Native.4.0.13\build\WixToolset.BootstrapperCore.Native.props'))" /> |
59 | <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props'))" /> | 57 | <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.18\build\WixToolset.DUtil.props'))" /> |
60 | </Target> | 58 | </Target> |
61 | </Project> | 59 | </Project> \ No newline at end of file |
diff --git a/src/be/utilsearch.cpp b/src/be/utilsearch.cpp new file mode 100644 index 00000000..4e9d86a1 --- /dev/null +++ b/src/be/utilsearch.cpp | |||
@@ -0,0 +1,137 @@ | |||
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 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | STDMETHODIMP UtilSearchParseFromXml( | ||
7 | __in UTIL_SEARCHES* pSearches, | ||
8 | __in IXMLDOMNode* pixnBundleExtension | ||
9 | ) | ||
10 | { | ||
11 | HRESULT hr = S_OK; | ||
12 | IXMLDOMNodeList* pixnNodes = NULL; | ||
13 | IXMLDOMNode* pixnNode = NULL; | ||
14 | DWORD cNodes = 0; | ||
15 | BSTR bstrNodeName = NULL; | ||
16 | |||
17 | // Select Util search nodes. | ||
18 | hr = XmlSelectNodes(pixnBundleExtension, L"WixDetectSHA2Support", &pixnNodes); | ||
19 | ExitOnFailure(hr, "Failed to select Util search nodes."); | ||
20 | |||
21 | // Get Util search node count. | ||
22 | hr = pixnNodes->get_length((long*)&cNodes); | ||
23 | ExitOnFailure(hr, "Failed to get Util search node count."); | ||
24 | |||
25 | if (!cNodes) | ||
26 | { | ||
27 | ExitFunction(); | ||
28 | } | ||
29 | |||
30 | // Allocate memory for searches. | ||
31 | pSearches->rgSearches = (UTIL_SEARCH*)MemAlloc(sizeof(UTIL_SEARCH) * cNodes, TRUE); | ||
32 | ExitOnNull(pSearches->rgSearches, hr, E_OUTOFMEMORY, "Failed to allocate memory for search structs."); | ||
33 | |||
34 | pSearches->cSearches = cNodes; | ||
35 | |||
36 | // Parse search elements. | ||
37 | for (DWORD i = 0; i < cNodes; ++i) | ||
38 | { | ||
39 | UTIL_SEARCH* pSearch = &pSearches->rgSearches[i]; | ||
40 | |||
41 | hr = XmlNextElement(pixnNodes, &pixnNode, &bstrNodeName); | ||
42 | ExitOnFailure(hr, "Failed to get next node."); | ||
43 | |||
44 | // @Id | ||
45 | hr = XmlGetAttributeEx(pixnNode, L"Id", &pSearch->sczId); | ||
46 | ExitOnFailure(hr, "Failed to get @Id."); | ||
47 | |||
48 | // Read type specific attributes. | ||
49 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"WixDetectSHA2Support", -1)) | ||
50 | { | ||
51 | pSearch->Type = UTIL_SEARCH_TYPE_DETECT_SHA2_SUPPORT; | ||
52 | } | ||
53 | else | ||
54 | { | ||
55 | hr = E_UNEXPECTED; | ||
56 | ExitOnFailure(hr, "Unexpected element name: %ls", bstrNodeName); | ||
57 | } | ||
58 | |||
59 | // prepare next iteration | ||
60 | ReleaseNullObject(pixnNode); | ||
61 | ReleaseNullBSTR(bstrNodeName); | ||
62 | } | ||
63 | |||
64 | LExit: | ||
65 | ReleaseBSTR(bstrNodeName); | ||
66 | ReleaseObject(pixnNode); | ||
67 | ReleaseObject(pixnNodes); | ||
68 | |||
69 | return hr; | ||
70 | } | ||
71 | |||
72 | void UtilSearchUninitialize( | ||
73 | __in UTIL_SEARCHES* pSearches | ||
74 | ) | ||
75 | { | ||
76 | if (pSearches->rgSearches) | ||
77 | { | ||
78 | for (DWORD i = 0; i < pSearches->cSearches; ++i) | ||
79 | { | ||
80 | UTIL_SEARCH* pSearch = &pSearches->rgSearches[i]; | ||
81 | |||
82 | ReleaseStr(pSearch->sczId); | ||
83 | } | ||
84 | MemFree(pSearches->rgSearches); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | STDMETHODIMP UtilSearchExecute( | ||
89 | __in UTIL_SEARCHES* pSearches, | ||
90 | __in LPCWSTR wzSearchId, | ||
91 | __in LPCWSTR wzVariable, | ||
92 | __in IBundleExtensionEngine* pEngine | ||
93 | ) | ||
94 | { | ||
95 | HRESULT hr = S_OK; | ||
96 | UTIL_SEARCH* pSearch = NULL; | ||
97 | |||
98 | hr = UtilSearchFindById(pSearches, wzSearchId, &pSearch); | ||
99 | ExitOnFailure(hr, "Search id '%ls' is unknown to the util extension."); | ||
100 | |||
101 | switch (pSearch->Type) | ||
102 | { | ||
103 | case UTIL_SEARCH_TYPE_DETECT_SHA2_SUPPORT: | ||
104 | hr = UtilPerformDetectSHA2Support(wzVariable, pSearch, pEngine); | ||
105 | break; | ||
106 | default: | ||
107 | hr = E_UNEXPECTED; | ||
108 | } | ||
109 | |||
110 | LExit: | ||
111 | return hr; | ||
112 | } | ||
113 | |||
114 | STDMETHODIMP UtilSearchFindById( | ||
115 | __in UTIL_SEARCHES* pSearches, | ||
116 | __in LPCWSTR wzId, | ||
117 | __out UTIL_SEARCH** ppSearch | ||
118 | ) | ||
119 | { | ||
120 | HRESULT hr = S_OK; | ||
121 | |||
122 | for (DWORD i = 0; i < pSearches->cSearches; ++i) | ||
123 | { | ||
124 | UTIL_SEARCH* pSearch = &pSearches->rgSearches[i]; | ||
125 | |||
126 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pSearch->sczId, -1, wzId, -1)) | ||
127 | { | ||
128 | *ppSearch = pSearch; | ||
129 | ExitFunction1(hr = S_OK); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | hr = E_NOTFOUND; | ||
134 | |||
135 | LExit: | ||
136 | return hr; | ||
137 | } | ||
diff --git a/src/be/utilsearch.h b/src/be/utilsearch.h new file mode 100644 index 00000000..1e0ca96d --- /dev/null +++ b/src/be/utilsearch.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #pragma once | ||
2 | // 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. | ||
3 | |||
4 | |||
5 | // constants | ||
6 | |||
7 | enum UTIL_SEARCH_TYPE | ||
8 | { | ||
9 | UTIL_SEARCH_TYPE_NONE, | ||
10 | UTIL_SEARCH_TYPE_DETECT_SHA2_SUPPORT, | ||
11 | }; | ||
12 | |||
13 | |||
14 | // structs | ||
15 | |||
16 | typedef struct _UTIL_SEARCH | ||
17 | { | ||
18 | LPWSTR sczId; | ||
19 | |||
20 | UTIL_SEARCH_TYPE Type; | ||
21 | } UTIL_SEARCH; | ||
22 | |||
23 | typedef struct _UTIL_SEARCHES | ||
24 | { | ||
25 | UTIL_SEARCH* rgSearches; | ||
26 | DWORD cSearches; | ||
27 | } UTIL_SEARCHES; | ||
28 | |||
29 | |||
30 | // function declarations | ||
31 | |||
32 | STDMETHODIMP UtilSearchParseFromXml( | ||
33 | __in UTIL_SEARCHES* pSearches, | ||
34 | __in IXMLDOMNode* pixnBundleExtension | ||
35 | ); | ||
36 | |||
37 | void UtilSearchUninitialize( | ||
38 | __in UTIL_SEARCHES* pSearches | ||
39 | ); | ||
40 | |||
41 | STDMETHODIMP UtilSearchExecute( | ||
42 | __in UTIL_SEARCHES* pSearches, | ||
43 | __in LPCWSTR wzSearchId, | ||
44 | __in LPCWSTR wzVariable, | ||
45 | __in IBundleExtensionEngine* pEngine | ||
46 | ); | ||
47 | |||
48 | STDMETHODIMP UtilSearchFindById( | ||
49 | __in UTIL_SEARCHES* pSearches, | ||
50 | __in LPCWSTR wzId, | ||
51 | __out UTIL_SEARCH** ppSearch | ||
52 | ); | ||
diff --git a/src/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs b/src/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs index cafd4255..82646b37 100644 --- a/src/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs +++ b/src/test/WixToolsetTest.Util/TestData/BundleWithSearches/Bundle.wxs | |||
@@ -7,6 +7,7 @@ | |||
7 | <util:RegistrySearchRef Id="RegistrySearchId" /> | 7 | <util:RegistrySearchRef Id="RegistrySearchId" /> |
8 | <util:ProductSearchRef Id="ProductSearchId" /> | 8 | <util:ProductSearchRef Id="ProductSearchId" /> |
9 | <util:FileSearchRef Id="FileSearchId" /> | 9 | <util:FileSearchRef Id="FileSearchId" /> |
10 | <util:DetectSHA2SupportRef Id="DetectSHA2SupportId" /> | ||
10 | 11 | ||
11 | <Chain> | 12 | <Chain> |
12 | <MsiPackage SourceFile="test.msi"> | 13 | <MsiPackage SourceFile="test.msi"> |
@@ -32,4 +33,8 @@ | |||
32 | <Fragment> | 33 | <Fragment> |
33 | <util:FileSearch Id="FileSearchId" Variable="FileSearchVariable" Path="%windir%\System32\mscoree.dll" Result="exists" /> | 34 | <util:FileSearch Id="FileSearchId" Variable="FileSearchVariable" Path="%windir%\System32\mscoree.dll" Result="exists" /> |
34 | </Fragment> | 35 | </Fragment> |
36 | |||
37 | <Fragment> | ||
38 | <util:DetectSHA2Support Id="DetectSHA2SupportId" Variable="IsSHA2Supported" /> | ||
39 | </Fragment> | ||
35 | </Wix> | 40 | </Wix> |
diff --git a/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs b/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs index 8f33eff5..c5b370ac 100644 --- a/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs +++ b/src/test/WixToolsetTest.Util/UtilExtensionFixture.cs | |||
@@ -146,6 +146,9 @@ namespace WixToolsetTest.Util | |||
146 | { | 146 | { |
147 | var baseFolder = fs.GetFolder(); | 147 | var baseFolder = fs.GetFolder(); |
148 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | 148 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
149 | var bundlePath = Path.Combine(baseFolder, @"bin\test.exe"); | ||
150 | var baFolderPath = Path.Combine(baseFolder, "ba"); | ||
151 | var extractFolderPath = Path.Combine(baseFolder, "extract"); | ||
149 | 152 | ||
150 | var result = WixRunner.Execute(new[] | 153 | var result = WixRunner.Execute(new[] |
151 | { | 154 | { |
@@ -156,45 +159,35 @@ namespace WixToolsetTest.Util | |||
156 | "-bindpath", Path.Combine(folder, "data"), | 159 | "-bindpath", Path.Combine(folder, "data"), |
157 | "-intermediateFolder", intermediateFolder, | 160 | "-intermediateFolder", intermediateFolder, |
158 | "-burnStub", burnStubPath, | 161 | "-burnStub", burnStubPath, |
159 | "-o", Path.Combine(baseFolder, @"bin\test.exe") | 162 | "-o", bundlePath |
160 | }); | 163 | }); |
161 | 164 | ||
162 | result.AssertSuccess(); | 165 | result.AssertSuccess(); |
163 | 166 | ||
164 | Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.exe"))); | 167 | Assert.True(File.Exists(bundlePath)); |
165 | #if TODO | 168 | #if TODO |
166 | Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb"))); | 169 | Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb"))); |
167 | #endif | 170 | #endif |
168 | 171 | ||
169 | var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); | 172 | var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath); |
170 | var section = intermediate.Sections.Single(); | 173 | extractResult.AssertSuccess(); |
171 | 174 | ||
172 | var searchTuples = section.Tuples.OfType<WixSearchTuple>().OrderBy(t => t.Id.Id).ToList(); | 175 | var bundleExtensionDatas = extractResult.SelectBundleExtensionDataNodes("/be:BundleExtensionData/be:BundleExtension[@Id='WixUtilBundleExtension']"); |
173 | Assert.Equal(3, searchTuples.Count); | 176 | Assert.Equal(1, bundleExtensionDatas.Count); |
174 | Assert.Equal("FileSearchId", searchTuples[0].Id.Id); | 177 | Assert.Equal("<BundleExtension Id='WixUtilBundleExtension'>" + |
175 | Assert.Equal("FileSearchVariable", searchTuples[0].Variable); | 178 | "<WixDetectSHA2Support Id='DetectSHA2SupportId' />" + |
176 | Assert.Equal("ProductSearchId", searchTuples[1].Id.Id); | 179 | "</BundleExtension>", bundleExtensionDatas[0].GetTestXml()); |
177 | Assert.Equal("ProductSearchVariable", searchTuples[1].Variable); | 180 | |
178 | Assert.Equal("1 & 2 < 3", searchTuples[1].Condition); | 181 | var utilSearches = extractResult.SelectManifestNodes("/burn:BurnManifest/*[self::burn:ExtensionSearch or self::burn:FileSearch or self::burn:MsiProductSearch or self::burn:RegistrySearch]"); |
179 | Assert.Equal("RegistrySearchId", searchTuples[2].Id.Id); | 182 | Assert.Equal(4, utilSearches.Count); |
180 | Assert.Equal("RegistrySearchVariable", searchTuples[2].Variable); | 183 | Assert.Equal("<ExtensionSearch Id='DetectSHA2SupportId' Variable='IsSHA2Supported' " + |
181 | 184 | "ExtensionId='WixUtilBundleExtension' />", utilSearches[0].GetTestXml()); | |
182 | var fileSearchTuple = section.Tuples.OfType<WixFileSearchTuple>().Single(); | 185 | Assert.Equal("<FileSearch Id='FileSearchId' Variable='FileSearchVariable' " + |
183 | Assert.Equal("FileSearchId", fileSearchTuple.Id.Id); | 186 | $@"Path='%windir%\System32\mscoree.dll' Type='exists' />", utilSearches[1].GetTestXml()); |
184 | Assert.Equal(@"%windir%\System32\mscoree.dll", fileSearchTuple.Path); | 187 | Assert.Equal("<MsiProductSearch Id='ProductSearchId' Variable='ProductSearchVariable' Condition='1 & 2 < 3' " + |
185 | Assert.Equal(WixFileSearchAttributes.Default | WixFileSearchAttributes.WantExists, fileSearchTuple.Attributes); | 188 | "UpgradeCode='{738D02BF-E231-4370-8209-E9FD4E1BE2A1}' Type='version' />", utilSearches[2].GetTestXml()); |
186 | 189 | Assert.Equal("<RegistrySearch Id='RegistrySearchId' Variable='RegistrySearchVariable' " + | |
187 | var productSearchTuple = section.Tuples.OfType<WixProductSearchTuple>().Single(); | 190 | @"Root='HKLM' Key='SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' Value='Release' Type='value' VariableType='string' />", utilSearches[3].GetTestXml()); |
188 | Assert.Equal("ProductSearchId", productSearchTuple.Id.Id); | ||
189 | Assert.Equal("{738D02BF-E231-4370-8209-E9FD4E1BE2A1}", productSearchTuple.Guid); | ||
190 | Assert.Equal(WixProductSearchAttributes.Version | WixProductSearchAttributes.UpgradeCode, productSearchTuple.Attributes); | ||
191 | |||
192 | var registrySearchTuple = section.Tuples.OfType<WixRegistrySearchTuple>().Single(); | ||
193 | Assert.Equal("RegistrySearchId", registrySearchTuple.Id.Id); | ||
194 | Assert.Equal(RegistryRootType.LocalMachine, registrySearchTuple.Root); | ||
195 | Assert.Equal(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", registrySearchTuple.Key); | ||
196 | Assert.Equal("Release", registrySearchTuple.Value); | ||
197 | Assert.Equal(WixRegistrySearchAttributes.WantValue | WixRegistrySearchAttributes.Raw, registrySearchTuple.Attributes); | ||
198 | } | 191 | } |
199 | } | 192 | } |
200 | 193 | ||
diff --git a/src/wixext/Tuples/UtilTupleDefinitions.cs b/src/wixext/Tuples/UtilTupleDefinitions.cs index 00c98337..ece64502 100644 --- a/src/wixext/Tuples/UtilTupleDefinitions.cs +++ b/src/wixext/Tuples/UtilTupleDefinitions.cs | |||
@@ -4,6 +4,7 @@ namespace WixToolset.Util | |||
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using WixToolset.Data; | 6 | using WixToolset.Data; |
7 | using WixToolset.Data.Burn; | ||
7 | 8 | ||
8 | public enum UtilTupleDefinitionType | 9 | public enum UtilTupleDefinitionType |
9 | { | 10 | { |
@@ -19,6 +20,7 @@ namespace WixToolset.Util | |||
19 | User, | 20 | User, |
20 | UserGroup, | 21 | UserGroup, |
21 | WixCloseApplication, | 22 | WixCloseApplication, |
23 | WixDetectSHA2Support, | ||
22 | WixFormatFiles, | 24 | WixFormatFiles, |
23 | WixInternetShortcut, | 25 | WixInternetShortcut, |
24 | WixRemoveFolderEx, | 26 | WixRemoveFolderEx, |
@@ -82,6 +84,9 @@ namespace WixToolset.Util | |||
82 | case UtilTupleDefinitionType.WixCloseApplication: | 84 | case UtilTupleDefinitionType.WixCloseApplication: |
83 | return UtilTupleDefinitions.WixCloseApplication; | 85 | return UtilTupleDefinitions.WixCloseApplication; |
84 | 86 | ||
87 | case UtilTupleDefinitionType.WixDetectSHA2Support: | ||
88 | return UtilTupleDefinitions.WixDetectSHA2Support; | ||
89 | |||
85 | case UtilTupleDefinitionType.WixFormatFiles: | 90 | case UtilTupleDefinitionType.WixFormatFiles: |
86 | return UtilTupleDefinitions.WixFormatFiles; | 91 | return UtilTupleDefinitions.WixFormatFiles; |
87 | 92 | ||
@@ -107,5 +112,10 @@ namespace WixToolset.Util | |||
107 | throw new ArgumentOutOfRangeException(nameof(type)); | 112 | throw new ArgumentOutOfRangeException(nameof(type)); |
108 | } | 113 | } |
109 | } | 114 | } |
115 | |||
116 | static UtilTupleDefinitions() | ||
117 | { | ||
118 | WixDetectSHA2Support.AddTag(BurnConstants.BundleExtensionSearchTupleDefinitionTag); | ||
119 | } | ||
110 | } | 120 | } |
111 | } | 121 | } |
diff --git a/src/wixext/Tuples/WixDetectSHA2SupportTuple.cs b/src/wixext/Tuples/WixDetectSHA2SupportTuple.cs new file mode 100644 index 00000000..38b76ff2 --- /dev/null +++ b/src/wixext/Tuples/WixDetectSHA2SupportTuple.cs | |||
@@ -0,0 +1,33 @@ | |||
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 WixToolset.Util | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | using WixToolset.Util.Tuples; | ||
7 | |||
8 | public static partial class UtilTupleDefinitions | ||
9 | { | ||
10 | public static readonly IntermediateTupleDefinition WixDetectSHA2Support = new IntermediateTupleDefinition( | ||
11 | UtilTupleDefinitionType.WixDetectSHA2Support.ToString(), | ||
12 | new IntermediateFieldDefinition[0], | ||
13 | typeof(WixDetectSHA2SupportTuple)); | ||
14 | } | ||
15 | } | ||
16 | |||
17 | namespace WixToolset.Util.Tuples | ||
18 | { | ||
19 | using WixToolset.Data; | ||
20 | |||
21 | public class WixDetectSHA2SupportTuple : IntermediateTuple | ||
22 | { | ||
23 | public WixDetectSHA2SupportTuple() : base(UtilTupleDefinitions.WixDetectSHA2Support, null, null) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | public WixDetectSHA2SupportTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(UtilTupleDefinitions.WixDetectSHA2Support, sourceLineNumber, id) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | public IntermediateField this[GroupTupleFields index] => this.Fields[(int)index]; | ||
32 | } | ||
33 | } | ||
diff --git a/src/wixext/UtilBinder.cs b/src/wixext/UtilBinder.cs deleted file mode 100644 index ef80a876..00000000 --- a/src/wixext/UtilBinder.cs +++ /dev/null | |||
@@ -1,347 +0,0 @@ | |||
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 WixToolset.Extensions | ||
4 | { | ||
5 | #if TODO_BRINGBACK_FOR_BUNDLES | ||
6 | using System; | ||
7 | using System.Collections.Generic; | ||
8 | using System.Globalization; | ||
9 | using WixToolset.Data; | ||
10 | using WixToolset.Extensibility; | ||
11 | |||
12 | /// <summary> | ||
13 | /// The binder for the WiX Toolset Utility Extension. | ||
14 | /// </summary> | ||
15 | public sealed class UtilBinder : BinderExtension | ||
16 | { | ||
17 | // TODO: When WixSearch is supported in Product, etc, we may need to call | ||
18 | // ReorderWixSearch() from each of those initializers. | ||
19 | |||
20 | // TODO: A general-purpose "reorder this table given these constraints" | ||
21 | // mechanism may end up being helpful. This could be declaratively stated | ||
22 | // in the table definitions, or exposed from the core Wix.dll and called | ||
23 | // as-needed by any extensions. | ||
24 | |||
25 | /// <summary> | ||
26 | /// Called before bundle binding occurs. | ||
27 | /// </summary> | ||
28 | public override void Initialize(Output bundle) | ||
29 | { | ||
30 | if (OutputType.Bundle == bundle.Type) | ||
31 | { | ||
32 | this.ReorderWixSearch(bundle); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | /// <summary> | ||
37 | /// Reorders Any WixSearch items. | ||
38 | /// </summary> | ||
39 | /// <param name="output">Output containing the tables to process.</param> | ||
40 | private void ReorderWixSearch(Output output) | ||
41 | { | ||
42 | Table wixSearchTable = output.Tables["WixSearch"]; | ||
43 | if (null == wixSearchTable || wixSearchTable.Rows.Count == 0) | ||
44 | { | ||
45 | // nothing to do! | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | RowDictionary rowDictionary = new RowDictionary(); | ||
50 | foreach (Row row in wixSearchTable.Rows) | ||
51 | { | ||
52 | rowDictionary.AddRow(row); | ||
53 | } | ||
54 | |||
55 | Constraints constraints = new Constraints(); | ||
56 | Table wixSearchRelationTable = output.Tables["WixSearchRelation"]; | ||
57 | if (null != wixSearchRelationTable && wixSearchRelationTable.Rows.Count > 0) | ||
58 | { | ||
59 | // add relational info to our data... | ||
60 | foreach (Row row in wixSearchRelationTable.Rows) | ||
61 | { | ||
62 | constraints.AddConstraint((string)row[0], (string)row[1]); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | this.FindCircularReference(constraints); | ||
67 | |||
68 | if (this.Core.EncounteredError) | ||
69 | { | ||
70 | return; | ||
71 | } | ||
72 | |||
73 | this.FlattenDependentReferences(constraints); | ||
74 | |||
75 | // Reorder by topographical sort (http://en.wikipedia.org/wiki/Topological_sorting) | ||
76 | // We use a variation of Kahn (1962) algorithm as described in | ||
77 | // Wikipedia, with the additional criteria that start nodes are sorted | ||
78 | // lexicographically at each step to ensure a deterministic ordering | ||
79 | // based on 'after' dependencies and ID. | ||
80 | TopologicalSort sorter = new TopologicalSort(); | ||
81 | List <string> sortedIds = sorter.Sort(rowDictionary.Keys, constraints); | ||
82 | |||
83 | // Now, re-write the table with the searches in order... | ||
84 | wixSearchTable.Rows.Clear(); | ||
85 | foreach (string id in sortedIds) | ||
86 | { | ||
87 | wixSearchTable.Rows.Add(rowDictionary[id]); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /// <summary> | ||
92 | /// A dictionary of Row items, indexed by their first column. | ||
93 | /// </summary> | ||
94 | private class RowDictionary : Dictionary<string, Row> | ||
95 | { | ||
96 | public void AddRow(Row row) | ||
97 | { | ||
98 | this.Add((string)row[0], row); | ||
99 | } | ||
100 | |||
101 | // TODO: Hide other Add methods? | ||
102 | } | ||
103 | |||
104 | /// <summary> | ||
105 | /// A dictionary of constraints, mapping an id to a list of ids. | ||
106 | /// </summary> | ||
107 | private class Constraints : Dictionary<string, List<string>> | ||
108 | { | ||
109 | public void AddConstraint(string id, string afterId) | ||
110 | { | ||
111 | if (!this.ContainsKey(id)) | ||
112 | { | ||
113 | this.Add(id, new List<string>()); | ||
114 | } | ||
115 | |||
116 | // TODO: Show warning if a constraint is seen twice? | ||
117 | if (!this[id].Contains(afterId)) | ||
118 | { | ||
119 | this[id].Add(afterId); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | // TODO: Hide other Add methods? | ||
124 | } | ||
125 | |||
126 | /// <summary> | ||
127 | /// Finds circular references in the constraints. | ||
128 | /// </summary> | ||
129 | /// <param name="constraints">Constraints to check.</param> | ||
130 | /// <remarks>This is not particularly performant, but it works.</remarks> | ||
131 | private void FindCircularReference(Constraints constraints) | ||
132 | { | ||
133 | foreach (string id in constraints.Keys) | ||
134 | { | ||
135 | List<string> seenIds = new List<string>(); | ||
136 | string chain = null; | ||
137 | if (FindCircularReference(constraints, id, id, seenIds, out chain)) | ||
138 | { | ||
139 | // We will show a separate message for every ID that's in | ||
140 | // the loop. We could bail after the first one, but then | ||
141 | // we wouldn't catch disjoint loops in a single run. | ||
142 | this.Core.OnMessage(UtilErrors.CircularSearchReference(chain)); | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | |||
147 | /// <summary> | ||
148 | /// Recursive function that finds circular references in the constraints. | ||
149 | /// </summary> | ||
150 | /// <param name="constraints">Constraints to check.</param> | ||
151 | /// <param name="checkId">The identifier currently being looking for. (Fixed across a given run.)</param> | ||
152 | /// <param name="currentId">The idenifier curently being tested.</param> | ||
153 | /// <param name="seenIds">A list of identifiers seen, to ensure each identifier is only expanded once.</param> | ||
154 | /// <param name="chain">If a circular reference is found, will contain the chain of references.</param> | ||
155 | /// <returns>True if a circular reference is found, false otherwise.</returns> | ||
156 | private bool FindCircularReference(Constraints constraints, string checkId, string currentId, List<string> seenIds, out string chain) | ||
157 | { | ||
158 | chain = null; | ||
159 | List<string> afterList = null; | ||
160 | if (constraints.TryGetValue(currentId, out afterList)) | ||
161 | { | ||
162 | foreach (string afterId in afterList) | ||
163 | { | ||
164 | if (afterId == checkId) | ||
165 | { | ||
166 | chain = String.Format(CultureInfo.InvariantCulture, "{0} -> {1}", currentId, afterId); | ||
167 | return true; | ||
168 | } | ||
169 | |||
170 | if (!seenIds.Contains(afterId)) | ||
171 | { | ||
172 | seenIds.Add(afterId); | ||
173 | if (FindCircularReference(constraints, checkId, afterId, seenIds, out chain)) | ||
174 | { | ||
175 | chain = String.Format(CultureInfo.InvariantCulture, "{0} -> {1}", currentId, chain); | ||
176 | return true; | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | return false; | ||
183 | } | ||
184 | |||
185 | /// <summary> | ||
186 | /// Flattens any dependency chains to simplify reordering. | ||
187 | /// </summary> | ||
188 | /// <param name="constraints"></param> | ||
189 | private void FlattenDependentReferences(Constraints constraints) | ||
190 | { | ||
191 | foreach (string id in constraints.Keys) | ||
192 | { | ||
193 | List<string> flattenedIds = new List<string>(); | ||
194 | AddDependentReferences(constraints, id, flattenedIds); | ||
195 | List<string> constraintList = constraints[id]; | ||
196 | foreach (string flattenedId in flattenedIds) | ||
197 | { | ||
198 | if (!constraintList.Contains(flattenedId)) | ||
199 | { | ||
200 | constraintList.Add(flattenedId); | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /// <summary> | ||
207 | /// Adds dependent references to a list. | ||
208 | /// </summary> | ||
209 | /// <param name="constraints"></param> | ||
210 | /// <param name="currentId"></param> | ||
211 | /// <param name="seenIds"></param> | ||
212 | private void AddDependentReferences(Constraints constraints, string currentId, List<string> seenIds) | ||
213 | { | ||
214 | List<string> afterList = null; | ||
215 | if (constraints.TryGetValue(currentId, out afterList)) | ||
216 | { | ||
217 | foreach (string afterId in afterList) | ||
218 | { | ||
219 | if (!seenIds.Contains(afterId)) | ||
220 | { | ||
221 | seenIds.Add(afterId); | ||
222 | AddDependentReferences(constraints, afterId, seenIds); | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | |||
228 | /// <summary> | ||
229 | /// Reorder by topological sort | ||
230 | /// </summary> | ||
231 | /// <remarks> | ||
232 | /// We use a variation of Kahn (1962) algorithm as described in | ||
233 | /// Wikipedia (http://en.wikipedia.org/wiki/Topological_sorting), with | ||
234 | /// the additional criteria that start nodes are sorted lexicographically | ||
235 | /// at each step to ensure a deterministic ordering based on 'after' | ||
236 | /// dependencies and ID. | ||
237 | /// </remarks> | ||
238 | private class TopologicalSort | ||
239 | { | ||
240 | private List<string> startIds = new List<string>(); | ||
241 | private Constraints constraints; | ||
242 | |||
243 | /// <summary> | ||
244 | /// Reorder by topological sort | ||
245 | /// </summary> | ||
246 | /// <param name="allIds">The complete list of IDs.</param> | ||
247 | /// <param name="constraints">Constraints to use.</param> | ||
248 | /// <returns>The topologically sorted list of IDs.</returns> | ||
249 | internal List<string> Sort(IEnumerable<string> allIds, Constraints constraints) | ||
250 | { | ||
251 | this.startIds.Clear(); | ||
252 | this.CopyConstraints(constraints); | ||
253 | |||
254 | this.FindInitialStartIds(allIds); | ||
255 | |||
256 | // We always create a new sortedId list, because we return it | ||
257 | // to the caller and don't know what its lifetime may be. | ||
258 | List<string> sortedIds = new List<string>(); | ||
259 | |||
260 | while (this.startIds.Count > 0) | ||
261 | { | ||
262 | this.SortStartIds(); | ||
263 | |||
264 | string currentId = this.startIds[0]; | ||
265 | sortedIds.Add(currentId); | ||
266 | this.startIds.RemoveAt(0); | ||
267 | |||
268 | this.ResolveConstraint(currentId); | ||
269 | } | ||
270 | |||
271 | return sortedIds; | ||
272 | } | ||
273 | |||
274 | /// <summary> | ||
275 | /// Copies a Constraints set (to prevent modifying the incoming data). | ||
276 | /// </summary> | ||
277 | /// <param name="constraints">Constraints to copy.</param> | ||
278 | private void CopyConstraints(Constraints constraints) | ||
279 | { | ||
280 | this.constraints = new Constraints(); | ||
281 | foreach (string id in constraints.Keys) | ||
282 | { | ||
283 | foreach (string afterId in constraints[id]) | ||
284 | { | ||
285 | this.constraints.AddConstraint(id, afterId); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | /// <summary> | ||
291 | /// Finds initial start IDs. (Those with no constraints.) | ||
292 | /// </summary> | ||
293 | /// <param name="allIds">The complete list of IDs.</param> | ||
294 | private void FindInitialStartIds(IEnumerable<string> allIds) | ||
295 | { | ||
296 | foreach (string id in allIds) | ||
297 | { | ||
298 | if (!this.constraints.ContainsKey(id)) | ||
299 | { | ||
300 | this.startIds.Add(id); | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | |||
305 | /// <summary> | ||
306 | /// Sorts start IDs. | ||
307 | /// </summary> | ||
308 | private void SortStartIds() | ||
309 | { | ||
310 | this.startIds.Sort(); | ||
311 | } | ||
312 | |||
313 | /// <summary> | ||
314 | /// Removes the resolved constraint and updates the list of startIds | ||
315 | /// with any now-valid (all constraints resolved) IDs. | ||
316 | /// </summary> | ||
317 | /// <param name="resolvedId">The ID to resolve from the set of constraints.</param> | ||
318 | private void ResolveConstraint(string resolvedId) | ||
319 | { | ||
320 | List<string> newStartIds = new List<string>(); | ||
321 | |||
322 | foreach (string id in constraints.Keys) | ||
323 | { | ||
324 | if (this.constraints[id].Contains(resolvedId)) | ||
325 | { | ||
326 | this.constraints[id].Remove(resolvedId); | ||
327 | |||
328 | // If we just removed the last constraint for this | ||
329 | // ID, it is now a valid start ID. | ||
330 | if (0 == this.constraints[id].Count) | ||
331 | { | ||
332 | newStartIds.Add(id); | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | |||
337 | foreach (string id in newStartIds) | ||
338 | { | ||
339 | this.constraints.Remove(id); | ||
340 | } | ||
341 | |||
342 | this.startIds.AddRange(newStartIds); | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | #endif | ||
347 | } | ||
diff --git a/src/wixext/UtilCompiler.cs b/src/wixext/UtilCompiler.cs index 6b359591..6e3c2531 100644 --- a/src/wixext/UtilCompiler.cs +++ b/src/wixext/UtilCompiler.cs | |||
@@ -230,6 +230,8 @@ namespace WixToolset.Util | |||
230 | break; | 230 | break; |
231 | case "ComponentSearch": | 231 | case "ComponentSearch": |
232 | case "ComponentSearchRef": | 232 | case "ComponentSearchRef": |
233 | case "DetectSHA2Support": | ||
234 | case "DetectSHA2SupportRef": | ||
233 | case "DirectorySearch": | 235 | case "DirectorySearch": |
234 | case "DirectorySearchRef": | 236 | case "DirectorySearchRef": |
235 | case "FileSearch": | 237 | case "FileSearch": |
@@ -251,6 +253,12 @@ namespace WixToolset.Util | |||
251 | case "ComponentSearchRef": | 253 | case "ComponentSearchRef": |
252 | this.ParseComponentSearchRefElement(intermediate, section, element); | 254 | this.ParseComponentSearchRefElement(intermediate, section, element); |
253 | break; | 255 | break; |
256 | case "DetectSHA2Support": | ||
257 | this.ParseDetectSHA2SupportElement(intermediate, section, element); | ||
258 | break; | ||
259 | case "DetectSHA2SupportRef": | ||
260 | this.ParseDetectSHA2SupportRefElement(intermediate, section, element); | ||
261 | break; | ||
254 | case "DirectorySearch": | 262 | case "DirectorySearch": |
255 | this.ParseDirectorySearchElement(intermediate, section, element); | 263 | this.ParseDirectorySearchElement(intermediate, section, element); |
256 | break; | 264 | break; |
@@ -422,11 +430,6 @@ namespace WixToolset.Util | |||
422 | } | 430 | } |
423 | } | 431 | } |
424 | 432 | ||
425 | if (null == variable) | ||
426 | { | ||
427 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Variable")); | ||
428 | } | ||
429 | |||
430 | if (null == guid) | 433 | if (null == guid) |
431 | { | 434 | { |
432 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Guid")); | 435 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Guid")); |
@@ -439,16 +442,10 @@ namespace WixToolset.Util | |||
439 | 442 | ||
440 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | 443 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); |
441 | 444 | ||
445 | this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null); | ||
446 | |||
442 | if (!this.Messaging.EncounteredError) | 447 | if (!this.Messaging.EncounteredError) |
443 | { | 448 | { |
444 | this.CreateWixSearchRow(section, sourceLineNumbers, id, variable, condition); | ||
445 | if (after != null) | ||
446 | { | ||
447 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixSearch", after); | ||
448 | // TODO: We're currently defaulting to "always run after", which we will need to change... | ||
449 | this.CreateWixSearchRelationRow(section, sourceLineNumbers, id, after, 2); | ||
450 | } | ||
451 | |||
452 | WixComponentSearchAttributes attributes = WixComponentSearchAttributes.KeyPath; | 449 | WixComponentSearchAttributes attributes = WixComponentSearchAttributes.KeyPath; |
453 | switch (result) | 450 | switch (result) |
454 | { | 451 | { |
@@ -506,6 +503,89 @@ namespace WixToolset.Util | |||
506 | } | 503 | } |
507 | 504 | ||
508 | /// <summary> | 505 | /// <summary> |
506 | /// Parses a DetectSHA2Support element. | ||
507 | /// </summary> | ||
508 | /// <param name="element">Element to parse.</param> | ||
509 | private void ParseDetectSHA2SupportElement(Intermediate intermediate, IntermediateSection section, XElement element) | ||
510 | { | ||
511 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); | ||
512 | Identifier id = null; | ||
513 | string variable = null; | ||
514 | string condition = null; | ||
515 | string after = null; | ||
516 | |||
517 | foreach (var attrib in element.Attributes()) | ||
518 | { | ||
519 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
520 | { | ||
521 | switch (attrib.Name.LocalName) | ||
522 | { | ||
523 | case "Id": | ||
524 | case "Variable": | ||
525 | case "Condition": | ||
526 | case "After": | ||
527 | this.ParseCommonSearchAttributes(sourceLineNumbers, attrib, ref id, ref variable, ref condition, ref after); | ||
528 | break; | ||
529 | default: | ||
530 | this.ParseHelper.UnexpectedAttribute(element, attrib); | ||
531 | break; | ||
532 | } | ||
533 | } | ||
534 | else | ||
535 | { | ||
536 | this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | if (id == null) | ||
541 | { | ||
542 | id = this.ParseHelper.CreateIdentifier("wds2s", variable, condition, after); | ||
543 | } | ||
544 | |||
545 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | ||
546 | |||
547 | this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, UtilConstants.UtilBundleExtensionId); | ||
548 | |||
549 | if (!this.Messaging.EncounteredError) | ||
550 | { | ||
551 | section.Tuples.Add(new WixDetectSHA2SupportTuple(sourceLineNumbers, id)); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | /// <summary> | ||
556 | /// Parses a DetectSHA2SupportRef element | ||
557 | /// </summary> | ||
558 | /// <param name="element">Element to parse.</param> | ||
559 | private void ParseDetectSHA2SupportRefElement(Intermediate intermediate, IntermediateSection section, XElement element) | ||
560 | { | ||
561 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); | ||
562 | string refId = null; | ||
563 | |||
564 | foreach (var attrib in element.Attributes()) | ||
565 | { | ||
566 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
567 | { | ||
568 | switch (attrib.Name.LocalName) | ||
569 | { | ||
570 | case "Id": | ||
571 | refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
572 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixDetectSHA2Support", refId); | ||
573 | break; | ||
574 | default: | ||
575 | this.ParseHelper.UnexpectedAttribute(element, attrib); | ||
576 | break; | ||
577 | } | ||
578 | } | ||
579 | else | ||
580 | { | ||
581 | this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | ||
586 | } | ||
587 | |||
588 | /// <summary> | ||
509 | /// Parses an event source element. | 589 | /// Parses an event source element. |
510 | /// </summary> | 590 | /// </summary> |
511 | /// <param name="element">Element to parse.</param> | 591 | /// <param name="element">Element to parse.</param> |
@@ -868,11 +948,6 @@ namespace WixToolset.Util | |||
868 | } | 948 | } |
869 | } | 949 | } |
870 | 950 | ||
871 | if (null == variable) | ||
872 | { | ||
873 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Variable")); | ||
874 | } | ||
875 | |||
876 | if (null == path) | 951 | if (null == path) |
877 | { | 952 | { |
878 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Path")); | 953 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Path")); |
@@ -885,16 +960,10 @@ namespace WixToolset.Util | |||
885 | 960 | ||
886 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | 961 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); |
887 | 962 | ||
963 | this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null); | ||
964 | |||
888 | if (!this.Messaging.EncounteredError) | 965 | if (!this.Messaging.EncounteredError) |
889 | { | 966 | { |
890 | this.CreateWixSearchRow(section, sourceLineNumbers, id, variable, condition); | ||
891 | if (after != null) | ||
892 | { | ||
893 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixSearch", after); | ||
894 | // TODO: We're currently defaulting to "always run after", which we will need to change... | ||
895 | this.CreateWixSearchRelationRow(section, sourceLineNumbers, id, after, 2); | ||
896 | } | ||
897 | |||
898 | WixFileSearchAttributes attributes = WixFileSearchAttributes.IsDirectory; | 967 | WixFileSearchAttributes attributes = WixFileSearchAttributes.IsDirectory; |
899 | switch (result) | 968 | switch (result) |
900 | { | 969 | { |
@@ -990,11 +1059,6 @@ namespace WixToolset.Util | |||
990 | } | 1059 | } |
991 | } | 1060 | } |
992 | 1061 | ||
993 | if (null == variable) | ||
994 | { | ||
995 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Variable")); | ||
996 | } | ||
997 | |||
998 | if (null == path) | 1062 | if (null == path) |
999 | { | 1063 | { |
1000 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Path")); | 1064 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Path")); |
@@ -1007,16 +1071,10 @@ namespace WixToolset.Util | |||
1007 | 1071 | ||
1008 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); | 1072 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); |
1009 | 1073 | ||
1074 | this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, node.Name.LocalName, id, variable, condition, after, null); | ||
1075 | |||
1010 | if (!this.Messaging.EncounteredError) | 1076 | if (!this.Messaging.EncounteredError) |
1011 | { | 1077 | { |
1012 | this.CreateWixSearchRow(section, sourceLineNumbers, id, variable, condition); | ||
1013 | if (after != null) | ||
1014 | { | ||
1015 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixSearch", after); | ||
1016 | // TODO: We're currently defaulting to "always run after", which we will need to change... | ||
1017 | this.CreateWixSearchRelationRow(section, sourceLineNumbers, id, after, 2); | ||
1018 | } | ||
1019 | |||
1020 | WixFileSearchAttributes attributes = WixFileSearchAttributes.Default; | 1078 | WixFileSearchAttributes attributes = WixFileSearchAttributes.Default; |
1021 | switch (result) | 1079 | switch (result) |
1022 | { | 1080 | { |
@@ -1049,38 +1107,6 @@ namespace WixToolset.Util | |||
1049 | } | 1107 | } |
1050 | 1108 | ||
1051 | /// <summary> | 1109 | /// <summary> |
1052 | /// Creates a row in the WixSearch table. | ||
1053 | /// </summary> | ||
1054 | /// <param name="sourceLineNumbers">Source line number for the parent element.</param> | ||
1055 | /// <param name="id">Identifier of the search.</param> | ||
1056 | /// <param name="variable">The Burn variable to store the result into.</param> | ||
1057 | /// <param name="condition">A condition to test before evaluating the search.</param> | ||
1058 | private void CreateWixSearchRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string variable, string condition) | ||
1059 | { | ||
1060 | section.Tuples.Add(new WixSearchTuple(sourceLineNumbers, id) | ||
1061 | { | ||
1062 | Variable = variable, | ||
1063 | Condition = condition, | ||
1064 | }); | ||
1065 | } | ||
1066 | |||
1067 | /// <summary> | ||
1068 | /// | ||
1069 | /// </summary> | ||
1070 | /// <param name="sourceLineNumbers">Source line number for the parent element.</param> | ||
1071 | /// <param name="id">Identifier of the search (key into the WixSearch table)</param> | ||
1072 | /// <param name="parentId">Identifier of the search that comes before (key into the WixSearch table)</param> | ||
1073 | /// <param name="attributes">Further details about the relation between id and parentId.</param> | ||
1074 | private void CreateWixSearchRelationRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, int attributes) | ||
1075 | { | ||
1076 | section.Tuples.Add(new WixSearchRelationTuple(sourceLineNumbers, id) | ||
1077 | { | ||
1078 | ParentSearchRef = parentId, | ||
1079 | Attributes = attributes, | ||
1080 | }); | ||
1081 | } | ||
1082 | |||
1083 | /// <summary> | ||
1084 | /// Parses a file share element. | 1110 | /// Parses a file share element. |
1085 | /// </summary> | 1111 | /// </summary> |
1086 | /// <param name="element">Element to parse.</param> | 1112 | /// <param name="element">Element to parse.</param> |
@@ -2523,11 +2549,6 @@ namespace WixToolset.Util | |||
2523 | } | 2549 | } |
2524 | } | 2550 | } |
2525 | 2551 | ||
2526 | if (null == variable) | ||
2527 | { | ||
2528 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Variable")); | ||
2529 | } | ||
2530 | |||
2531 | if (null == upgradeCode && null == productCode) | 2552 | if (null == upgradeCode && null == productCode) |
2532 | { | 2553 | { |
2533 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "ProductCode", "UpgradeCode", true)); | 2554 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "ProductCode", "UpgradeCode", true)); |
@@ -2545,16 +2566,10 @@ namespace WixToolset.Util | |||
2545 | 2566 | ||
2546 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | 2567 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); |
2547 | 2568 | ||
2569 | this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null); | ||
2570 | |||
2548 | if (!this.Messaging.EncounteredError) | 2571 | if (!this.Messaging.EncounteredError) |
2549 | { | 2572 | { |
2550 | this.CreateWixSearchRow(section, sourceLineNumbers, id, variable, condition); | ||
2551 | if (after != null) | ||
2552 | { | ||
2553 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixSearch", after); | ||
2554 | // TODO: We're currently defaulting to "always run after", which we will need to change... | ||
2555 | this.CreateWixSearchRelationRow(section, sourceLineNumbers, id, after, 2); | ||
2556 | } | ||
2557 | |||
2558 | WixProductSearchAttributes attributes = WixProductSearchAttributes.Version; | 2573 | WixProductSearchAttributes attributes = WixProductSearchAttributes.Version; |
2559 | switch (result) | 2574 | switch (result) |
2560 | { | 2575 | { |
@@ -2662,11 +2677,6 @@ namespace WixToolset.Util | |||
2662 | } | 2677 | } |
2663 | } | 2678 | } |
2664 | 2679 | ||
2665 | if (null == variable) | ||
2666 | { | ||
2667 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Variable")); | ||
2668 | } | ||
2669 | |||
2670 | if (!root.HasValue) | 2680 | if (!root.HasValue) |
2671 | { | 2681 | { |
2672 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Root")); | 2682 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Root")); |
@@ -2726,16 +2736,10 @@ namespace WixToolset.Util | |||
2726 | 2736 | ||
2727 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | 2737 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); |
2728 | 2738 | ||
2739 | this.ParseHelper.CreateWixSearchTuple(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null); | ||
2740 | |||
2729 | if (!this.Messaging.EncounteredError) | 2741 | if (!this.Messaging.EncounteredError) |
2730 | { | 2742 | { |
2731 | this.CreateWixSearchRow(section, sourceLineNumbers, id, variable, condition); | ||
2732 | if (after != null) | ||
2733 | { | ||
2734 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixSearch", after); | ||
2735 | // TODO: We're currently defaulting to "always run after", which we will need to change... | ||
2736 | this.CreateWixSearchRelationRow(section, sourceLineNumbers, id, after, 2); | ||
2737 | } | ||
2738 | |||
2739 | section.Tuples.Add(new WixRegistrySearchTuple(sourceLineNumbers, id) | 2743 | section.Tuples.Add(new WixRegistrySearchTuple(sourceLineNumbers, id) |
2740 | { | 2744 | { |
2741 | Root = (RegistryRootType)root, | 2745 | Root = (RegistryRootType)root, |
diff --git a/src/wixext/UtilConstants.cs b/src/wixext/UtilConstants.cs index 28ff368f..d9ad460f 100644 --- a/src/wixext/UtilConstants.cs +++ b/src/wixext/UtilConstants.cs | |||
@@ -13,5 +13,7 @@ namespace WixToolset.Util | |||
13 | internal static readonly string[] RegistryPermissions = { "Read", "Write", "CreateSubkeys", "EnumerateSubkeys", "Notify", "CreateLink" }; | 13 | internal static readonly string[] RegistryPermissions = { "Read", "Write", "CreateSubkeys", "EnumerateSubkeys", "Notify", "CreateLink" }; |
14 | internal static readonly string[] ServicePermissions = { "ServiceQueryConfig", "ServiceChangeConfig", "ServiceQueryStatus", "ServiceEnumerateDependents", "ServiceStart", "ServiceStop", "ServicePauseContinue", "ServiceInterrogate", "ServiceUserDefinedControl" }; | 14 | internal static readonly string[] ServicePermissions = { "ServiceQueryConfig", "ServiceChangeConfig", "ServiceQueryStatus", "ServiceEnumerateDependents", "ServiceStart", "ServiceStop", "ServicePauseContinue", "ServiceInterrogate", "ServiceUserDefinedControl" }; |
15 | internal static readonly string[] StandardPermissions = { "Delete", "ReadPermission", "ChangePermission", "TakeOwnership", "Synchronize" }; | 15 | internal static readonly string[] StandardPermissions = { "Delete", "ReadPermission", "ChangePermission", "TakeOwnership", "Synchronize" }; |
16 | |||
17 | internal const string UtilBundleExtensionId = "WixUtilBundleExtension"; | ||
16 | } | 18 | } |
17 | } | 19 | } |
diff --git a/src/wixext/UtilErrors.cs b/src/wixext/UtilErrors.cs index 988b8321..c04f0449 100644 --- a/src/wixext/UtilErrors.cs +++ b/src/wixext/UtilErrors.cs | |||
@@ -13,11 +13,6 @@ namespace WixToolset.Util | |||
13 | return Message(null, Ids.ArgumentRequiresValue, "The argument '{0}' does not have a value specified and it is required.", argument); | 13 | return Message(null, Ids.ArgumentRequiresValue, "The argument '{0}' does not have a value specified and it is required.", argument); |
14 | } | 14 | } |
15 | 15 | ||
16 | public static Message CircularSearchReference(string chain) | ||
17 | { | ||
18 | return Message(null, Ids.CircularSearchReference, "A circular reference of search ordering constraints was detected: {0}. Search ordering references must form a directed acyclic graph.", chain); | ||
19 | } | ||
20 | |||
21 | public static Message DirectoryNotFound(string directory) | 16 | public static Message DirectoryNotFound(string directory) |
22 | { | 17 | { |
23 | return Message(null, Ids.DirectoryNotFound, "The directory '{0}' could not be found.", directory); | 18 | return Message(null, Ids.DirectoryNotFound, "The directory '{0}' could not be found.", directory); |
@@ -102,7 +97,6 @@ namespace WixToolset.Util | |||
102 | FileNotFound = 5059, | 97 | FileNotFound = 5059, |
103 | PerformanceCategoryNotFound = 5060, | 98 | PerformanceCategoryNotFound = 5060, |
104 | UnsupportedPerformanceCounterType = 5061, | 99 | UnsupportedPerformanceCounterType = 5061, |
105 | CircularSearchReference = 5062, | ||
106 | InvalidRegistryObject = 5063, | 100 | InvalidRegistryObject = 5063, |
107 | } | 101 | } |
108 | } | 102 | } |
diff --git a/src/wixext/util.xsd b/src/wixext/util.xsd index fb8d8032..a8c3d208 100644 --- a/src/wixext/util.xsd +++ b/src/wixext/util.xsd | |||
@@ -172,6 +172,30 @@ | |||
172 | <xs:attribute name="Id" type="xs:string" use="required" /> | 172 | <xs:attribute name="Id" type="xs:string" use="required" /> |
173 | </xs:complexType> | 173 | </xs:complexType> |
174 | </xs:element> | 174 | </xs:element> |
175 | <xs:element name="DetectSHA2Support"> | ||
176 | <xs:annotation> | ||
177 | <xs:documentation>Detects support for SHA2.</xs:documentation> | ||
178 | <xs:appinfo> | ||
179 | <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Bundle" /> | ||
180 | <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" /> | ||
181 | </xs:appinfo> | ||
182 | </xs:annotation> | ||
183 | <xs:complexType> | ||
184 | <xs:attributeGroup ref="SearchCommonAttributes" /> | ||
185 | </xs:complexType> | ||
186 | </xs:element> | ||
187 | <xs:element name="DetectSHA2SupportRef"> | ||
188 | <xs:annotation> | ||
189 | <xs:documentation>References a DetectSHA2Support.</xs:documentation> | ||
190 | <xs:appinfo> | ||
191 | <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Bundle" /> | ||
192 | <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" /> | ||
193 | </xs:appinfo> | ||
194 | </xs:annotation> | ||
195 | <xs:complexType> | ||
196 | <xs:attribute name="Id" type="xs:string" use="required" /> | ||
197 | </xs:complexType> | ||
198 | </xs:element> | ||
175 | <xs:element name="DirectorySearch"> | 199 | <xs:element name="DirectorySearch"> |
176 | <xs:annotation> | 200 | <xs:annotation> |
177 | <xs:documentation>Describes a directory search.</xs:documentation> | 201 | <xs:documentation>Describes a directory search.</xs:documentation> |