From d77dca43e87e8711b19910a8fd49138f939bf0a4 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 4 May 2021 22:48:58 -0700 Subject: Move Msmq.wixext into ext --- .editorconfig | 37 - Msmq.wixext.sln | 61 -- README.md | 2 - appveyor.cmd | 14 - appveyor.yml | 40 - global.json | 5 - nuget.config | 17 - src/.editorconfig | 37 + src/CSharp.Build.props | 11 - src/Cpp.Build.props | 86 -- src/Directory.Build.props | 29 - src/Directory.Build.targets | 48 -- src/ca/custommsierrors.h | 4 - src/ca/dllmain.cpp | 26 - src/ca/mqcost.h | 9 - src/ca/mqexec.cpp | 192 ----- src/ca/mqqueueexec.cpp | 927 --------------------- src/ca/mqqueueexec.h | 30 - src/ca/mqqueuesched.cpp | 582 ------------- src/ca/mqqueuesched.h | 92 -- src/ca/mqsched.cpp | 196 ----- src/ca/mqutilexec.cpp | 380 --------- src/ca/mqutilexec.h | 23 - src/ca/mqutilsched.cpp | 43 - src/ca/mqutilsched.h | 9 - src/ca/msmqca.def | 12 - src/ca/msmqca.vcxproj | 71 -- src/ca/packages.config | 5 - src/ca/precomp.h | 23 - src/ext/Msmq/CSharp.Build.props | 11 + src/ext/Msmq/Cpp.Build.props | 86 ++ src/ext/Msmq/Directory.Build.props | 29 + src/ext/Msmq/Directory.Build.targets | 48 ++ src/ext/Msmq/Msmq.wixext.sln | 61 ++ src/ext/Msmq/README.md | 2 + src/ext/Msmq/appveyor.cmd | 14 + src/ext/Msmq/appveyor.yml | 40 + src/ext/Msmq/ca/custommsierrors.h | 4 + src/ext/Msmq/ca/dllmain.cpp | 26 + src/ext/Msmq/ca/mqcost.h | 9 + src/ext/Msmq/ca/mqexec.cpp | 192 +++++ src/ext/Msmq/ca/mqqueueexec.cpp | 927 +++++++++++++++++++++ src/ext/Msmq/ca/mqqueueexec.h | 30 + src/ext/Msmq/ca/mqqueuesched.cpp | 582 +++++++++++++ src/ext/Msmq/ca/mqqueuesched.h | 92 ++ src/ext/Msmq/ca/mqsched.cpp | 196 +++++ src/ext/Msmq/ca/mqutilexec.cpp | 380 +++++++++ src/ext/Msmq/ca/mqutilexec.h | 23 + src/ext/Msmq/ca/mqutilsched.cpp | 43 + src/ext/Msmq/ca/mqutilsched.h | 9 + src/ext/Msmq/ca/msmqca.def | 12 + src/ext/Msmq/ca/msmqca.vcxproj | 71 ++ src/ext/Msmq/ca/packages.config | 5 + src/ext/Msmq/ca/precomp.h | 23 + src/ext/Msmq/nuget.config | 17 + .../WixToolsetTest.Msmq/MsmqExtensionFixture.cs | 32 + .../TestData/UsingMessageQueue/Package.en-us.wxl | 11 + .../TestData/UsingMessageQueue/Package.wxs | 15 + .../UsingMessageQueue/PackageComponents.wxs | 12 + .../TestData/UsingMessageQueue/example.txt | 1 + .../WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj | 41 + src/ext/Msmq/wix.snk | Bin 0 -> 596 bytes src/ext/Msmq/wixext/MsmqCompiler.cs | 528 ++++++++++++ src/ext/Msmq/wixext/MsmqDecompiler.cs | 305 +++++++ src/ext/Msmq/wixext/MsmqErrors.cs | 71 ++ src/ext/Msmq/wixext/MsmqExtensionData.cs | 30 + src/ext/Msmq/wixext/MsmqExtensionFactory.cs | 18 + src/ext/Msmq/wixext/MsmqTableDefinitions.cs | 64 ++ src/ext/Msmq/wixext/MsmqWarnings.cs | 30 + .../wixext/MsmqWindowsInstallerBackendExtension.cs | 13 + .../Symbols/MessageQueueGroupPermissionSymbol.cs | 71 ++ src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs | 119 +++ .../Symbols/MessageQueueUserPermissionSymbol.cs | 71 ++ .../Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs | 47 ++ src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj | 30 + src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets | 11 + src/ext/Msmq/wixlib/MsmqExtension.wxs | 29 + src/ext/Msmq/wixlib/caerr.wxi | 96 +++ src/ext/Msmq/wixlib/en-us.wxl | 10 + src/ext/Msmq/wixlib/ja-jp.wxl | 10 + src/ext/Msmq/wixlib/msmq.wixproj | 18 + src/ext/global.json | 5 + .../WixToolsetTest.Msmq/MsmqExtensionFixture.cs | 32 - .../TestData/UsingMessageQueue/Package.en-us.wxl | 11 - .../TestData/UsingMessageQueue/Package.wxs | 15 - .../UsingMessageQueue/PackageComponents.wxs | 12 - .../TestData/UsingMessageQueue/example.txt | 1 - .../WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj | 41 - src/version.json | 11 + src/wix.snk | Bin 596 -> 0 bytes src/wixext/MsmqCompiler.cs | 528 ------------ src/wixext/MsmqDecompiler.cs | 305 ------- src/wixext/MsmqErrors.cs | 71 -- src/wixext/MsmqExtensionData.cs | 30 - src/wixext/MsmqExtensionFactory.cs | 18 - src/wixext/MsmqTableDefinitions.cs | 64 -- src/wixext/MsmqWarnings.cs | 30 - src/wixext/MsmqWindowsInstallerBackendExtension.cs | 13 - .../Symbols/MessageQueueGroupPermissionSymbol.cs | 71 -- src/wixext/Symbols/MessageQueueSymbol.cs | 119 --- .../Symbols/MessageQueueUserPermissionSymbol.cs | 71 -- src/wixext/Symbols/MsmqSymbolDefinitions.cs | 47 -- src/wixext/WixToolset.Msmq.wixext.csproj | 30 - src/wixext/WixToolset.Msmq.wixext.targets | 11 - src/wixlib/MsmqExtension.wxs | 29 - src/wixlib/caerr.wxi | 96 --- src/wixlib/en-us.wxl | 10 - src/wixlib/ja-jp.wxl | 10 - src/wixlib/msmq.wixproj | 18 - version.json | 11 - 110 files changed, 4668 insertions(+), 4668 deletions(-) delete mode 100644 .editorconfig delete mode 100644 Msmq.wixext.sln delete mode 100644 README.md delete mode 100644 appveyor.cmd delete mode 100644 appveyor.yml delete mode 100644 global.json delete mode 100644 nuget.config create mode 100644 src/.editorconfig delete mode 100644 src/CSharp.Build.props delete mode 100644 src/Cpp.Build.props delete mode 100644 src/Directory.Build.props delete mode 100644 src/Directory.Build.targets delete mode 100644 src/ca/custommsierrors.h delete mode 100644 src/ca/dllmain.cpp delete mode 100644 src/ca/mqcost.h delete mode 100644 src/ca/mqexec.cpp delete mode 100644 src/ca/mqqueueexec.cpp delete mode 100644 src/ca/mqqueueexec.h delete mode 100644 src/ca/mqqueuesched.cpp delete mode 100644 src/ca/mqqueuesched.h delete mode 100644 src/ca/mqsched.cpp delete mode 100644 src/ca/mqutilexec.cpp delete mode 100644 src/ca/mqutilexec.h delete mode 100644 src/ca/mqutilsched.cpp delete mode 100644 src/ca/mqutilsched.h delete mode 100644 src/ca/msmqca.def delete mode 100644 src/ca/msmqca.vcxproj delete mode 100644 src/ca/packages.config delete mode 100644 src/ca/precomp.h create mode 100644 src/ext/Msmq/CSharp.Build.props create mode 100644 src/ext/Msmq/Cpp.Build.props create mode 100644 src/ext/Msmq/Directory.Build.props create mode 100644 src/ext/Msmq/Directory.Build.targets create mode 100644 src/ext/Msmq/Msmq.wixext.sln create mode 100644 src/ext/Msmq/README.md create mode 100644 src/ext/Msmq/appveyor.cmd create mode 100644 src/ext/Msmq/appveyor.yml create mode 100644 src/ext/Msmq/ca/custommsierrors.h create mode 100644 src/ext/Msmq/ca/dllmain.cpp create mode 100644 src/ext/Msmq/ca/mqcost.h create mode 100644 src/ext/Msmq/ca/mqexec.cpp create mode 100644 src/ext/Msmq/ca/mqqueueexec.cpp create mode 100644 src/ext/Msmq/ca/mqqueueexec.h create mode 100644 src/ext/Msmq/ca/mqqueuesched.cpp create mode 100644 src/ext/Msmq/ca/mqqueuesched.h create mode 100644 src/ext/Msmq/ca/mqsched.cpp create mode 100644 src/ext/Msmq/ca/mqutilexec.cpp create mode 100644 src/ext/Msmq/ca/mqutilexec.h create mode 100644 src/ext/Msmq/ca/mqutilsched.cpp create mode 100644 src/ext/Msmq/ca/mqutilsched.h create mode 100644 src/ext/Msmq/ca/msmqca.def create mode 100644 src/ext/Msmq/ca/msmqca.vcxproj create mode 100644 src/ext/Msmq/ca/packages.config create mode 100644 src/ext/Msmq/ca/precomp.h create mode 100644 src/ext/Msmq/nuget.config create mode 100644 src/ext/Msmq/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs create mode 100644 src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl create mode 100644 src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs create mode 100644 src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs create mode 100644 src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt create mode 100644 src/ext/Msmq/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj create mode 100644 src/ext/Msmq/wix.snk create mode 100644 src/ext/Msmq/wixext/MsmqCompiler.cs create mode 100644 src/ext/Msmq/wixext/MsmqDecompiler.cs create mode 100644 src/ext/Msmq/wixext/MsmqErrors.cs create mode 100644 src/ext/Msmq/wixext/MsmqExtensionData.cs create mode 100644 src/ext/Msmq/wixext/MsmqExtensionFactory.cs create mode 100644 src/ext/Msmq/wixext/MsmqTableDefinitions.cs create mode 100644 src/ext/Msmq/wixext/MsmqWarnings.cs create mode 100644 src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs create mode 100644 src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs create mode 100644 src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs create mode 100644 src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs create mode 100644 src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs create mode 100644 src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj create mode 100644 src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets create mode 100644 src/ext/Msmq/wixlib/MsmqExtension.wxs create mode 100644 src/ext/Msmq/wixlib/caerr.wxi create mode 100644 src/ext/Msmq/wixlib/en-us.wxl create mode 100644 src/ext/Msmq/wixlib/ja-jp.wxl create mode 100644 src/ext/Msmq/wixlib/msmq.wixproj create mode 100644 src/ext/global.json delete mode 100644 src/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs delete mode 100644 src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl delete mode 100644 src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs delete mode 100644 src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs delete mode 100644 src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt delete mode 100644 src/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj create mode 100644 src/version.json delete mode 100644 src/wix.snk delete mode 100644 src/wixext/MsmqCompiler.cs delete mode 100644 src/wixext/MsmqDecompiler.cs delete mode 100644 src/wixext/MsmqErrors.cs delete mode 100644 src/wixext/MsmqExtensionData.cs delete mode 100644 src/wixext/MsmqExtensionFactory.cs delete mode 100644 src/wixext/MsmqTableDefinitions.cs delete mode 100644 src/wixext/MsmqWarnings.cs delete mode 100644 src/wixext/MsmqWindowsInstallerBackendExtension.cs delete mode 100644 src/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs delete mode 100644 src/wixext/Symbols/MessageQueueSymbol.cs delete mode 100644 src/wixext/Symbols/MessageQueueUserPermissionSymbol.cs delete mode 100644 src/wixext/Symbols/MsmqSymbolDefinitions.cs delete mode 100644 src/wixext/WixToolset.Msmq.wixext.csproj delete mode 100644 src/wixext/WixToolset.Msmq.wixext.targets delete mode 100644 src/wixlib/MsmqExtension.wxs delete mode 100644 src/wixlib/caerr.wxi delete mode 100644 src/wixlib/en-us.wxl delete mode 100644 src/wixlib/ja-jp.wxl delete mode 100644 src/wixlib/msmq.wixproj delete mode 100644 version.json diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 1d72e683..00000000 --- a/.editorconfig +++ /dev/null @@ -1,37 +0,0 @@ -# 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. -# -# Do NOT modify this file. Update the canonical version in Home\repo-template\src\.editorconfig -# then update all of the repos. - -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 4 -trim_trailing_whitespace = true - -[*.{cs,vb}] -dotnet_sort_system_directives_first = true - -[*.cs] -csharp_indent_case_contents = true : error -csharp_indent_switch_labels = true : error -csharp_new_line_before_open_brace = all -csharp_prefer_braces = true : error -csharp_style_expression_bodied_methods = when_on_single_line : suggestion -csharp_style_expression_bodied_constructors = when_on_single_line : suggestion -csharp_style_expression_bodied_operators = when_on_single_line : suggestion -csharp_style_expression_bodied_properties = when_on_single_line : suggestion -csharp_style_expression_bodied_indexers = when_on_single_line : suggestion -csharp_style_expression_bodied_accessors = when_on_single_line : suggestion -csharp_style_var_elsewhere = true : suggestion -csharp_style_var_for_built_in_types = true : suggestion -csharp_style_var_when_type_is_apparent = true : suggestion -dotnet_style_qualification_for_event = true : error -dotnet_style_qualification_for_field = true : error -dotnet_style_qualification_for_method = true : error -dotnet_style_qualification_for_property = true : error - -[*.targets] -indent_size = 2 diff --git a/Msmq.wixext.sln b/Msmq.wixext.sln deleted file mode 100644 index e3ebed6d..00000000 --- a/Msmq.wixext.sln +++ /dev/null @@ -1,61 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28010.2016 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msmqca", "src\ca\msmqca.vcxproj", "{CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}" -EndProject -Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "msmq", "src\wixlib\msmq.wixproj", "{42493058-5FC8-4F85-9884-FF3190E084B6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Msmq.wixext", "src\wixext\WixToolset.Msmq.wixext.csproj", "{B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Msmq", "src\test\WixToolsetTest.Msmq\WixToolsetTest.Msmq.csproj", "{B63DA068-338F-473B-9097-FC4E64830A2A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|Any CPU.Build.0 = Debug|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|x86.ActiveCfg = Debug|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|x86.Build.0 = Debug|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|Any CPU.ActiveCfg = Release|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|Any CPU.Build.0 = Release|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|x86.ActiveCfg = Release|Win32 - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|x86.Build.0 = Release|Win32 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|Any CPU.ActiveCfg = Debug|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|Any CPU.Build.0 = Debug|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|x86.ActiveCfg = Debug|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|x86.Build.0 = Debug|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|Any CPU.ActiveCfg = Release|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|Any CPU.Build.0 = Release|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|x86.ActiveCfg = Release|x86 - {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|x86.Build.0 = Release|x86 - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|x86.ActiveCfg = Debug|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|x86.Build.0 = Debug|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|Any CPU.Build.0 = Release|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|x86.ActiveCfg = Release|Any CPU - {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|x86.Build.0 = Release|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|x86.ActiveCfg = Debug|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|x86.Build.0 = Debug|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|Any CPU.Build.0 = Release|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|x86.ActiveCfg = Release|Any CPU - {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5524C948-C115-4690-9BC4-44E3E963F960} - EndGlobalSection -EndGlobal diff --git a/README.md b/README.md deleted file mode 100644 index fa3c277f..00000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Msmq.wixext -WixToolset.Msmq.wixext - MSMQ WiX Toolset Extension diff --git a/appveyor.cmd b/appveyor.cmd deleted file mode 100644 index f493b577..00000000 --- a/appveyor.cmd +++ /dev/null @@ -1,14 +0,0 @@ -@setlocal -@pushd %~dp0 - -nuget restore || exit /b - -msbuild -p:Configuration=Release -t:Restore || exit /b - -msbuild -p:Configuration=Release src\test\WixToolsetTest.Msmq\WixToolsetTest.Msmq.csproj || exit /b -dotnet test -c Release --no-build src\test\WixToolsetTest.Msmq || exit /b - -msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Msmq.wixext.csproj || exit /b - -@popd -@endlocal \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 7c686b04..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,40 +0,0 @@ -# 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. -# -# Do NOT modify this file. Update the canonical version in Home\repo-template\src\appveyor.yml -# then update all of the repos. - -branches: - only: - - master - - develop - -image: Visual Studio 2019 - -version: 0.0.0.{build} -configuration: Release - -environment: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - NUGET_XMLDOC_MODE: skip - -build_script: - - appveyor.cmd - -pull_requests: - do_not_increment_build_number: true - -nuget: - disable_publish_on_pr: true - -skip_branch_with_pr: true -skip_tags: true - -artifacts: -- path: build\Release\**\*.nupkg - name: nuget - -notifications: -- provider: Slack - incoming_webhook: - secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA= diff --git a/global.json b/global.json deleted file mode 100644 index 23dd3fa6..00000000 --- a/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "msbuild-sdks": { - "WixToolset.Sdk": "4.0.0-build-0211" - } -} diff --git a/nuget.config b/nuget.config deleted file mode 100644 index db7aba29..00000000 --- a/nuget.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 00000000..1d72e683 --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,37 @@ +# 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. +# +# Do NOT modify this file. Update the canonical version in Home\repo-template\src\.editorconfig +# then update all of the repos. + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.{cs,vb}] +dotnet_sort_system_directives_first = true + +[*.cs] +csharp_indent_case_contents = true : error +csharp_indent_switch_labels = true : error +csharp_new_line_before_open_brace = all +csharp_prefer_braces = true : error +csharp_style_expression_bodied_methods = when_on_single_line : suggestion +csharp_style_expression_bodied_constructors = when_on_single_line : suggestion +csharp_style_expression_bodied_operators = when_on_single_line : suggestion +csharp_style_expression_bodied_properties = when_on_single_line : suggestion +csharp_style_expression_bodied_indexers = when_on_single_line : suggestion +csharp_style_expression_bodied_accessors = when_on_single_line : suggestion +csharp_style_var_elsewhere = true : suggestion +csharp_style_var_for_built_in_types = true : suggestion +csharp_style_var_when_type_is_apparent = true : suggestion +dotnet_style_qualification_for_event = true : error +dotnet_style_qualification_for_field = true : error +dotnet_style_qualification_for_method = true : error +dotnet_style_qualification_for_property = true : error + +[*.targets] +indent_size = 2 diff --git a/src/CSharp.Build.props b/src/CSharp.Build.props deleted file mode 100644 index b12f4c6e..00000000 --- a/src/CSharp.Build.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - - true - $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk)) - - diff --git a/src/Cpp.Build.props b/src/Cpp.Build.props deleted file mode 100644 index 9b7a1bb5..00000000 --- a/src/Cpp.Build.props +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - Win32 - $(BaseIntermediateOutputPath)$(Configuration)\$(Platform)\ - $(OutputPath)$(Platform)\ - - - - $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) - - - - - $(DisableSpecificCompilerWarnings) - Level4 - $(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) - Use - precomp.h - StdCall - true - false - -YlprecompDefine - /Zc:threadSafeInit- %(AdditionalOptions) - true - - - $(ArmPreprocessorDefinitions);%(PreprocessorDefinitions) - $(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories) - - - $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories) - - - $(ProjectSubSystem) - $(ProjectModuleDefinitionFile) - $(ResourceOnlyDll) - true - $(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies) - $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories) - /IGNORE:4099 %(AdditionalOptions) - - - - - - NoExtensions - - - - - CDecl - - - - - OldStyle - true - true - - - - - Disabled - EnableFastChecks - _DEBUG;DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebug - - - - - MinSpace - NDEBUG;%(PreprocessorDefinitions) - true - true - MultiThreaded - - - true - true - - - diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index f83cc154..00000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - Debug - false - MSB3246 - - $(MSBuildProjectName) - $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\)) - $(BaseOutputPath)obj\$(ProjectName)\ - $(BaseOutputPath)$(Configuration)\ - - WiX Toolset Team - WiX Toolset - Copyright (c) .NET Foundation and contributors. All rights reserved. - MS-RL - WiX Toolset - - - - - - - diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets deleted file mode 100644 index dac7452a..00000000 --- a/src/Directory.Build.targets +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - true - $(SolutionPath) - $(NCrunchOriginalSolutionPath) - - - - - - - $([System.IO.File]::ReadAllText($(TheSolutionPath))) - $([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) )) - (?<="[PackageName]", ")(.*)(?=", ") - - - - - - %(Identity) - $(SolutionFileContent.Contains('\%(Identity).csproj')) - - - - - $(RegexPattern.Replace('[PackageName]','%(PackageName)') ) - $([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)')) - - - - - - - - - - - diff --git a/src/ca/custommsierrors.h b/src/ca/custommsierrors.h deleted file mode 100644 index 0c1b23b7..00000000 --- a/src/ca/custommsierrors.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// 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. - -#define msierrMsmqCannotConnect 28101 diff --git a/src/ca/dllmain.cpp b/src/ca/dllmain.cpp deleted file mode 100644 index 35ae6d1c..00000000 --- a/src/ca/dllmain.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -#include "precomp.h" - -/******************************************************************** -DllMain - standard entry point for all WiX custom actions - -********************************************************************/ -extern "C" BOOL WINAPI DllMain( - IN HINSTANCE hInst, - IN ULONG ulReason, - IN LPVOID) -{ - switch(ulReason) - { - case DLL_PROCESS_ATTACH: - WcaGlobalInitialize(hInst); - break; - - case DLL_PROCESS_DETACH: - WcaGlobalFinalize(); - break; - } - - return TRUE; -} diff --git a/src/ca/mqcost.h b/src/ca/mqcost.h deleted file mode 100644 index a40b7437..00000000 --- a/src/ca/mqcost.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -// 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. - - -#define COST_MESSAGE_QUEUE_CREATE 10000 -#define COST_MESSAGE_QUEUE_DELETE 10000 - -#define COST_MESSAGE_QUEUE_PERMISSION_ADD 10000 -#define COST_MESSAGE_QUEUE_PERMISSION_REMOVE 10000 diff --git a/src/ca/mqexec.cpp b/src/ca/mqexec.cpp deleted file mode 100644 index ff7e9b14..00000000 --- a/src/ca/mqexec.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// 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. - -#include "precomp.h" - - -/******************************************************************** - MessageQueuingExecuteInstall - CUSTOM ACTION ENTRY POINT - - Input: deferred CustomActionData - MessageQueuingExecuteInstall -********************************************************************/ -extern "C" UINT __stdcall MessageQueuingExecuteInstall(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - LPWSTR pwzCustomActionData = NULL; - LPWSTR pwzData = NULL; - - // initialize - hr = WcaInitialize(hInstall, "MessageQueuingExecuteInstall"); - ExitOnFailure(hr, "Failed to initialize MessageQueuingExecuteInstall"); - - hr = MqiExecInitialize(); - ExitOnFailure(hr, "Failed to initialize"); - - // get custom action data - hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); - ExitOnFailure(hr, "Failed to get CustomActionData"); - pwzData = pwzCustomActionData; - - // create message queues - hr = MqiCreateMessageQueues(&pwzData); - ExitOnFailure(hr, "Failed to create message queues"); - if (S_FALSE == hr) ExitFunction(); - - // add message queue permissions - hr = MqiAddMessageQueuePermissions(&pwzData); - ExitOnFailure(hr, "Failed to add message queue permissions"); - if (S_FALSE == hr) ExitFunction(); - - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzCustomActionData); - - // uninitialize - MqiExecUninitialize(); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - -/******************************************************************** - MessageQueuingRollbackInstall - CUSTOM ACTION ENTRY POINT - - Input: deferred CustomActionData - MessageQueuingRollbackInstall -********************************************************************/ -extern "C" UINT __stdcall MessageQueuingRollbackInstall(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - LPWSTR pwzCustomActionData = NULL; - LPWSTR pwzData = NULL; - - // initialize - hr = WcaInitialize(hInstall, "MessageQueuingRollbackInstall"); - ExitOnFailure(hr, "Failed to initialize MessageQueuingRollbackInstall"); - - hr = MqiExecInitialize(); - ExitOnFailure(hr, "Failed to initialize"); - - // get custom action data - hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); - ExitOnFailure(hr, "Failed to get CustomActionData"); - pwzData = pwzCustomActionData; - - // add message queue permissions - hr = MqiRollbackAddMessageQueuePermissions(&pwzData); - ExitOnFailure(hr, "Failed to rollback add message queue permissions"); - - // create message queues - hr = MqiRollbackCreateMessageQueues(&pwzData); - ExitOnFailure(hr, "Failed to rollback create message queues"); - - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzCustomActionData); - - // uninitialize - MqiExecUninitialize(); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - -/******************************************************************** - MessageQueuingExecuteUninstall - CUSTOM ACTION ENTRY POINT - - Input: deferred CustomActionData - MessageQueuingExecuteUninstall -********************************************************************/ -extern "C" UINT __stdcall MessageQueuingExecuteUninstall(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - LPWSTR pwzCustomActionData = NULL; - LPWSTR pwzData = NULL; - - // initialize - hr = WcaInitialize(hInstall, "MessageQueuingExecuteUninstall"); - ExitOnFailure(hr, "Failed to initialize MessageQueuingExecuteUninstall"); - - hr = MqiExecInitialize(); - ExitOnFailure(hr, "Failed to initialize"); - - // get custom action data - hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); - ExitOnFailure(hr, "Failed to get CustomActionData"); - pwzData = pwzCustomActionData; - - // remove message queue permissions - hr = MqiRemoveMessageQueuePermissions(&pwzData); - ExitOnFailure(hr, "Failed to remove message queue permissions"); - if (S_FALSE == hr) ExitFunction(); - - // delete message queues - hr = MqiDeleteMessageQueues(&pwzData); - ExitOnFailure(hr, "Failed to delete message queues"); - if (S_FALSE == hr) ExitFunction(); - - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzCustomActionData); - - // uninitialize - MqiExecUninitialize(); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - -/******************************************************************** - MessageQueuingRollbackUninstall - CUSTOM ACTION ENTRY POINT - - Input: deferred CustomActionData - MessageQueuingRollbackUninstall -********************************************************************/ -extern "C" UINT __stdcall MessageQueuingRollbackUninstall(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - LPWSTR pwzCustomActionData = NULL; - LPWSTR pwzData = NULL; - - // initialize - hr = WcaInitialize(hInstall, "MessageQueuingRollbackUninstall"); - ExitOnFailure(hr, "Failed to initialize MessageQueuingRollbackUninstall"); - - hr = MqiExecInitialize(); - ExitOnFailure(hr, "Failed to initialize"); - - // get custom action data - hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); - ExitOnFailure(hr, "Failed to get CustomActionData"); - pwzData = pwzCustomActionData; - - // delete message queues - hr = MqiRollbackDeleteMessageQueues(&pwzData); - ExitOnFailure(hr, "Failed to delete message queues"); - - // remove message queue permissions - hr = MqiRollbackRemoveMessageQueuePermissions(&pwzData); - ExitOnFailure(hr, "Failed to remove message queue permissions"); - - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzCustomActionData); - - // uninitialize - MqiExecUninitialize(); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} diff --git a/src/ca/mqqueueexec.cpp b/src/ca/mqqueueexec.cpp deleted file mode 100644 index e4304ab8..00000000 --- a/src/ca/mqqueueexec.cpp +++ /dev/null @@ -1,927 +0,0 @@ -// 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. - -#include "precomp.h" - - -// private typedefs - -typedef HRESULT (__stdcall *MQCreateQueueFunc)(PSECURITY_DESCRIPTOR, MQQUEUEPROPS*, LPWSTR, LPDWORD); -typedef HRESULT (__stdcall *MQDeleteQueueFunc)(LPCWSTR); -typedef HRESULT (__stdcall *MQPathNameToFormatNameFunc)(LPCWSTR, LPWSTR, LPDWORD); -typedef HRESULT (__stdcall *MQGetQueueSecurityFunc)(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD); -typedef HRESULT (__stdcall *MQSetQueueSecurityFunc)(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); - - -// private enums - -enum eMessageQueueAttributes -{ - mqaAuthenticate = (1 << 0), - mqaJournal = (1 << 1), - mqaTransactional = (1 << 2) -}; - -enum eMessageQueuePrivacyLevel -{ - mqplNone = 0, - mqplOptional = 1, - mqplBody = 2 -}; - -enum eMessageQueuePermission -{ - mqpDeleteMessage = (1 << 0), - mqpPeekMessage = (1 << 1), - mqpWriteMessage = (1 << 2), - mqpDeleteJournalMessage = (1 << 3), - mqpSetQueueProperties = (1 << 4), - mqpGetQueueProperties = (1 << 5), - mqpDeleteQueue = (1 << 6), - mqpGetQueuePermissions = (1 << 7), - mqpChangeQueuePermissions = (1 << 8), - mqpTakeQueueOwnership = (1 << 9), - mqpReceiveMessage = (1 << 10), - mqpReceiveJournalMessage = (1 << 11), - mqpQueueGenericRead = (1 << 12), - mqpQueueGenericWrite = (1 << 13), - mqpQueueGenericExecute = (1 << 14), - mqpQueueGenericAll = (1 << 15) -}; - - -// private structs - -struct MQI_MESSAGE_QUEUE_ATTRIBUTES -{ - LPWSTR pwzKey; - int iBasePriority; - int iJournalQuota; - LPWSTR pwzLabel; - LPWSTR pwzMulticastAddress; - LPWSTR pwzPathName; - int iPrivLevel; - int iQuota; - LPWSTR pwzServiceTypeGuid; - int iAttributes; -}; - -struct MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES -{ - LPWSTR pwzKey; - LPWSTR pwzPathName; - LPWSTR pwzDomain; - LPWSTR pwzName; - int iPermissions; -}; - - -// prototypes for private helper functions - -static HRESULT ReadMessageQueueAttributes( - LPWSTR* ppwzData, - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ); -static void FreeMessageQueueAttributes( - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ); -static HRESULT ReadMessageQueuePermissionAttributes( - LPWSTR* ppwzData, - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs - ); -static void FreeMessageQueuePermissionAttributes( - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs - ); -static HRESULT CreateMessageQueue( - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ); -static HRESULT DeleteMessageQueue( - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ); -static HRESULT SetMessageQueuePermissions( - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs, - BOOL fRevoke - ); -static void SetAccessPermissions( - int iPermissions, - LPDWORD pgrfAccessPermissions - ); - - -// private variables - -static HMODULE ghMQRT; -static MQCreateQueueFunc gpfnMQCreateQueue; -static MQDeleteQueueFunc gpfnMQDeleteQueue; -static MQPathNameToFormatNameFunc gpfnMQPathNameToFormatName; -static MQGetQueueSecurityFunc gpfnMQGetQueueSecurity; -static MQSetQueueSecurityFunc gpfnMQSetQueueSecurity; - - -// function definitions - -HRESULT MqiExecInitialize() -{ - HRESULT hr = S_OK; - - // load mqrt.dll - ghMQRT = ::LoadLibraryW(L"mqrt.dll"); - ExitOnNull(ghMQRT, hr, E_FAIL, "Failed to load mqrt.dll"); - - // get MQCreateQueue function address - gpfnMQCreateQueue = (MQCreateQueueFunc)::GetProcAddress(ghMQRT, "MQCreateQueue"); - ExitOnNull(gpfnMQCreateQueue, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQCreateQueue() function"); - - // get MQDeleteQueue function address - gpfnMQDeleteQueue = (MQDeleteQueueFunc)::GetProcAddress(ghMQRT, "MQDeleteQueue"); - ExitOnNull(gpfnMQDeleteQueue, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQDeleteQueue() function"); - - // get MQPathNameToFormatName function address - gpfnMQPathNameToFormatName = (MQPathNameToFormatNameFunc)::GetProcAddress(ghMQRT, "MQPathNameToFormatName"); - ExitOnNull(gpfnMQPathNameToFormatName, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQPathNameToFormatName() function"); - - // get MQGetQueueSecurity function address - gpfnMQGetQueueSecurity = (MQGetQueueSecurityFunc)::GetProcAddress(ghMQRT, "MQGetQueueSecurity"); - ExitOnNull(gpfnMQGetQueueSecurity, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQGetQueueSecurity() function"); - - // get MQSetQueueSecurity function address - gpfnMQSetQueueSecurity = (MQSetQueueSecurityFunc)::GetProcAddress(ghMQRT, "MQSetQueueSecurity"); - ExitOnNull(gpfnMQSetQueueSecurity, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQSetQueueSecurity() function"); - - hr = S_OK; - -LExit: - return hr; -} - -void MqiExecUninitialize() -{ - if (ghMQRT) - ::FreeLibrary(ghMQRT); -} - -HRESULT MqiCreateMessageQueues( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueueAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // progress message - hr = PcaActionDataMessage(1, attrs.pwzPathName); - ExitOnFailure(hr, "Failed to send progress messages, key: %S", attrs.pwzKey); - - // create message queue - hr = CreateMessageQueue(&attrs); - ExitOnFailure(hr, "Failed to create message queue, key: %S", attrs.pwzKey); - - // progress tics - hr = WcaProgressMessage(COST_MESSAGE_QUEUE_CREATE, FALSE); - ExitOnFailure(hr, "Failed to update progress"); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueueAttributes(&attrs); - - return hr; -} - -HRESULT MqiRollbackCreateMessageQueues( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueueAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // create message queue - hr = DeleteMessageQueue(&attrs); - if (FAILED(hr)) - WcaLog(LOGMSG_STANDARD, "Failed to delete message queue, hr: 0x%x, key: %S", hr, attrs.pwzKey); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueueAttributes(&attrs); - - return hr; -} - -HRESULT MqiDeleteMessageQueues( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueueAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // progress message - hr = PcaActionDataMessage(1, attrs.pwzPathName); - ExitOnFailure(hr, "Failed to send progress messages, key: %S", attrs.pwzKey); - - // create message queue - hr = DeleteMessageQueue(&attrs); - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "Failed to delete queue, hr: 0x%x, key: %S", hr, attrs.pwzKey); - continue; - } - - // progress tics - hr = WcaProgressMessage(COST_MESSAGE_QUEUE_DELETE, FALSE); - ExitOnFailure(hr, "Failed to update progress"); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueueAttributes(&attrs); - - return hr; -} - -HRESULT MqiRollbackDeleteMessageQueues( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueueAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // create message queue - hr = CreateMessageQueue(&attrs); - if (FAILED(hr)) - WcaLog(LOGMSG_STANDARD, "Failed to create message queue, hr: 0x%x, key: %S", hr, attrs.pwzKey); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueueAttributes(&attrs); - - return hr; -} - -HRESULT MqiAddMessageQueuePermissions( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // progress message - hr = PcaActionDataMessage(1, attrs.pwzPathName); - ExitOnFailure(hr, "Failed to send progress messages"); - - // add message queue permission - hr = SetMessageQueuePermissions(&attrs, FALSE); - ExitOnFailure(hr, "Failed to add message queue permission"); - - // progress tics - hr = WcaProgressMessage(COST_MESSAGE_QUEUE_PERMISSION_ADD, FALSE); - ExitOnFailure(hr, "Failed to update progress"); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueuePermissionAttributes(&attrs); - - return hr; -} - -HRESULT MqiRollbackAddMessageQueuePermissions( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // add message queue permission - hr = SetMessageQueuePermissions(&attrs, TRUE); - if (FAILED(hr)) - WcaLog(LOGMSG_STANDARD, "Failed to rollback add message queue permission, hr: 0x%x, key: %S", hr, attrs.pwzKey); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueuePermissionAttributes(&attrs); - - return hr; -} - -HRESULT MqiRemoveMessageQueuePermissions( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // progress message - hr = PcaActionDataMessage(1, attrs.pwzPathName); - ExitOnFailure(hr, "Failed to send progress messages"); - - // add message queue permission - hr = SetMessageQueuePermissions(&attrs, TRUE); - ExitOnFailure(hr, "Failed to remove message queue permission"); - - // progress tics - hr = WcaProgressMessage(COST_MESSAGE_QUEUE_PERMISSION_ADD, FALSE); - ExitOnFailure(hr, "Failed to update progress"); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueuePermissionAttributes(&attrs); - - return hr; -} - -HRESULT MqiRollbackRemoveMessageQueuePermissions( - LPWSTR* ppwzData - ) -{ - HRESULT hr = S_OK; - - int iCnt = 0; - - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; - ::ZeroMemory(&attrs, sizeof(attrs)); - - // ger count - hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); - ExitOnFailure(hr, "Failed to read count"); - - for (int i = 0; i < iCnt; i++) - { - // read attributes from CustomActionData - hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); - ExitOnFailure(hr, "Failed to read attributes"); - - // add message queue permission - hr = SetMessageQueuePermissions(&attrs, FALSE); - if (FAILED(hr)) - WcaLog(LOGMSG_STANDARD, "Failed to rollback remove message queue permission, hr: 0x%x, key: %S", hr, attrs.pwzKey); - } - - hr = S_OK; - -LExit: - // clean up - FreeMessageQueuePermissionAttributes(&attrs); - - return hr; -} - - -// helper function definitions - -static HRESULT ReadMessageQueueAttributes( - LPWSTR* ppwzData, - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ) -{ - HRESULT hr = S_OK; - - // read message queue information from custom action data - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey); - ExitOnFailure(hr, "Failed to read key from custom action data"); - hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iBasePriority); - ExitOnFailure(hr, "Failed to read base priority from custom action data"); - hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iJournalQuota); - ExitOnFailure(hr, "Failed to read journal quota from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzLabel); - ExitOnFailure(hr, "Failed to read label from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzMulticastAddress); - ExitOnFailure(hr, "Failed to read multicast address from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPathName); - ExitOnFailure(hr, "Failed to read path name from custom action data"); - hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iPrivLevel); - ExitOnFailure(hr, "Failed to read privacy level from custom action data"); - hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iQuota); - ExitOnFailure(hr, "Failed to read quota from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzServiceTypeGuid); - ExitOnFailure(hr, "Failed to read service type guid from custom action data"); - hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iAttributes); - ExitOnFailure(hr, "Failed to read attributes from custom action data"); - - hr = S_OK; - -LExit: - return hr; -} - -static void FreeMessageQueueAttributes( - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ) -{ - ReleaseStr(pAttrs->pwzKey); - ReleaseStr(pAttrs->pwzLabel); - ReleaseStr(pAttrs->pwzMulticastAddress); - ReleaseStr(pAttrs->pwzPathName); - ReleaseStr(pAttrs->pwzServiceTypeGuid); -} - -static HRESULT ReadMessageQueuePermissionAttributes( - LPWSTR* ppwzData, - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs - ) -{ - HRESULT hr = S_OK; - - // read message queue permission information from custom action data - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey); - ExitOnFailure(hr, "Failed to read key from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPathName); - ExitOnFailure(hr, "Failed to read path name from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzDomain); - ExitOnFailure(hr, "Failed to read domain from custom action data"); - hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName); - ExitOnFailure(hr, "Failed to read name from custom action data"); - hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iPermissions); - ExitOnFailure(hr, "Failed to read permissions from custom action data"); - - hr = S_OK; - -LExit: - return hr; -} - -static void FreeMessageQueuePermissionAttributes( - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs - ) -{ - ReleaseStr(pAttrs->pwzKey); - ReleaseStr(pAttrs->pwzPathName); - ReleaseStr(pAttrs->pwzDomain); - ReleaseStr(pAttrs->pwzName); -} - -static HRESULT CreateMessageQueue( - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ) -{ - HRESULT hr = S_OK; - - SECURITY_DESCRIPTOR sd; - PSID pOwner = NULL; - DWORD cbDacl = 0; - PACL pDacl = NULL; - QUEUEPROPID aPropID[11]; - MQPROPVARIANT aPropVar[11]; - MQQUEUEPROPS props; - - GUID guidType; - - DWORD dwFormatNameLength = 0; - - ::ZeroMemory(&sd, sizeof(sd)); - ::ZeroMemory(aPropID, sizeof(aPropID)); - ::ZeroMemory(aPropVar, sizeof(aPropVar)); - ::ZeroMemory(&props, sizeof(props)); - ::ZeroMemory(&guidType, sizeof(guidType)); - - // initialize security descriptor - if (!::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize security descriptor"); - - // set security descriptor owner - hr = PcaAccountNameToSid(L"\\Administrators", &pOwner); - ExitOnFailure(hr, "Failed to get sid for account name"); - - if (!::SetSecurityDescriptorOwner(&sd, pOwner, FALSE)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set security descriptor owner"); - - // set security descriptor DACL - cbDacl = sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + ::GetLengthSid(pOwner); - pDacl = (PACL)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, cbDacl); - ExitOnNull(pDacl, hr, E_OUTOFMEMORY, "Failed to allocate buffer for DACL"); - - if (!::InitializeAcl(pDacl, cbDacl, ACL_REVISION)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize DACL"); - - if (!::AddAccessAllowedAce(pDacl, ACL_REVISION, MQSEC_QUEUE_GENERIC_ALL, pOwner)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to add ACE to DACL"); - - if (!::SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set security descriptor DACL"); - - // set property values - props.aPropID = aPropID; - props.aPropVar = aPropVar; - - aPropID[0] = PROPID_Q_LABEL; - aPropVar[0].vt = VT_LPWSTR; - aPropVar[0].pwszVal = pAttrs->pwzLabel; - - aPropID[1] = PROPID_Q_PATHNAME; - aPropVar[1].vt = VT_LPWSTR; - aPropVar[1].pwszVal = pAttrs->pwzPathName; - - aPropID[2] = PROPID_Q_AUTHENTICATE; - aPropVar[2].vt = VT_UI1; - aPropVar[2].bVal = mqaAuthenticate == (pAttrs->iAttributes & mqaAuthenticate); - - aPropID[3] = PROPID_Q_JOURNAL; - aPropVar[3].vt = VT_UI1; - aPropVar[3].bVal = mqaJournal == (pAttrs->iAttributes & mqaJournal); - - aPropID[4] = PROPID_Q_TRANSACTION; - aPropVar[4].vt = VT_UI1; - aPropVar[4].bVal = mqaTransactional == (pAttrs->iAttributes & mqaTransactional); - - props.cProp = 5; - - if (MSI_NULL_INTEGER != pAttrs->iBasePriority) - { - aPropID[props.cProp] = PROPID_Q_BASEPRIORITY; - aPropVar[props.cProp].vt = VT_I2; - aPropVar[props.cProp].iVal = (SHORT)pAttrs->iBasePriority; - props.cProp++; - } - - if (MSI_NULL_INTEGER != pAttrs->iJournalQuota) - { - aPropID[props.cProp] = PROPID_Q_JOURNAL_QUOTA; - aPropVar[props.cProp].vt = VT_UI4; - aPropVar[props.cProp].ulVal = (ULONG)pAttrs->iJournalQuota; - props.cProp++; - } - - if (*pAttrs->pwzMulticastAddress) - { - aPropID[props.cProp] = PROPID_Q_MULTICAST_ADDRESS; - aPropVar[props.cProp].vt = VT_LPWSTR; - aPropVar[props.cProp].pwszVal = pAttrs->pwzMulticastAddress; - props.cProp++; - } - - if (MSI_NULL_INTEGER != pAttrs->iPrivLevel) - { - aPropID[props.cProp] = PROPID_Q_PRIV_LEVEL; - aPropVar[props.cProp].vt = VT_UI4; - switch (pAttrs->iPrivLevel) - { - case mqplNone: - aPropVar[props.cProp].ulVal = MQ_PRIV_LEVEL_NONE; - break; - case mqplBody: - aPropVar[props.cProp].ulVal = MQ_PRIV_LEVEL_BODY; - break; - case mqplOptional: - aPropVar[props.cProp].ulVal = MQ_PRIV_LEVEL_OPTIONAL; - break; - } - props.cProp++; - } - - if (MSI_NULL_INTEGER != pAttrs->iQuota) - { - aPropID[props.cProp] = PROPID_Q_QUOTA; - aPropVar[props.cProp].vt = VT_UI4; - aPropVar[props.cProp].ulVal = (ULONG)pAttrs->iQuota; - props.cProp++; - } - - if (*pAttrs->pwzServiceTypeGuid) - { - // parse guid string - hr = PcaGuidFromString(pAttrs->pwzServiceTypeGuid, &guidType); - ExitOnFailure(hr, "Failed to parse service type GUID string"); - - aPropID[props.cProp] = PROPID_Q_TYPE; - aPropVar[props.cProp].vt = VT_CLSID; - aPropVar[props.cProp].puuid = &guidType; - props.cProp++; - } - - // create message queue - hr = gpfnMQCreateQueue(&sd, &props, NULL, &dwFormatNameLength); - ExitOnFailure(hr, "Failed to create message queue"); - - // log - WcaLog(LOGMSG_VERBOSE, "Message queue created, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); - - hr = S_OK; - -LExit: - // clean up - if (pOwner) - ::HeapFree(::GetProcessHeap(), 0, pOwner); - if (pDacl) - ::HeapFree(::GetProcessHeap(), 0, pDacl); - - return hr; -} - -static HRESULT DeleteMessageQueue( - MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs - ) -{ - HRESULT hr = S_OK; - - LPWSTR pwzFormatName = NULL; - DWORD dwCount = 128; - - // get format name - hr = StrAlloc(&pwzFormatName, dwCount); - ExitOnFailure(hr, "Failed to allocate format name string"); - do { - hr = gpfnMQPathNameToFormatName(pAttrs->pwzPathName, pwzFormatName, &dwCount); - switch (hr) - { - case MQ_ERROR_QUEUE_NOT_FOUND: - ExitFunction1(hr = S_OK); // nothing to delete - case MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL: - hr = StrAlloc(&pwzFormatName, dwCount); - ExitOnFailure(hr, "Failed to reallocate format name string"); - hr = S_FALSE; // retry - break; - default: - ExitOnFailure(hr, "Failed to get format name"); - hr = S_OK; - } - } while (S_FALSE == hr); - - // delete queue - hr = gpfnMQDeleteQueue(pwzFormatName); - ExitOnFailure(hr, "Failed to delete queue"); - - // log - WcaLog(LOGMSG_VERBOSE, "Message queue deleted, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); - - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzFormatName); - - return hr; -} - -static HRESULT SetMessageQueuePermissions( - MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs, - BOOL fRevoke - ) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - DWORD dw = 0; - - LPWSTR pwzAccount = NULL; - LPWSTR pwzFormatName = NULL; - - PSECURITY_DESCRIPTOR psd = NULL; - PSECURITY_DESCRIPTOR ptsd = NULL; - - PACL pAclExisting = NULL; - PACL pAclNew = NULL; - BOOL fDaclPresent = FALSE; - BOOL fDaclDefaulted = FALSE; - - PSID psid = NULL; - - EXPLICIT_ACCESSW ea; - SECURITY_DESCRIPTOR sdNew; - - ::ZeroMemory(&ea, sizeof(ea)); - ::ZeroMemory(&sdNew, sizeof(sdNew)); - - // get format name - dw = 128; - hr = StrAlloc(&pwzFormatName, dw); - ExitOnFailure(hr, "Failed to allocate format name string"); - do { - hr = gpfnMQPathNameToFormatName(pAttrs->pwzPathName, pwzFormatName, &dw); - if (MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL == hr) - { - hr = StrAlloc(&pwzFormatName, dw); - ExitOnFailure(hr, "Failed to reallocate format name string"); - hr = S_FALSE; // retry - } - else - { - ExitOnFailure(hr, "Failed to get format name"); - hr = S_OK; - } - } while (S_FALSE == hr); - - // get queue security information - dw = 256; - psd = (PSECURITY_DESCRIPTOR)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dw); - ExitOnNull(psd, hr, E_OUTOFMEMORY, "Failed to allocate buffer for security descriptor"); - do { - hr = gpfnMQGetQueueSecurity(pwzFormatName, DACL_SECURITY_INFORMATION, psd, dw, &dw); - if (MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL == hr) - { - ptsd = (PSECURITY_DESCRIPTOR)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, psd, dw); - ExitOnNull(ptsd, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for security descriptor"); - psd = ptsd; - hr = S_FALSE; // retry - } - else - { - ExitOnFailure(hr, "Failed to get queue security information"); - hr = S_OK; - } - } while (S_FALSE == hr); - - // get dacl - if (!::GetSecurityDescriptorDacl(psd, &fDaclPresent, &pAclExisting, &fDaclDefaulted)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get DACL for security descriptor"); - if (!fDaclPresent || !pAclExisting) - ExitOnFailure(hr = E_ACCESSDENIED, "Failed to get DACL for security descriptor, access denied"); - - // build account name string - hr = PcaBuildAccountName(pAttrs->pwzDomain, pAttrs->pwzName, &pwzAccount); - ExitOnFailure(hr, "Failed to build account name string"); - - // get sid for account name - hr = PcaAccountNameToSid(pwzAccount, &psid); - ExitOnFailure(hr, "Failed to get SID for account name"); - - // set acl entry - SetAccessPermissions(pAttrs->iPermissions, &ea.grfAccessPermissions); - ea.grfAccessMode = fRevoke ? REVOKE_ACCESS : SET_ACCESS; - ea.grfInheritance = NO_INHERITANCE; - ::BuildTrusteeWithSidW(&ea.Trustee, psid); - - er = ::SetEntriesInAclW(1, &ea, pAclExisting, &pAclNew); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set ACL entry"); - - // create new security descriptor - if (!::InitializeSecurityDescriptor(&sdNew, SECURITY_DESCRIPTOR_REVISION)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize security descriptor"); - - if (!::SetSecurityDescriptorDacl(&sdNew, TRUE, pAclNew, FALSE)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set DACL for security descriptor"); - - // set queue security information - hr = gpfnMQSetQueueSecurity(pwzFormatName, DACL_SECURITY_INFORMATION, &sdNew); - ExitOnFailure(hr, "Failed to set queue security information"); - - // log - WcaLog(LOGMSG_VERBOSE, "Permission set for message queue, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); - - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzFormatName); - ReleaseStr(pwzAccount); - - if (psd) - ::HeapFree(::GetProcessHeap(), 0, psd); - if (psid) - ::HeapFree(::GetProcessHeap(), 0, psid); - if (pAclNew) - ::LocalFree(pAclNew); - - return hr; -} - -static void SetAccessPermissions( - int iPermissions, - LPDWORD pgrfAccessPermissions - ) -{ - if (iPermissions & mqpDeleteMessage) - *pgrfAccessPermissions |= MQSEC_DELETE_MESSAGE; - if (iPermissions & mqpPeekMessage) - *pgrfAccessPermissions |= MQSEC_PEEK_MESSAGE; - if (iPermissions & mqpWriteMessage) - *pgrfAccessPermissions |= MQSEC_WRITE_MESSAGE; - if (iPermissions & mqpDeleteJournalMessage) - *pgrfAccessPermissions |= MQSEC_DELETE_JOURNAL_MESSAGE; - if (iPermissions & mqpSetQueueProperties) - *pgrfAccessPermissions |= MQSEC_SET_QUEUE_PROPERTIES; - if (iPermissions & mqpGetQueueProperties) - *pgrfAccessPermissions |= MQSEC_GET_QUEUE_PROPERTIES; - if (iPermissions & mqpDeleteQueue) - *pgrfAccessPermissions |= MQSEC_DELETE_QUEUE; - if (iPermissions & mqpGetQueuePermissions) - *pgrfAccessPermissions |= MQSEC_GET_QUEUE_PERMISSIONS; - if (iPermissions & mqpChangeQueuePermissions) - *pgrfAccessPermissions |= MQSEC_CHANGE_QUEUE_PERMISSIONS; - if (iPermissions & mqpTakeQueueOwnership) - *pgrfAccessPermissions |= MQSEC_TAKE_QUEUE_OWNERSHIP; - if (iPermissions & mqpReceiveMessage) - *pgrfAccessPermissions |= MQSEC_RECEIVE_MESSAGE; - if (iPermissions & mqpReceiveJournalMessage) - *pgrfAccessPermissions |= MQSEC_RECEIVE_JOURNAL_MESSAGE; - if (iPermissions & mqpQueueGenericRead) - *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_READ; - if (iPermissions & mqpQueueGenericWrite) - *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_WRITE; - if (iPermissions & mqpQueueGenericExecute) - *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_EXECUTE; - if (iPermissions & mqpQueueGenericAll) - *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_ALL; -} diff --git a/src/ca/mqqueueexec.h b/src/ca/mqqueueexec.h deleted file mode 100644 index 76bc2023..00000000 --- a/src/ca/mqqueueexec.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -// 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. - - -HRESULT MqiExecInitialize(); -void MqiExecUninitialize(); -HRESULT MqiCreateMessageQueues( - LPWSTR* ppwzData - ); -HRESULT MqiRollbackCreateMessageQueues( - LPWSTR* ppwzData - ); -HRESULT MqiDeleteMessageQueues( - LPWSTR* ppwzData - ); -HRESULT MqiRollbackDeleteMessageQueues( - LPWSTR* ppwzData - ); -HRESULT MqiAddMessageQueuePermissions( - LPWSTR* ppwzData - ); -HRESULT MqiRollbackAddMessageQueuePermissions( - LPWSTR* ppwzData - ); -HRESULT MqiRemoveMessageQueuePermissions( - LPWSTR* ppwzData - ); -HRESULT MqiRollbackRemoveMessageQueuePermissions( - LPWSTR* ppwzData - ); diff --git a/src/ca/mqqueuesched.cpp b/src/ca/mqqueuesched.cpp deleted file mode 100644 index 01777ea4..00000000 --- a/src/ca/mqqueuesched.cpp +++ /dev/null @@ -1,582 +0,0 @@ -// 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. - -#include "precomp.h" - - -// sql queries - -LPCWSTR vcsMessageQueueQuery = - L"SELECT `MessageQueue`, `Component_`, `BasePriority`, `JournalQuota`, `Label`, `MulticastAddress`, `PathName`, `PrivLevel`, `Quota`, `ServiceTypeGuid`, `Attributes` FROM `MessageQueue`"; -enum eMessageQueueQuery { mqqMessageQueue = 1, mqqComponent, mqqBasePriority, mqqJournalQuota, mqqLabel, mqqMulticastAddress, mqqPathName, mqqPrivLevel, mqqQuota, mqqServiceTypeGuid, mqqAttributes }; - -LPCWSTR vcsMessageQueueUserPermissionQuery = - L"SELECT `MessageQueueUserPermission`, `MessageQueue_`, `MessageQueueUserPermission`.`Component_`, `Domain`, `Name`, `Permissions` FROM `MessageQueueUserPermission`, `User` WHERE `User_` = `User`"; -LPCWSTR vcsMessageQueueGroupPermissionQuery = - L"SELECT `MessageQueueGroupPermission`, `MessageQueue_`, `MessageQueueGroupPermission`.`Component_`, `Domain`, `Name`, `Permissions` FROM `MessageQueueGroupPermission`, `Group` WHERE `Group_` = `Group`"; -enum eMessageQueuePermissionQuery { mqpqMessageQueuePermission = 1, mqpqMessageQueue, mqpqComponent, mqpqDomain, mqpqName, mqpqPermissions }; - - -// prototypes for private helper functions - -static HRESULT MqiMessageQueueFindByKey( - MQI_MESSAGE_QUEUE_LIST* pList, - LPCWSTR pwzKey, - MQI_MESSAGE_QUEUE** ppItm - ); -static HRESULT AddMessageQueueToActionData( - MQI_MESSAGE_QUEUE* pItm, - LPWSTR* ppwzActionData - ); -static HRESULT MessageQueueTrusteePermissionsRead( - LPCWSTR pwzQuery, - MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList - ); -static HRESULT AddMessageQueuePermissionToActionData( - MQI_MESSAGE_QUEUE_PERMISSION* pItm, - LPWSTR* ppwzActionData - ); - - -// private typedefs - -typedef HRESULT (__stdcall *MQPathNameToFormatNameFunc)(LPCWSTR, LPWSTR, LPDWORD); - - -// private variables - -static HMODULE ghMQRT; -static MQPathNameToFormatNameFunc gpfnMQPathNameToFormatName; - - -// function definitions - -HRESULT MqiSchedInitialize() -{ - HRESULT hr = S_OK; - - // load mqrt.dll - ghMQRT = ::LoadLibraryW(L"mqrt.dll"); - if (!ghMQRT) - { - ExitFunction1(hr = S_FALSE); - } - - // get MQPathNameToFormatName function address - gpfnMQPathNameToFormatName = (MQPathNameToFormatNameFunc)::GetProcAddress(ghMQRT, "MQPathNameToFormatName"); - ExitOnNullWithLastError(gpfnMQPathNameToFormatName, hr, "Failed get address for MQPathNameToFormatName() function"); - - hr = S_OK; - -LExit: - return hr; -} - -void MqiSchedUninitialize() -{ - if (ghMQRT) - { - ::FreeLibrary(ghMQRT); - } -} - -HRESULT MqiMessageQueueRead( - MQI_MESSAGE_QUEUE_LIST* pList - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - PMSIHANDLE hView, hRec; - - MQI_MESSAGE_QUEUE* pItm = NULL; - LPWSTR pwzData = NULL; - - // loop through all partitions - hr = WcaOpenExecuteView(vcsMessageQueueQuery, &hView); - ExitOnFailure(hr, "Failed to execute view on MessageQueue table"); - - while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) - { - // create entry - pItm = (MQI_MESSAGE_QUEUE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MQI_MESSAGE_QUEUE)); - if (!pItm) - ExitFunction1(hr = E_OUTOFMEMORY); - - // get key - hr = WcaGetRecordString(hRec, mqqMessageQueue, &pwzData); - ExitOnFailure(hr, "Failed to get key"); - StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); - - // get component install state - hr = WcaGetRecordString(hRec, mqqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get component"); - - // get component install state - er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); - - // get base priority - hr = WcaGetRecordInteger(hRec, mqqBasePriority, &pItm->iBasePriority); - ExitOnFailure(hr, "Failed to get base priority"); - - // get journal quota - hr = WcaGetRecordInteger(hRec, mqqJournalQuota, &pItm->iJournalQuota); - ExitOnFailure(hr, "Failed to get journal quota"); - - // get label - hr = WcaGetRecordFormattedString(hRec, mqqLabel, &pwzData); - ExitOnFailure(hr, "Failed to get label"); - StringCchCopyW(pItm->wzLabel, countof(pItm->wzLabel), pwzData); - - // get multicast address - hr = WcaGetRecordFormattedString(hRec, mqqMulticastAddress, &pwzData); - ExitOnFailure(hr, "Failed to get multicast address"); - StringCchCopyW(pItm->wzMulticastAddress, countof(pItm->wzMulticastAddress), pwzData); - - // get path name - hr = WcaGetRecordFormattedString(hRec, mqqPathName, &pwzData); - ExitOnFailure(hr, "Failed to get path name"); - StringCchCopyW(pItm->wzPathName, countof(pItm->wzPathName), pwzData); - - // get privacy level - hr = WcaGetRecordInteger(hRec, mqqPrivLevel, &pItm->iPrivLevel); - ExitOnFailure(hr, "Failed to get privacy level"); - - // get quota - hr = WcaGetRecordInteger(hRec, mqqQuota, &pItm->iQuota); - ExitOnFailure(hr, "Failed to get quota"); - - // get service type guid - hr = WcaGetRecordFormattedString(hRec, mqqServiceTypeGuid, &pwzData); - ExitOnFailure(hr, "Failed to get service type guid"); - StringCchCopyW(pItm->wzServiceTypeGuid, countof(pItm->wzServiceTypeGuid), pwzData); - - // get attributes - hr = WcaGetRecordInteger(hRec, mqqAttributes, &pItm->iAttributes); - ExitOnFailure(hr, "Failed to get attributes"); - - // increment counters - if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) - pList->iInstallCount++; - if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) - pList->iUninstallCount++; - - // add entry - pItm->pNext = pList->pFirst; - pList->pFirst = pItm; - pItm = NULL; - } - - if (E_NOMOREITEMS == hr) - hr = S_OK; - -LExit: - // clean up - if (pItm) - ::HeapFree(::GetProcessHeap(), 0, pItm); - - ReleaseStr(pwzData); - - return hr; -} - -HRESULT MqiMessageQueueVerify( - MQI_MESSAGE_QUEUE_LIST* pList - ) -{ - HRESULT hr = S_OK; - LPWSTR pwzFormatName = NULL; - DWORD dwCount = 128; - - for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) - { - // queues that are being installed only - if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) - continue; - - // get format name - hr = StrAlloc(&pwzFormatName, dwCount); - ExitOnFailure(hr, "Failed to allocate format name string"); - do { - hr = gpfnMQPathNameToFormatName(pItm->wzPathName, pwzFormatName, &dwCount); - switch (hr) - { - case MQ_ERROR_QUEUE_NOT_FOUND: - break; // break - case MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL: - hr = StrAlloc(&pwzFormatName, dwCount); - ExitOnFailure(hr, "Failed to reallocate format name string"); - hr = S_FALSE; // retry - break; - default: - ExitOnFailure(hr, "Failed to get format name"); - hr = S_OK; - } - } while (S_FALSE == hr); - - if (MQ_ERROR_QUEUE_NOT_FOUND == hr) - { - continue; - } - pItm->fExists = TRUE; - pList->iInstallCount--; - - // clean up - ReleaseNullStr(pwzFormatName); - } - - hr = S_OK; - -LExit: - ReleaseStr(pwzFormatName); - return hr; -} - -HRESULT MqiMessageQueueInstall( - MQI_MESSAGE_QUEUE_LIST* pList, - BOOL fRollback, - LPWSTR* ppwzActionData - ) -{ - HRESULT hr = S_OK; - - // add count to action data - hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData); - ExitOnFailure(hr, "Failed to add count to custom action data"); - - for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) - { - // queues that are being installed only - if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) - continue; - - // if the queue exists we should not try to create it - if (pItm->fExists && !fRollback) - { - continue; - } - - // add message queue to action data - hr = AddMessageQueueToActionData(pItm, ppwzActionData); - ExitOnFailure(hr, "Failed to add message queue to action data"); - } - - hr = S_OK; - -LExit: - return hr; -} - -HRESULT MqiMessageQueueUninstall( - MQI_MESSAGE_QUEUE_LIST* pList, - BOOL fRollback, - LPWSTR* ppwzActionData - ) -{ - HRESULT hr = S_OK; - - // add count to action data - hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData); - ExitOnFailure(hr, "Failed to add count to custom action data"); - - for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) - { - // queues that are being uninstalled only - if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) - continue; - - // if we did not create the queue we should not try to delete it - if (pItm->fExists && fRollback) - { - continue; - } - - // add message queue to action data - hr = AddMessageQueueToActionData(pItm, ppwzActionData); - ExitOnFailure(hr, "Failed to add message queue to action data"); - } - - hr = S_OK; - -LExit: - return hr; -} - -void MqiMessageQueueFreeList( - MQI_MESSAGE_QUEUE_LIST* pList - ) -{ - MQI_MESSAGE_QUEUE* pItm = pList->pFirst; - while (pItm) - { - MQI_MESSAGE_QUEUE* pDelete = pItm; - pItm = pItm->pNext; - ::HeapFree(::GetProcessHeap(), 0, pDelete); - } -} - -HRESULT MqiMessageQueuePermissionRead( - MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList - ) -{ - HRESULT hr = S_OK; - - // read message queue user permissions - if (S_OK == WcaTableExists(L"MessageQueueUserPermission")) - { - hr = MessageQueueTrusteePermissionsRead(vcsMessageQueueUserPermissionQuery, pMessageQueueList, pList); - ExitOnFailure(hr, "Failed to read message queue user permissions"); - } - - // read message queue group permissions - if (S_OK == WcaTableExists(L"MessageQueueGroupPermission")) - { - hr = MessageQueueTrusteePermissionsRead(vcsMessageQueueGroupPermissionQuery, pMessageQueueList, pList); - ExitOnFailure(hr, "Failed to read message queue group permissions"); - } - - hr = S_OK; - -LExit: - return hr; -} - -HRESULT MqiMessageQueuePermissionInstall( - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, - LPWSTR* ppwzActionData - ) -{ - HRESULT hr = S_OK; - - // add count to action data - hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData); - ExitOnFailure(hr, "Failed to add count to custom action data"); - - for (MQI_MESSAGE_QUEUE_PERMISSION* pItm = pList->pFirst; pItm; pItm = pItm->pNext) - { - // queue permissions that are being installed only - if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) - continue; - - // add message queue permission to action data - hr = AddMessageQueuePermissionToActionData(pItm, ppwzActionData); - ExitOnFailure(hr, "Failed to add message queue permission to action data"); - } - - hr = S_OK; - -LExit: - return hr; -} - -HRESULT MqiMessageQueuePermissionUninstall( - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, - LPWSTR* ppwzActionData - ) -{ - HRESULT hr = S_OK; - - // add count to action data - hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData); - ExitOnFailure(hr, "Failed to add count to custom action data"); - - for (MQI_MESSAGE_QUEUE_PERMISSION* pItm = pList->pFirst; pItm; pItm = pItm->pNext) - { - // queue permissions that are being uninstalled only - if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) - continue; - - // add message queue permission to action data - hr = AddMessageQueuePermissionToActionData(pItm, ppwzActionData); - ExitOnFailure(hr, "Failed to add message queue permission to action data"); - } - - hr = S_OK; - -LExit: - return hr; -} - -void MqiMessageQueuePermissionFreeList( - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList - ) -{ - MQI_MESSAGE_QUEUE_PERMISSION* pItm = pList->pFirst; - while (pItm) - { - MQI_MESSAGE_QUEUE_PERMISSION* pDelete = pItm; - pItm = pItm->pNext; - ::HeapFree(::GetProcessHeap(), 0, pDelete); - } -} - - -// helper function definitions - -static HRESULT MqiMessageQueueFindByKey( - MQI_MESSAGE_QUEUE_LIST* pList, - LPCWSTR pwzKey, - MQI_MESSAGE_QUEUE** ppItm - ) -{ - for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) - { - if (0 == lstrcmpW(pItm->wzKey, pwzKey)) - { - *ppItm = pItm; - return S_OK; - } - } - - return S_FALSE; -} - -static HRESULT AddMessageQueueToActionData( - MQI_MESSAGE_QUEUE* pItm, - LPWSTR* ppwzActionData - ) -{ - HRESULT hr = S_OK; - - // add message queue information to custom action data - hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData); - ExitOnFailure(hr, "Failed to add key to custom action data"); - hr = WcaWriteIntegerToCaData(pItm->iBasePriority, ppwzActionData); - ExitOnFailure(hr, "Failed to add base priority to custom action data"); - hr = WcaWriteIntegerToCaData(pItm->iJournalQuota, ppwzActionData); - ExitOnFailure(hr, "Failed to add journal quota to custom action data"); - hr = WcaWriteStringToCaData(pItm->wzLabel, ppwzActionData); - ExitOnFailure(hr, "Failed to add label to custom action data"); - hr = WcaWriteStringToCaData(pItm->wzMulticastAddress, ppwzActionData); - ExitOnFailure(hr, "Failed to add multicast address to custom action data"); - hr = WcaWriteStringToCaData(pItm->wzPathName, ppwzActionData); - ExitOnFailure(hr, "Failed to add path name to custom action data"); - hr = WcaWriteIntegerToCaData(pItm->iPrivLevel, ppwzActionData); - ExitOnFailure(hr, "Failed to add privacy level to custom action data"); - hr = WcaWriteIntegerToCaData(pItm->iQuota, ppwzActionData); - ExitOnFailure(hr, "Failed to add quota to custom action data"); - hr = WcaWriteStringToCaData(pItm->wzServiceTypeGuid, ppwzActionData); - ExitOnFailure(hr, "Failed to add service type guid to custom action data"); - hr = WcaWriteIntegerToCaData(pItm->iAttributes, ppwzActionData); - ExitOnFailure(hr, "Failed to add attributes to custom action data"); - - hr = S_OK; - -LExit: - return hr; -} - -static HRESULT MessageQueueTrusteePermissionsRead( - LPCWSTR pwzQuery, - MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - PMSIHANDLE hView, hRec; - - LPWSTR pwzData = NULL; - - MQI_MESSAGE_QUEUE_PERMISSION* pItm = NULL; - - // loop through all application roles - hr = WcaOpenExecuteView(pwzQuery, &hView); - ExitOnFailure(hr, "Failed to execute view on table"); - - while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) - { - // create entry - pItm = (MQI_MESSAGE_QUEUE_PERMISSION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MQI_MESSAGE_QUEUE_PERMISSION)); - if (!pItm) - ExitFunction1(hr = E_OUTOFMEMORY); - - // get key - hr = WcaGetRecordString(hRec, mqpqMessageQueuePermission, &pwzData); - ExitOnFailure(hr, "Failed to get key"); - StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); - - // get component - hr = WcaGetRecordString(hRec, mqpqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get component"); - - // get component install state - er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); - - // get message queue - hr = WcaGetRecordString(hRec, mqpqMessageQueue, &pwzData); - ExitOnFailure(hr, "Failed to get application role"); - - hr = MqiMessageQueueFindByKey(pMessageQueueList, pwzData, &pItm->pMessageQueue); - if (S_FALSE == hr) - hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); - ExitOnFailure(hr, "Failed to find message queue, key: %S", pwzData); - - // get user domain - hr = WcaGetRecordFormattedString(hRec, mqpqDomain, &pwzData); - ExitOnFailure(hr, "Failed to get domain"); - StringCchCopyW(pItm->wzDomain, countof(pItm->wzDomain), pwzData); - - // get user name - hr = WcaGetRecordFormattedString(hRec, mqpqName, &pwzData); - ExitOnFailure(hr, "Failed to get name"); - StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); - - // get permissions - hr = WcaGetRecordInteger(hRec, mqpqPermissions, &pItm->iPermissions); - ExitOnFailure(hr, "Failed to get permissions"); - - // set references & increment counters - if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) - pList->iInstallCount++; - if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) - pList->iUninstallCount++; - - // add entry - if (pList->pFirst) - pItm->pNext = pList->pFirst; - pList->pFirst = pItm; - pItm = NULL; - } - - if (E_NOMOREITEMS == hr) - hr = S_OK; - -LExit: - // clean up - ReleaseStr(pwzData); - - if (pItm) - ::HeapFree(::GetProcessHeap(), 0, pItm); - - return hr; -} - -static HRESULT AddMessageQueuePermissionToActionData( - MQI_MESSAGE_QUEUE_PERMISSION* pItm, - LPWSTR* ppwzActionData - ) -{ - HRESULT hr = S_OK; - - // add message queue information to custom action data - hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData); - ExitOnFailure(hr, "Failed to add key to custom action data"); - hr = WcaWriteStringToCaData(pItm->pMessageQueue->wzPathName, ppwzActionData); - ExitOnFailure(hr, "Failed to add path name to custom action data"); - hr = WcaWriteStringToCaData(pItm->wzDomain, ppwzActionData); - ExitOnFailure(hr, "Failed to add domain to custom action data"); - hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData); - ExitOnFailure(hr, "Failed to add name to custom action data"); - hr = WcaWriteIntegerToCaData(pItm->iPermissions, ppwzActionData); - ExitOnFailure(hr, "Failed to add permissions to custom action data"); - - hr = S_OK; - -LExit: - return hr; -} diff --git a/src/ca/mqqueuesched.h b/src/ca/mqqueuesched.h deleted file mode 100644 index c9381e0a..00000000 --- a/src/ca/mqqueuesched.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once -// 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. - - -struct MQI_MESSAGE_QUEUE -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - int iBasePriority; - int iJournalQuota; - WCHAR wzLabel[MAX_DARWIN_COLUMN + 1]; - WCHAR wzMulticastAddress[MAX_DARWIN_COLUMN + 1]; - WCHAR wzPathName[MAX_DARWIN_COLUMN + 1]; - int iPrivLevel; - int iQuota; - WCHAR wzServiceTypeGuid[MAX_DARWIN_COLUMN + 1]; - int iAttributes; - - INSTALLSTATE isInstalled, isAction; - BOOL fExists; - - MQI_MESSAGE_QUEUE* pNext; -}; - -struct MQI_MESSAGE_QUEUE_LIST -{ - MQI_MESSAGE_QUEUE* pFirst; - - int iInstallCount; - int iUninstallCount; -}; - -struct MQI_MESSAGE_QUEUE_PERMISSION -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; - WCHAR wzName[MAX_DARWIN_COLUMN + 1]; - int iPermissions; - - MQI_MESSAGE_QUEUE* pMessageQueue; - - INSTALLSTATE isInstalled, isAction; - - MQI_MESSAGE_QUEUE_PERMISSION* pNext; -}; - -struct MQI_MESSAGE_QUEUE_PERMISSION_LIST -{ - MQI_MESSAGE_QUEUE_PERMISSION* pFirst; - - int iInstallCount; - int iUninstallCount; -}; - - -// function prototypes - -HRESULT MqiSchedInitialize(); -void MqiSchedUninitialize(); -HRESULT MqiMessageQueueRead( - MQI_MESSAGE_QUEUE_LIST* pList - ); -HRESULT MqiMessageQueueVerify( - MQI_MESSAGE_QUEUE_LIST* pList - ); -HRESULT MqiMessageQueueInstall( - MQI_MESSAGE_QUEUE_LIST* pList, - BOOL fRollback, - LPWSTR* ppwzActionData - ); -HRESULT MqiMessageQueueUninstall( - MQI_MESSAGE_QUEUE_LIST* pList, - BOOL fRollback, - LPWSTR* ppwzActionData - ); -void MqiMessageQueueFreeList( - MQI_MESSAGE_QUEUE_LIST* pList - ); -HRESULT MqiMessageQueuePermissionRead( - MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList - ); -HRESULT MqiMessageQueuePermissionInstall( - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, - LPWSTR* ppwzActionData - ); -HRESULT MqiMessageQueuePermissionUninstall( - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, - LPWSTR* ppwzActionData - ); -void MqiMessageQueuePermissionFreeList( - MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList - ); diff --git a/src/ca/mqsched.cpp b/src/ca/mqsched.cpp deleted file mode 100644 index 4c994901..00000000 --- a/src/ca/mqsched.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// 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. - -#include "precomp.h" - - -/******************************************************************** - MessageQueuingInstall - CUSTOM ACTION ENTRY POINT for installing MSMQ message queues - -********************************************************************/ -extern "C" UINT __stdcall MessageQueuingInstall(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - MQI_MESSAGE_QUEUE_LIST lstMessageQueues; - MQI_MESSAGE_QUEUE_PERMISSION_LIST lstMessageQueuePermissions; - - int iCost = 0; - LPWSTR pwzRollbackActionData = NULL; - LPWSTR pwzExecuteActionData = NULL; - - ::ZeroMemory(&lstMessageQueues, sizeof(lstMessageQueues)); - ::ZeroMemory(&lstMessageQueuePermissions, sizeof(lstMessageQueuePermissions)); - - // initialize - hr = WcaInitialize(hInstall, "MessageQueuingInstall"); - ExitOnFailure(hr, "Failed to initialize"); - - do - { - hr = MqiSchedInitialize(); - if (S_FALSE == hr) - { - WcaLog(LOGMSG_STANDARD, "Failed to load mqrt.dll."); - er = WcaErrorMessage(msierrMsmqCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); - switch (er) - { - case IDABORT: - ExitFunction1(hr = E_FAIL); // bail with error - case IDRETRY: - break; // retry - case IDIGNORE: __fallthrough; - default: - ExitFunction1(hr = S_OK); // pretend everything is okay and bail - } - } - ExitOnFailure(hr, "Failed to initialize MSMQ."); - } while (S_FALSE == hr); - - // read message queues - hr = MqiMessageQueueRead(&lstMessageQueues); - ExitOnFailure(hr, "Failed to read MessageQueue table"); - - // read message queue permissions - hr = MqiMessageQueuePermissionRead(&lstMessageQueues, &lstMessageQueuePermissions); - ExitOnFailure(hr, "Failed to read message queue permissions"); - - // verify message queue elementes - hr = MqiMessageQueueVerify(&lstMessageQueues); - ExitOnFailure(hr, "Failed to verify message queue elements."); - - if (lstMessageQueues.iInstallCount || lstMessageQueuePermissions.iInstallCount) - { - // schedule rollback action - hr = MqiMessageQueuePermissionInstall(&lstMessageQueuePermissions, &pwzRollbackActionData); - ExitOnFailure(hr, "Failed to add message queue permissions to rollback action data"); - - hr = MqiMessageQueueInstall(&lstMessageQueues, TRUE, &pwzRollbackActionData); - ExitOnFailure(hr, "Failed to add message queues to rollback action data"); - - hr = WcaDoDeferredAction(L"MessageQueuingRollbackInstall", pwzRollbackActionData, 0); - ExitOnFailure(hr, "Failed to schedule MessageQueuingRollbackInstall"); - - // schedule execute action - hr = MqiMessageQueueInstall(&lstMessageQueues, FALSE, &pwzExecuteActionData); - ExitOnFailure(hr, "Failed to add message queues to execute action data"); - iCost += lstMessageQueues.iInstallCount * COST_MESSAGE_QUEUE_CREATE; - - hr = MqiMessageQueuePermissionInstall(&lstMessageQueuePermissions, &pwzExecuteActionData); - ExitOnFailure(hr, "Failed to add message queue permissions to execute action data"); - iCost += lstMessageQueues.iInstallCount * COST_MESSAGE_QUEUE_PERMISSION_ADD; - - hr = WcaDoDeferredAction(L"MessageQueuingExecuteInstall", pwzExecuteActionData, iCost); - ExitOnFailure(hr, "Failed to schedule MessageQueuingExecuteInstall"); - } - - hr = S_OK; - -LExit: - // clean up - MqiMessageQueueFreeList(&lstMessageQueues); - MqiMessageQueuePermissionFreeList(&lstMessageQueuePermissions); - - ReleaseStr(pwzRollbackActionData); - ReleaseStr(pwzExecuteActionData); - - // uninitialize - MqiSchedUninitialize(); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/******************************************************************** - MessageQueuingUninstall - CUSTOM ACTION ENTRY POINT for uninstalling MSMQ message queues - -********************************************************************/ -extern "C" UINT __stdcall MessageQueuingUninstall(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - MQI_MESSAGE_QUEUE_LIST lstMessageQueues; - MQI_MESSAGE_QUEUE_PERMISSION_LIST lstMessageQueuePermissions; - - int iCost = 0; - LPWSTR pwzRollbackActionData = NULL; - LPWSTR pwzExecuteActionData = NULL; - - ::ZeroMemory(&lstMessageQueues, sizeof(lstMessageQueues)); - ::ZeroMemory(&lstMessageQueuePermissions, sizeof(lstMessageQueuePermissions)); - - // initialize - hr = WcaInitialize(hInstall, "MessageQueuingUninstall"); - ExitOnFailure(hr, "Failed to initialize"); - - do - { - hr = MqiSchedInitialize(); - if (S_FALSE == hr) - { - WcaLog(LOGMSG_STANDARD, "Failed to load mqrt.dll."); - er = WcaErrorMessage(msierrMsmqCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); - switch (er) - { - case IDABORT: - ExitFunction1(hr = E_FAIL); // bail with error - case IDRETRY: - break; // retry - case IDIGNORE: __fallthrough; - default: - ExitFunction1(hr = S_OK); // pretend everything is okay and bail - } - } - ExitOnFailure(hr, "Failed to initialize MSMQ."); - } while (S_FALSE == hr); - - // read message queues - hr = MqiMessageQueueRead(&lstMessageQueues); - ExitOnFailure(hr, "Failed to read MessageQueue table"); - - // read message queue permissions - hr = MqiMessageQueuePermissionRead(&lstMessageQueues, &lstMessageQueuePermissions); - ExitOnFailure(hr, "Failed to read message queue permissions"); - - if (lstMessageQueues.iUninstallCount || lstMessageQueuePermissions.iUninstallCount) - { - // schedule rollback action - hr = MqiMessageQueueUninstall(&lstMessageQueues, TRUE, &pwzRollbackActionData); - ExitOnFailure(hr, "Failed to add message queues to rollback action data"); - - hr = MqiMessageQueuePermissionUninstall(&lstMessageQueuePermissions, &pwzRollbackActionData); - ExitOnFailure(hr, "Failed to add message queue permissions to rollback action data"); - - hr = WcaDoDeferredAction(L"MessageQueuingRollbackUninstall", pwzRollbackActionData, 0); - ExitOnFailure(hr, "Failed to schedule MessageQueuingRollbackUninstall"); - - // schedule execute action - hr = MqiMessageQueuePermissionUninstall(&lstMessageQueuePermissions, &pwzExecuteActionData); - ExitOnFailure(hr, "Failed to add message queue permissions to execute action data"); - - hr = MqiMessageQueueUninstall(&lstMessageQueues, FALSE, &pwzExecuteActionData); - ExitOnFailure(hr, "Failed to add message queues to execute action data"); - iCost += lstMessageQueues.iUninstallCount * COST_MESSAGE_QUEUE_DELETE; - - hr = WcaDoDeferredAction(L"MessageQueuingExecuteUninstall", pwzExecuteActionData, iCost); - ExitOnFailure(hr, "Failed to schedule MessageQueuingExecuteUninstall"); - } - - hr = S_OK; - -LExit: - // clean up - MqiMessageQueueFreeList(&lstMessageQueues); - MqiMessageQueuePermissionFreeList(&lstMessageQueuePermissions); - - ReleaseStr(pwzRollbackActionData); - ReleaseStr(pwzExecuteActionData); - - // uninitialize - MqiSchedUninitialize(); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} diff --git a/src/ca/mqutilexec.cpp b/src/ca/mqutilexec.cpp deleted file mode 100644 index a9c56e02..00000000 --- a/src/ca/mqutilexec.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// 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. - -#include "precomp.h" - - -// private structs - -struct PCA_WELLKNOWN_SID -{ - LPCWSTR pwzName; - SID_IDENTIFIER_AUTHORITY iaIdentifierAuthority; - BYTE nSubAuthorityCount; - DWORD dwSubAuthority[8]; -}; - - -// well known SIDs - -PCA_WELLKNOWN_SID wsWellKnownSids[] = { - {L"\\Everyone", SECURITY_WORLD_SID_AUTHORITY, 1, {SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0}}, - {L"\\Administrators", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0}}, - {L"\\LocalSystem", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0}}, - {L"\\LocalService", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}}, - {L"\\NetworkService", SECURITY_NT_AUTHORITY, 1, {SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}}, - {L"\\AuthenticatedUser", SECURITY_NT_AUTHORITY, 1, {SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0}}, - {L"\\Guests", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS, 0, 0, 0, 0, 0, 0}}, - {L"\\Users", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0}}, - {L"\\CREATOR OWNER", SECURITY_NT_AUTHORITY, 1, {SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0}}, - {NULL, SECURITY_NULL_SID_AUTHORITY, 0, {0, 0, 0, 0, 0, 0, 0, 0}} -}; - - -// prototypes for private helper functions - -static HRESULT CreateSidFromDomainRidPair( - PSID pDomainSid, - DWORD dwRid, - PSID* ppSid - ); -static HRESULT InitLsaUnicodeString( - PLSA_UNICODE_STRING plusStr, - LPCWSTR pwzStr, - DWORD dwLen - ); -static void FreeLsaUnicodeString( - PLSA_UNICODE_STRING plusStr - ); - - -// function definitions - -HRESULT PcaActionDataMessage( - DWORD cArgs, - ... - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - PMSIHANDLE hRec; - va_list args; - - // record - hRec = ::MsiCreateRecord(cArgs); - ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record"); - - va_start(args, cArgs); - for (DWORD i = 1; i <= cArgs; i++) - { - LPCWSTR pwzArg = va_arg(args, WCHAR*); - if (pwzArg && *pwzArg) - { - er = ::MsiRecordSetStringW(hRec, i, pwzArg); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set record field string"); - } - } - va_end(args); - - // message - er = WcaProcessMessage(INSTALLMESSAGE_ACTIONDATA, hRec); - if (0 == er || IDOK == er || IDYES == er) - { - hr = S_OK; - } - else if (ERROR_INSTALL_USEREXIT == er || IDABORT == er || IDCANCEL == er) - { - WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit - hr = S_FALSE; - } - else - hr = E_UNEXPECTED; - -LExit: - return hr; -} - -HRESULT PcaAccountNameToSid( - LPCWSTR pwzAccountName, - PSID* ppSid - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - NTSTATUS st = 0; - - PSID pSid = NULL; - LSA_OBJECT_ATTRIBUTES loaAttributes; - LSA_HANDLE lsahPolicy = NULL; - LSA_UNICODE_STRING lusName; - PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL; - PLSA_TRANSLATED_SID pltsSid = NULL; - - ::ZeroMemory(&loaAttributes, sizeof(loaAttributes)); - ::ZeroMemory(&lusName, sizeof(lusName)); - - // identify well known SIDs - for (PCA_WELLKNOWN_SID* pWS = wsWellKnownSids; pWS->pwzName; pWS++) - { - if (0 == lstrcmpiW(pwzAccountName, pWS->pwzName)) - { - // allocate SID buffer - pSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, ::GetSidLengthRequired(pWS->nSubAuthorityCount)); - ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID"); - - // initialize SID - ::InitializeSid(pSid, &pWS->iaIdentifierAuthority, pWS->nSubAuthorityCount); - - // copy sub autorities - for (DWORD i = 0; i < pWS->nSubAuthorityCount; i++) - *::GetSidSubAuthority(pSid, i) = pWS->dwSubAuthority[i]; - - break; - } - } - - // lookup name - if (!pSid) - { - // open policy handle - st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy); - er = ::LsaNtStatusToWinError(st); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle"); - - // create account name lsa unicode string - hr = InitLsaUnicodeString(&lusName, pwzAccountName, wcslen(pwzAccountName)); - ExitOnFailure(hr, "Failed to initialize account name string"); - - // lookup name - st = ::LsaLookupNames(lsahPolicy, 1, &lusName, &plrdsDomains, &pltsSid); - er = ::LsaNtStatusToWinError(st); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names"); - - if (SidTypeDomain == pltsSid->Use) - ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported"); - - // convert sid - hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pSid); - ExitOnFailure(hr, "Failed to convert SID"); - } - - *ppSid = pSid; - pSid = NULL; - - hr = S_OK; - -LExit: - // clean up - if (pSid) - ::HeapFree(::GetProcessHeap(), 0, pSid); - if (lsahPolicy) - ::LsaClose(lsahPolicy); - if (plrdsDomains) - ::LsaFreeMemory(plrdsDomains); - if (pltsSid) - ::LsaFreeMemory(pltsSid); - FreeLsaUnicodeString(&lusName); - - return hr; -} - -HRESULT PcaSidToAccountName( - PSID pSid, - LPWSTR* ppwzAccountName - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - NTSTATUS st = 0; - - LSA_OBJECT_ATTRIBUTES loaAttributes; - LSA_HANDLE lsahPolicy = NULL; - PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL; - PLSA_TRANSLATED_NAME pltnName = NULL; - - LPWSTR pwzDomain = NULL; - LPWSTR pwzName = NULL; - - ::ZeroMemory(&loaAttributes, sizeof(loaAttributes)); - - // open policy handle - st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy); - er = ::LsaNtStatusToWinError(st); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle"); - - // lookup SID - st = ::LsaLookupSids(lsahPolicy, 1, &pSid, &plrdsDomains, &pltnName); - er = ::LsaNtStatusToWinError(st); - ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup SID"); - - if (SidTypeDomain == pltnName->Use) - ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported"); - - // format account name string - if (SidTypeWellKnownGroup != pltnName->Use) - { - PLSA_UNICODE_STRING plusDomain = &plrdsDomains->Domains[pltnName->DomainIndex].Name; - hr = StrAllocString(&pwzDomain, plusDomain->Buffer, plusDomain->Length / sizeof(WCHAR)); - ExitOnFailure(hr, "Failed to allocate name string"); - } - - hr = StrAllocString(&pwzName, pltnName->Name.Buffer, pltnName->Name.Length / sizeof(WCHAR)); - ExitOnFailure(hr, "Failed to allocate domain string"); - - hr = StrAllocFormatted(ppwzAccountName, L"%s\\%s", pwzDomain ? pwzDomain : L"", pwzName); - ExitOnFailure(hr, "Failed to format account name string"); - - hr = S_OK; - -LExit: - // clean up - if (lsahPolicy) - ::LsaClose(lsahPolicy); - if (plrdsDomains) - ::LsaFreeMemory(plrdsDomains); - if (pltnName) - ::LsaFreeMemory(pltnName); - - ReleaseStr(pwzDomain); - ReleaseStr(pwzName); - - return hr; -} - -HRESULT PcaBuildAccountName( - LPCWSTR pwzDomain, - LPCWSTR pwzName, - LPWSTR* ppwzAccount - ) -{ - HRESULT hr = S_OK; - - WCHAR wzComputerName[MAX_COMPUTERNAME_LENGTH + 1]; - ::ZeroMemory(wzComputerName, sizeof(wzComputerName)); - - // if domain is '.', get computer name - if (0 == lstrcmpW(pwzDomain, L".")) - { - DWORD dwSize = countof(wzComputerName); - if (!::GetComputerNameW(wzComputerName, &dwSize)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get computer name"); - } - - // build account name - hr = StrAllocFormatted(ppwzAccount, L"%s\\%s", *wzComputerName ? wzComputerName : pwzDomain, pwzName); - ExitOnFailure(hr, "Failed to build domain user name"); - - hr = S_OK; - -LExit: - return hr; -} - -HRESULT PcaGuidFromString( - LPCWSTR pwzGuid, - LPGUID pGuid - ) -{ - HRESULT hr = S_OK; - - int cch = 0; - - WCHAR wz[39]; - ::ZeroMemory(wz, sizeof(wz)); - - cch = lstrlenW(pwzGuid); - - if (38 == cch && L'{' == pwzGuid[0] && L'}' == pwzGuid[37]) - StringCchCopyW(wz, countof(wz), pwzGuid); - else if (36 == cch) - StringCchPrintfW(wz, countof(wz), L"{%s}", pwzGuid); - else - ExitFunction1(hr = E_INVALIDARG); - - hr = ::CLSIDFromString(wz, pGuid); - -LExit: - return hr; -} - - -// helper function definitions - -static HRESULT CreateSidFromDomainRidPair( - PSID pDomainSid, - DWORD dwRid, - PSID* ppSid - ) -{ - HRESULT hr = S_OK; - - PSID pSid = NULL; - - // get domain SID sub authority count - UCHAR ucSubAuthorityCount = *::GetSidSubAuthorityCount(pDomainSid); - - // allocate SID buffer - DWORD dwLengthRequired = ::GetSidLengthRequired(ucSubAuthorityCount + (UCHAR)1); - if (*ppSid) - { - SIZE_T ccb = ::HeapSize(::GetProcessHeap(), 0, *ppSid); - if (-1 == ccb) - ExitOnFailure(hr = E_FAIL, "Failed to get size of SID buffer"); - - if (ccb < dwLengthRequired) - { - pSid = (PSID)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, *ppSid, dwLengthRequired); - ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for SID, len: %d", dwLengthRequired); - *ppSid = pSid; - } - } - else - { - *ppSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLengthRequired); - ExitOnNull(*ppSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID, len: %d", dwLengthRequired); - } - - ::InitializeSid(*ppSid, ::GetSidIdentifierAuthority(pDomainSid), ucSubAuthorityCount + (UCHAR)1); - - // copy sub autorities - DWORD i = 0; - for (; i < ucSubAuthorityCount; i++) - *::GetSidSubAuthority(*ppSid, i) = *::GetSidSubAuthority(pDomainSid, i); - *::GetSidSubAuthority(*ppSid, i) = dwRid; - - hr = S_OK; - -LExit: - return hr; -} - -static HRESULT InitLsaUnicodeString( - PLSA_UNICODE_STRING plusStr, - LPCWSTR pwzStr, - DWORD dwLen - ) -{ - HRESULT hr = S_OK; - - plusStr->Length = (USHORT)dwLen * sizeof(WCHAR); - plusStr->MaximumLength = (USHORT)(dwLen + 1) * sizeof(WCHAR); - - plusStr->Buffer = (WCHAR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * (dwLen + 1)); - ExitOnNull(plusStr->Buffer, hr, E_OUTOFMEMORY, "Failed to allocate account name string"); - - hr = StringCchCopyW(plusStr->Buffer, dwLen + 1, pwzStr); - ExitOnFailure(hr, "Failed to copy buffer"); - - hr = S_OK; - -LExit: - return hr; -} - -static void FreeLsaUnicodeString( - PLSA_UNICODE_STRING plusStr - ) -{ - if (plusStr->Buffer) - ::HeapFree(::GetProcessHeap(), 0, plusStr->Buffer); -} diff --git a/src/ca/mqutilexec.h b/src/ca/mqutilexec.h deleted file mode 100644 index d3dc17a1..00000000 --- a/src/ca/mqutilexec.h +++ /dev/null @@ -1,23 +0,0 @@ -// 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. - -HRESULT PcaActionDataMessage( - DWORD cArgs, - ... - ); -HRESULT PcaAccountNameToSid( - LPCWSTR pwzAccountName, - PSID* ppSid - ); -HRESULT PcaSidToAccountName( - PSID pSid, - LPWSTR* ppwzAccountName - ); -HRESULT PcaBuildAccountName( - LPCWSTR pwzDomain, - LPCWSTR pwzName, - LPWSTR* ppwzAccount - ); -HRESULT PcaGuidFromString( - LPCWSTR pwzGuid, - GUID* pGuid - ); diff --git a/src/ca/mqutilsched.cpp b/src/ca/mqutilsched.cpp deleted file mode 100644 index 4353a6d6..00000000 --- a/src/ca/mqutilsched.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// 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. - -#include "precomp.h" - - -// function definitions - -HRESULT PcaGuidToRegFormat( - LPWSTR pwzGuid, - LPWSTR pwzDest, - SIZE_T cchDest - ) -{ - HRESULT hr = S_OK; - - GUID guid = GUID_NULL; - int cch = 0; - - WCHAR wz[39]; - ::ZeroMemory(wz, sizeof(wz)); - - cch = lstrlenW(pwzGuid); - - if (38 == cch && L'{' == pwzGuid[0] && L'}' == pwzGuid[37]) - StringCchCopyW(wz, countof(wz), pwzGuid); - else if (36 == cch) - StringCchPrintfW(wz, countof(wz), L"{%s}", pwzGuid); - else - ExitFunction1(hr = E_INVALIDARG); - - // convert string to guid - hr = ::CLSIDFromString(wz, &guid); - ExitOnFailure(hr, "Failed to parse guid string"); - - // convert guid to string - if (0 == ::StringFromGUID2(guid, pwzDest, cchDest)) - ExitOnFailure(hr = E_FAIL, "Failed to convert guid to string"); - - hr = S_OK; - -LExit: - return hr; -} diff --git a/src/ca/mqutilsched.h b/src/ca/mqutilsched.h deleted file mode 100644 index e172257d..00000000 --- a/src/ca/mqutilsched.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -// 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. - - -HRESULT PcaGuidToRegFormat( - LPWSTR pwzGuid, - LPWSTR pwzDest, - SIZE_T cchDest - ); diff --git a/src/ca/msmqca.def b/src/ca/msmqca.def deleted file mode 100644 index 4902858f..00000000 --- a/src/ca/msmqca.def +++ /dev/null @@ -1,12 +0,0 @@ -; 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. - - -LIBRARY "msmqca" - -EXPORTS - MessageQueuingInstall - MessageQueuingUninstall - MessageQueuingExecuteInstall - MessageQueuingRollbackInstall - MessageQueuingExecuteUninstall - MessageQueuingRollbackUninstall diff --git a/src/ca/msmqca.vcxproj b/src/ca/msmqca.vcxproj deleted file mode 100644 index c4cb3323..00000000 --- a/src/ca/msmqca.vcxproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - Debug - Win32 - - - Release - Win32 - - - - - {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D} - DynamicLibrary - msmqca - v142 - Unicode - msmqca.def - WiX Toolset MSMQ CustomAction - - - - - - - msi.lib - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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}. - - - - - diff --git a/src/ca/packages.config b/src/ca/packages.config deleted file mode 100644 index 9d88f529..00000000 --- a/src/ca/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/ca/precomp.h b/src/ca/precomp.h deleted file mode 100644 index cbbff6ea..00000000 --- a/src/ca/precomp.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -// 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. - - -#include -#include -#include -#include -#include -#include - -#include "wcautil.h" -#include "memutil.h" -#include "strutil.h" -#include "wiutil.h" - -#include "CustomMsiErrors.h" - -#include "mqcost.h" -#include "mqutilsched.h" -#include "mqqueuesched.h" -#include "mqutilexec.h" -#include "mqqueueexec.h" diff --git a/src/ext/Msmq/CSharp.Build.props b/src/ext/Msmq/CSharp.Build.props new file mode 100644 index 00000000..b12f4c6e --- /dev/null +++ b/src/ext/Msmq/CSharp.Build.props @@ -0,0 +1,11 @@ + + + + + true + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk)) + + diff --git a/src/ext/Msmq/Cpp.Build.props b/src/ext/Msmq/Cpp.Build.props new file mode 100644 index 00000000..9b7a1bb5 --- /dev/null +++ b/src/ext/Msmq/Cpp.Build.props @@ -0,0 +1,86 @@ + + + + + + Win32 + $(BaseIntermediateOutputPath)$(Configuration)\$(Platform)\ + $(OutputPath)$(Platform)\ + + + + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + + $(DisableSpecificCompilerWarnings) + Level4 + $(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + Use + precomp.h + StdCall + true + false + -YlprecompDefine + /Zc:threadSafeInit- %(AdditionalOptions) + true + + + $(ArmPreprocessorDefinitions);%(PreprocessorDefinitions) + $(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories) + + + $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories) + + + $(ProjectSubSystem) + $(ProjectModuleDefinitionFile) + $(ResourceOnlyDll) + true + $(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies) + $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories) + /IGNORE:4099 %(AdditionalOptions) + + + + + + NoExtensions + + + + + CDecl + + + + + OldStyle + true + true + + + + + Disabled + EnableFastChecks + _DEBUG;DEBUG;%(PreprocessorDefinitions) + MultiThreadedDebug + + + + + MinSpace + NDEBUG;%(PreprocessorDefinitions) + true + true + MultiThreaded + + + true + true + + + diff --git a/src/ext/Msmq/Directory.Build.props b/src/ext/Msmq/Directory.Build.props new file mode 100644 index 00000000..f83cc154 --- /dev/null +++ b/src/ext/Msmq/Directory.Build.props @@ -0,0 +1,29 @@ + + + + + + Debug + false + MSB3246 + + $(MSBuildProjectName) + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\)) + $(BaseOutputPath)obj\$(ProjectName)\ + $(BaseOutputPath)$(Configuration)\ + + WiX Toolset Team + WiX Toolset + Copyright (c) .NET Foundation and contributors. All rights reserved. + MS-RL + WiX Toolset + + + + + + + diff --git a/src/ext/Msmq/Directory.Build.targets b/src/ext/Msmq/Directory.Build.targets new file mode 100644 index 00000000..dac7452a --- /dev/null +++ b/src/ext/Msmq/Directory.Build.targets @@ -0,0 +1,48 @@ + + + + + + + true + $(SolutionPath) + $(NCrunchOriginalSolutionPath) + + + + + + + $([System.IO.File]::ReadAllText($(TheSolutionPath))) + $([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) )) + (?<="[PackageName]", ")(.*)(?=", ") + + + + + + %(Identity) + $(SolutionFileContent.Contains('\%(Identity).csproj')) + + + + + $(RegexPattern.Replace('[PackageName]','%(PackageName)') ) + $([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)')) + + + + + + + + + + + diff --git a/src/ext/Msmq/Msmq.wixext.sln b/src/ext/Msmq/Msmq.wixext.sln new file mode 100644 index 00000000..e3ebed6d --- /dev/null +++ b/src/ext/Msmq/Msmq.wixext.sln @@ -0,0 +1,61 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2016 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msmqca", "src\ca\msmqca.vcxproj", "{CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}" +EndProject +Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "msmq", "src\wixlib\msmq.wixproj", "{42493058-5FC8-4F85-9884-FF3190E084B6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Msmq.wixext", "src\wixext\WixToolset.Msmq.wixext.csproj", "{B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Msmq", "src\test\WixToolsetTest.Msmq\WixToolsetTest.Msmq.csproj", "{B63DA068-338F-473B-9097-FC4E64830A2A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|Any CPU.Build.0 = Debug|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|x86.ActiveCfg = Debug|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Debug|x86.Build.0 = Debug|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|Any CPU.ActiveCfg = Release|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|Any CPU.Build.0 = Release|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|x86.ActiveCfg = Release|Win32 + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D}.Release|x86.Build.0 = Release|Win32 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|Any CPU.ActiveCfg = Debug|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|Any CPU.Build.0 = Debug|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|x86.ActiveCfg = Debug|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Debug|x86.Build.0 = Debug|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|Any CPU.ActiveCfg = Release|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|Any CPU.Build.0 = Release|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|x86.ActiveCfg = Release|x86 + {42493058-5FC8-4F85-9884-FF3190E084B6}.Release|x86.Build.0 = Release|x86 + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Debug|x86.Build.0 = Debug|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|Any CPU.Build.0 = Release|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|x86.ActiveCfg = Release|Any CPU + {B990D81B-9F60-4EEE-B31D-B5D1EAA799EE}.Release|x86.Build.0 = Release|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|x86.ActiveCfg = Debug|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Debug|x86.Build.0 = Debug|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|Any CPU.Build.0 = Release|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|x86.ActiveCfg = Release|Any CPU + {B63DA068-338F-473B-9097-FC4E64830A2A}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5524C948-C115-4690-9BC4-44E3E963F960} + EndGlobalSection +EndGlobal diff --git a/src/ext/Msmq/README.md b/src/ext/Msmq/README.md new file mode 100644 index 00000000..fa3c277f --- /dev/null +++ b/src/ext/Msmq/README.md @@ -0,0 +1,2 @@ +# Msmq.wixext +WixToolset.Msmq.wixext - MSMQ WiX Toolset Extension diff --git a/src/ext/Msmq/appveyor.cmd b/src/ext/Msmq/appveyor.cmd new file mode 100644 index 00000000..f493b577 --- /dev/null +++ b/src/ext/Msmq/appveyor.cmd @@ -0,0 +1,14 @@ +@setlocal +@pushd %~dp0 + +nuget restore || exit /b + +msbuild -p:Configuration=Release -t:Restore || exit /b + +msbuild -p:Configuration=Release src\test\WixToolsetTest.Msmq\WixToolsetTest.Msmq.csproj || exit /b +dotnet test -c Release --no-build src\test\WixToolsetTest.Msmq || exit /b + +msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Msmq.wixext.csproj || exit /b + +@popd +@endlocal \ No newline at end of file diff --git a/src/ext/Msmq/appveyor.yml b/src/ext/Msmq/appveyor.yml new file mode 100644 index 00000000..7c686b04 --- /dev/null +++ b/src/ext/Msmq/appveyor.yml @@ -0,0 +1,40 @@ +# 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. +# +# Do NOT modify this file. Update the canonical version in Home\repo-template\src\appveyor.yml +# then update all of the repos. + +branches: + only: + - master + - develop + +image: Visual Studio 2019 + +version: 0.0.0.{build} +configuration: Release + +environment: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + NUGET_XMLDOC_MODE: skip + +build_script: + - appveyor.cmd + +pull_requests: + do_not_increment_build_number: true + +nuget: + disable_publish_on_pr: true + +skip_branch_with_pr: true +skip_tags: true + +artifacts: +- path: build\Release\**\*.nupkg + name: nuget + +notifications: +- provider: Slack + incoming_webhook: + secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA= diff --git a/src/ext/Msmq/ca/custommsierrors.h b/src/ext/Msmq/ca/custommsierrors.h new file mode 100644 index 00000000..0c1b23b7 --- /dev/null +++ b/src/ext/Msmq/ca/custommsierrors.h @@ -0,0 +1,4 @@ +#pragma once +// 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. + +#define msierrMsmqCannotConnect 28101 diff --git a/src/ext/Msmq/ca/dllmain.cpp b/src/ext/Msmq/ca/dllmain.cpp new file mode 100644 index 00000000..35ae6d1c --- /dev/null +++ b/src/ext/Msmq/ca/dllmain.cpp @@ -0,0 +1,26 @@ +// 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. + +#include "precomp.h" + +/******************************************************************** +DllMain - standard entry point for all WiX custom actions + +********************************************************************/ +extern "C" BOOL WINAPI DllMain( + IN HINSTANCE hInst, + IN ULONG ulReason, + IN LPVOID) +{ + switch(ulReason) + { + case DLL_PROCESS_ATTACH: + WcaGlobalInitialize(hInst); + break; + + case DLL_PROCESS_DETACH: + WcaGlobalFinalize(); + break; + } + + return TRUE; +} diff --git a/src/ext/Msmq/ca/mqcost.h b/src/ext/Msmq/ca/mqcost.h new file mode 100644 index 00000000..a40b7437 --- /dev/null +++ b/src/ext/Msmq/ca/mqcost.h @@ -0,0 +1,9 @@ +#pragma once +// 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. + + +#define COST_MESSAGE_QUEUE_CREATE 10000 +#define COST_MESSAGE_QUEUE_DELETE 10000 + +#define COST_MESSAGE_QUEUE_PERMISSION_ADD 10000 +#define COST_MESSAGE_QUEUE_PERMISSION_REMOVE 10000 diff --git a/src/ext/Msmq/ca/mqexec.cpp b/src/ext/Msmq/ca/mqexec.cpp new file mode 100644 index 00000000..ff7e9b14 --- /dev/null +++ b/src/ext/Msmq/ca/mqexec.cpp @@ -0,0 +1,192 @@ +// 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. + +#include "precomp.h" + + +/******************************************************************** + MessageQueuingExecuteInstall - CUSTOM ACTION ENTRY POINT + + Input: deferred CustomActionData - MessageQueuingExecuteInstall +********************************************************************/ +extern "C" UINT __stdcall MessageQueuingExecuteInstall(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzCustomActionData = NULL; + LPWSTR pwzData = NULL; + + // initialize + hr = WcaInitialize(hInstall, "MessageQueuingExecuteInstall"); + ExitOnFailure(hr, "Failed to initialize MessageQueuingExecuteInstall"); + + hr = MqiExecInitialize(); + ExitOnFailure(hr, "Failed to initialize"); + + // get custom action data + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); + ExitOnFailure(hr, "Failed to get CustomActionData"); + pwzData = pwzCustomActionData; + + // create message queues + hr = MqiCreateMessageQueues(&pwzData); + ExitOnFailure(hr, "Failed to create message queues"); + if (S_FALSE == hr) ExitFunction(); + + // add message queue permissions + hr = MqiAddMessageQueuePermissions(&pwzData); + ExitOnFailure(hr, "Failed to add message queue permissions"); + if (S_FALSE == hr) ExitFunction(); + + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzCustomActionData); + + // uninitialize + MqiExecUninitialize(); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +/******************************************************************** + MessageQueuingRollbackInstall - CUSTOM ACTION ENTRY POINT + + Input: deferred CustomActionData - MessageQueuingRollbackInstall +********************************************************************/ +extern "C" UINT __stdcall MessageQueuingRollbackInstall(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzCustomActionData = NULL; + LPWSTR pwzData = NULL; + + // initialize + hr = WcaInitialize(hInstall, "MessageQueuingRollbackInstall"); + ExitOnFailure(hr, "Failed to initialize MessageQueuingRollbackInstall"); + + hr = MqiExecInitialize(); + ExitOnFailure(hr, "Failed to initialize"); + + // get custom action data + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); + ExitOnFailure(hr, "Failed to get CustomActionData"); + pwzData = pwzCustomActionData; + + // add message queue permissions + hr = MqiRollbackAddMessageQueuePermissions(&pwzData); + ExitOnFailure(hr, "Failed to rollback add message queue permissions"); + + // create message queues + hr = MqiRollbackCreateMessageQueues(&pwzData); + ExitOnFailure(hr, "Failed to rollback create message queues"); + + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzCustomActionData); + + // uninitialize + MqiExecUninitialize(); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +/******************************************************************** + MessageQueuingExecuteUninstall - CUSTOM ACTION ENTRY POINT + + Input: deferred CustomActionData - MessageQueuingExecuteUninstall +********************************************************************/ +extern "C" UINT __stdcall MessageQueuingExecuteUninstall(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzCustomActionData = NULL; + LPWSTR pwzData = NULL; + + // initialize + hr = WcaInitialize(hInstall, "MessageQueuingExecuteUninstall"); + ExitOnFailure(hr, "Failed to initialize MessageQueuingExecuteUninstall"); + + hr = MqiExecInitialize(); + ExitOnFailure(hr, "Failed to initialize"); + + // get custom action data + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); + ExitOnFailure(hr, "Failed to get CustomActionData"); + pwzData = pwzCustomActionData; + + // remove message queue permissions + hr = MqiRemoveMessageQueuePermissions(&pwzData); + ExitOnFailure(hr, "Failed to remove message queue permissions"); + if (S_FALSE == hr) ExitFunction(); + + // delete message queues + hr = MqiDeleteMessageQueues(&pwzData); + ExitOnFailure(hr, "Failed to delete message queues"); + if (S_FALSE == hr) ExitFunction(); + + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzCustomActionData); + + // uninitialize + MqiExecUninitialize(); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +/******************************************************************** + MessageQueuingRollbackUninstall - CUSTOM ACTION ENTRY POINT + + Input: deferred CustomActionData - MessageQueuingRollbackUninstall +********************************************************************/ +extern "C" UINT __stdcall MessageQueuingRollbackUninstall(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzCustomActionData = NULL; + LPWSTR pwzData = NULL; + + // initialize + hr = WcaInitialize(hInstall, "MessageQueuingRollbackUninstall"); + ExitOnFailure(hr, "Failed to initialize MessageQueuingRollbackUninstall"); + + hr = MqiExecInitialize(); + ExitOnFailure(hr, "Failed to initialize"); + + // get custom action data + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); + ExitOnFailure(hr, "Failed to get CustomActionData"); + pwzData = pwzCustomActionData; + + // delete message queues + hr = MqiRollbackDeleteMessageQueues(&pwzData); + ExitOnFailure(hr, "Failed to delete message queues"); + + // remove message queue permissions + hr = MqiRollbackRemoveMessageQueuePermissions(&pwzData); + ExitOnFailure(hr, "Failed to remove message queue permissions"); + + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzCustomActionData); + + // uninitialize + MqiExecUninitialize(); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} diff --git a/src/ext/Msmq/ca/mqqueueexec.cpp b/src/ext/Msmq/ca/mqqueueexec.cpp new file mode 100644 index 00000000..e4304ab8 --- /dev/null +++ b/src/ext/Msmq/ca/mqqueueexec.cpp @@ -0,0 +1,927 @@ +// 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. + +#include "precomp.h" + + +// private typedefs + +typedef HRESULT (__stdcall *MQCreateQueueFunc)(PSECURITY_DESCRIPTOR, MQQUEUEPROPS*, LPWSTR, LPDWORD); +typedef HRESULT (__stdcall *MQDeleteQueueFunc)(LPCWSTR); +typedef HRESULT (__stdcall *MQPathNameToFormatNameFunc)(LPCWSTR, LPWSTR, LPDWORD); +typedef HRESULT (__stdcall *MQGetQueueSecurityFunc)(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD); +typedef HRESULT (__stdcall *MQSetQueueSecurityFunc)(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); + + +// private enums + +enum eMessageQueueAttributes +{ + mqaAuthenticate = (1 << 0), + mqaJournal = (1 << 1), + mqaTransactional = (1 << 2) +}; + +enum eMessageQueuePrivacyLevel +{ + mqplNone = 0, + mqplOptional = 1, + mqplBody = 2 +}; + +enum eMessageQueuePermission +{ + mqpDeleteMessage = (1 << 0), + mqpPeekMessage = (1 << 1), + mqpWriteMessage = (1 << 2), + mqpDeleteJournalMessage = (1 << 3), + mqpSetQueueProperties = (1 << 4), + mqpGetQueueProperties = (1 << 5), + mqpDeleteQueue = (1 << 6), + mqpGetQueuePermissions = (1 << 7), + mqpChangeQueuePermissions = (1 << 8), + mqpTakeQueueOwnership = (1 << 9), + mqpReceiveMessage = (1 << 10), + mqpReceiveJournalMessage = (1 << 11), + mqpQueueGenericRead = (1 << 12), + mqpQueueGenericWrite = (1 << 13), + mqpQueueGenericExecute = (1 << 14), + mqpQueueGenericAll = (1 << 15) +}; + + +// private structs + +struct MQI_MESSAGE_QUEUE_ATTRIBUTES +{ + LPWSTR pwzKey; + int iBasePriority; + int iJournalQuota; + LPWSTR pwzLabel; + LPWSTR pwzMulticastAddress; + LPWSTR pwzPathName; + int iPrivLevel; + int iQuota; + LPWSTR pwzServiceTypeGuid; + int iAttributes; +}; + +struct MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES +{ + LPWSTR pwzKey; + LPWSTR pwzPathName; + LPWSTR pwzDomain; + LPWSTR pwzName; + int iPermissions; +}; + + +// prototypes for private helper functions + +static HRESULT ReadMessageQueueAttributes( + LPWSTR* ppwzData, + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ); +static void FreeMessageQueueAttributes( + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ); +static HRESULT ReadMessageQueuePermissionAttributes( + LPWSTR* ppwzData, + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs + ); +static void FreeMessageQueuePermissionAttributes( + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs + ); +static HRESULT CreateMessageQueue( + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ); +static HRESULT DeleteMessageQueue( + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ); +static HRESULT SetMessageQueuePermissions( + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs, + BOOL fRevoke + ); +static void SetAccessPermissions( + int iPermissions, + LPDWORD pgrfAccessPermissions + ); + + +// private variables + +static HMODULE ghMQRT; +static MQCreateQueueFunc gpfnMQCreateQueue; +static MQDeleteQueueFunc gpfnMQDeleteQueue; +static MQPathNameToFormatNameFunc gpfnMQPathNameToFormatName; +static MQGetQueueSecurityFunc gpfnMQGetQueueSecurity; +static MQSetQueueSecurityFunc gpfnMQSetQueueSecurity; + + +// function definitions + +HRESULT MqiExecInitialize() +{ + HRESULT hr = S_OK; + + // load mqrt.dll + ghMQRT = ::LoadLibraryW(L"mqrt.dll"); + ExitOnNull(ghMQRT, hr, E_FAIL, "Failed to load mqrt.dll"); + + // get MQCreateQueue function address + gpfnMQCreateQueue = (MQCreateQueueFunc)::GetProcAddress(ghMQRT, "MQCreateQueue"); + ExitOnNull(gpfnMQCreateQueue, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQCreateQueue() function"); + + // get MQDeleteQueue function address + gpfnMQDeleteQueue = (MQDeleteQueueFunc)::GetProcAddress(ghMQRT, "MQDeleteQueue"); + ExitOnNull(gpfnMQDeleteQueue, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQDeleteQueue() function"); + + // get MQPathNameToFormatName function address + gpfnMQPathNameToFormatName = (MQPathNameToFormatNameFunc)::GetProcAddress(ghMQRT, "MQPathNameToFormatName"); + ExitOnNull(gpfnMQPathNameToFormatName, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQPathNameToFormatName() function"); + + // get MQGetQueueSecurity function address + gpfnMQGetQueueSecurity = (MQGetQueueSecurityFunc)::GetProcAddress(ghMQRT, "MQGetQueueSecurity"); + ExitOnNull(gpfnMQGetQueueSecurity, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQGetQueueSecurity() function"); + + // get MQSetQueueSecurity function address + gpfnMQSetQueueSecurity = (MQSetQueueSecurityFunc)::GetProcAddress(ghMQRT, "MQSetQueueSecurity"); + ExitOnNull(gpfnMQSetQueueSecurity, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for MQSetQueueSecurity() function"); + + hr = S_OK; + +LExit: + return hr; +} + +void MqiExecUninitialize() +{ + if (ghMQRT) + ::FreeLibrary(ghMQRT); +} + +HRESULT MqiCreateMessageQueues( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueueAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // progress message + hr = PcaActionDataMessage(1, attrs.pwzPathName); + ExitOnFailure(hr, "Failed to send progress messages, key: %S", attrs.pwzKey); + + // create message queue + hr = CreateMessageQueue(&attrs); + ExitOnFailure(hr, "Failed to create message queue, key: %S", attrs.pwzKey); + + // progress tics + hr = WcaProgressMessage(COST_MESSAGE_QUEUE_CREATE, FALSE); + ExitOnFailure(hr, "Failed to update progress"); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueueAttributes(&attrs); + + return hr; +} + +HRESULT MqiRollbackCreateMessageQueues( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueueAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // create message queue + hr = DeleteMessageQueue(&attrs); + if (FAILED(hr)) + WcaLog(LOGMSG_STANDARD, "Failed to delete message queue, hr: 0x%x, key: %S", hr, attrs.pwzKey); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueueAttributes(&attrs); + + return hr; +} + +HRESULT MqiDeleteMessageQueues( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueueAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // progress message + hr = PcaActionDataMessage(1, attrs.pwzPathName); + ExitOnFailure(hr, "Failed to send progress messages, key: %S", attrs.pwzKey); + + // create message queue + hr = DeleteMessageQueue(&attrs); + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "Failed to delete queue, hr: 0x%x, key: %S", hr, attrs.pwzKey); + continue; + } + + // progress tics + hr = WcaProgressMessage(COST_MESSAGE_QUEUE_DELETE, FALSE); + ExitOnFailure(hr, "Failed to update progress"); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueueAttributes(&attrs); + + return hr; +} + +HRESULT MqiRollbackDeleteMessageQueues( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueueAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // create message queue + hr = CreateMessageQueue(&attrs); + if (FAILED(hr)) + WcaLog(LOGMSG_STANDARD, "Failed to create message queue, hr: 0x%x, key: %S", hr, attrs.pwzKey); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueueAttributes(&attrs); + + return hr; +} + +HRESULT MqiAddMessageQueuePermissions( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // progress message + hr = PcaActionDataMessage(1, attrs.pwzPathName); + ExitOnFailure(hr, "Failed to send progress messages"); + + // add message queue permission + hr = SetMessageQueuePermissions(&attrs, FALSE); + ExitOnFailure(hr, "Failed to add message queue permission"); + + // progress tics + hr = WcaProgressMessage(COST_MESSAGE_QUEUE_PERMISSION_ADD, FALSE); + ExitOnFailure(hr, "Failed to update progress"); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueuePermissionAttributes(&attrs); + + return hr; +} + +HRESULT MqiRollbackAddMessageQueuePermissions( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // add message queue permission + hr = SetMessageQueuePermissions(&attrs, TRUE); + if (FAILED(hr)) + WcaLog(LOGMSG_STANDARD, "Failed to rollback add message queue permission, hr: 0x%x, key: %S", hr, attrs.pwzKey); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueuePermissionAttributes(&attrs); + + return hr; +} + +HRESULT MqiRemoveMessageQueuePermissions( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // progress message + hr = PcaActionDataMessage(1, attrs.pwzPathName); + ExitOnFailure(hr, "Failed to send progress messages"); + + // add message queue permission + hr = SetMessageQueuePermissions(&attrs, TRUE); + ExitOnFailure(hr, "Failed to remove message queue permission"); + + // progress tics + hr = WcaProgressMessage(COST_MESSAGE_QUEUE_PERMISSION_ADD, FALSE); + ExitOnFailure(hr, "Failed to update progress"); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueuePermissionAttributes(&attrs); + + return hr; +} + +HRESULT MqiRollbackRemoveMessageQueuePermissions( + LPWSTR* ppwzData + ) +{ + HRESULT hr = S_OK; + + int iCnt = 0; + + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES attrs; + ::ZeroMemory(&attrs, sizeof(attrs)); + + // ger count + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt); + ExitOnFailure(hr, "Failed to read count"); + + for (int i = 0; i < iCnt; i++) + { + // read attributes from CustomActionData + hr = ReadMessageQueuePermissionAttributes(ppwzData, &attrs); + ExitOnFailure(hr, "Failed to read attributes"); + + // add message queue permission + hr = SetMessageQueuePermissions(&attrs, FALSE); + if (FAILED(hr)) + WcaLog(LOGMSG_STANDARD, "Failed to rollback remove message queue permission, hr: 0x%x, key: %S", hr, attrs.pwzKey); + } + + hr = S_OK; + +LExit: + // clean up + FreeMessageQueuePermissionAttributes(&attrs); + + return hr; +} + + +// helper function definitions + +static HRESULT ReadMessageQueueAttributes( + LPWSTR* ppwzData, + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + // read message queue information from custom action data + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey); + ExitOnFailure(hr, "Failed to read key from custom action data"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iBasePriority); + ExitOnFailure(hr, "Failed to read base priority from custom action data"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iJournalQuota); + ExitOnFailure(hr, "Failed to read journal quota from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzLabel); + ExitOnFailure(hr, "Failed to read label from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzMulticastAddress); + ExitOnFailure(hr, "Failed to read multicast address from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPathName); + ExitOnFailure(hr, "Failed to read path name from custom action data"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iPrivLevel); + ExitOnFailure(hr, "Failed to read privacy level from custom action data"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iQuota); + ExitOnFailure(hr, "Failed to read quota from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzServiceTypeGuid); + ExitOnFailure(hr, "Failed to read service type guid from custom action data"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iAttributes); + ExitOnFailure(hr, "Failed to read attributes from custom action data"); + + hr = S_OK; + +LExit: + return hr; +} + +static void FreeMessageQueueAttributes( + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ) +{ + ReleaseStr(pAttrs->pwzKey); + ReleaseStr(pAttrs->pwzLabel); + ReleaseStr(pAttrs->pwzMulticastAddress); + ReleaseStr(pAttrs->pwzPathName); + ReleaseStr(pAttrs->pwzServiceTypeGuid); +} + +static HRESULT ReadMessageQueuePermissionAttributes( + LPWSTR* ppwzData, + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + // read message queue permission information from custom action data + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey); + ExitOnFailure(hr, "Failed to read key from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPathName); + ExitOnFailure(hr, "Failed to read path name from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzDomain); + ExitOnFailure(hr, "Failed to read domain from custom action data"); + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName); + ExitOnFailure(hr, "Failed to read name from custom action data"); + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iPermissions); + ExitOnFailure(hr, "Failed to read permissions from custom action data"); + + hr = S_OK; + +LExit: + return hr; +} + +static void FreeMessageQueuePermissionAttributes( + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs + ) +{ + ReleaseStr(pAttrs->pwzKey); + ReleaseStr(pAttrs->pwzPathName); + ReleaseStr(pAttrs->pwzDomain); + ReleaseStr(pAttrs->pwzName); +} + +static HRESULT CreateMessageQueue( + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + SECURITY_DESCRIPTOR sd; + PSID pOwner = NULL; + DWORD cbDacl = 0; + PACL pDacl = NULL; + QUEUEPROPID aPropID[11]; + MQPROPVARIANT aPropVar[11]; + MQQUEUEPROPS props; + + GUID guidType; + + DWORD dwFormatNameLength = 0; + + ::ZeroMemory(&sd, sizeof(sd)); + ::ZeroMemory(aPropID, sizeof(aPropID)); + ::ZeroMemory(aPropVar, sizeof(aPropVar)); + ::ZeroMemory(&props, sizeof(props)); + ::ZeroMemory(&guidType, sizeof(guidType)); + + // initialize security descriptor + if (!::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize security descriptor"); + + // set security descriptor owner + hr = PcaAccountNameToSid(L"\\Administrators", &pOwner); + ExitOnFailure(hr, "Failed to get sid for account name"); + + if (!::SetSecurityDescriptorOwner(&sd, pOwner, FALSE)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set security descriptor owner"); + + // set security descriptor DACL + cbDacl = sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + ::GetLengthSid(pOwner); + pDacl = (PACL)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, cbDacl); + ExitOnNull(pDacl, hr, E_OUTOFMEMORY, "Failed to allocate buffer for DACL"); + + if (!::InitializeAcl(pDacl, cbDacl, ACL_REVISION)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize DACL"); + + if (!::AddAccessAllowedAce(pDacl, ACL_REVISION, MQSEC_QUEUE_GENERIC_ALL, pOwner)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to add ACE to DACL"); + + if (!::SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set security descriptor DACL"); + + // set property values + props.aPropID = aPropID; + props.aPropVar = aPropVar; + + aPropID[0] = PROPID_Q_LABEL; + aPropVar[0].vt = VT_LPWSTR; + aPropVar[0].pwszVal = pAttrs->pwzLabel; + + aPropID[1] = PROPID_Q_PATHNAME; + aPropVar[1].vt = VT_LPWSTR; + aPropVar[1].pwszVal = pAttrs->pwzPathName; + + aPropID[2] = PROPID_Q_AUTHENTICATE; + aPropVar[2].vt = VT_UI1; + aPropVar[2].bVal = mqaAuthenticate == (pAttrs->iAttributes & mqaAuthenticate); + + aPropID[3] = PROPID_Q_JOURNAL; + aPropVar[3].vt = VT_UI1; + aPropVar[3].bVal = mqaJournal == (pAttrs->iAttributes & mqaJournal); + + aPropID[4] = PROPID_Q_TRANSACTION; + aPropVar[4].vt = VT_UI1; + aPropVar[4].bVal = mqaTransactional == (pAttrs->iAttributes & mqaTransactional); + + props.cProp = 5; + + if (MSI_NULL_INTEGER != pAttrs->iBasePriority) + { + aPropID[props.cProp] = PROPID_Q_BASEPRIORITY; + aPropVar[props.cProp].vt = VT_I2; + aPropVar[props.cProp].iVal = (SHORT)pAttrs->iBasePriority; + props.cProp++; + } + + if (MSI_NULL_INTEGER != pAttrs->iJournalQuota) + { + aPropID[props.cProp] = PROPID_Q_JOURNAL_QUOTA; + aPropVar[props.cProp].vt = VT_UI4; + aPropVar[props.cProp].ulVal = (ULONG)pAttrs->iJournalQuota; + props.cProp++; + } + + if (*pAttrs->pwzMulticastAddress) + { + aPropID[props.cProp] = PROPID_Q_MULTICAST_ADDRESS; + aPropVar[props.cProp].vt = VT_LPWSTR; + aPropVar[props.cProp].pwszVal = pAttrs->pwzMulticastAddress; + props.cProp++; + } + + if (MSI_NULL_INTEGER != pAttrs->iPrivLevel) + { + aPropID[props.cProp] = PROPID_Q_PRIV_LEVEL; + aPropVar[props.cProp].vt = VT_UI4; + switch (pAttrs->iPrivLevel) + { + case mqplNone: + aPropVar[props.cProp].ulVal = MQ_PRIV_LEVEL_NONE; + break; + case mqplBody: + aPropVar[props.cProp].ulVal = MQ_PRIV_LEVEL_BODY; + break; + case mqplOptional: + aPropVar[props.cProp].ulVal = MQ_PRIV_LEVEL_OPTIONAL; + break; + } + props.cProp++; + } + + if (MSI_NULL_INTEGER != pAttrs->iQuota) + { + aPropID[props.cProp] = PROPID_Q_QUOTA; + aPropVar[props.cProp].vt = VT_UI4; + aPropVar[props.cProp].ulVal = (ULONG)pAttrs->iQuota; + props.cProp++; + } + + if (*pAttrs->pwzServiceTypeGuid) + { + // parse guid string + hr = PcaGuidFromString(pAttrs->pwzServiceTypeGuid, &guidType); + ExitOnFailure(hr, "Failed to parse service type GUID string"); + + aPropID[props.cProp] = PROPID_Q_TYPE; + aPropVar[props.cProp].vt = VT_CLSID; + aPropVar[props.cProp].puuid = &guidType; + props.cProp++; + } + + // create message queue + hr = gpfnMQCreateQueue(&sd, &props, NULL, &dwFormatNameLength); + ExitOnFailure(hr, "Failed to create message queue"); + + // log + WcaLog(LOGMSG_VERBOSE, "Message queue created, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); + + hr = S_OK; + +LExit: + // clean up + if (pOwner) + ::HeapFree(::GetProcessHeap(), 0, pOwner); + if (pDacl) + ::HeapFree(::GetProcessHeap(), 0, pDacl); + + return hr; +} + +static HRESULT DeleteMessageQueue( + MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs + ) +{ + HRESULT hr = S_OK; + + LPWSTR pwzFormatName = NULL; + DWORD dwCount = 128; + + // get format name + hr = StrAlloc(&pwzFormatName, dwCount); + ExitOnFailure(hr, "Failed to allocate format name string"); + do { + hr = gpfnMQPathNameToFormatName(pAttrs->pwzPathName, pwzFormatName, &dwCount); + switch (hr) + { + case MQ_ERROR_QUEUE_NOT_FOUND: + ExitFunction1(hr = S_OK); // nothing to delete + case MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL: + hr = StrAlloc(&pwzFormatName, dwCount); + ExitOnFailure(hr, "Failed to reallocate format name string"); + hr = S_FALSE; // retry + break; + default: + ExitOnFailure(hr, "Failed to get format name"); + hr = S_OK; + } + } while (S_FALSE == hr); + + // delete queue + hr = gpfnMQDeleteQueue(pwzFormatName); + ExitOnFailure(hr, "Failed to delete queue"); + + // log + WcaLog(LOGMSG_VERBOSE, "Message queue deleted, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); + + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzFormatName); + + return hr; +} + +static HRESULT SetMessageQueuePermissions( + MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs, + BOOL fRevoke + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + + DWORD dw = 0; + + LPWSTR pwzAccount = NULL; + LPWSTR pwzFormatName = NULL; + + PSECURITY_DESCRIPTOR psd = NULL; + PSECURITY_DESCRIPTOR ptsd = NULL; + + PACL pAclExisting = NULL; + PACL pAclNew = NULL; + BOOL fDaclPresent = FALSE; + BOOL fDaclDefaulted = FALSE; + + PSID psid = NULL; + + EXPLICIT_ACCESSW ea; + SECURITY_DESCRIPTOR sdNew; + + ::ZeroMemory(&ea, sizeof(ea)); + ::ZeroMemory(&sdNew, sizeof(sdNew)); + + // get format name + dw = 128; + hr = StrAlloc(&pwzFormatName, dw); + ExitOnFailure(hr, "Failed to allocate format name string"); + do { + hr = gpfnMQPathNameToFormatName(pAttrs->pwzPathName, pwzFormatName, &dw); + if (MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL == hr) + { + hr = StrAlloc(&pwzFormatName, dw); + ExitOnFailure(hr, "Failed to reallocate format name string"); + hr = S_FALSE; // retry + } + else + { + ExitOnFailure(hr, "Failed to get format name"); + hr = S_OK; + } + } while (S_FALSE == hr); + + // get queue security information + dw = 256; + psd = (PSECURITY_DESCRIPTOR)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dw); + ExitOnNull(psd, hr, E_OUTOFMEMORY, "Failed to allocate buffer for security descriptor"); + do { + hr = gpfnMQGetQueueSecurity(pwzFormatName, DACL_SECURITY_INFORMATION, psd, dw, &dw); + if (MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL == hr) + { + ptsd = (PSECURITY_DESCRIPTOR)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, psd, dw); + ExitOnNull(ptsd, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for security descriptor"); + psd = ptsd; + hr = S_FALSE; // retry + } + else + { + ExitOnFailure(hr, "Failed to get queue security information"); + hr = S_OK; + } + } while (S_FALSE == hr); + + // get dacl + if (!::GetSecurityDescriptorDacl(psd, &fDaclPresent, &pAclExisting, &fDaclDefaulted)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get DACL for security descriptor"); + if (!fDaclPresent || !pAclExisting) + ExitOnFailure(hr = E_ACCESSDENIED, "Failed to get DACL for security descriptor, access denied"); + + // build account name string + hr = PcaBuildAccountName(pAttrs->pwzDomain, pAttrs->pwzName, &pwzAccount); + ExitOnFailure(hr, "Failed to build account name string"); + + // get sid for account name + hr = PcaAccountNameToSid(pwzAccount, &psid); + ExitOnFailure(hr, "Failed to get SID for account name"); + + // set acl entry + SetAccessPermissions(pAttrs->iPermissions, &ea.grfAccessPermissions); + ea.grfAccessMode = fRevoke ? REVOKE_ACCESS : SET_ACCESS; + ea.grfInheritance = NO_INHERITANCE; + ::BuildTrusteeWithSidW(&ea.Trustee, psid); + + er = ::SetEntriesInAclW(1, &ea, pAclExisting, &pAclNew); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set ACL entry"); + + // create new security descriptor + if (!::InitializeSecurityDescriptor(&sdNew, SECURITY_DESCRIPTOR_REVISION)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize security descriptor"); + + if (!::SetSecurityDescriptorDacl(&sdNew, TRUE, pAclNew, FALSE)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set DACL for security descriptor"); + + // set queue security information + hr = gpfnMQSetQueueSecurity(pwzFormatName, DACL_SECURITY_INFORMATION, &sdNew); + ExitOnFailure(hr, "Failed to set queue security information"); + + // log + WcaLog(LOGMSG_VERBOSE, "Permission set for message queue, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); + + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzFormatName); + ReleaseStr(pwzAccount); + + if (psd) + ::HeapFree(::GetProcessHeap(), 0, psd); + if (psid) + ::HeapFree(::GetProcessHeap(), 0, psid); + if (pAclNew) + ::LocalFree(pAclNew); + + return hr; +} + +static void SetAccessPermissions( + int iPermissions, + LPDWORD pgrfAccessPermissions + ) +{ + if (iPermissions & mqpDeleteMessage) + *pgrfAccessPermissions |= MQSEC_DELETE_MESSAGE; + if (iPermissions & mqpPeekMessage) + *pgrfAccessPermissions |= MQSEC_PEEK_MESSAGE; + if (iPermissions & mqpWriteMessage) + *pgrfAccessPermissions |= MQSEC_WRITE_MESSAGE; + if (iPermissions & mqpDeleteJournalMessage) + *pgrfAccessPermissions |= MQSEC_DELETE_JOURNAL_MESSAGE; + if (iPermissions & mqpSetQueueProperties) + *pgrfAccessPermissions |= MQSEC_SET_QUEUE_PROPERTIES; + if (iPermissions & mqpGetQueueProperties) + *pgrfAccessPermissions |= MQSEC_GET_QUEUE_PROPERTIES; + if (iPermissions & mqpDeleteQueue) + *pgrfAccessPermissions |= MQSEC_DELETE_QUEUE; + if (iPermissions & mqpGetQueuePermissions) + *pgrfAccessPermissions |= MQSEC_GET_QUEUE_PERMISSIONS; + if (iPermissions & mqpChangeQueuePermissions) + *pgrfAccessPermissions |= MQSEC_CHANGE_QUEUE_PERMISSIONS; + if (iPermissions & mqpTakeQueueOwnership) + *pgrfAccessPermissions |= MQSEC_TAKE_QUEUE_OWNERSHIP; + if (iPermissions & mqpReceiveMessage) + *pgrfAccessPermissions |= MQSEC_RECEIVE_MESSAGE; + if (iPermissions & mqpReceiveJournalMessage) + *pgrfAccessPermissions |= MQSEC_RECEIVE_JOURNAL_MESSAGE; + if (iPermissions & mqpQueueGenericRead) + *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_READ; + if (iPermissions & mqpQueueGenericWrite) + *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_WRITE; + if (iPermissions & mqpQueueGenericExecute) + *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_EXECUTE; + if (iPermissions & mqpQueueGenericAll) + *pgrfAccessPermissions |= MQSEC_QUEUE_GENERIC_ALL; +} diff --git a/src/ext/Msmq/ca/mqqueueexec.h b/src/ext/Msmq/ca/mqqueueexec.h new file mode 100644 index 00000000..76bc2023 --- /dev/null +++ b/src/ext/Msmq/ca/mqqueueexec.h @@ -0,0 +1,30 @@ +#pragma once +// 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. + + +HRESULT MqiExecInitialize(); +void MqiExecUninitialize(); +HRESULT MqiCreateMessageQueues( + LPWSTR* ppwzData + ); +HRESULT MqiRollbackCreateMessageQueues( + LPWSTR* ppwzData + ); +HRESULT MqiDeleteMessageQueues( + LPWSTR* ppwzData + ); +HRESULT MqiRollbackDeleteMessageQueues( + LPWSTR* ppwzData + ); +HRESULT MqiAddMessageQueuePermissions( + LPWSTR* ppwzData + ); +HRESULT MqiRollbackAddMessageQueuePermissions( + LPWSTR* ppwzData + ); +HRESULT MqiRemoveMessageQueuePermissions( + LPWSTR* ppwzData + ); +HRESULT MqiRollbackRemoveMessageQueuePermissions( + LPWSTR* ppwzData + ); diff --git a/src/ext/Msmq/ca/mqqueuesched.cpp b/src/ext/Msmq/ca/mqqueuesched.cpp new file mode 100644 index 00000000..01777ea4 --- /dev/null +++ b/src/ext/Msmq/ca/mqqueuesched.cpp @@ -0,0 +1,582 @@ +// 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. + +#include "precomp.h" + + +// sql queries + +LPCWSTR vcsMessageQueueQuery = + L"SELECT `MessageQueue`, `Component_`, `BasePriority`, `JournalQuota`, `Label`, `MulticastAddress`, `PathName`, `PrivLevel`, `Quota`, `ServiceTypeGuid`, `Attributes` FROM `MessageQueue`"; +enum eMessageQueueQuery { mqqMessageQueue = 1, mqqComponent, mqqBasePriority, mqqJournalQuota, mqqLabel, mqqMulticastAddress, mqqPathName, mqqPrivLevel, mqqQuota, mqqServiceTypeGuid, mqqAttributes }; + +LPCWSTR vcsMessageQueueUserPermissionQuery = + L"SELECT `MessageQueueUserPermission`, `MessageQueue_`, `MessageQueueUserPermission`.`Component_`, `Domain`, `Name`, `Permissions` FROM `MessageQueueUserPermission`, `User` WHERE `User_` = `User`"; +LPCWSTR vcsMessageQueueGroupPermissionQuery = + L"SELECT `MessageQueueGroupPermission`, `MessageQueue_`, `MessageQueueGroupPermission`.`Component_`, `Domain`, `Name`, `Permissions` FROM `MessageQueueGroupPermission`, `Group` WHERE `Group_` = `Group`"; +enum eMessageQueuePermissionQuery { mqpqMessageQueuePermission = 1, mqpqMessageQueue, mqpqComponent, mqpqDomain, mqpqName, mqpqPermissions }; + + +// prototypes for private helper functions + +static HRESULT MqiMessageQueueFindByKey( + MQI_MESSAGE_QUEUE_LIST* pList, + LPCWSTR pwzKey, + MQI_MESSAGE_QUEUE** ppItm + ); +static HRESULT AddMessageQueueToActionData( + MQI_MESSAGE_QUEUE* pItm, + LPWSTR* ppwzActionData + ); +static HRESULT MessageQueueTrusteePermissionsRead( + LPCWSTR pwzQuery, + MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList + ); +static HRESULT AddMessageQueuePermissionToActionData( + MQI_MESSAGE_QUEUE_PERMISSION* pItm, + LPWSTR* ppwzActionData + ); + + +// private typedefs + +typedef HRESULT (__stdcall *MQPathNameToFormatNameFunc)(LPCWSTR, LPWSTR, LPDWORD); + + +// private variables + +static HMODULE ghMQRT; +static MQPathNameToFormatNameFunc gpfnMQPathNameToFormatName; + + +// function definitions + +HRESULT MqiSchedInitialize() +{ + HRESULT hr = S_OK; + + // load mqrt.dll + ghMQRT = ::LoadLibraryW(L"mqrt.dll"); + if (!ghMQRT) + { + ExitFunction1(hr = S_FALSE); + } + + // get MQPathNameToFormatName function address + gpfnMQPathNameToFormatName = (MQPathNameToFormatNameFunc)::GetProcAddress(ghMQRT, "MQPathNameToFormatName"); + ExitOnNullWithLastError(gpfnMQPathNameToFormatName, hr, "Failed get address for MQPathNameToFormatName() function"); + + hr = S_OK; + +LExit: + return hr; +} + +void MqiSchedUninitialize() +{ + if (ghMQRT) + { + ::FreeLibrary(ghMQRT); + } +} + +HRESULT MqiMessageQueueRead( + MQI_MESSAGE_QUEUE_LIST* pList + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + PMSIHANDLE hView, hRec; + + MQI_MESSAGE_QUEUE* pItm = NULL; + LPWSTR pwzData = NULL; + + // loop through all partitions + hr = WcaOpenExecuteView(vcsMessageQueueQuery, &hView); + ExitOnFailure(hr, "Failed to execute view on MessageQueue table"); + + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + // create entry + pItm = (MQI_MESSAGE_QUEUE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MQI_MESSAGE_QUEUE)); + if (!pItm) + ExitFunction1(hr = E_OUTOFMEMORY); + + // get key + hr = WcaGetRecordString(hRec, mqqMessageQueue, &pwzData); + ExitOnFailure(hr, "Failed to get key"); + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); + + // get component install state + hr = WcaGetRecordString(hRec, mqqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get component"); + + // get component install state + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); + + // get base priority + hr = WcaGetRecordInteger(hRec, mqqBasePriority, &pItm->iBasePriority); + ExitOnFailure(hr, "Failed to get base priority"); + + // get journal quota + hr = WcaGetRecordInteger(hRec, mqqJournalQuota, &pItm->iJournalQuota); + ExitOnFailure(hr, "Failed to get journal quota"); + + // get label + hr = WcaGetRecordFormattedString(hRec, mqqLabel, &pwzData); + ExitOnFailure(hr, "Failed to get label"); + StringCchCopyW(pItm->wzLabel, countof(pItm->wzLabel), pwzData); + + // get multicast address + hr = WcaGetRecordFormattedString(hRec, mqqMulticastAddress, &pwzData); + ExitOnFailure(hr, "Failed to get multicast address"); + StringCchCopyW(pItm->wzMulticastAddress, countof(pItm->wzMulticastAddress), pwzData); + + // get path name + hr = WcaGetRecordFormattedString(hRec, mqqPathName, &pwzData); + ExitOnFailure(hr, "Failed to get path name"); + StringCchCopyW(pItm->wzPathName, countof(pItm->wzPathName), pwzData); + + // get privacy level + hr = WcaGetRecordInteger(hRec, mqqPrivLevel, &pItm->iPrivLevel); + ExitOnFailure(hr, "Failed to get privacy level"); + + // get quota + hr = WcaGetRecordInteger(hRec, mqqQuota, &pItm->iQuota); + ExitOnFailure(hr, "Failed to get quota"); + + // get service type guid + hr = WcaGetRecordFormattedString(hRec, mqqServiceTypeGuid, &pwzData); + ExitOnFailure(hr, "Failed to get service type guid"); + StringCchCopyW(pItm->wzServiceTypeGuid, countof(pItm->wzServiceTypeGuid), pwzData); + + // get attributes + hr = WcaGetRecordInteger(hRec, mqqAttributes, &pItm->iAttributes); + ExitOnFailure(hr, "Failed to get attributes"); + + // increment counters + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) + pList->iInstallCount++; + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) + pList->iUninstallCount++; + + // add entry + pItm->pNext = pList->pFirst; + pList->pFirst = pItm; + pItm = NULL; + } + + if (E_NOMOREITEMS == hr) + hr = S_OK; + +LExit: + // clean up + if (pItm) + ::HeapFree(::GetProcessHeap(), 0, pItm); + + ReleaseStr(pwzData); + + return hr; +} + +HRESULT MqiMessageQueueVerify( + MQI_MESSAGE_QUEUE_LIST* pList + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzFormatName = NULL; + DWORD dwCount = 128; + + for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) + { + // queues that are being installed only + if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) + continue; + + // get format name + hr = StrAlloc(&pwzFormatName, dwCount); + ExitOnFailure(hr, "Failed to allocate format name string"); + do { + hr = gpfnMQPathNameToFormatName(pItm->wzPathName, pwzFormatName, &dwCount); + switch (hr) + { + case MQ_ERROR_QUEUE_NOT_FOUND: + break; // break + case MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL: + hr = StrAlloc(&pwzFormatName, dwCount); + ExitOnFailure(hr, "Failed to reallocate format name string"); + hr = S_FALSE; // retry + break; + default: + ExitOnFailure(hr, "Failed to get format name"); + hr = S_OK; + } + } while (S_FALSE == hr); + + if (MQ_ERROR_QUEUE_NOT_FOUND == hr) + { + continue; + } + pItm->fExists = TRUE; + pList->iInstallCount--; + + // clean up + ReleaseNullStr(pwzFormatName); + } + + hr = S_OK; + +LExit: + ReleaseStr(pwzFormatName); + return hr; +} + +HRESULT MqiMessageQueueInstall( + MQI_MESSAGE_QUEUE_LIST* pList, + BOOL fRollback, + LPWSTR* ppwzActionData + ) +{ + HRESULT hr = S_OK; + + // add count to action data + hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData); + ExitOnFailure(hr, "Failed to add count to custom action data"); + + for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) + { + // queues that are being installed only + if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) + continue; + + // if the queue exists we should not try to create it + if (pItm->fExists && !fRollback) + { + continue; + } + + // add message queue to action data + hr = AddMessageQueueToActionData(pItm, ppwzActionData); + ExitOnFailure(hr, "Failed to add message queue to action data"); + } + + hr = S_OK; + +LExit: + return hr; +} + +HRESULT MqiMessageQueueUninstall( + MQI_MESSAGE_QUEUE_LIST* pList, + BOOL fRollback, + LPWSTR* ppwzActionData + ) +{ + HRESULT hr = S_OK; + + // add count to action data + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData); + ExitOnFailure(hr, "Failed to add count to custom action data"); + + for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) + { + // queues that are being uninstalled only + if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) + continue; + + // if we did not create the queue we should not try to delete it + if (pItm->fExists && fRollback) + { + continue; + } + + // add message queue to action data + hr = AddMessageQueueToActionData(pItm, ppwzActionData); + ExitOnFailure(hr, "Failed to add message queue to action data"); + } + + hr = S_OK; + +LExit: + return hr; +} + +void MqiMessageQueueFreeList( + MQI_MESSAGE_QUEUE_LIST* pList + ) +{ + MQI_MESSAGE_QUEUE* pItm = pList->pFirst; + while (pItm) + { + MQI_MESSAGE_QUEUE* pDelete = pItm; + pItm = pItm->pNext; + ::HeapFree(::GetProcessHeap(), 0, pDelete); + } +} + +HRESULT MqiMessageQueuePermissionRead( + MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList + ) +{ + HRESULT hr = S_OK; + + // read message queue user permissions + if (S_OK == WcaTableExists(L"MessageQueueUserPermission")) + { + hr = MessageQueueTrusteePermissionsRead(vcsMessageQueueUserPermissionQuery, pMessageQueueList, pList); + ExitOnFailure(hr, "Failed to read message queue user permissions"); + } + + // read message queue group permissions + if (S_OK == WcaTableExists(L"MessageQueueGroupPermission")) + { + hr = MessageQueueTrusteePermissionsRead(vcsMessageQueueGroupPermissionQuery, pMessageQueueList, pList); + ExitOnFailure(hr, "Failed to read message queue group permissions"); + } + + hr = S_OK; + +LExit: + return hr; +} + +HRESULT MqiMessageQueuePermissionInstall( + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, + LPWSTR* ppwzActionData + ) +{ + HRESULT hr = S_OK; + + // add count to action data + hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData); + ExitOnFailure(hr, "Failed to add count to custom action data"); + + for (MQI_MESSAGE_QUEUE_PERMISSION* pItm = pList->pFirst; pItm; pItm = pItm->pNext) + { + // queue permissions that are being installed only + if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) + continue; + + // add message queue permission to action data + hr = AddMessageQueuePermissionToActionData(pItm, ppwzActionData); + ExitOnFailure(hr, "Failed to add message queue permission to action data"); + } + + hr = S_OK; + +LExit: + return hr; +} + +HRESULT MqiMessageQueuePermissionUninstall( + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, + LPWSTR* ppwzActionData + ) +{ + HRESULT hr = S_OK; + + // add count to action data + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData); + ExitOnFailure(hr, "Failed to add count to custom action data"); + + for (MQI_MESSAGE_QUEUE_PERMISSION* pItm = pList->pFirst; pItm; pItm = pItm->pNext) + { + // queue permissions that are being uninstalled only + if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) + continue; + + // add message queue permission to action data + hr = AddMessageQueuePermissionToActionData(pItm, ppwzActionData); + ExitOnFailure(hr, "Failed to add message queue permission to action data"); + } + + hr = S_OK; + +LExit: + return hr; +} + +void MqiMessageQueuePermissionFreeList( + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList + ) +{ + MQI_MESSAGE_QUEUE_PERMISSION* pItm = pList->pFirst; + while (pItm) + { + MQI_MESSAGE_QUEUE_PERMISSION* pDelete = pItm; + pItm = pItm->pNext; + ::HeapFree(::GetProcessHeap(), 0, pDelete); + } +} + + +// helper function definitions + +static HRESULT MqiMessageQueueFindByKey( + MQI_MESSAGE_QUEUE_LIST* pList, + LPCWSTR pwzKey, + MQI_MESSAGE_QUEUE** ppItm + ) +{ + for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) + { + if (0 == lstrcmpW(pItm->wzKey, pwzKey)) + { + *ppItm = pItm; + return S_OK; + } + } + + return S_FALSE; +} + +static HRESULT AddMessageQueueToActionData( + MQI_MESSAGE_QUEUE* pItm, + LPWSTR* ppwzActionData + ) +{ + HRESULT hr = S_OK; + + // add message queue information to custom action data + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData); + ExitOnFailure(hr, "Failed to add key to custom action data"); + hr = WcaWriteIntegerToCaData(pItm->iBasePriority, ppwzActionData); + ExitOnFailure(hr, "Failed to add base priority to custom action data"); + hr = WcaWriteIntegerToCaData(pItm->iJournalQuota, ppwzActionData); + ExitOnFailure(hr, "Failed to add journal quota to custom action data"); + hr = WcaWriteStringToCaData(pItm->wzLabel, ppwzActionData); + ExitOnFailure(hr, "Failed to add label to custom action data"); + hr = WcaWriteStringToCaData(pItm->wzMulticastAddress, ppwzActionData); + ExitOnFailure(hr, "Failed to add multicast address to custom action data"); + hr = WcaWriteStringToCaData(pItm->wzPathName, ppwzActionData); + ExitOnFailure(hr, "Failed to add path name to custom action data"); + hr = WcaWriteIntegerToCaData(pItm->iPrivLevel, ppwzActionData); + ExitOnFailure(hr, "Failed to add privacy level to custom action data"); + hr = WcaWriteIntegerToCaData(pItm->iQuota, ppwzActionData); + ExitOnFailure(hr, "Failed to add quota to custom action data"); + hr = WcaWriteStringToCaData(pItm->wzServiceTypeGuid, ppwzActionData); + ExitOnFailure(hr, "Failed to add service type guid to custom action data"); + hr = WcaWriteIntegerToCaData(pItm->iAttributes, ppwzActionData); + ExitOnFailure(hr, "Failed to add attributes to custom action data"); + + hr = S_OK; + +LExit: + return hr; +} + +static HRESULT MessageQueueTrusteePermissionsRead( + LPCWSTR pwzQuery, + MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + PMSIHANDLE hView, hRec; + + LPWSTR pwzData = NULL; + + MQI_MESSAGE_QUEUE_PERMISSION* pItm = NULL; + + // loop through all application roles + hr = WcaOpenExecuteView(pwzQuery, &hView); + ExitOnFailure(hr, "Failed to execute view on table"); + + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + // create entry + pItm = (MQI_MESSAGE_QUEUE_PERMISSION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MQI_MESSAGE_QUEUE_PERMISSION)); + if (!pItm) + ExitFunction1(hr = E_OUTOFMEMORY); + + // get key + hr = WcaGetRecordString(hRec, mqpqMessageQueuePermission, &pwzData); + ExitOnFailure(hr, "Failed to get key"); + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); + + // get component + hr = WcaGetRecordString(hRec, mqpqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get component"); + + // get component install state + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); + + // get message queue + hr = WcaGetRecordString(hRec, mqpqMessageQueue, &pwzData); + ExitOnFailure(hr, "Failed to get application role"); + + hr = MqiMessageQueueFindByKey(pMessageQueueList, pwzData, &pItm->pMessageQueue); + if (S_FALSE == hr) + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + ExitOnFailure(hr, "Failed to find message queue, key: %S", pwzData); + + // get user domain + hr = WcaGetRecordFormattedString(hRec, mqpqDomain, &pwzData); + ExitOnFailure(hr, "Failed to get domain"); + StringCchCopyW(pItm->wzDomain, countof(pItm->wzDomain), pwzData); + + // get user name + hr = WcaGetRecordFormattedString(hRec, mqpqName, &pwzData); + ExitOnFailure(hr, "Failed to get name"); + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); + + // get permissions + hr = WcaGetRecordInteger(hRec, mqpqPermissions, &pItm->iPermissions); + ExitOnFailure(hr, "Failed to get permissions"); + + // set references & increment counters + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) + pList->iInstallCount++; + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) + pList->iUninstallCount++; + + // add entry + if (pList->pFirst) + pItm->pNext = pList->pFirst; + pList->pFirst = pItm; + pItm = NULL; + } + + if (E_NOMOREITEMS == hr) + hr = S_OK; + +LExit: + // clean up + ReleaseStr(pwzData); + + if (pItm) + ::HeapFree(::GetProcessHeap(), 0, pItm); + + return hr; +} + +static HRESULT AddMessageQueuePermissionToActionData( + MQI_MESSAGE_QUEUE_PERMISSION* pItm, + LPWSTR* ppwzActionData + ) +{ + HRESULT hr = S_OK; + + // add message queue information to custom action data + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData); + ExitOnFailure(hr, "Failed to add key to custom action data"); + hr = WcaWriteStringToCaData(pItm->pMessageQueue->wzPathName, ppwzActionData); + ExitOnFailure(hr, "Failed to add path name to custom action data"); + hr = WcaWriteStringToCaData(pItm->wzDomain, ppwzActionData); + ExitOnFailure(hr, "Failed to add domain to custom action data"); + hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData); + ExitOnFailure(hr, "Failed to add name to custom action data"); + hr = WcaWriteIntegerToCaData(pItm->iPermissions, ppwzActionData); + ExitOnFailure(hr, "Failed to add permissions to custom action data"); + + hr = S_OK; + +LExit: + return hr; +} diff --git a/src/ext/Msmq/ca/mqqueuesched.h b/src/ext/Msmq/ca/mqqueuesched.h new file mode 100644 index 00000000..c9381e0a --- /dev/null +++ b/src/ext/Msmq/ca/mqqueuesched.h @@ -0,0 +1,92 @@ +#pragma once +// 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. + + +struct MQI_MESSAGE_QUEUE +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + int iBasePriority; + int iJournalQuota; + WCHAR wzLabel[MAX_DARWIN_COLUMN + 1]; + WCHAR wzMulticastAddress[MAX_DARWIN_COLUMN + 1]; + WCHAR wzPathName[MAX_DARWIN_COLUMN + 1]; + int iPrivLevel; + int iQuota; + WCHAR wzServiceTypeGuid[MAX_DARWIN_COLUMN + 1]; + int iAttributes; + + INSTALLSTATE isInstalled, isAction; + BOOL fExists; + + MQI_MESSAGE_QUEUE* pNext; +}; + +struct MQI_MESSAGE_QUEUE_LIST +{ + MQI_MESSAGE_QUEUE* pFirst; + + int iInstallCount; + int iUninstallCount; +}; + +struct MQI_MESSAGE_QUEUE_PERMISSION +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; + WCHAR wzName[MAX_DARWIN_COLUMN + 1]; + int iPermissions; + + MQI_MESSAGE_QUEUE* pMessageQueue; + + INSTALLSTATE isInstalled, isAction; + + MQI_MESSAGE_QUEUE_PERMISSION* pNext; +}; + +struct MQI_MESSAGE_QUEUE_PERMISSION_LIST +{ + MQI_MESSAGE_QUEUE_PERMISSION* pFirst; + + int iInstallCount; + int iUninstallCount; +}; + + +// function prototypes + +HRESULT MqiSchedInitialize(); +void MqiSchedUninitialize(); +HRESULT MqiMessageQueueRead( + MQI_MESSAGE_QUEUE_LIST* pList + ); +HRESULT MqiMessageQueueVerify( + MQI_MESSAGE_QUEUE_LIST* pList + ); +HRESULT MqiMessageQueueInstall( + MQI_MESSAGE_QUEUE_LIST* pList, + BOOL fRollback, + LPWSTR* ppwzActionData + ); +HRESULT MqiMessageQueueUninstall( + MQI_MESSAGE_QUEUE_LIST* pList, + BOOL fRollback, + LPWSTR* ppwzActionData + ); +void MqiMessageQueueFreeList( + MQI_MESSAGE_QUEUE_LIST* pList + ); +HRESULT MqiMessageQueuePermissionRead( + MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList + ); +HRESULT MqiMessageQueuePermissionInstall( + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, + LPWSTR* ppwzActionData + ); +HRESULT MqiMessageQueuePermissionUninstall( + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList, + LPWSTR* ppwzActionData + ); +void MqiMessageQueuePermissionFreeList( + MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList + ); diff --git a/src/ext/Msmq/ca/mqsched.cpp b/src/ext/Msmq/ca/mqsched.cpp new file mode 100644 index 00000000..4c994901 --- /dev/null +++ b/src/ext/Msmq/ca/mqsched.cpp @@ -0,0 +1,196 @@ +// 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. + +#include "precomp.h" + + +/******************************************************************** + MessageQueuingInstall - CUSTOM ACTION ENTRY POINT for installing MSMQ message queues + +********************************************************************/ +extern "C" UINT __stdcall MessageQueuingInstall(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + MQI_MESSAGE_QUEUE_LIST lstMessageQueues; + MQI_MESSAGE_QUEUE_PERMISSION_LIST lstMessageQueuePermissions; + + int iCost = 0; + LPWSTR pwzRollbackActionData = NULL; + LPWSTR pwzExecuteActionData = NULL; + + ::ZeroMemory(&lstMessageQueues, sizeof(lstMessageQueues)); + ::ZeroMemory(&lstMessageQueuePermissions, sizeof(lstMessageQueuePermissions)); + + // initialize + hr = WcaInitialize(hInstall, "MessageQueuingInstall"); + ExitOnFailure(hr, "Failed to initialize"); + + do + { + hr = MqiSchedInitialize(); + if (S_FALSE == hr) + { + WcaLog(LOGMSG_STANDARD, "Failed to load mqrt.dll."); + er = WcaErrorMessage(msierrMsmqCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); + switch (er) + { + case IDABORT: + ExitFunction1(hr = E_FAIL); // bail with error + case IDRETRY: + break; // retry + case IDIGNORE: __fallthrough; + default: + ExitFunction1(hr = S_OK); // pretend everything is okay and bail + } + } + ExitOnFailure(hr, "Failed to initialize MSMQ."); + } while (S_FALSE == hr); + + // read message queues + hr = MqiMessageQueueRead(&lstMessageQueues); + ExitOnFailure(hr, "Failed to read MessageQueue table"); + + // read message queue permissions + hr = MqiMessageQueuePermissionRead(&lstMessageQueues, &lstMessageQueuePermissions); + ExitOnFailure(hr, "Failed to read message queue permissions"); + + // verify message queue elementes + hr = MqiMessageQueueVerify(&lstMessageQueues); + ExitOnFailure(hr, "Failed to verify message queue elements."); + + if (lstMessageQueues.iInstallCount || lstMessageQueuePermissions.iInstallCount) + { + // schedule rollback action + hr = MqiMessageQueuePermissionInstall(&lstMessageQueuePermissions, &pwzRollbackActionData); + ExitOnFailure(hr, "Failed to add message queue permissions to rollback action data"); + + hr = MqiMessageQueueInstall(&lstMessageQueues, TRUE, &pwzRollbackActionData); + ExitOnFailure(hr, "Failed to add message queues to rollback action data"); + + hr = WcaDoDeferredAction(L"MessageQueuingRollbackInstall", pwzRollbackActionData, 0); + ExitOnFailure(hr, "Failed to schedule MessageQueuingRollbackInstall"); + + // schedule execute action + hr = MqiMessageQueueInstall(&lstMessageQueues, FALSE, &pwzExecuteActionData); + ExitOnFailure(hr, "Failed to add message queues to execute action data"); + iCost += lstMessageQueues.iInstallCount * COST_MESSAGE_QUEUE_CREATE; + + hr = MqiMessageQueuePermissionInstall(&lstMessageQueuePermissions, &pwzExecuteActionData); + ExitOnFailure(hr, "Failed to add message queue permissions to execute action data"); + iCost += lstMessageQueues.iInstallCount * COST_MESSAGE_QUEUE_PERMISSION_ADD; + + hr = WcaDoDeferredAction(L"MessageQueuingExecuteInstall", pwzExecuteActionData, iCost); + ExitOnFailure(hr, "Failed to schedule MessageQueuingExecuteInstall"); + } + + hr = S_OK; + +LExit: + // clean up + MqiMessageQueueFreeList(&lstMessageQueues); + MqiMessageQueuePermissionFreeList(&lstMessageQueuePermissions); + + ReleaseStr(pwzRollbackActionData); + ReleaseStr(pwzExecuteActionData); + + // uninitialize + MqiSchedUninitialize(); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/******************************************************************** + MessageQueuingUninstall - CUSTOM ACTION ENTRY POINT for uninstalling MSMQ message queues + +********************************************************************/ +extern "C" UINT __stdcall MessageQueuingUninstall(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + MQI_MESSAGE_QUEUE_LIST lstMessageQueues; + MQI_MESSAGE_QUEUE_PERMISSION_LIST lstMessageQueuePermissions; + + int iCost = 0; + LPWSTR pwzRollbackActionData = NULL; + LPWSTR pwzExecuteActionData = NULL; + + ::ZeroMemory(&lstMessageQueues, sizeof(lstMessageQueues)); + ::ZeroMemory(&lstMessageQueuePermissions, sizeof(lstMessageQueuePermissions)); + + // initialize + hr = WcaInitialize(hInstall, "MessageQueuingUninstall"); + ExitOnFailure(hr, "Failed to initialize"); + + do + { + hr = MqiSchedInitialize(); + if (S_FALSE == hr) + { + WcaLog(LOGMSG_STANDARD, "Failed to load mqrt.dll."); + er = WcaErrorMessage(msierrMsmqCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); + switch (er) + { + case IDABORT: + ExitFunction1(hr = E_FAIL); // bail with error + case IDRETRY: + break; // retry + case IDIGNORE: __fallthrough; + default: + ExitFunction1(hr = S_OK); // pretend everything is okay and bail + } + } + ExitOnFailure(hr, "Failed to initialize MSMQ."); + } while (S_FALSE == hr); + + // read message queues + hr = MqiMessageQueueRead(&lstMessageQueues); + ExitOnFailure(hr, "Failed to read MessageQueue table"); + + // read message queue permissions + hr = MqiMessageQueuePermissionRead(&lstMessageQueues, &lstMessageQueuePermissions); + ExitOnFailure(hr, "Failed to read message queue permissions"); + + if (lstMessageQueues.iUninstallCount || lstMessageQueuePermissions.iUninstallCount) + { + // schedule rollback action + hr = MqiMessageQueueUninstall(&lstMessageQueues, TRUE, &pwzRollbackActionData); + ExitOnFailure(hr, "Failed to add message queues to rollback action data"); + + hr = MqiMessageQueuePermissionUninstall(&lstMessageQueuePermissions, &pwzRollbackActionData); + ExitOnFailure(hr, "Failed to add message queue permissions to rollback action data"); + + hr = WcaDoDeferredAction(L"MessageQueuingRollbackUninstall", pwzRollbackActionData, 0); + ExitOnFailure(hr, "Failed to schedule MessageQueuingRollbackUninstall"); + + // schedule execute action + hr = MqiMessageQueuePermissionUninstall(&lstMessageQueuePermissions, &pwzExecuteActionData); + ExitOnFailure(hr, "Failed to add message queue permissions to execute action data"); + + hr = MqiMessageQueueUninstall(&lstMessageQueues, FALSE, &pwzExecuteActionData); + ExitOnFailure(hr, "Failed to add message queues to execute action data"); + iCost += lstMessageQueues.iUninstallCount * COST_MESSAGE_QUEUE_DELETE; + + hr = WcaDoDeferredAction(L"MessageQueuingExecuteUninstall", pwzExecuteActionData, iCost); + ExitOnFailure(hr, "Failed to schedule MessageQueuingExecuteUninstall"); + } + + hr = S_OK; + +LExit: + // clean up + MqiMessageQueueFreeList(&lstMessageQueues); + MqiMessageQueuePermissionFreeList(&lstMessageQueuePermissions); + + ReleaseStr(pwzRollbackActionData); + ReleaseStr(pwzExecuteActionData); + + // uninitialize + MqiSchedUninitialize(); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} diff --git a/src/ext/Msmq/ca/mqutilexec.cpp b/src/ext/Msmq/ca/mqutilexec.cpp new file mode 100644 index 00000000..a9c56e02 --- /dev/null +++ b/src/ext/Msmq/ca/mqutilexec.cpp @@ -0,0 +1,380 @@ +// 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. + +#include "precomp.h" + + +// private structs + +struct PCA_WELLKNOWN_SID +{ + LPCWSTR pwzName; + SID_IDENTIFIER_AUTHORITY iaIdentifierAuthority; + BYTE nSubAuthorityCount; + DWORD dwSubAuthority[8]; +}; + + +// well known SIDs + +PCA_WELLKNOWN_SID wsWellKnownSids[] = { + {L"\\Everyone", SECURITY_WORLD_SID_AUTHORITY, 1, {SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0}}, + {L"\\Administrators", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0}}, + {L"\\LocalSystem", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0}}, + {L"\\LocalService", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}}, + {L"\\NetworkService", SECURITY_NT_AUTHORITY, 1, {SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}}, + {L"\\AuthenticatedUser", SECURITY_NT_AUTHORITY, 1, {SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0}}, + {L"\\Guests", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS, 0, 0, 0, 0, 0, 0}}, + {L"\\Users", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0}}, + {L"\\CREATOR OWNER", SECURITY_NT_AUTHORITY, 1, {SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0}}, + {NULL, SECURITY_NULL_SID_AUTHORITY, 0, {0, 0, 0, 0, 0, 0, 0, 0}} +}; + + +// prototypes for private helper functions + +static HRESULT CreateSidFromDomainRidPair( + PSID pDomainSid, + DWORD dwRid, + PSID* ppSid + ); +static HRESULT InitLsaUnicodeString( + PLSA_UNICODE_STRING plusStr, + LPCWSTR pwzStr, + DWORD dwLen + ); +static void FreeLsaUnicodeString( + PLSA_UNICODE_STRING plusStr + ); + + +// function definitions + +HRESULT PcaActionDataMessage( + DWORD cArgs, + ... + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + PMSIHANDLE hRec; + va_list args; + + // record + hRec = ::MsiCreateRecord(cArgs); + ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record"); + + va_start(args, cArgs); + for (DWORD i = 1; i <= cArgs; i++) + { + LPCWSTR pwzArg = va_arg(args, WCHAR*); + if (pwzArg && *pwzArg) + { + er = ::MsiRecordSetStringW(hRec, i, pwzArg); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set record field string"); + } + } + va_end(args); + + // message + er = WcaProcessMessage(INSTALLMESSAGE_ACTIONDATA, hRec); + if (0 == er || IDOK == er || IDYES == er) + { + hr = S_OK; + } + else if (ERROR_INSTALL_USEREXIT == er || IDABORT == er || IDCANCEL == er) + { + WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit + hr = S_FALSE; + } + else + hr = E_UNEXPECTED; + +LExit: + return hr; +} + +HRESULT PcaAccountNameToSid( + LPCWSTR pwzAccountName, + PSID* ppSid + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + NTSTATUS st = 0; + + PSID pSid = NULL; + LSA_OBJECT_ATTRIBUTES loaAttributes; + LSA_HANDLE lsahPolicy = NULL; + LSA_UNICODE_STRING lusName; + PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL; + PLSA_TRANSLATED_SID pltsSid = NULL; + + ::ZeroMemory(&loaAttributes, sizeof(loaAttributes)); + ::ZeroMemory(&lusName, sizeof(lusName)); + + // identify well known SIDs + for (PCA_WELLKNOWN_SID* pWS = wsWellKnownSids; pWS->pwzName; pWS++) + { + if (0 == lstrcmpiW(pwzAccountName, pWS->pwzName)) + { + // allocate SID buffer + pSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, ::GetSidLengthRequired(pWS->nSubAuthorityCount)); + ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID"); + + // initialize SID + ::InitializeSid(pSid, &pWS->iaIdentifierAuthority, pWS->nSubAuthorityCount); + + // copy sub autorities + for (DWORD i = 0; i < pWS->nSubAuthorityCount; i++) + *::GetSidSubAuthority(pSid, i) = pWS->dwSubAuthority[i]; + + break; + } + } + + // lookup name + if (!pSid) + { + // open policy handle + st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy); + er = ::LsaNtStatusToWinError(st); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle"); + + // create account name lsa unicode string + hr = InitLsaUnicodeString(&lusName, pwzAccountName, wcslen(pwzAccountName)); + ExitOnFailure(hr, "Failed to initialize account name string"); + + // lookup name + st = ::LsaLookupNames(lsahPolicy, 1, &lusName, &plrdsDomains, &pltsSid); + er = ::LsaNtStatusToWinError(st); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names"); + + if (SidTypeDomain == pltsSid->Use) + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported"); + + // convert sid + hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pSid); + ExitOnFailure(hr, "Failed to convert SID"); + } + + *ppSid = pSid; + pSid = NULL; + + hr = S_OK; + +LExit: + // clean up + if (pSid) + ::HeapFree(::GetProcessHeap(), 0, pSid); + if (lsahPolicy) + ::LsaClose(lsahPolicy); + if (plrdsDomains) + ::LsaFreeMemory(plrdsDomains); + if (pltsSid) + ::LsaFreeMemory(pltsSid); + FreeLsaUnicodeString(&lusName); + + return hr; +} + +HRESULT PcaSidToAccountName( + PSID pSid, + LPWSTR* ppwzAccountName + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + NTSTATUS st = 0; + + LSA_OBJECT_ATTRIBUTES loaAttributes; + LSA_HANDLE lsahPolicy = NULL; + PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL; + PLSA_TRANSLATED_NAME pltnName = NULL; + + LPWSTR pwzDomain = NULL; + LPWSTR pwzName = NULL; + + ::ZeroMemory(&loaAttributes, sizeof(loaAttributes)); + + // open policy handle + st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy); + er = ::LsaNtStatusToWinError(st); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle"); + + // lookup SID + st = ::LsaLookupSids(lsahPolicy, 1, &pSid, &plrdsDomains, &pltnName); + er = ::LsaNtStatusToWinError(st); + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup SID"); + + if (SidTypeDomain == pltnName->Use) + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported"); + + // format account name string + if (SidTypeWellKnownGroup != pltnName->Use) + { + PLSA_UNICODE_STRING plusDomain = &plrdsDomains->Domains[pltnName->DomainIndex].Name; + hr = StrAllocString(&pwzDomain, plusDomain->Buffer, plusDomain->Length / sizeof(WCHAR)); + ExitOnFailure(hr, "Failed to allocate name string"); + } + + hr = StrAllocString(&pwzName, pltnName->Name.Buffer, pltnName->Name.Length / sizeof(WCHAR)); + ExitOnFailure(hr, "Failed to allocate domain string"); + + hr = StrAllocFormatted(ppwzAccountName, L"%s\\%s", pwzDomain ? pwzDomain : L"", pwzName); + ExitOnFailure(hr, "Failed to format account name string"); + + hr = S_OK; + +LExit: + // clean up + if (lsahPolicy) + ::LsaClose(lsahPolicy); + if (plrdsDomains) + ::LsaFreeMemory(plrdsDomains); + if (pltnName) + ::LsaFreeMemory(pltnName); + + ReleaseStr(pwzDomain); + ReleaseStr(pwzName); + + return hr; +} + +HRESULT PcaBuildAccountName( + LPCWSTR pwzDomain, + LPCWSTR pwzName, + LPWSTR* ppwzAccount + ) +{ + HRESULT hr = S_OK; + + WCHAR wzComputerName[MAX_COMPUTERNAME_LENGTH + 1]; + ::ZeroMemory(wzComputerName, sizeof(wzComputerName)); + + // if domain is '.', get computer name + if (0 == lstrcmpW(pwzDomain, L".")) + { + DWORD dwSize = countof(wzComputerName); + if (!::GetComputerNameW(wzComputerName, &dwSize)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get computer name"); + } + + // build account name + hr = StrAllocFormatted(ppwzAccount, L"%s\\%s", *wzComputerName ? wzComputerName : pwzDomain, pwzName); + ExitOnFailure(hr, "Failed to build domain user name"); + + hr = S_OK; + +LExit: + return hr; +} + +HRESULT PcaGuidFromString( + LPCWSTR pwzGuid, + LPGUID pGuid + ) +{ + HRESULT hr = S_OK; + + int cch = 0; + + WCHAR wz[39]; + ::ZeroMemory(wz, sizeof(wz)); + + cch = lstrlenW(pwzGuid); + + if (38 == cch && L'{' == pwzGuid[0] && L'}' == pwzGuid[37]) + StringCchCopyW(wz, countof(wz), pwzGuid); + else if (36 == cch) + StringCchPrintfW(wz, countof(wz), L"{%s}", pwzGuid); + else + ExitFunction1(hr = E_INVALIDARG); + + hr = ::CLSIDFromString(wz, pGuid); + +LExit: + return hr; +} + + +// helper function definitions + +static HRESULT CreateSidFromDomainRidPair( + PSID pDomainSid, + DWORD dwRid, + PSID* ppSid + ) +{ + HRESULT hr = S_OK; + + PSID pSid = NULL; + + // get domain SID sub authority count + UCHAR ucSubAuthorityCount = *::GetSidSubAuthorityCount(pDomainSid); + + // allocate SID buffer + DWORD dwLengthRequired = ::GetSidLengthRequired(ucSubAuthorityCount + (UCHAR)1); + if (*ppSid) + { + SIZE_T ccb = ::HeapSize(::GetProcessHeap(), 0, *ppSid); + if (-1 == ccb) + ExitOnFailure(hr = E_FAIL, "Failed to get size of SID buffer"); + + if (ccb < dwLengthRequired) + { + pSid = (PSID)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, *ppSid, dwLengthRequired); + ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for SID, len: %d", dwLengthRequired); + *ppSid = pSid; + } + } + else + { + *ppSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLengthRequired); + ExitOnNull(*ppSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID, len: %d", dwLengthRequired); + } + + ::InitializeSid(*ppSid, ::GetSidIdentifierAuthority(pDomainSid), ucSubAuthorityCount + (UCHAR)1); + + // copy sub autorities + DWORD i = 0; + for (; i < ucSubAuthorityCount; i++) + *::GetSidSubAuthority(*ppSid, i) = *::GetSidSubAuthority(pDomainSid, i); + *::GetSidSubAuthority(*ppSid, i) = dwRid; + + hr = S_OK; + +LExit: + return hr; +} + +static HRESULT InitLsaUnicodeString( + PLSA_UNICODE_STRING plusStr, + LPCWSTR pwzStr, + DWORD dwLen + ) +{ + HRESULT hr = S_OK; + + plusStr->Length = (USHORT)dwLen * sizeof(WCHAR); + plusStr->MaximumLength = (USHORT)(dwLen + 1) * sizeof(WCHAR); + + plusStr->Buffer = (WCHAR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * (dwLen + 1)); + ExitOnNull(plusStr->Buffer, hr, E_OUTOFMEMORY, "Failed to allocate account name string"); + + hr = StringCchCopyW(plusStr->Buffer, dwLen + 1, pwzStr); + ExitOnFailure(hr, "Failed to copy buffer"); + + hr = S_OK; + +LExit: + return hr; +} + +static void FreeLsaUnicodeString( + PLSA_UNICODE_STRING plusStr + ) +{ + if (plusStr->Buffer) + ::HeapFree(::GetProcessHeap(), 0, plusStr->Buffer); +} diff --git a/src/ext/Msmq/ca/mqutilexec.h b/src/ext/Msmq/ca/mqutilexec.h new file mode 100644 index 00000000..d3dc17a1 --- /dev/null +++ b/src/ext/Msmq/ca/mqutilexec.h @@ -0,0 +1,23 @@ +// 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. + +HRESULT PcaActionDataMessage( + DWORD cArgs, + ... + ); +HRESULT PcaAccountNameToSid( + LPCWSTR pwzAccountName, + PSID* ppSid + ); +HRESULT PcaSidToAccountName( + PSID pSid, + LPWSTR* ppwzAccountName + ); +HRESULT PcaBuildAccountName( + LPCWSTR pwzDomain, + LPCWSTR pwzName, + LPWSTR* ppwzAccount + ); +HRESULT PcaGuidFromString( + LPCWSTR pwzGuid, + GUID* pGuid + ); diff --git a/src/ext/Msmq/ca/mqutilsched.cpp b/src/ext/Msmq/ca/mqutilsched.cpp new file mode 100644 index 00000000..4353a6d6 --- /dev/null +++ b/src/ext/Msmq/ca/mqutilsched.cpp @@ -0,0 +1,43 @@ +// 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. + +#include "precomp.h" + + +// function definitions + +HRESULT PcaGuidToRegFormat( + LPWSTR pwzGuid, + LPWSTR pwzDest, + SIZE_T cchDest + ) +{ + HRESULT hr = S_OK; + + GUID guid = GUID_NULL; + int cch = 0; + + WCHAR wz[39]; + ::ZeroMemory(wz, sizeof(wz)); + + cch = lstrlenW(pwzGuid); + + if (38 == cch && L'{' == pwzGuid[0] && L'}' == pwzGuid[37]) + StringCchCopyW(wz, countof(wz), pwzGuid); + else if (36 == cch) + StringCchPrintfW(wz, countof(wz), L"{%s}", pwzGuid); + else + ExitFunction1(hr = E_INVALIDARG); + + // convert string to guid + hr = ::CLSIDFromString(wz, &guid); + ExitOnFailure(hr, "Failed to parse guid string"); + + // convert guid to string + if (0 == ::StringFromGUID2(guid, pwzDest, cchDest)) + ExitOnFailure(hr = E_FAIL, "Failed to convert guid to string"); + + hr = S_OK; + +LExit: + return hr; +} diff --git a/src/ext/Msmq/ca/mqutilsched.h b/src/ext/Msmq/ca/mqutilsched.h new file mode 100644 index 00000000..e172257d --- /dev/null +++ b/src/ext/Msmq/ca/mqutilsched.h @@ -0,0 +1,9 @@ +#pragma once +// 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. + + +HRESULT PcaGuidToRegFormat( + LPWSTR pwzGuid, + LPWSTR pwzDest, + SIZE_T cchDest + ); diff --git a/src/ext/Msmq/ca/msmqca.def b/src/ext/Msmq/ca/msmqca.def new file mode 100644 index 00000000..4902858f --- /dev/null +++ b/src/ext/Msmq/ca/msmqca.def @@ -0,0 +1,12 @@ +; 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. + + +LIBRARY "msmqca" + +EXPORTS + MessageQueuingInstall + MessageQueuingUninstall + MessageQueuingExecuteInstall + MessageQueuingRollbackInstall + MessageQueuingExecuteUninstall + MessageQueuingRollbackUninstall diff --git a/src/ext/Msmq/ca/msmqca.vcxproj b/src/ext/Msmq/ca/msmqca.vcxproj new file mode 100644 index 00000000..c4cb3323 --- /dev/null +++ b/src/ext/Msmq/ca/msmqca.vcxproj @@ -0,0 +1,71 @@ + + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + + + {CAD56A7E-342B-4324-9DCB-BCEB8F3BC80D} + DynamicLibrary + msmqca + v142 + Unicode + msmqca.def + WiX Toolset MSMQ CustomAction + + + + + + + msi.lib + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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}. + + + + + diff --git a/src/ext/Msmq/ca/packages.config b/src/ext/Msmq/ca/packages.config new file mode 100644 index 00000000..9d88f529 --- /dev/null +++ b/src/ext/Msmq/ca/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/ext/Msmq/ca/precomp.h b/src/ext/Msmq/ca/precomp.h new file mode 100644 index 00000000..cbbff6ea --- /dev/null +++ b/src/ext/Msmq/ca/precomp.h @@ -0,0 +1,23 @@ +#pragma once +// 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. + + +#include +#include +#include +#include +#include +#include + +#include "wcautil.h" +#include "memutil.h" +#include "strutil.h" +#include "wiutil.h" + +#include "CustomMsiErrors.h" + +#include "mqcost.h" +#include "mqutilsched.h" +#include "mqqueuesched.h" +#include "mqutilexec.h" +#include "mqqueueexec.h" diff --git a/src/ext/Msmq/nuget.config b/src/ext/Msmq/nuget.config new file mode 100644 index 00000000..db7aba29 --- /dev/null +++ b/src/ext/Msmq/nuget.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/Msmq/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs b/src/ext/Msmq/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs new file mode 100644 index 00000000..057b0a9d --- /dev/null +++ b/src/ext/Msmq/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs @@ -0,0 +1,32 @@ +// 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. + +namespace WixToolsetTest.Msmq +{ + using System.Linq; + using WixBuildTools.TestSupport; + using WixToolset.Core.TestPackage; + using WixToolset.Msmq; + using Xunit; + + public class MsmqExtensionFixture + { + [Fact] + public void CanBuildUsingMessageQueue() + { + var folder = TestData.Get(@"TestData\UsingMessageQueue"); + var build = new Builder(folder, typeof(MsmqExtensionFactory), new[] { folder }); + + var results = build.BuildAndQuery(Build, "MessageQueue"); + Assert.Equal(new[] + { + "MessageQueue:TestMQ\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\t\t\tMQLabel\t\tMQPath\t\t\t\t0", + }, results); + } + + private static void Build(string[] args) + { + var result = WixRunner.Execute(args) + .AssertSuccess(); + } + } +} diff --git a/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl new file mode 100644 index 00000000..38c12ac1 --- /dev/null +++ b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl @@ -0,0 +1,11 @@ + + + + + + A newer version of [ProductName] is already installed. + MsiPackage + + diff --git a/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs new file mode 100644 index 00000000..bd31e81f --- /dev/null +++ b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs new file mode 100644 index 00000000..ff9f7d92 --- /dev/null +++ b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt new file mode 100644 index 00000000..1b4ffe8a --- /dev/null +++ b/src/ext/Msmq/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt @@ -0,0 +1 @@ +This is example.txt. \ No newline at end of file diff --git a/src/ext/Msmq/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj b/src/ext/Msmq/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj new file mode 100644 index 00000000..7f74e043 --- /dev/null +++ b/src/ext/Msmq/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj @@ -0,0 +1,41 @@ + + + + + + netcoreapp3.1 + false + + + + NU1701 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Msmq/wix.snk b/src/ext/Msmq/wix.snk new file mode 100644 index 00000000..3908a66a Binary files /dev/null and b/src/ext/Msmq/wix.snk differ diff --git a/src/ext/Msmq/wixext/MsmqCompiler.cs b/src/ext/Msmq/wixext/MsmqCompiler.cs new file mode 100644 index 00000000..cfc4ef65 --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqCompiler.cs @@ -0,0 +1,528 @@ +// 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. + +namespace WixToolset.Msmq +{ + using System; + using System.Collections.Generic; + using System.Xml.Linq; + using WixToolset.Data; + using WixToolset.Extensibility; + using WixToolset.Msmq.Symbols; + + /// + /// The compiler for the WiX Toolset MSMQ Extension. + /// + public sealed class MsmqCompiler : BaseCompilerExtension + { + public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/msmq"; + + /// + /// + /// + public enum MqiMessageQueueAttributes + { + Authenticate = (1 << 0), + Journal = (1 << 1), + Transactional = (1 << 2) + } + + /// + /// + /// + public enum MqiMessageQueuePrivacyLevel + { + None = 0, + Optional = 1, + Body = 2 + } + + /// + /// + /// + public enum MqiMessageQueuePermission + { + DeleteMessage = (1 << 0), + PeekMessage = (1 << 1), + WriteMessage = (1 << 2), + DeleteJournalMessage = (1 << 3), + SetQueueProperties = (1 << 4), + GetQueueProperties = (1 << 5), + DeleteQueue = (1 << 6), + GetQueuePermissions = (1 << 7), + ChangeQueuePermissions = (1 << 8), + TakeQueueOwnership = (1 << 9), + ReceiveMessage = (1 << 10), + ReceiveJournalMessage = (1 << 11), + QueueGenericRead = (1 << 12), + QueueGenericWrite = (1 << 13), + QueueGenericExecute = (1 << 14), + QueueGenericAll = (1 << 15) + } + + /// + /// Processes an element for the Compiler. + /// + /// Parent element of element to process. + /// Element to process. + /// Extra information about the context in which this element is being parsed. + public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary context) + { + switch (parentElement.Name.LocalName) + { + case "Component": + var componentId = context["ComponentId"]; + var directoryId = context["DirectoryId"]; + + switch (element.Name.LocalName) + { + case "MessageQueue": + this.ParseMessageQueueElement(intermediate, section, element, componentId); + break; + case "MessageQueuePermission": + this.ParseMessageQueuePermissionElement(intermediate, section, element, componentId, null); + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + } + + /// + /// Parses an MSMQ message queue element. + /// + /// Element to parse. + /// Identifier of parent component. + private void ParseMessageQueueElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); + + Identifier id = null; + var basePriority = CompilerConstants.IntegerNotSet; + var journalQuota = CompilerConstants.IntegerNotSet; + string label = null; + string multicastAddress = null; + string pathName = null; + var privLevel = CompilerConstants.IntegerNotSet; + var quota = CompilerConstants.IntegerNotSet; + string serviceTypeGuid = null; + int attributes = 0; + + foreach (var attrib in node.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + break; + case "Authenticate": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= (int)MqiMessageQueueAttributes.Authenticate; + } + else + { + attributes &= ~(int)MqiMessageQueueAttributes.Authenticate; + } + break; + case "BasePriority": + basePriority = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "Journal": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= (int)MqiMessageQueueAttributes.Journal; + } + else + { + attributes &= ~(int)MqiMessageQueueAttributes.Journal; + } + break; + case "JournalQuota": + journalQuota = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); + break; + case "Label": + label = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "MulticastAddress": + multicastAddress = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "PathName": + pathName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "PrivLevel": + var privLevelAttr = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + switch (privLevelAttr) + { + case "none": + privLevel = (int)MqiMessageQueuePrivacyLevel.None; + break; + case "optional": + privLevel = (int)MqiMessageQueuePrivacyLevel.Optional; + break; + case "body": + privLevel = (int)MqiMessageQueuePrivacyLevel.Body; + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "MessageQueue", "PrivLevel", privLevelAttr, "none", "body", "optional")); + break; + } + break; + case "Quota": + quota = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); + break; + case "Transactional": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= (int)MqiMessageQueueAttributes.Transactional; + } + else + { + attributes &= ~(int)MqiMessageQueueAttributes.Transactional; + } + break; + case "ServiceTypeGuid": + serviceTypeGuid = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib)); + break; + default: + this.ParseHelper.UnexpectedAttribute(node, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); + } + } + + foreach (var child in node.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + switch (child.Name.LocalName) + { + case "MessageQueuePermission": + this.ParseMessageQueuePermissionElement(intermediate, section, child, componentId, id?.Id); + break; + default: + this.ParseHelper.UnexpectedElement(node, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child); + } + } + + var symbol = section.AddSymbol(new MessageQueueSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + Label = label, + MulticastAddress = multicastAddress, + PathName = pathName, + ServiceTypeGuid = serviceTypeGuid, + Attributes = attributes, + }); + + if (CompilerConstants.IntegerNotSet != basePriority) + { + symbol.BasePriority = basePriority; + } + if (CompilerConstants.IntegerNotSet != journalQuota) + { + symbol.JournalQuota = journalQuota; + } + + if (CompilerConstants.IntegerNotSet != privLevel) + { + symbol.PrivLevel = privLevel; + } + if (CompilerConstants.IntegerNotSet != quota) + { + symbol.Quota = quota; + } + + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MessageQueuingInstall"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MessageQueuingUninstall"); + } + + /// + /// Parses an MSMQ message queue permission element. + /// + /// Element to parse. + /// Identifier of parent component. + /// Optional identifier of parent message queue. + private void ParseMessageQueuePermissionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, string messageQueueId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); + + Identifier id = null; + string user = null; + string group = null; + int permissions = 0; + + foreach (var attrib in node.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + break; + case "MessageQueue": + if (null != messageQueueId) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName)); + } + messageQueueId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, MsmqSymbolDefinitions.MessageQueue, messageQueueId); + break; + case "User": + if (null != group) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "User", "Group")); + } + user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); + break; + case "Group": + if (null != user) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Group", "User")); + } + group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group); + break; + case "DeleteMessage": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.DeleteMessage; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.DeleteMessage; + } + break; + case "PeekMessage": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.PeekMessage; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.PeekMessage; + } + break; + case "WriteMessage": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.WriteMessage; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.WriteMessage; + } + break; + case "DeleteJournalMessage": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.DeleteJournalMessage; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.DeleteJournalMessage; + } + break; + case "SetQueueProperties": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.SetQueueProperties; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.SetQueueProperties; + } + break; + case "GetQueueProperties": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.GetQueueProperties; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.GetQueueProperties; + } + break; + case "DeleteQueue": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.DeleteQueue; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.DeleteQueue; + } + break; + case "GetQueuePermissions": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.GetQueuePermissions; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.GetQueuePermissions; + } + break; + case "ChangeQueuePermissions": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.ChangeQueuePermissions; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.ChangeQueuePermissions; + } + break; + case "TakeQueueOwnership": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.TakeQueueOwnership; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.TakeQueueOwnership; + } + break; + case "ReceiveMessage": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.ReceiveMessage; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.ReceiveMessage; + } + break; + case "ReceiveJournalMessage": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.ReceiveJournalMessage; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.ReceiveJournalMessage; + } + break; + case "QueueGenericRead": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.QueueGenericRead; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.QueueGenericRead; + } + break; + case "QueueGenericWrite": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.QueueGenericWrite; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.QueueGenericWrite; + } + break; + case "QueueGenericExecute": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.QueueGenericExecute; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.QueueGenericExecute; + } + break; + case "QueueGenericAll": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + permissions |= (int)MqiMessageQueuePermission.QueueGenericAll; + } + else + { + permissions &= ~(int)MqiMessageQueuePermission.QueueGenericAll; + } + break; + default: + this.ParseHelper.UnexpectedAttribute(node, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("mqp", componentId, messageQueueId, user, group); + } + + if (null == messageQueueId) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MessageQueue")); + } + if (null == user && null == group) + { + this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "User", "Group")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); + + if (null != user) + { + section.AddSymbol(new MessageQueueUserPermissionSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + MessageQueueRef = messageQueueId, + UserRef = user, + Permissions = permissions, + }); + } + if (null != group) + { + section.AddSymbol(new MessageQueueGroupPermissionSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + MessageQueueRef = messageQueueId, + GroupRef = group, + Permissions = permissions, + }); + } + } + + /// + /// Attempts to parse the input value as a GUID, and in case the value is a valid + /// GUID returnes it in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}". + /// + /// + /// + string TryFormatGuidValue(string val) + { + if (!Guid.TryParse(val, out var guid)) + { + return val; + } + return guid.ToString("B").ToUpper(); + } + } +} diff --git a/src/ext/Msmq/wixext/MsmqDecompiler.cs b/src/ext/Msmq/wixext/MsmqDecompiler.cs new file mode 100644 index 00000000..aa8c34b6 --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqDecompiler.cs @@ -0,0 +1,305 @@ +// 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. + +namespace WixToolset.Msmq +{ +#if TODO_CONSIDER_DECOMPILER + using System; + using System.Collections; + using System.Globalization; + using WixToolset.Data; + using WixToolset.Extensibility; + using Msmq = WixToolset.Extensions.Serialize.Msmq; + using Wix = WixToolset.Data.Serialize; + + /// + /// The decompiler for the WiX Toolset MSMQ Extension. + /// + public sealed class MsmqDecompiler : DecompilerExtension + { + /// + /// Creates a decompiler for MSMQ Extension. + /// + public MsmqDecompiler() + { + this.TableDefinitions = MsmqExtensionData.GetExtensionTableDefinitions(); + } + + /// + /// Get the extensions library to be removed. + /// + /// Table definitions for library. + /// Library to remove from decompiled output. + public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) + { + return MsmqExtensionData.GetExtensionLibrary(tableDefinitions); + } + + /// + /// Decompiles an extension table. + /// + /// The table to decompile. + public override void DecompileTable(Table table) + { + switch (table.Name) + { + case "MessageQueue": + this.DecompileMessageQueueTable(table); + break; + case "MessageQueueUserPermission": + this.DecompileMessageQueueUserPermissionTable(table); + break; + case "MessageQueueGroupPermission": + this.DecompileMessageQueueGroupPermissionTable(table); + break; + default: + base.DecompileTable(table); + break; + } + } + + /// + /// Decompile the MessageQueue table. + /// + /// The table to decompile. + private void DecompileMessageQueueTable(Table table) + { + foreach (Row row in table.Rows) + { + Msmq.MessageQueue queue = new Msmq.MessageQueue(); + + queue.Id = (string)row[0]; + + if (null != row[2]) + { + queue.BasePriority = (int)row[2]; + } + + if (null != row[3]) + { + queue.JournalQuota = (int)row[3]; + } + + queue.Label = (string)row[4]; + + if (null != row[5]) + { + queue.MulticastAddress = (string)row[5]; + } + + queue.PathName = (string)row[6]; + + if (null != row[7]) + { + switch ((MsmqCompiler.MqiMessageQueuePrivacyLevel)row[7]) + { + case MsmqCompiler.MqiMessageQueuePrivacyLevel.None: + queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.none; + break; + case MsmqCompiler.MqiMessageQueuePrivacyLevel.Optional: + queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.optional; + break; + case MsmqCompiler.MqiMessageQueuePrivacyLevel.Body: + queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.body; + break; + default: + break; + } + } + + if (null != row[8]) + { + queue.Quota = (int)row[8]; + } + + if (null != row[9]) + { + queue.ServiceTypeGuid = (string)row[9]; + } + + int attributes = (int)row[10]; + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Authenticate)) + { + queue.Authenticate = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Journal)) + { + queue.Journal = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Transactional)) + { + queue.Transactional = Msmq.YesNoType.yes; + } + + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + if (null != component) + { + component.AddChild(queue); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + + /// + /// Decompile the MessageQueueUserPermission table. + /// + /// The table to decompile. + private void DecompileMessageQueueUserPermissionTable(Table table) + { + foreach (Row row in table.Rows) + { + Msmq.MessageQueuePermission queuePermission = new Msmq.MessageQueuePermission(); + + queuePermission.Id = (string)row[0]; + + if (null != row[2]) + { + queuePermission.MessageQueue = (string)row[2]; + } + + queuePermission.User = (string)row[3]; + + DecompileMessageQueuePermissionAttributes(row, queuePermission); + + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + if (null != component) + { + component.AddChild(queuePermission); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + + /// + /// Decompile the MessageQueueGroupPermission table. + /// + /// The table to decompile. + private void DecompileMessageQueueGroupPermissionTable(Table table) + { + foreach (Row row in table.Rows) + { + Msmq.MessageQueuePermission queuePermission = new Msmq.MessageQueuePermission(); + + queuePermission.Id = (string)row[0]; + + if (null != row[2]) + { + queuePermission.MessageQueue = (string)row[2]; + } + + queuePermission.Group = (string)row[3]; + + DecompileMessageQueuePermissionAttributes(row, queuePermission); + + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + if (null != component) + { + component.AddChild(queuePermission); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + + /// + /// Decompile row attributes for the MessageQueueUserPermission and MessageQueueGroupPermission tables. + /// + /// The row to decompile. + /// Target element. + private void DecompileMessageQueuePermissionAttributes(Row row, Msmq.MessageQueuePermission queuePermission) + { + int attributes = (int)row[4]; + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteMessage)) + { + queuePermission.DeleteMessage = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.PeekMessage)) + { + queuePermission.PeekMessage = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.WriteMessage)) + { + queuePermission.WriteMessage = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteJournalMessage)) + { + queuePermission.DeleteJournalMessage = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.SetQueueProperties)) + { + queuePermission.SetQueueProperties = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.GetQueueProperties)) + { + queuePermission.GetQueueProperties = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteQueue)) + { + queuePermission.DeleteQueue = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.GetQueuePermissions)) + { + queuePermission.GetQueuePermissions = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ChangeQueuePermissions)) + { + queuePermission.ChangeQueuePermissions = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.TakeQueueOwnership)) + { + queuePermission.TakeQueueOwnership = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ReceiveMessage)) + { + queuePermission.ReceiveMessage = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ReceiveJournalMessage)) + { + queuePermission.ReceiveJournalMessage = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericRead)) + { + queuePermission.QueueGenericRead = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericWrite)) + { + queuePermission.QueueGenericWrite = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericExecute)) + { + queuePermission.QueueGenericExecute = Msmq.YesNoType.yes; + } + + if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericAll)) + { + queuePermission.QueueGenericAll = Msmq.YesNoType.yes; + } + } + } +#endif +} diff --git a/src/ext/Msmq/wixext/MsmqErrors.cs b/src/ext/Msmq/wixext/MsmqErrors.cs new file mode 100644 index 00000000..4342e1cf --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqErrors.cs @@ -0,0 +1,71 @@ +// 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. + +namespace WixToolset.Data +{ + using System; + using System.Resources; + + public static class MsmqErrors + { + public static Message IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) + { + return Message(sourceLineNumbers, Ids.IllegalAttributeWithoutComponent, "The {0}/@{1} attribute cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName, attributeName); + } + + public static Message IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName) + { + return Message(sourceLineNumbers, Ids.IllegalElementWithoutComponent, "The {0} element cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName); + } + + public static Message RequiredAttribute(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2) + { + return Message(sourceLineNumbers, Ids.RequiredAttribute, "A {0} element must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2); + } + + public static Message RequiredAttributeNotUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2) + { + return Message(sourceLineNumbers, Ids.RequiredAttributeNotUnderComponent, "A {0} element not nested under a component must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2); + } + + public static Message RequiredAttributeUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) + { + return Message(sourceLineNumbers, Ids.RequiredAttributeUnderComponent, "The {0}/@{1} attribute must be provided when {0} element is nested under a component.", elementName, attributeName); + } + + public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue) + { + return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute cannot coexist with the {2} attribute's value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue); + } + + public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value, string otherAttributeName, string otherValue) + { + return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute's value, '{2}', cannot coexist with the {3} attribute's value of '{4}'.", elementName, attributeName, value, otherAttributeName, otherValue); + } + + public static Message UnexpectedAttributeWithoutOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue) + { + return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithoutOtherValue, "The {0}/@{1} cannot be provided unless the {2} attribute is provided with a value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue); + } + + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) + { + return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); + } + + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) + { + return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args); + } + + public enum Ids + { + IllegalAttributeWithoutComponent = 6000, + IllegalElementWithoutComponent = 6001, + UnexpectedAttributeWithOtherValue = 6002, + UnexpectedAttributeWithoutOtherValue = 6003, + RequiredAttributeUnderComponent = 6004, + RequiredAttribute = 6005, + RequiredAttributeNotUnderComponent = 6006, + } + } +} diff --git a/src/ext/Msmq/wixext/MsmqExtensionData.cs b/src/ext/Msmq/wixext/MsmqExtensionData.cs new file mode 100644 index 00000000..91485724 --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqExtensionData.cs @@ -0,0 +1,30 @@ +// 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. + +namespace WixToolset.Msmq +{ + using WixToolset.Data; + using WixToolset.Extensibility; + + /// + /// The WiX Toolset MSMQ Extension. + /// + public sealed class MsmqExtensionData : BaseExtensionData + { + /// + /// Gets the default culture. + /// + /// The default culture. + public override string DefaultCulture => "en-US"; + + public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) + { + symbolDefinition = MsmqSymbolDefinitions.ByName(name); + return symbolDefinition != null; + } + + public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) + { + return Intermediate.Load(typeof(MsmqExtensionData).Assembly, "WixToolset.Msmq.msmq.wixlib", symbolDefinitions); + } + } +} diff --git a/src/ext/Msmq/wixext/MsmqExtensionFactory.cs b/src/ext/Msmq/wixext/MsmqExtensionFactory.cs new file mode 100644 index 00000000..de9f786d --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqExtensionFactory.cs @@ -0,0 +1,18 @@ +// 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. + +namespace WixToolset.Msmq +{ + using System; + using System.Collections.Generic; + using WixToolset.Extensibility; + + public class MsmqExtensionFactory : BaseExtensionFactory + { + protected override IReadOnlyCollection ExtensionTypes => new[] + { + typeof(MsmqCompiler), + typeof(MsmqExtensionData), + typeof(MsmqWindowsInstallerBackendBinderExtension), + }; + } +} diff --git a/src/ext/Msmq/wixext/MsmqTableDefinitions.cs b/src/ext/Msmq/wixext/MsmqTableDefinitions.cs new file mode 100644 index 00000000..46e2dd10 --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqTableDefinitions.cs @@ -0,0 +1,64 @@ +// 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. + +namespace WixToolset.Msmq +{ + using WixToolset.Data.WindowsInstaller; + + public static class MsmqTableDefinitions + { + public static readonly TableDefinition MessageQueue = new TableDefinition( + "MessageQueue", + MsmqSymbolDefinitions.MessageQueue, + new[] + { + new ColumnDefinition("MessageQueue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("BasePriority", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), + new ColumnDefinition("JournalQuota", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), + new ColumnDefinition("Label", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("MulticastAddress", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("PathName", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("PrivLevel", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), + new ColumnDefinition("Quota", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), + new ColumnDefinition("ServiceTypeGuid", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition MessageQueueUserPermission = new TableDefinition( + "MessageQueueUserPermission", + MsmqSymbolDefinitions.MessageQueueUserPermission, + new[] + { + new ColumnDefinition("MessageQueueUserPermission", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("MessageQueue_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "MessageQueue", keyColumn: 1, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition MessageQueueGroupPermission = new TableDefinition( + "MessageQueueGroupPermission", + MsmqSymbolDefinitions.MessageQueueGroupPermission, + new[] + { + new ColumnDefinition("MessageQueueGroupPermission", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("MessageQueue_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "MessageQueue", keyColumn: 1, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Group_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition[] All = new[] + { + MessageQueue, + MessageQueueUserPermission, + MessageQueueGroupPermission, + }; + } +} diff --git a/src/ext/Msmq/wixext/MsmqWarnings.cs b/src/ext/Msmq/wixext/MsmqWarnings.cs new file mode 100644 index 00000000..41d160e9 --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqWarnings.cs @@ -0,0 +1,30 @@ +// 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. + +namespace WixToolset.Data +{ + using System; + using System.Resources; + + public static class MsmqWarnings + { + public static Message MissingComponents(SourceLineNumber sourceLineNumbers) + { + return Message(sourceLineNumbers, Ids.MissingComponents, "The MsmqAssembly element has a Type attribute with a value of 'native', but the element does not contain any MsmqComponent elements. All components contained in a native assembly must be listed, or they will not be correctly removed during uninstall."); + } + + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) + { + return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args); + } + + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) + { + return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, resourceManager, resourceName, args); + } + + public enum Ids + { + MissingComponents = 6007, + } + } +} diff --git a/src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs b/src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs new file mode 100644 index 00000000..d317fb60 --- /dev/null +++ b/src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs @@ -0,0 +1,13 @@ +// 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. + +namespace WixToolset.Msmq +{ + using System.Collections.Generic; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility; + + public class MsmqWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension + { + public override IReadOnlyCollection TableDefinitions => MsmqTableDefinitions.All; + } +} diff --git a/src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs b/src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs new file mode 100644 index 00000000..404c061c --- /dev/null +++ b/src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs @@ -0,0 +1,71 @@ +// 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. + +namespace WixToolset.Msmq +{ + using WixToolset.Data; + using WixToolset.Msmq.Symbols; + + public static partial class MsmqSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition MessageQueueGroupPermission = new IntermediateSymbolDefinition( + MsmqSymbolDefinitionType.MessageQueueGroupPermission.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.MessageQueueRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.GroupRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.Permissions), IntermediateFieldType.Number), + }, + typeof(MessageQueueGroupPermissionSymbol)); + } +} + +namespace WixToolset.Msmq.Symbols +{ + using WixToolset.Data; + + public enum MessageQueueGroupPermissionSymbolFields + { + ComponentRef, + MessageQueueRef, + GroupRef, + Permissions, + } + + public class MessageQueueGroupPermissionSymbol : IntermediateSymbol + { + public MessageQueueGroupPermissionSymbol() : base(MsmqSymbolDefinitions.MessageQueueGroupPermission, null, null) + { + } + + public MessageQueueGroupPermissionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueueGroupPermission, sourceLineNumber, id) + { + } + + public IntermediateField this[MessageQueueGroupPermissionSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.ComponentRef].AsString(); + set => this.Set((int)MessageQueueGroupPermissionSymbolFields.ComponentRef, value); + } + + public string MessageQueueRef + { + get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.MessageQueueRef].AsString(); + set => this.Set((int)MessageQueueGroupPermissionSymbolFields.MessageQueueRef, value); + } + + public string GroupRef + { + get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.GroupRef].AsString(); + set => this.Set((int)MessageQueueGroupPermissionSymbolFields.GroupRef, value); + } + + public int Permissions + { + get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.Permissions].AsNumber(); + set => this.Set((int)MessageQueueGroupPermissionSymbolFields.Permissions, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs b/src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs new file mode 100644 index 00000000..b911f0ea --- /dev/null +++ b/src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs @@ -0,0 +1,119 @@ +// 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. + +namespace WixToolset.Msmq +{ + using WixToolset.Data; + using WixToolset.Msmq.Symbols; + + public static partial class MsmqSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition MessageQueue = new IntermediateSymbolDefinition( + MsmqSymbolDefinitionType.MessageQueue.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.BasePriority), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.JournalQuota), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Label), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.MulticastAddress), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.PathName), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.PrivLevel), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Quota), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.ServiceTypeGuid), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Attributes), IntermediateFieldType.Number), + }, + typeof(MessageQueueSymbol)); + } +} + +namespace WixToolset.Msmq.Symbols +{ + using WixToolset.Data; + + public enum MessageQueueSymbolFields + { + ComponentRef, + BasePriority, + JournalQuota, + Label, + MulticastAddress, + PathName, + PrivLevel, + Quota, + ServiceTypeGuid, + Attributes, + } + + public class MessageQueueSymbol : IntermediateSymbol + { + public MessageQueueSymbol() : base(MsmqSymbolDefinitions.MessageQueue, null, null) + { + } + + public MessageQueueSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueue, sourceLineNumber, id) + { + } + + public IntermediateField this[MessageQueueSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)MessageQueueSymbolFields.ComponentRef].AsString(); + set => this.Set((int)MessageQueueSymbolFields.ComponentRef, value); + } + + public int? BasePriority + { + get => this.Fields[(int)MessageQueueSymbolFields.BasePriority].AsNullableNumber(); + set => this.Set((int)MessageQueueSymbolFields.BasePriority, value); + } + + public int? JournalQuota + { + get => this.Fields[(int)MessageQueueSymbolFields.JournalQuota].AsNullableNumber(); + set => this.Set((int)MessageQueueSymbolFields.JournalQuota, value); + } + + public string Label + { + get => this.Fields[(int)MessageQueueSymbolFields.Label].AsString(); + set => this.Set((int)MessageQueueSymbolFields.Label, value); + } + + public string MulticastAddress + { + get => this.Fields[(int)MessageQueueSymbolFields.MulticastAddress].AsString(); + set => this.Set((int)MessageQueueSymbolFields.MulticastAddress, value); + } + + public string PathName + { + get => this.Fields[(int)MessageQueueSymbolFields.PathName].AsString(); + set => this.Set((int)MessageQueueSymbolFields.PathName, value); + } + + public int? PrivLevel + { + get => this.Fields[(int)MessageQueueSymbolFields.PrivLevel].AsNullableNumber(); + set => this.Set((int)MessageQueueSymbolFields.PrivLevel, value); + } + + public int? Quota + { + get => this.Fields[(int)MessageQueueSymbolFields.Quota].AsNullableNumber(); + set => this.Set((int)MessageQueueSymbolFields.Quota, value); + } + + public string ServiceTypeGuid + { + get => this.Fields[(int)MessageQueueSymbolFields.ServiceTypeGuid].AsString(); + set => this.Set((int)MessageQueueSymbolFields.ServiceTypeGuid, value); + } + + public int Attributes + { + get => this.Fields[(int)MessageQueueSymbolFields.Attributes].AsNumber(); + set => this.Set((int)MessageQueueSymbolFields.Attributes, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs b/src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs new file mode 100644 index 00000000..cc783845 --- /dev/null +++ b/src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs @@ -0,0 +1,71 @@ +// 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. + +namespace WixToolset.Msmq +{ + using WixToolset.Data; + using WixToolset.Msmq.Symbols; + + public static partial class MsmqSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition MessageQueueUserPermission = new IntermediateSymbolDefinition( + MsmqSymbolDefinitionType.MessageQueueUserPermission.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.MessageQueueRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.UserRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.Permissions), IntermediateFieldType.Number), + }, + typeof(MessageQueueUserPermissionSymbol)); + } +} + +namespace WixToolset.Msmq.Symbols +{ + using WixToolset.Data; + + public enum MessageQueueUserPermissionSymbolFields + { + ComponentRef, + MessageQueueRef, + UserRef, + Permissions, + } + + public class MessageQueueUserPermissionSymbol : IntermediateSymbol + { + public MessageQueueUserPermissionSymbol() : base(MsmqSymbolDefinitions.MessageQueueUserPermission, null, null) + { + } + + public MessageQueueUserPermissionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueueUserPermission, sourceLineNumber, id) + { + } + + public IntermediateField this[MessageQueueUserPermissionSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.ComponentRef].AsString(); + set => this.Set((int)MessageQueueUserPermissionSymbolFields.ComponentRef, value); + } + + public string MessageQueueRef + { + get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.MessageQueueRef].AsString(); + set => this.Set((int)MessageQueueUserPermissionSymbolFields.MessageQueueRef, value); + } + + public string UserRef + { + get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.UserRef].AsString(); + set => this.Set((int)MessageQueueUserPermissionSymbolFields.UserRef, value); + } + + public int Permissions + { + get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.Permissions].AsNumber(); + set => this.Set((int)MessageQueueUserPermissionSymbolFields.Permissions, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs b/src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs new file mode 100644 index 00000000..229417fe --- /dev/null +++ b/src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs @@ -0,0 +1,47 @@ +// 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. + +namespace WixToolset.Msmq +{ + using System; + using WixToolset.Data; + + public enum MsmqSymbolDefinitionType + { + MessageQueue, + MessageQueueGroupPermission, + MessageQueueUserPermission, + } + + public static partial class MsmqSymbolDefinitions + { + public static readonly Version Version = new Version("4.0.0"); + + public static IntermediateSymbolDefinition ByName(string name) + { + if (!Enum.TryParse(name, out MsmqSymbolDefinitionType type)) + { + return null; + } + + return ByType(type); + } + + public static IntermediateSymbolDefinition ByType(MsmqSymbolDefinitionType type) + { + switch (type) + { + case MsmqSymbolDefinitionType.MessageQueue: + return MsmqSymbolDefinitions.MessageQueue; + + case MsmqSymbolDefinitionType.MessageQueueGroupPermission: + return MsmqSymbolDefinitions.MessageQueueGroupPermission; + + case MsmqSymbolDefinitionType.MessageQueueUserPermission: + return MsmqSymbolDefinitions.MessageQueueUserPermission; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + } +} diff --git a/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj new file mode 100644 index 00000000..4bd6a3f5 --- /dev/null +++ b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj @@ -0,0 +1,30 @@ + + + + + + netstandard2.0 + WixToolset.Msmq + WiX Toolset MSMQ Extension + WiX Toolset MSMQ Extension + true + build + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets new file mode 100644 index 00000000..5f69fe48 --- /dev/null +++ b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets @@ -0,0 +1,11 @@ + + + + + + $(MSBuildThisFileDirectory)..\tools\WixToolset.Msmq.wixext.dll + + + + + diff --git a/src/ext/Msmq/wixlib/MsmqExtension.wxs b/src/ext/Msmq/wixlib/MsmqExtension.wxs new file mode 100644 index 00000000..86239545 --- /dev/null +++ b/src/ext/Msmq/wixlib/MsmqExtension.wxs @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Msmq/wixlib/caerr.wxi b/src/ext/Msmq/wixlib/caerr.wxi new file mode 100644 index 00000000..ff7ec121 --- /dev/null +++ b/src/ext/Msmq/wixlib/caerr.wxi @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/Msmq/wixlib/en-us.wxl b/src/ext/Msmq/wixlib/en-us.wxl new file mode 100644 index 00000000..ebe08095 --- /dev/null +++ b/src/ext/Msmq/wixlib/en-us.wxl @@ -0,0 +1,10 @@ + + + + + + Configuring message queues + Queue: [1] + Configuring message queues + Queue: [1] + diff --git a/src/ext/Msmq/wixlib/ja-jp.wxl b/src/ext/Msmq/wixlib/ja-jp.wxl new file mode 100644 index 00000000..d56cd7ec --- /dev/null +++ b/src/ext/Msmq/wixlib/ja-jp.wxl @@ -0,0 +1,10 @@ + + + + + + メッセージ キューを構成しています + キュー: [1] + メッセージ キューを構成しています + キュー: [1] + diff --git a/src/ext/Msmq/wixlib/msmq.wixproj b/src/ext/Msmq/wixlib/msmq.wixproj new file mode 100644 index 00000000..ccccbf49 --- /dev/null +++ b/src/ext/Msmq/wixlib/msmq.wixproj @@ -0,0 +1,18 @@ + + + + + Library + true + en-us + + + + + + + + + + + diff --git a/src/ext/global.json b/src/ext/global.json new file mode 100644 index 00000000..23dd3fa6 --- /dev/null +++ b/src/ext/global.json @@ -0,0 +1,5 @@ +{ + "msbuild-sdks": { + "WixToolset.Sdk": "4.0.0-build-0211" + } +} diff --git a/src/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs b/src/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs deleted file mode 100644 index 057b0a9d..00000000 --- a/src/test/WixToolsetTest.Msmq/MsmqExtensionFixture.cs +++ /dev/null @@ -1,32 +0,0 @@ -// 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. - -namespace WixToolsetTest.Msmq -{ - using System.Linq; - using WixBuildTools.TestSupport; - using WixToolset.Core.TestPackage; - using WixToolset.Msmq; - using Xunit; - - public class MsmqExtensionFixture - { - [Fact] - public void CanBuildUsingMessageQueue() - { - var folder = TestData.Get(@"TestData\UsingMessageQueue"); - var build = new Builder(folder, typeof(MsmqExtensionFactory), new[] { folder }); - - var results = build.BuildAndQuery(Build, "MessageQueue"); - Assert.Equal(new[] - { - "MessageQueue:TestMQ\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\t\t\tMQLabel\t\tMQPath\t\t\t\t0", - }, results); - } - - private static void Build(string[] args) - { - var result = WixRunner.Execute(args) - .AssertSuccess(); - } - } -} diff --git a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl b/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl deleted file mode 100644 index 38c12ac1..00000000 --- a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.en-us.wxl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - A newer version of [ProductName] is already installed. - MsiPackage - - diff --git a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs b/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs deleted file mode 100644 index bd31e81f..00000000 --- a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/Package.wxs +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs b/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs deleted file mode 100644 index ff9f7d92..00000000 --- a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/PackageComponents.wxs +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt b/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt deleted file mode 100644 index 1b4ffe8a..00000000 --- a/src/test/WixToolsetTest.Msmq/TestData/UsingMessageQueue/example.txt +++ /dev/null @@ -1 +0,0 @@ -This is example.txt. \ No newline at end of file diff --git a/src/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj b/src/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj deleted file mode 100644 index 7f74e043..00000000 --- a/src/test/WixToolsetTest.Msmq/WixToolsetTest.Msmq.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - netcoreapp3.1 - false - - - - NU1701 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/version.json b/src/version.json new file mode 100644 index 00000000..5f857771 --- /dev/null +++ b/src/version.json @@ -0,0 +1,11 @@ +{ + "version": "4.0", + "publicReleaseRefSpec": [ + "^refs/heads/master$" + ], + "cloudBuild": { + "buildNumber": { + "enabled": true + } + } +} diff --git a/src/wix.snk b/src/wix.snk deleted file mode 100644 index 3908a66a..00000000 Binary files a/src/wix.snk and /dev/null differ diff --git a/src/wixext/MsmqCompiler.cs b/src/wixext/MsmqCompiler.cs deleted file mode 100644 index cfc4ef65..00000000 --- a/src/wixext/MsmqCompiler.cs +++ /dev/null @@ -1,528 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using System; - using System.Collections.Generic; - using System.Xml.Linq; - using WixToolset.Data; - using WixToolset.Extensibility; - using WixToolset.Msmq.Symbols; - - /// - /// The compiler for the WiX Toolset MSMQ Extension. - /// - public sealed class MsmqCompiler : BaseCompilerExtension - { - public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/msmq"; - - /// - /// - /// - public enum MqiMessageQueueAttributes - { - Authenticate = (1 << 0), - Journal = (1 << 1), - Transactional = (1 << 2) - } - - /// - /// - /// - public enum MqiMessageQueuePrivacyLevel - { - None = 0, - Optional = 1, - Body = 2 - } - - /// - /// - /// - public enum MqiMessageQueuePermission - { - DeleteMessage = (1 << 0), - PeekMessage = (1 << 1), - WriteMessage = (1 << 2), - DeleteJournalMessage = (1 << 3), - SetQueueProperties = (1 << 4), - GetQueueProperties = (1 << 5), - DeleteQueue = (1 << 6), - GetQueuePermissions = (1 << 7), - ChangeQueuePermissions = (1 << 8), - TakeQueueOwnership = (1 << 9), - ReceiveMessage = (1 << 10), - ReceiveJournalMessage = (1 << 11), - QueueGenericRead = (1 << 12), - QueueGenericWrite = (1 << 13), - QueueGenericExecute = (1 << 14), - QueueGenericAll = (1 << 15) - } - - /// - /// Processes an element for the Compiler. - /// - /// Parent element of element to process. - /// Element to process. - /// Extra information about the context in which this element is being parsed. - public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary context) - { - switch (parentElement.Name.LocalName) - { - case "Component": - var componentId = context["ComponentId"]; - var directoryId = context["DirectoryId"]; - - switch (element.Name.LocalName) - { - case "MessageQueue": - this.ParseMessageQueueElement(intermediate, section, element, componentId); - break; - case "MessageQueuePermission": - this.ParseMessageQueuePermissionElement(intermediate, section, element, componentId, null); - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - } - - /// - /// Parses an MSMQ message queue element. - /// - /// Element to parse. - /// Identifier of parent component. - private void ParseMessageQueueElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); - - Identifier id = null; - var basePriority = CompilerConstants.IntegerNotSet; - var journalQuota = CompilerConstants.IntegerNotSet; - string label = null; - string multicastAddress = null; - string pathName = null; - var privLevel = CompilerConstants.IntegerNotSet; - var quota = CompilerConstants.IntegerNotSet; - string serviceTypeGuid = null; - int attributes = 0; - - foreach (var attrib in node.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - break; - case "Authenticate": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= (int)MqiMessageQueueAttributes.Authenticate; - } - else - { - attributes &= ~(int)MqiMessageQueueAttributes.Authenticate; - } - break; - case "BasePriority": - basePriority = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "Journal": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= (int)MqiMessageQueueAttributes.Journal; - } - else - { - attributes &= ~(int)MqiMessageQueueAttributes.Journal; - } - break; - case "JournalQuota": - journalQuota = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); - break; - case "Label": - label = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "MulticastAddress": - multicastAddress = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "PathName": - pathName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "PrivLevel": - var privLevelAttr = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - switch (privLevelAttr) - { - case "none": - privLevel = (int)MqiMessageQueuePrivacyLevel.None; - break; - case "optional": - privLevel = (int)MqiMessageQueuePrivacyLevel.Optional; - break; - case "body": - privLevel = (int)MqiMessageQueuePrivacyLevel.Body; - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "MessageQueue", "PrivLevel", privLevelAttr, "none", "body", "optional")); - break; - } - break; - case "Quota": - quota = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); - break; - case "Transactional": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= (int)MqiMessageQueueAttributes.Transactional; - } - else - { - attributes &= ~(int)MqiMessageQueueAttributes.Transactional; - } - break; - case "ServiceTypeGuid": - serviceTypeGuid = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib)); - break; - default: - this.ParseHelper.UnexpectedAttribute(node, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); - } - } - - foreach (var child in node.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - switch (child.Name.LocalName) - { - case "MessageQueuePermission": - this.ParseMessageQueuePermissionElement(intermediate, section, child, componentId, id?.Id); - break; - default: - this.ParseHelper.UnexpectedElement(node, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child); - } - } - - var symbol = section.AddSymbol(new MessageQueueSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - Label = label, - MulticastAddress = multicastAddress, - PathName = pathName, - ServiceTypeGuid = serviceTypeGuid, - Attributes = attributes, - }); - - if (CompilerConstants.IntegerNotSet != basePriority) - { - symbol.BasePriority = basePriority; - } - if (CompilerConstants.IntegerNotSet != journalQuota) - { - symbol.JournalQuota = journalQuota; - } - - if (CompilerConstants.IntegerNotSet != privLevel) - { - symbol.PrivLevel = privLevel; - } - if (CompilerConstants.IntegerNotSet != quota) - { - symbol.Quota = quota; - } - - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MessageQueuingInstall"); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MessageQueuingUninstall"); - } - - /// - /// Parses an MSMQ message queue permission element. - /// - /// Element to parse. - /// Identifier of parent component. - /// Optional identifier of parent message queue. - private void ParseMessageQueuePermissionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, string messageQueueId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); - - Identifier id = null; - string user = null; - string group = null; - int permissions = 0; - - foreach (var attrib in node.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - break; - case "MessageQueue": - if (null != messageQueueId) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName)); - } - messageQueueId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, MsmqSymbolDefinitions.MessageQueue, messageQueueId); - break; - case "User": - if (null != group) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "User", "Group")); - } - user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); - break; - case "Group": - if (null != user) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Group", "User")); - } - group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group); - break; - case "DeleteMessage": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.DeleteMessage; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.DeleteMessage; - } - break; - case "PeekMessage": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.PeekMessage; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.PeekMessage; - } - break; - case "WriteMessage": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.WriteMessage; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.WriteMessage; - } - break; - case "DeleteJournalMessage": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.DeleteJournalMessage; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.DeleteJournalMessage; - } - break; - case "SetQueueProperties": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.SetQueueProperties; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.SetQueueProperties; - } - break; - case "GetQueueProperties": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.GetQueueProperties; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.GetQueueProperties; - } - break; - case "DeleteQueue": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.DeleteQueue; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.DeleteQueue; - } - break; - case "GetQueuePermissions": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.GetQueuePermissions; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.GetQueuePermissions; - } - break; - case "ChangeQueuePermissions": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.ChangeQueuePermissions; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.ChangeQueuePermissions; - } - break; - case "TakeQueueOwnership": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.TakeQueueOwnership; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.TakeQueueOwnership; - } - break; - case "ReceiveMessage": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.ReceiveMessage; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.ReceiveMessage; - } - break; - case "ReceiveJournalMessage": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.ReceiveJournalMessage; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.ReceiveJournalMessage; - } - break; - case "QueueGenericRead": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.QueueGenericRead; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.QueueGenericRead; - } - break; - case "QueueGenericWrite": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.QueueGenericWrite; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.QueueGenericWrite; - } - break; - case "QueueGenericExecute": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.QueueGenericExecute; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.QueueGenericExecute; - } - break; - case "QueueGenericAll": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - permissions |= (int)MqiMessageQueuePermission.QueueGenericAll; - } - else - { - permissions &= ~(int)MqiMessageQueuePermission.QueueGenericAll; - } - break; - default: - this.ParseHelper.UnexpectedAttribute(node, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("mqp", componentId, messageQueueId, user, group); - } - - if (null == messageQueueId) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MessageQueue")); - } - if (null == user && null == group) - { - this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "User", "Group")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); - - if (null != user) - { - section.AddSymbol(new MessageQueueUserPermissionSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - MessageQueueRef = messageQueueId, - UserRef = user, - Permissions = permissions, - }); - } - if (null != group) - { - section.AddSymbol(new MessageQueueGroupPermissionSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - MessageQueueRef = messageQueueId, - GroupRef = group, - Permissions = permissions, - }); - } - } - - /// - /// Attempts to parse the input value as a GUID, and in case the value is a valid - /// GUID returnes it in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}". - /// - /// - /// - string TryFormatGuidValue(string val) - { - if (!Guid.TryParse(val, out var guid)) - { - return val; - } - return guid.ToString("B").ToUpper(); - } - } -} diff --git a/src/wixext/MsmqDecompiler.cs b/src/wixext/MsmqDecompiler.cs deleted file mode 100644 index aa8c34b6..00000000 --- a/src/wixext/MsmqDecompiler.cs +++ /dev/null @@ -1,305 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ -#if TODO_CONSIDER_DECOMPILER - using System; - using System.Collections; - using System.Globalization; - using WixToolset.Data; - using WixToolset.Extensibility; - using Msmq = WixToolset.Extensions.Serialize.Msmq; - using Wix = WixToolset.Data.Serialize; - - /// - /// The decompiler for the WiX Toolset MSMQ Extension. - /// - public sealed class MsmqDecompiler : DecompilerExtension - { - /// - /// Creates a decompiler for MSMQ Extension. - /// - public MsmqDecompiler() - { - this.TableDefinitions = MsmqExtensionData.GetExtensionTableDefinitions(); - } - - /// - /// Get the extensions library to be removed. - /// - /// Table definitions for library. - /// Library to remove from decompiled output. - public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) - { - return MsmqExtensionData.GetExtensionLibrary(tableDefinitions); - } - - /// - /// Decompiles an extension table. - /// - /// The table to decompile. - public override void DecompileTable(Table table) - { - switch (table.Name) - { - case "MessageQueue": - this.DecompileMessageQueueTable(table); - break; - case "MessageQueueUserPermission": - this.DecompileMessageQueueUserPermissionTable(table); - break; - case "MessageQueueGroupPermission": - this.DecompileMessageQueueGroupPermissionTable(table); - break; - default: - base.DecompileTable(table); - break; - } - } - - /// - /// Decompile the MessageQueue table. - /// - /// The table to decompile. - private void DecompileMessageQueueTable(Table table) - { - foreach (Row row in table.Rows) - { - Msmq.MessageQueue queue = new Msmq.MessageQueue(); - - queue.Id = (string)row[0]; - - if (null != row[2]) - { - queue.BasePriority = (int)row[2]; - } - - if (null != row[3]) - { - queue.JournalQuota = (int)row[3]; - } - - queue.Label = (string)row[4]; - - if (null != row[5]) - { - queue.MulticastAddress = (string)row[5]; - } - - queue.PathName = (string)row[6]; - - if (null != row[7]) - { - switch ((MsmqCompiler.MqiMessageQueuePrivacyLevel)row[7]) - { - case MsmqCompiler.MqiMessageQueuePrivacyLevel.None: - queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.none; - break; - case MsmqCompiler.MqiMessageQueuePrivacyLevel.Optional: - queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.optional; - break; - case MsmqCompiler.MqiMessageQueuePrivacyLevel.Body: - queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.body; - break; - default: - break; - } - } - - if (null != row[8]) - { - queue.Quota = (int)row[8]; - } - - if (null != row[9]) - { - queue.ServiceTypeGuid = (string)row[9]; - } - - int attributes = (int)row[10]; - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Authenticate)) - { - queue.Authenticate = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Journal)) - { - queue.Journal = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Transactional)) - { - queue.Transactional = Msmq.YesNoType.yes; - } - - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - if (null != component) - { - component.AddChild(queue); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - - /// - /// Decompile the MessageQueueUserPermission table. - /// - /// The table to decompile. - private void DecompileMessageQueueUserPermissionTable(Table table) - { - foreach (Row row in table.Rows) - { - Msmq.MessageQueuePermission queuePermission = new Msmq.MessageQueuePermission(); - - queuePermission.Id = (string)row[0]; - - if (null != row[2]) - { - queuePermission.MessageQueue = (string)row[2]; - } - - queuePermission.User = (string)row[3]; - - DecompileMessageQueuePermissionAttributes(row, queuePermission); - - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - if (null != component) - { - component.AddChild(queuePermission); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - - /// - /// Decompile the MessageQueueGroupPermission table. - /// - /// The table to decompile. - private void DecompileMessageQueueGroupPermissionTable(Table table) - { - foreach (Row row in table.Rows) - { - Msmq.MessageQueuePermission queuePermission = new Msmq.MessageQueuePermission(); - - queuePermission.Id = (string)row[0]; - - if (null != row[2]) - { - queuePermission.MessageQueue = (string)row[2]; - } - - queuePermission.Group = (string)row[3]; - - DecompileMessageQueuePermissionAttributes(row, queuePermission); - - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - if (null != component) - { - component.AddChild(queuePermission); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - - /// - /// Decompile row attributes for the MessageQueueUserPermission and MessageQueueGroupPermission tables. - /// - /// The row to decompile. - /// Target element. - private void DecompileMessageQueuePermissionAttributes(Row row, Msmq.MessageQueuePermission queuePermission) - { - int attributes = (int)row[4]; - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteMessage)) - { - queuePermission.DeleteMessage = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.PeekMessage)) - { - queuePermission.PeekMessage = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.WriteMessage)) - { - queuePermission.WriteMessage = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteJournalMessage)) - { - queuePermission.DeleteJournalMessage = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.SetQueueProperties)) - { - queuePermission.SetQueueProperties = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.GetQueueProperties)) - { - queuePermission.GetQueueProperties = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteQueue)) - { - queuePermission.DeleteQueue = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.GetQueuePermissions)) - { - queuePermission.GetQueuePermissions = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ChangeQueuePermissions)) - { - queuePermission.ChangeQueuePermissions = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.TakeQueueOwnership)) - { - queuePermission.TakeQueueOwnership = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ReceiveMessage)) - { - queuePermission.ReceiveMessage = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ReceiveJournalMessage)) - { - queuePermission.ReceiveJournalMessage = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericRead)) - { - queuePermission.QueueGenericRead = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericWrite)) - { - queuePermission.QueueGenericWrite = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericExecute)) - { - queuePermission.QueueGenericExecute = Msmq.YesNoType.yes; - } - - if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericAll)) - { - queuePermission.QueueGenericAll = Msmq.YesNoType.yes; - } - } - } -#endif -} diff --git a/src/wixext/MsmqErrors.cs b/src/wixext/MsmqErrors.cs deleted file mode 100644 index 4342e1cf..00000000 --- a/src/wixext/MsmqErrors.cs +++ /dev/null @@ -1,71 +0,0 @@ -// 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. - -namespace WixToolset.Data -{ - using System; - using System.Resources; - - public static class MsmqErrors - { - public static Message IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) - { - return Message(sourceLineNumbers, Ids.IllegalAttributeWithoutComponent, "The {0}/@{1} attribute cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName, attributeName); - } - - public static Message IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName) - { - return Message(sourceLineNumbers, Ids.IllegalElementWithoutComponent, "The {0} element cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName); - } - - public static Message RequiredAttribute(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2) - { - return Message(sourceLineNumbers, Ids.RequiredAttribute, "A {0} element must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2); - } - - public static Message RequiredAttributeNotUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2) - { - return Message(sourceLineNumbers, Ids.RequiredAttributeNotUnderComponent, "A {0} element not nested under a component must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2); - } - - public static Message RequiredAttributeUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) - { - return Message(sourceLineNumbers, Ids.RequiredAttributeUnderComponent, "The {0}/@{1} attribute must be provided when {0} element is nested under a component.", elementName, attributeName); - } - - public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue) - { - return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute cannot coexist with the {2} attribute's value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue); - } - - public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value, string otherAttributeName, string otherValue) - { - return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute's value, '{2}', cannot coexist with the {3} attribute's value of '{4}'.", elementName, attributeName, value, otherAttributeName, otherValue); - } - - public static Message UnexpectedAttributeWithoutOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue) - { - return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithoutOtherValue, "The {0}/@{1} cannot be provided unless the {2} attribute is provided with a value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue); - } - - private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) - { - return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); - } - - private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) - { - return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args); - } - - public enum Ids - { - IllegalAttributeWithoutComponent = 6000, - IllegalElementWithoutComponent = 6001, - UnexpectedAttributeWithOtherValue = 6002, - UnexpectedAttributeWithoutOtherValue = 6003, - RequiredAttributeUnderComponent = 6004, - RequiredAttribute = 6005, - RequiredAttributeNotUnderComponent = 6006, - } - } -} diff --git a/src/wixext/MsmqExtensionData.cs b/src/wixext/MsmqExtensionData.cs deleted file mode 100644 index 91485724..00000000 --- a/src/wixext/MsmqExtensionData.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using WixToolset.Data; - using WixToolset.Extensibility; - - /// - /// The WiX Toolset MSMQ Extension. - /// - public sealed class MsmqExtensionData : BaseExtensionData - { - /// - /// Gets the default culture. - /// - /// The default culture. - public override string DefaultCulture => "en-US"; - - public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) - { - symbolDefinition = MsmqSymbolDefinitions.ByName(name); - return symbolDefinition != null; - } - - public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) - { - return Intermediate.Load(typeof(MsmqExtensionData).Assembly, "WixToolset.Msmq.msmq.wixlib", symbolDefinitions); - } - } -} diff --git a/src/wixext/MsmqExtensionFactory.cs b/src/wixext/MsmqExtensionFactory.cs deleted file mode 100644 index de9f786d..00000000 --- a/src/wixext/MsmqExtensionFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using System; - using System.Collections.Generic; - using WixToolset.Extensibility; - - public class MsmqExtensionFactory : BaseExtensionFactory - { - protected override IReadOnlyCollection ExtensionTypes => new[] - { - typeof(MsmqCompiler), - typeof(MsmqExtensionData), - typeof(MsmqWindowsInstallerBackendBinderExtension), - }; - } -} diff --git a/src/wixext/MsmqTableDefinitions.cs b/src/wixext/MsmqTableDefinitions.cs deleted file mode 100644 index 46e2dd10..00000000 --- a/src/wixext/MsmqTableDefinitions.cs +++ /dev/null @@ -1,64 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using WixToolset.Data.WindowsInstaller; - - public static class MsmqTableDefinitions - { - public static readonly TableDefinition MessageQueue = new TableDefinition( - "MessageQueue", - MsmqSymbolDefinitions.MessageQueue, - new[] - { - new ColumnDefinition("MessageQueue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("BasePriority", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), - new ColumnDefinition("JournalQuota", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), - new ColumnDefinition("Label", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("MulticastAddress", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("PathName", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("PrivLevel", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), - new ColumnDefinition("Quota", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown), - new ColumnDefinition("ServiceTypeGuid", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition MessageQueueUserPermission = new TableDefinition( - "MessageQueueUserPermission", - MsmqSymbolDefinitions.MessageQueueUserPermission, - new[] - { - new ColumnDefinition("MessageQueueUserPermission", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("MessageQueue_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "MessageQueue", keyColumn: 1, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition MessageQueueGroupPermission = new TableDefinition( - "MessageQueueGroupPermission", - MsmqSymbolDefinitions.MessageQueueGroupPermission, - new[] - { - new ColumnDefinition("MessageQueueGroupPermission", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("MessageQueue_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "MessageQueue", keyColumn: 1, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Group_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition[] All = new[] - { - MessageQueue, - MessageQueueUserPermission, - MessageQueueGroupPermission, - }; - } -} diff --git a/src/wixext/MsmqWarnings.cs b/src/wixext/MsmqWarnings.cs deleted file mode 100644 index 41d160e9..00000000 --- a/src/wixext/MsmqWarnings.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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. - -namespace WixToolset.Data -{ - using System; - using System.Resources; - - public static class MsmqWarnings - { - public static Message MissingComponents(SourceLineNumber sourceLineNumbers) - { - return Message(sourceLineNumbers, Ids.MissingComponents, "The MsmqAssembly element has a Type attribute with a value of 'native', but the element does not contain any MsmqComponent elements. All components contained in a native assembly must be listed, or they will not be correctly removed during uninstall."); - } - - private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) - { - return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args); - } - - private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) - { - return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, resourceManager, resourceName, args); - } - - public enum Ids - { - MissingComponents = 6007, - } - } -} diff --git a/src/wixext/MsmqWindowsInstallerBackendExtension.cs b/src/wixext/MsmqWindowsInstallerBackendExtension.cs deleted file mode 100644 index d317fb60..00000000 --- a/src/wixext/MsmqWindowsInstallerBackendExtension.cs +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using System.Collections.Generic; - using WixToolset.Data.WindowsInstaller; - using WixToolset.Extensibility; - - public class MsmqWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension - { - public override IReadOnlyCollection TableDefinitions => MsmqTableDefinitions.All; - } -} diff --git a/src/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs b/src/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs deleted file mode 100644 index 404c061c..00000000 --- a/src/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs +++ /dev/null @@ -1,71 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using WixToolset.Data; - using WixToolset.Msmq.Symbols; - - public static partial class MsmqSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition MessageQueueGroupPermission = new IntermediateSymbolDefinition( - MsmqSymbolDefinitionType.MessageQueueGroupPermission.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.MessageQueueRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.GroupRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.Permissions), IntermediateFieldType.Number), - }, - typeof(MessageQueueGroupPermissionSymbol)); - } -} - -namespace WixToolset.Msmq.Symbols -{ - using WixToolset.Data; - - public enum MessageQueueGroupPermissionSymbolFields - { - ComponentRef, - MessageQueueRef, - GroupRef, - Permissions, - } - - public class MessageQueueGroupPermissionSymbol : IntermediateSymbol - { - public MessageQueueGroupPermissionSymbol() : base(MsmqSymbolDefinitions.MessageQueueGroupPermission, null, null) - { - } - - public MessageQueueGroupPermissionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueueGroupPermission, sourceLineNumber, id) - { - } - - public IntermediateField this[MessageQueueGroupPermissionSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.ComponentRef].AsString(); - set => this.Set((int)MessageQueueGroupPermissionSymbolFields.ComponentRef, value); - } - - public string MessageQueueRef - { - get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.MessageQueueRef].AsString(); - set => this.Set((int)MessageQueueGroupPermissionSymbolFields.MessageQueueRef, value); - } - - public string GroupRef - { - get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.GroupRef].AsString(); - set => this.Set((int)MessageQueueGroupPermissionSymbolFields.GroupRef, value); - } - - public int Permissions - { - get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.Permissions].AsNumber(); - set => this.Set((int)MessageQueueGroupPermissionSymbolFields.Permissions, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/MessageQueueSymbol.cs b/src/wixext/Symbols/MessageQueueSymbol.cs deleted file mode 100644 index b911f0ea..00000000 --- a/src/wixext/Symbols/MessageQueueSymbol.cs +++ /dev/null @@ -1,119 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using WixToolset.Data; - using WixToolset.Msmq.Symbols; - - public static partial class MsmqSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition MessageQueue = new IntermediateSymbolDefinition( - MsmqSymbolDefinitionType.MessageQueue.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.BasePriority), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.JournalQuota), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Label), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.MulticastAddress), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.PathName), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.PrivLevel), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Quota), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.ServiceTypeGuid), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Attributes), IntermediateFieldType.Number), - }, - typeof(MessageQueueSymbol)); - } -} - -namespace WixToolset.Msmq.Symbols -{ - using WixToolset.Data; - - public enum MessageQueueSymbolFields - { - ComponentRef, - BasePriority, - JournalQuota, - Label, - MulticastAddress, - PathName, - PrivLevel, - Quota, - ServiceTypeGuid, - Attributes, - } - - public class MessageQueueSymbol : IntermediateSymbol - { - public MessageQueueSymbol() : base(MsmqSymbolDefinitions.MessageQueue, null, null) - { - } - - public MessageQueueSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueue, sourceLineNumber, id) - { - } - - public IntermediateField this[MessageQueueSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)MessageQueueSymbolFields.ComponentRef].AsString(); - set => this.Set((int)MessageQueueSymbolFields.ComponentRef, value); - } - - public int? BasePriority - { - get => this.Fields[(int)MessageQueueSymbolFields.BasePriority].AsNullableNumber(); - set => this.Set((int)MessageQueueSymbolFields.BasePriority, value); - } - - public int? JournalQuota - { - get => this.Fields[(int)MessageQueueSymbolFields.JournalQuota].AsNullableNumber(); - set => this.Set((int)MessageQueueSymbolFields.JournalQuota, value); - } - - public string Label - { - get => this.Fields[(int)MessageQueueSymbolFields.Label].AsString(); - set => this.Set((int)MessageQueueSymbolFields.Label, value); - } - - public string MulticastAddress - { - get => this.Fields[(int)MessageQueueSymbolFields.MulticastAddress].AsString(); - set => this.Set((int)MessageQueueSymbolFields.MulticastAddress, value); - } - - public string PathName - { - get => this.Fields[(int)MessageQueueSymbolFields.PathName].AsString(); - set => this.Set((int)MessageQueueSymbolFields.PathName, value); - } - - public int? PrivLevel - { - get => this.Fields[(int)MessageQueueSymbolFields.PrivLevel].AsNullableNumber(); - set => this.Set((int)MessageQueueSymbolFields.PrivLevel, value); - } - - public int? Quota - { - get => this.Fields[(int)MessageQueueSymbolFields.Quota].AsNullableNumber(); - set => this.Set((int)MessageQueueSymbolFields.Quota, value); - } - - public string ServiceTypeGuid - { - get => this.Fields[(int)MessageQueueSymbolFields.ServiceTypeGuid].AsString(); - set => this.Set((int)MessageQueueSymbolFields.ServiceTypeGuid, value); - } - - public int Attributes - { - get => this.Fields[(int)MessageQueueSymbolFields.Attributes].AsNumber(); - set => this.Set((int)MessageQueueSymbolFields.Attributes, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/MessageQueueUserPermissionSymbol.cs b/src/wixext/Symbols/MessageQueueUserPermissionSymbol.cs deleted file mode 100644 index cc783845..00000000 --- a/src/wixext/Symbols/MessageQueueUserPermissionSymbol.cs +++ /dev/null @@ -1,71 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using WixToolset.Data; - using WixToolset.Msmq.Symbols; - - public static partial class MsmqSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition MessageQueueUserPermission = new IntermediateSymbolDefinition( - MsmqSymbolDefinitionType.MessageQueueUserPermission.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.MessageQueueRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.UserRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.Permissions), IntermediateFieldType.Number), - }, - typeof(MessageQueueUserPermissionSymbol)); - } -} - -namespace WixToolset.Msmq.Symbols -{ - using WixToolset.Data; - - public enum MessageQueueUserPermissionSymbolFields - { - ComponentRef, - MessageQueueRef, - UserRef, - Permissions, - } - - public class MessageQueueUserPermissionSymbol : IntermediateSymbol - { - public MessageQueueUserPermissionSymbol() : base(MsmqSymbolDefinitions.MessageQueueUserPermission, null, null) - { - } - - public MessageQueueUserPermissionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueueUserPermission, sourceLineNumber, id) - { - } - - public IntermediateField this[MessageQueueUserPermissionSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.ComponentRef].AsString(); - set => this.Set((int)MessageQueueUserPermissionSymbolFields.ComponentRef, value); - } - - public string MessageQueueRef - { - get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.MessageQueueRef].AsString(); - set => this.Set((int)MessageQueueUserPermissionSymbolFields.MessageQueueRef, value); - } - - public string UserRef - { - get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.UserRef].AsString(); - set => this.Set((int)MessageQueueUserPermissionSymbolFields.UserRef, value); - } - - public int Permissions - { - get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.Permissions].AsNumber(); - set => this.Set((int)MessageQueueUserPermissionSymbolFields.Permissions, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/MsmqSymbolDefinitions.cs b/src/wixext/Symbols/MsmqSymbolDefinitions.cs deleted file mode 100644 index 229417fe..00000000 --- a/src/wixext/Symbols/MsmqSymbolDefinitions.cs +++ /dev/null @@ -1,47 +0,0 @@ -// 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. - -namespace WixToolset.Msmq -{ - using System; - using WixToolset.Data; - - public enum MsmqSymbolDefinitionType - { - MessageQueue, - MessageQueueGroupPermission, - MessageQueueUserPermission, - } - - public static partial class MsmqSymbolDefinitions - { - public static readonly Version Version = new Version("4.0.0"); - - public static IntermediateSymbolDefinition ByName(string name) - { - if (!Enum.TryParse(name, out MsmqSymbolDefinitionType type)) - { - return null; - } - - return ByType(type); - } - - public static IntermediateSymbolDefinition ByType(MsmqSymbolDefinitionType type) - { - switch (type) - { - case MsmqSymbolDefinitionType.MessageQueue: - return MsmqSymbolDefinitions.MessageQueue; - - case MsmqSymbolDefinitionType.MessageQueueGroupPermission: - return MsmqSymbolDefinitions.MessageQueueGroupPermission; - - case MsmqSymbolDefinitionType.MessageQueueUserPermission: - return MsmqSymbolDefinitions.MessageQueueUserPermission; - - default: - throw new ArgumentOutOfRangeException(nameof(type)); - } - } - } -} diff --git a/src/wixext/WixToolset.Msmq.wixext.csproj b/src/wixext/WixToolset.Msmq.wixext.csproj deleted file mode 100644 index 4bd6a3f5..00000000 --- a/src/wixext/WixToolset.Msmq.wixext.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - netstandard2.0 - WixToolset.Msmq - WiX Toolset MSMQ Extension - WiX Toolset MSMQ Extension - true - build - - - - - - - - - - - - - - - - - - - diff --git a/src/wixext/WixToolset.Msmq.wixext.targets b/src/wixext/WixToolset.Msmq.wixext.targets deleted file mode 100644 index 5f69fe48..00000000 --- a/src/wixext/WixToolset.Msmq.wixext.targets +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - $(MSBuildThisFileDirectory)..\tools\WixToolset.Msmq.wixext.dll - - - - - diff --git a/src/wixlib/MsmqExtension.wxs b/src/wixlib/MsmqExtension.wxs deleted file mode 100644 index 86239545..00000000 --- a/src/wixlib/MsmqExtension.wxs +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/wixlib/caerr.wxi b/src/wixlib/caerr.wxi deleted file mode 100644 index ff7ec121..00000000 --- a/src/wixlib/caerr.wxi +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/wixlib/en-us.wxl b/src/wixlib/en-us.wxl deleted file mode 100644 index ebe08095..00000000 --- a/src/wixlib/en-us.wxl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - Configuring message queues - Queue: [1] - Configuring message queues - Queue: [1] - diff --git a/src/wixlib/ja-jp.wxl b/src/wixlib/ja-jp.wxl deleted file mode 100644 index d56cd7ec..00000000 --- a/src/wixlib/ja-jp.wxl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - メッセージ キューを構成しています - キュー: [1] - メッセージ キューを構成しています - キュー: [1] - diff --git a/src/wixlib/msmq.wixproj b/src/wixlib/msmq.wixproj deleted file mode 100644 index ccccbf49..00000000 --- a/src/wixlib/msmq.wixproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Library - true - en-us - - - - - - - - - - - diff --git a/version.json b/version.json deleted file mode 100644 index 5f857771..00000000 --- a/version.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "4.0", - "publicReleaseRefSpec": [ - "^refs/heads/master$" - ], - "cloudBuild": { - "buildNumber": { - "enabled": true - } - } -} -- cgit v1.2.3-55-g6feb