From 7c8e34de56b3348c5a421cd0cced183e1394c5c7 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 4 May 2021 22:48:12 -0700 Subject: Move Iis.wixext into ext --- .editorconfig | 37 - Iis.wixext.sln | 58 - 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 | 48 - src/ca/caDecor.h | 13 - src/ca/dllmain.cpp | 26 - src/ca/iisca.cpp | 3 - src/ca/iisca.def | 30 - src/ca/iisca.vcxproj | 147 - src/ca/packages.config | 5 - src/ca/precomp.h | 66 - src/ca/sca.h | 124 - src/ca/scaapppool.cpp | 594 --- src/ca/scaapppool.h | 88 - src/ca/scaapppool7.cpp | 401 -- src/ca/scaapppool7.h | 36 - src/ca/scacert.cpp | 1482 ------- src/ca/scacert.h | 23 - src/ca/scacertexec.cpp | 431 -- src/ca/scacost.h | 15 - src/ca/scaexec.cpp | 1184 ------ src/ca/scaexecIIS7.cpp | 4205 -------------------- src/ca/scaexecIIS7.h | 5 - src/ca/scafilter.cpp | 510 --- src/ca/scafilter.h | 46 - src/ca/scafilter7.cpp | 284 -- src/ca/scafilter7.h | 21 - src/ca/scahttpheader.cpp | 323 -- src/ca/scahttpheader.h | 40 - src/ca/scahttpheader7.cpp | 130 - src/ca/scahttpheader7.h | 15 - src/ca/scaiis.cpp | 481 --- src/ca/scaiis.h | 33 - src/ca/scaiis7.cpp | 74 - src/ca/scaiis7.h | 17 - src/ca/scamimemap.cpp | 200 - src/ca/scamimemap.h | 33 - src/ca/scamimemap7.cpp | 68 - src/ca/scamimemap7.h | 10 - src/ca/scaproperty.cpp | 252 -- src/ca/scaproperty.h | 54 - src/ca/scaproperty7.cpp | 108 - src/ca/scaproperty7.h | 26 - src/ca/scasched.cpp | 823 ---- src/ca/scassl.cpp | 115 - src/ca/scassl.h | 36 - src/ca/scassl7.cpp | 34 - src/ca/scassl7.h | 8 - src/ca/scauser.cpp | 91 - src/ca/scauser.h | 39 - src/ca/scavdir.cpp | 331 -- src/ca/scavdir.h | 71 - src/ca/scavdir7.cpp | 380 -- src/ca/scavdir7.h | 66 - src/ca/scaweb.cpp | 1187 ------ src/ca/scaweb.h | 123 - src/ca/scaweb7.cpp | 953 ----- src/ca/scaweb7.h | 97 - src/ca/scawebapp.cpp | 194 - src/ca/scawebapp.h | 42 - src/ca/scawebapp7.cpp | 120 - src/ca/scawebapp7.h | 10 - src/ca/scawebappext.cpp | 207 - src/ca/scawebappext.h | 32 - src/ca/scawebappext7.cpp | 61 - src/ca/scawebappext7.h | 9 - src/ca/scawebdir.cpp | 241 -- src/ca/scawebdir.h | 57 - src/ca/scawebdir7.cpp | 219 - src/ca/scawebdir7.h | 51 - src/ca/scaweberr.cpp | 371 -- src/ca/scaweberr.h | 30 - src/ca/scaweberr7.cpp | 88 - src/ca/scaweberr7.h | 10 - src/ca/scaweblog.cpp | 177 - src/ca/scaweblog.h | 27 - src/ca/scaweblog7.cpp | 120 - src/ca/scaweblog7.h | 14 - src/ca/scawebprop.cpp | 301 -- src/ca/scawebprop.h | 60 - src/ca/scawebprop7.cpp | 155 - src/ca/scawebprop7.h | 12 - src/ca/scawebsvcext.cpp | 343 -- src/ca/scawebsvcext.h | 35 - src/ca/scawebsvcext7.cpp | 106 - src/ca/scawebsvcext7.h | 8 - src/ext/Iis/CSharp.Build.props | 11 + src/ext/Iis/Cpp.Build.props | 86 + src/ext/Iis/Directory.Build.props | 29 + src/ext/Iis/Directory.Build.targets | 48 + src/ext/Iis/Iis.wixext.sln | 58 + src/ext/Iis/README.md | 2 + src/ext/Iis/appveyor.cmd | 14 + src/ext/Iis/appveyor.yml | 40 + src/ext/Iis/ca/CustomMsiErrors.h | 48 + src/ext/Iis/ca/caDecor.h | 13 + src/ext/Iis/ca/dllmain.cpp | 26 + src/ext/Iis/ca/iisca.cpp | 3 + src/ext/Iis/ca/iisca.def | 30 + src/ext/Iis/ca/iisca.vcxproj | 147 + src/ext/Iis/ca/packages.config | 5 + src/ext/Iis/ca/precomp.h | 66 + src/ext/Iis/ca/sca.h | 124 + src/ext/Iis/ca/scaapppool.cpp | 594 +++ src/ext/Iis/ca/scaapppool.h | 88 + src/ext/Iis/ca/scaapppool7.cpp | 401 ++ src/ext/Iis/ca/scaapppool7.h | 36 + src/ext/Iis/ca/scacert.cpp | 1482 +++++++ src/ext/Iis/ca/scacert.h | 23 + src/ext/Iis/ca/scacertexec.cpp | 431 ++ src/ext/Iis/ca/scacost.h | 15 + src/ext/Iis/ca/scaexec.cpp | 1184 ++++++ src/ext/Iis/ca/scaexecIIS7.cpp | 4205 ++++++++++++++++++++ src/ext/Iis/ca/scaexecIIS7.h | 5 + src/ext/Iis/ca/scafilter.cpp | 510 +++ src/ext/Iis/ca/scafilter.h | 46 + src/ext/Iis/ca/scafilter7.cpp | 284 ++ src/ext/Iis/ca/scafilter7.h | 21 + src/ext/Iis/ca/scahttpheader.cpp | 323 ++ src/ext/Iis/ca/scahttpheader.h | 40 + src/ext/Iis/ca/scahttpheader7.cpp | 130 + src/ext/Iis/ca/scahttpheader7.h | 15 + src/ext/Iis/ca/scaiis.cpp | 481 +++ src/ext/Iis/ca/scaiis.h | 33 + src/ext/Iis/ca/scaiis7.cpp | 74 + src/ext/Iis/ca/scaiis7.h | 17 + src/ext/Iis/ca/scamimemap.cpp | 200 + src/ext/Iis/ca/scamimemap.h | 33 + src/ext/Iis/ca/scamimemap7.cpp | 68 + src/ext/Iis/ca/scamimemap7.h | 10 + src/ext/Iis/ca/scaproperty.cpp | 252 ++ src/ext/Iis/ca/scaproperty.h | 54 + src/ext/Iis/ca/scaproperty7.cpp | 108 + src/ext/Iis/ca/scaproperty7.h | 26 + src/ext/Iis/ca/scasched.cpp | 823 ++++ src/ext/Iis/ca/scassl.cpp | 115 + src/ext/Iis/ca/scassl.h | 36 + src/ext/Iis/ca/scassl7.cpp | 34 + src/ext/Iis/ca/scassl7.h | 8 + src/ext/Iis/ca/scauser.cpp | 91 + src/ext/Iis/ca/scauser.h | 39 + src/ext/Iis/ca/scavdir.cpp | 331 ++ src/ext/Iis/ca/scavdir.h | 71 + src/ext/Iis/ca/scavdir7.cpp | 380 ++ src/ext/Iis/ca/scavdir7.h | 66 + src/ext/Iis/ca/scaweb.cpp | 1187 ++++++ src/ext/Iis/ca/scaweb.h | 123 + src/ext/Iis/ca/scaweb7.cpp | 953 +++++ src/ext/Iis/ca/scaweb7.h | 97 + src/ext/Iis/ca/scawebapp.cpp | 194 + src/ext/Iis/ca/scawebapp.h | 42 + src/ext/Iis/ca/scawebapp7.cpp | 120 + src/ext/Iis/ca/scawebapp7.h | 10 + src/ext/Iis/ca/scawebappext.cpp | 207 + src/ext/Iis/ca/scawebappext.h | 32 + src/ext/Iis/ca/scawebappext7.cpp | 61 + src/ext/Iis/ca/scawebappext7.h | 9 + src/ext/Iis/ca/scawebdir.cpp | 241 ++ src/ext/Iis/ca/scawebdir.h | 57 + src/ext/Iis/ca/scawebdir7.cpp | 219 + src/ext/Iis/ca/scawebdir7.h | 51 + src/ext/Iis/ca/scaweberr.cpp | 371 ++ src/ext/Iis/ca/scaweberr.h | 30 + src/ext/Iis/ca/scaweberr7.cpp | 88 + src/ext/Iis/ca/scaweberr7.h | 10 + src/ext/Iis/ca/scaweblog.cpp | 177 + src/ext/Iis/ca/scaweblog.h | 27 + src/ext/Iis/ca/scaweblog7.cpp | 120 + src/ext/Iis/ca/scaweblog7.h | 14 + src/ext/Iis/ca/scawebprop.cpp | 301 ++ src/ext/Iis/ca/scawebprop.h | 60 + src/ext/Iis/ca/scawebprop7.cpp | 155 + src/ext/Iis/ca/scawebprop7.h | 12 + src/ext/Iis/ca/scawebsvcext.cpp | 343 ++ src/ext/Iis/ca/scawebsvcext.h | 35 + src/ext/Iis/ca/scawebsvcext7.cpp | 106 + src/ext/Iis/ca/scawebsvcext7.h | 8 + src/ext/Iis/nuget.config | 17 + .../test/WixToolsetTest.Iis/IisExtensionFixture.cs | 32 + .../TestData/UsingIis/Package.en-us.wxl | 11 + .../TestData/UsingIis/Package.wxs | 17 + .../TestData/UsingIis/PackageComponents.wxs | 16 + .../TestData/UsingIis/example.txt | 1 + .../WixToolsetTest.Iis/WixToolsetTest.Iis.csproj | 41 + .../WixToolsetTest.Iis.v3.ncrunchproject | 5 + src/ext/Iis/wix.snk | Bin 0 -> 596 bytes src/ext/Iis/wixext/IIsCompiler.cs | 2620 ++++++++++++ src/ext/Iis/wixext/IIsDecompiler.cs | 1549 +++++++ src/ext/Iis/wixext/IIsExtensionData.cs | 30 + src/ext/Iis/wixext/IisErrors.cs | 78 + src/ext/Iis/wixext/IisExtensionFactory.cs | 18 + src/ext/Iis/wixext/IisTableDefinitions.cs | 324 ++ .../IisWindowsInstallerBackendBinderExtension.cs | 13 + .../Iis/wixext/Symbols/CertificateHashSymbol.cs | 55 + src/ext/Iis/wixext/Symbols/CertificateSymbol.cs | 103 + src/ext/Iis/wixext/Symbols/IIsAppPoolSymbol.cs | 159 + src/ext/Iis/wixext/Symbols/IIsFilterSymbol.cs | 95 + src/ext/Iis/wixext/Symbols/IIsHttpHeaderSymbol.cs | 95 + src/ext/Iis/wixext/Symbols/IIsMimeMapSymbol.cs | 71 + src/ext/Iis/wixext/Symbols/IIsPropertySymbol.cs | 63 + src/ext/Iis/wixext/Symbols/IIsWebAddressSymbol.cs | 79 + .../Symbols/IIsWebApplicationExtensionSymbol.cs | 79 + .../Iis/wixext/Symbols/IIsWebApplicationSymbol.cs | 127 + .../wixext/Symbols/IIsWebDirPropertiesSymbol.cs | 151 + src/ext/Iis/wixext/Symbols/IIsWebDirSymbol.cs | 79 + src/ext/Iis/wixext/Symbols/IIsWebErrorSymbol.cs | 87 + src/ext/Iis/wixext/Symbols/IIsWebLogSymbol.cs | 47 + .../wixext/Symbols/IIsWebServiceExtensionSymbol.cs | 79 + .../wixext/Symbols/IIsWebSiteCertificatesSymbol.cs | 55 + src/ext/Iis/wixext/Symbols/IIsWebSiteSymbol.cs | 135 + .../Iis/wixext/Symbols/IIsWebVirtualDirSymbol.cs | 87 + src/ext/Iis/wixext/Symbols/IisSymbolDefinitions.cs | 107 + src/ext/Iis/wixext/WixToolset.Iis.wixext.csproj | 31 + src/ext/Iis/wixext/WixToolset.Iis.wixext.targets | 11 + src/ext/Iis/wixlib/IIsExtension.wxs | 58 + src/ext/Iis/wixlib/IIsExtension_Platform.wxi | 66 + src/ext/Iis/wixlib/IIsExtension_arm64.wxs | 7 + src/ext/Iis/wixlib/IIsExtension_x64.wxs | 7 + src/ext/Iis/wixlib/IIsExtension_x86.wxs | 7 + src/ext/Iis/wixlib/caDecor.wxi | 39 + src/ext/Iis/wixlib/caerr.wxi | 96 + src/ext/Iis/wixlib/de-de.wxl | 55 + src/ext/Iis/wixlib/en-us.wxl | 55 + src/ext/Iis/wixlib/iis.v3.ncrunchproject | 5 + src/ext/Iis/wixlib/iis.wixproj | 26 + src/ext/Iis/wixlib/ja-jp.wxl | 47 + src/ext/Iis/wixlib/pt-br.wxl | 50 + src/ext/global.json | 5 + src/test/WixToolsetTest.Iis/IisExtensionFixture.cs | 32 - .../TestData/UsingIis/Package.en-us.wxl | 11 - .../TestData/UsingIis/Package.wxs | 17 - .../TestData/UsingIis/PackageComponents.wxs | 16 - .../TestData/UsingIis/example.txt | 1 - .../WixToolsetTest.Iis/WixToolsetTest.Iis.csproj | 41 - .../WixToolsetTest.Iis.v3.ncrunchproject | 5 - src/version.json | 11 + src/wix.snk | Bin 596 -> 0 bytes src/wixext/IIsCompiler.cs | 2620 ------------ src/wixext/IIsDecompiler.cs | 1549 ------- src/wixext/IIsExtensionData.cs | 30 - src/wixext/IisErrors.cs | 78 - src/wixext/IisExtensionFactory.cs | 18 - src/wixext/IisTableDefinitions.cs | 324 -- .../IisWindowsInstallerBackendBinderExtension.cs | 13 - src/wixext/Symbols/CertificateHashSymbol.cs | 55 - src/wixext/Symbols/CertificateSymbol.cs | 103 - src/wixext/Symbols/IIsAppPoolSymbol.cs | 159 - src/wixext/Symbols/IIsFilterSymbol.cs | 95 - src/wixext/Symbols/IIsHttpHeaderSymbol.cs | 95 - src/wixext/Symbols/IIsMimeMapSymbol.cs | 71 - src/wixext/Symbols/IIsPropertySymbol.cs | 63 - src/wixext/Symbols/IIsWebAddressSymbol.cs | 79 - .../Symbols/IIsWebApplicationExtensionSymbol.cs | 79 - src/wixext/Symbols/IIsWebApplicationSymbol.cs | 127 - src/wixext/Symbols/IIsWebDirPropertiesSymbol.cs | 151 - src/wixext/Symbols/IIsWebDirSymbol.cs | 79 - src/wixext/Symbols/IIsWebErrorSymbol.cs | 87 - src/wixext/Symbols/IIsWebLogSymbol.cs | 47 - src/wixext/Symbols/IIsWebServiceExtensionSymbol.cs | 79 - src/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs | 55 - src/wixext/Symbols/IIsWebSiteSymbol.cs | 135 - src/wixext/Symbols/IIsWebVirtualDirSymbol.cs | 87 - src/wixext/Symbols/IisSymbolDefinitions.cs | 107 - src/wixext/WixToolset.Iis.wixext.csproj | 31 - src/wixext/WixToolset.Iis.wixext.targets | 11 - src/wixlib/IIsExtension.wxs | 58 - src/wixlib/IIsExtension_Platform.wxi | 66 - src/wixlib/IIsExtension_arm64.wxs | 7 - src/wixlib/IIsExtension_x64.wxs | 7 - src/wixlib/IIsExtension_x86.wxs | 7 - src/wixlib/caDecor.wxi | 39 - src/wixlib/caerr.wxi | 96 - src/wixlib/de-de.wxl | 55 - src/wixlib/en-us.wxl | 55 - src/wixlib/iis.v3.ncrunchproject | 5 - src/wixlib/iis.wixproj | 26 - src/wixlib/ja-jp.wxl | 47 - src/wixlib/pt-br.wxl | 50 - version.json | 11 - 288 files changed, 26531 insertions(+), 26531 deletions(-) delete mode 100644 .editorconfig delete mode 100644 Iis.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/caDecor.h delete mode 100644 src/ca/dllmain.cpp delete mode 100644 src/ca/iisca.cpp delete mode 100644 src/ca/iisca.def delete mode 100644 src/ca/iisca.vcxproj delete mode 100644 src/ca/packages.config delete mode 100644 src/ca/precomp.h delete mode 100644 src/ca/sca.h delete mode 100644 src/ca/scaapppool.cpp delete mode 100644 src/ca/scaapppool.h delete mode 100644 src/ca/scaapppool7.cpp delete mode 100644 src/ca/scaapppool7.h delete mode 100644 src/ca/scacert.cpp delete mode 100644 src/ca/scacert.h delete mode 100644 src/ca/scacertexec.cpp delete mode 100644 src/ca/scacost.h delete mode 100644 src/ca/scaexec.cpp delete mode 100644 src/ca/scaexecIIS7.cpp delete mode 100644 src/ca/scaexecIIS7.h delete mode 100644 src/ca/scafilter.cpp delete mode 100644 src/ca/scafilter.h delete mode 100644 src/ca/scafilter7.cpp delete mode 100644 src/ca/scafilter7.h delete mode 100644 src/ca/scahttpheader.cpp delete mode 100644 src/ca/scahttpheader.h delete mode 100644 src/ca/scahttpheader7.cpp delete mode 100644 src/ca/scahttpheader7.h delete mode 100644 src/ca/scaiis.cpp delete mode 100644 src/ca/scaiis.h delete mode 100644 src/ca/scaiis7.cpp delete mode 100644 src/ca/scaiis7.h delete mode 100644 src/ca/scamimemap.cpp delete mode 100644 src/ca/scamimemap.h delete mode 100644 src/ca/scamimemap7.cpp delete mode 100644 src/ca/scamimemap7.h delete mode 100644 src/ca/scaproperty.cpp delete mode 100644 src/ca/scaproperty.h delete mode 100644 src/ca/scaproperty7.cpp delete mode 100644 src/ca/scaproperty7.h delete mode 100644 src/ca/scasched.cpp delete mode 100644 src/ca/scassl.cpp delete mode 100644 src/ca/scassl.h delete mode 100644 src/ca/scassl7.cpp delete mode 100644 src/ca/scassl7.h delete mode 100644 src/ca/scauser.cpp delete mode 100644 src/ca/scauser.h delete mode 100644 src/ca/scavdir.cpp delete mode 100644 src/ca/scavdir.h delete mode 100644 src/ca/scavdir7.cpp delete mode 100644 src/ca/scavdir7.h delete mode 100644 src/ca/scaweb.cpp delete mode 100644 src/ca/scaweb.h delete mode 100644 src/ca/scaweb7.cpp delete mode 100644 src/ca/scaweb7.h delete mode 100644 src/ca/scawebapp.cpp delete mode 100644 src/ca/scawebapp.h delete mode 100644 src/ca/scawebapp7.cpp delete mode 100644 src/ca/scawebapp7.h delete mode 100644 src/ca/scawebappext.cpp delete mode 100644 src/ca/scawebappext.h delete mode 100644 src/ca/scawebappext7.cpp delete mode 100644 src/ca/scawebappext7.h delete mode 100644 src/ca/scawebdir.cpp delete mode 100644 src/ca/scawebdir.h delete mode 100644 src/ca/scawebdir7.cpp delete mode 100644 src/ca/scawebdir7.h delete mode 100644 src/ca/scaweberr.cpp delete mode 100644 src/ca/scaweberr.h delete mode 100644 src/ca/scaweberr7.cpp delete mode 100644 src/ca/scaweberr7.h delete mode 100644 src/ca/scaweblog.cpp delete mode 100644 src/ca/scaweblog.h delete mode 100644 src/ca/scaweblog7.cpp delete mode 100644 src/ca/scaweblog7.h delete mode 100644 src/ca/scawebprop.cpp delete mode 100644 src/ca/scawebprop.h delete mode 100644 src/ca/scawebprop7.cpp delete mode 100644 src/ca/scawebprop7.h delete mode 100644 src/ca/scawebsvcext.cpp delete mode 100644 src/ca/scawebsvcext.h delete mode 100644 src/ca/scawebsvcext7.cpp delete mode 100644 src/ca/scawebsvcext7.h create mode 100644 src/ext/Iis/CSharp.Build.props create mode 100644 src/ext/Iis/Cpp.Build.props create mode 100644 src/ext/Iis/Directory.Build.props create mode 100644 src/ext/Iis/Directory.Build.targets create mode 100644 src/ext/Iis/Iis.wixext.sln create mode 100644 src/ext/Iis/README.md create mode 100644 src/ext/Iis/appveyor.cmd create mode 100644 src/ext/Iis/appveyor.yml create mode 100644 src/ext/Iis/ca/CustomMsiErrors.h create mode 100644 src/ext/Iis/ca/caDecor.h create mode 100644 src/ext/Iis/ca/dllmain.cpp create mode 100644 src/ext/Iis/ca/iisca.cpp create mode 100644 src/ext/Iis/ca/iisca.def create mode 100644 src/ext/Iis/ca/iisca.vcxproj create mode 100644 src/ext/Iis/ca/packages.config create mode 100644 src/ext/Iis/ca/precomp.h create mode 100644 src/ext/Iis/ca/sca.h create mode 100644 src/ext/Iis/ca/scaapppool.cpp create mode 100644 src/ext/Iis/ca/scaapppool.h create mode 100644 src/ext/Iis/ca/scaapppool7.cpp create mode 100644 src/ext/Iis/ca/scaapppool7.h create mode 100644 src/ext/Iis/ca/scacert.cpp create mode 100644 src/ext/Iis/ca/scacert.h create mode 100644 src/ext/Iis/ca/scacertexec.cpp create mode 100644 src/ext/Iis/ca/scacost.h create mode 100644 src/ext/Iis/ca/scaexec.cpp create mode 100644 src/ext/Iis/ca/scaexecIIS7.cpp create mode 100644 src/ext/Iis/ca/scaexecIIS7.h create mode 100644 src/ext/Iis/ca/scafilter.cpp create mode 100644 src/ext/Iis/ca/scafilter.h create mode 100644 src/ext/Iis/ca/scafilter7.cpp create mode 100644 src/ext/Iis/ca/scafilter7.h create mode 100644 src/ext/Iis/ca/scahttpheader.cpp create mode 100644 src/ext/Iis/ca/scahttpheader.h create mode 100644 src/ext/Iis/ca/scahttpheader7.cpp create mode 100644 src/ext/Iis/ca/scahttpheader7.h create mode 100644 src/ext/Iis/ca/scaiis.cpp create mode 100644 src/ext/Iis/ca/scaiis.h create mode 100644 src/ext/Iis/ca/scaiis7.cpp create mode 100644 src/ext/Iis/ca/scaiis7.h create mode 100644 src/ext/Iis/ca/scamimemap.cpp create mode 100644 src/ext/Iis/ca/scamimemap.h create mode 100644 src/ext/Iis/ca/scamimemap7.cpp create mode 100644 src/ext/Iis/ca/scamimemap7.h create mode 100644 src/ext/Iis/ca/scaproperty.cpp create mode 100644 src/ext/Iis/ca/scaproperty.h create mode 100644 src/ext/Iis/ca/scaproperty7.cpp create mode 100644 src/ext/Iis/ca/scaproperty7.h create mode 100644 src/ext/Iis/ca/scasched.cpp create mode 100644 src/ext/Iis/ca/scassl.cpp create mode 100644 src/ext/Iis/ca/scassl.h create mode 100644 src/ext/Iis/ca/scassl7.cpp create mode 100644 src/ext/Iis/ca/scassl7.h create mode 100644 src/ext/Iis/ca/scauser.cpp create mode 100644 src/ext/Iis/ca/scauser.h create mode 100644 src/ext/Iis/ca/scavdir.cpp create mode 100644 src/ext/Iis/ca/scavdir.h create mode 100644 src/ext/Iis/ca/scavdir7.cpp create mode 100644 src/ext/Iis/ca/scavdir7.h create mode 100644 src/ext/Iis/ca/scaweb.cpp create mode 100644 src/ext/Iis/ca/scaweb.h create mode 100644 src/ext/Iis/ca/scaweb7.cpp create mode 100644 src/ext/Iis/ca/scaweb7.h create mode 100644 src/ext/Iis/ca/scawebapp.cpp create mode 100644 src/ext/Iis/ca/scawebapp.h create mode 100644 src/ext/Iis/ca/scawebapp7.cpp create mode 100644 src/ext/Iis/ca/scawebapp7.h create mode 100644 src/ext/Iis/ca/scawebappext.cpp create mode 100644 src/ext/Iis/ca/scawebappext.h create mode 100644 src/ext/Iis/ca/scawebappext7.cpp create mode 100644 src/ext/Iis/ca/scawebappext7.h create mode 100644 src/ext/Iis/ca/scawebdir.cpp create mode 100644 src/ext/Iis/ca/scawebdir.h create mode 100644 src/ext/Iis/ca/scawebdir7.cpp create mode 100644 src/ext/Iis/ca/scawebdir7.h create mode 100644 src/ext/Iis/ca/scaweberr.cpp create mode 100644 src/ext/Iis/ca/scaweberr.h create mode 100644 src/ext/Iis/ca/scaweberr7.cpp create mode 100644 src/ext/Iis/ca/scaweberr7.h create mode 100644 src/ext/Iis/ca/scaweblog.cpp create mode 100644 src/ext/Iis/ca/scaweblog.h create mode 100644 src/ext/Iis/ca/scaweblog7.cpp create mode 100644 src/ext/Iis/ca/scaweblog7.h create mode 100644 src/ext/Iis/ca/scawebprop.cpp create mode 100644 src/ext/Iis/ca/scawebprop.h create mode 100644 src/ext/Iis/ca/scawebprop7.cpp create mode 100644 src/ext/Iis/ca/scawebprop7.h create mode 100644 src/ext/Iis/ca/scawebsvcext.cpp create mode 100644 src/ext/Iis/ca/scawebsvcext.h create mode 100644 src/ext/Iis/ca/scawebsvcext7.cpp create mode 100644 src/ext/Iis/ca/scawebsvcext7.h create mode 100644 src/ext/Iis/nuget.config create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/IisExtensionFixture.cs create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj create mode 100644 src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject create mode 100644 src/ext/Iis/wix.snk create mode 100644 src/ext/Iis/wixext/IIsCompiler.cs create mode 100644 src/ext/Iis/wixext/IIsDecompiler.cs create mode 100644 src/ext/Iis/wixext/IIsExtensionData.cs create mode 100644 src/ext/Iis/wixext/IisErrors.cs create mode 100644 src/ext/Iis/wixext/IisExtensionFactory.cs create mode 100644 src/ext/Iis/wixext/IisTableDefinitions.cs create mode 100644 src/ext/Iis/wixext/IisWindowsInstallerBackendBinderExtension.cs create mode 100644 src/ext/Iis/wixext/Symbols/CertificateHashSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/CertificateSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsAppPoolSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsFilterSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsHttpHeaderSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsMimeMapSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsPropertySymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebAddressSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebApplicationSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebDirPropertiesSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebDirSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebErrorSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebLogSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebServiceExtensionSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebSiteSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IIsWebVirtualDirSymbol.cs create mode 100644 src/ext/Iis/wixext/Symbols/IisSymbolDefinitions.cs create mode 100644 src/ext/Iis/wixext/WixToolset.Iis.wixext.csproj create mode 100644 src/ext/Iis/wixext/WixToolset.Iis.wixext.targets create mode 100644 src/ext/Iis/wixlib/IIsExtension.wxs create mode 100644 src/ext/Iis/wixlib/IIsExtension_Platform.wxi create mode 100644 src/ext/Iis/wixlib/IIsExtension_arm64.wxs create mode 100644 src/ext/Iis/wixlib/IIsExtension_x64.wxs create mode 100644 src/ext/Iis/wixlib/IIsExtension_x86.wxs create mode 100644 src/ext/Iis/wixlib/caDecor.wxi create mode 100644 src/ext/Iis/wixlib/caerr.wxi create mode 100644 src/ext/Iis/wixlib/de-de.wxl create mode 100644 src/ext/Iis/wixlib/en-us.wxl create mode 100644 src/ext/Iis/wixlib/iis.v3.ncrunchproject create mode 100644 src/ext/Iis/wixlib/iis.wixproj create mode 100644 src/ext/Iis/wixlib/ja-jp.wxl create mode 100644 src/ext/Iis/wixlib/pt-br.wxl create mode 100644 src/ext/global.json delete mode 100644 src/test/WixToolsetTest.Iis/IisExtensionFixture.cs delete mode 100644 src/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl delete mode 100644 src/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs delete mode 100644 src/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs delete mode 100644 src/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt delete mode 100644 src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj delete mode 100644 src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject create mode 100644 src/version.json delete mode 100644 src/wix.snk delete mode 100644 src/wixext/IIsCompiler.cs delete mode 100644 src/wixext/IIsDecompiler.cs delete mode 100644 src/wixext/IIsExtensionData.cs delete mode 100644 src/wixext/IisErrors.cs delete mode 100644 src/wixext/IisExtensionFactory.cs delete mode 100644 src/wixext/IisTableDefinitions.cs delete mode 100644 src/wixext/IisWindowsInstallerBackendBinderExtension.cs delete mode 100644 src/wixext/Symbols/CertificateHashSymbol.cs delete mode 100644 src/wixext/Symbols/CertificateSymbol.cs delete mode 100644 src/wixext/Symbols/IIsAppPoolSymbol.cs delete mode 100644 src/wixext/Symbols/IIsFilterSymbol.cs delete mode 100644 src/wixext/Symbols/IIsHttpHeaderSymbol.cs delete mode 100644 src/wixext/Symbols/IIsMimeMapSymbol.cs delete mode 100644 src/wixext/Symbols/IIsPropertySymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebAddressSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebApplicationSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebDirPropertiesSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebDirSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebErrorSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebLogSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebServiceExtensionSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebSiteSymbol.cs delete mode 100644 src/wixext/Symbols/IIsWebVirtualDirSymbol.cs delete mode 100644 src/wixext/Symbols/IisSymbolDefinitions.cs delete mode 100644 src/wixext/WixToolset.Iis.wixext.csproj delete mode 100644 src/wixext/WixToolset.Iis.wixext.targets delete mode 100644 src/wixlib/IIsExtension.wxs delete mode 100644 src/wixlib/IIsExtension_Platform.wxi delete mode 100644 src/wixlib/IIsExtension_arm64.wxs delete mode 100644 src/wixlib/IIsExtension_x64.wxs delete mode 100644 src/wixlib/IIsExtension_x86.wxs delete mode 100644 src/wixlib/caDecor.wxi delete mode 100644 src/wixlib/caerr.wxi delete mode 100644 src/wixlib/de-de.wxl delete mode 100644 src/wixlib/en-us.wxl delete mode 100644 src/wixlib/iis.v3.ncrunchproject delete mode 100644 src/wixlib/iis.wixproj delete mode 100644 src/wixlib/ja-jp.wxl delete mode 100644 src/wixlib/pt-br.wxl 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/Iis.wixext.sln b/Iis.wixext.sln deleted file mode 100644 index 85323fde..00000000 --- a/Iis.wixext.sln +++ /dev/null @@ -1,58 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30204.135 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iisca", "src\ca\iisca.vcxproj", "{CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}" -EndProject -Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "iis", "src\wixlib\iis.wixproj", "{92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Iis.wixext", "src\wixext\WixToolset.Iis.wixext.csproj", "{612029FB-B5D4-4D7E-B794-A0E202BFE493}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Iis", "src\test\WixToolsetTest.Iis\WixToolsetTest.Iis.csproj", "{E62712D7-31A1-49E4-B1F4-0084FAD14193}" -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 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|Any CPU.Build.0 = Debug|Win32 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|x86.ActiveCfg = Debug|Win32 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|x86.Build.0 = Debug|Win32 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Release|Any CPU.ActiveCfg = Release|Win32 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Release|x86.ActiveCfg = Release|Win32 - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Release|x86.Build.0 = Release|Win32 - {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Debug|Any CPU.ActiveCfg = Debug|x86 - {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Debug|x86.ActiveCfg = Debug|x86 - {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Debug|x86.Build.0 = Debug|x86 - {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Release|Any CPU.ActiveCfg = Release|x86 - {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Release|x86.ActiveCfg = Release|x86 - {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Release|x86.Build.0 = Release|x86 - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|Any CPU.Build.0 = Debug|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|x86.ActiveCfg = Debug|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|x86.Build.0 = Debug|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|Any CPU.ActiveCfg = Release|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|Any CPU.Build.0 = Release|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|x86.ActiveCfg = Release|Any CPU - {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|x86.Build.0 = Release|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|x86.ActiveCfg = Debug|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|x86.Build.0 = Debug|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|Any CPU.Build.0 = Release|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|x86.ActiveCfg = Release|Any CPU - {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {89256463-14A3-4968-8688-F75EC230B021} - EndGlobalSection -EndGlobal diff --git a/README.md b/README.md deleted file mode 100644 index ddb21a82..00000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Iis.wixext -WixToolset.Iis.wixext - Iis WiX Toolset Extension diff --git a/appveyor.cmd b/appveyor.cmd deleted file mode 100644 index af993a8f..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.Iis\WixToolsetTest.Iis.csproj || exit /b -dotnet test -c Release --no-build src\test\WixToolsetTest.Iis || exit /b - -msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Iis.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 1fd8d050..00000000 --- a/src/ca/CustomMsiErrors.h +++ /dev/null @@ -1,48 +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 msierrIISCannotConnect 26001 -#define msierrIISFailedReadWebSite 26002 -#define msierrIISFailedReadWebDirs 26003 -#define msierrIISFailedReadVDirs 26004 -#define msierrIISFailedReadFilters 26005 -#define msierrIISFailedReadAppPool 26006 -#define msierrIISFailedReadMimeMap 26007 -#define msierrIISFailedReadProp 26008 -#define msierrIISFailedReadWebSvcExt 26009 -#define msierrIISFailedReadWebError 26010 -#define msierrIISFailedReadHttpHeader 26011 - -#define msierrIISFailedSchedTransaction 26031 -#define msierrIISFailedSchedInstallWebs 26032 -#define msierrIISFailedSchedInstallWebDirs 26033 -#define msierrIISFailedSchedInstallVDirs 26034 -#define msierrIISFailedSchedInstallFilters 26035 -#define msierrIISFailedSchedInstallAppPool 26036 -#define msierrIISFailedSchedInstallProp 26037 -#define msierrIISFailedSchedInstallWebSvcExt 26038 - -#define msierrIISFailedSchedUninstallWebs 26051 -#define msierrIISFailedSchedUninstallWebDirs 26052 -#define msierrIISFailedSchedUninstallVDirs 26053 -#define msierrIISFailedSchedUninstallFilters 26054 -#define msierrIISFailedSchedUninstallAppPool 26055 -#define msierrIISFailedSchedUninstallProp 26056 -#define msierrIISFailedSchedUninstallWebSvcExt 26057 - -#define msierrIISFailedStartTransaction 26101 -#define msierrIISFailedOpenKey 26102 -#define msierrIISFailedCreateKey 26103 -#define msierrIISFailedWriteData 26104 -#define msierrIISFailedCreateApp 26105 -#define msierrIISFailedDeleteKey 26106 -#define msierrIISFailedDeleteApp 26107 -#define msierrIISFailedDeleteValue 26108 -#define msierrIISFailedCommitInUse 26109 - -// Last available value 26200 - -#define msierrCERTFailedOpen 26351 -#define msierrCERTFailedAdd 26352 - -// Last available value 26450 diff --git a/src/ca/caDecor.h b/src/ca/caDecor.h deleted file mode 100644 index da274650..00000000 --- a/src/ca/caDecor.h +++ /dev/null @@ -1,13 +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. - - -#if defined(_M_ARM64) -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_A64" -#elif defined(_M_AMD64) -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X64" -#elif defined(_M_ARM) -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_ARM" -#else -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X86" -#endif 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/iisca.cpp b/src/ca/iisca.cpp deleted file mode 100644 index 37664a1c..00000000 --- a/src/ca/iisca.cpp +++ /dev/null @@ -1,3 +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" diff --git a/src/ca/iisca.def b/src/ca/iisca.def deleted file mode 100644 index b9127da6..00000000 --- a/src/ca/iisca.def +++ /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. - - -LIBRARY "iisca" - -EXPORTS -;scacert.cpp - InstallCertificates - UninstallCertificates -;scacertexec.cpp - AddUserCertificate - AddMachineCertificate - DeleteUserCertificate - DeleteMachineCertificate -;scaexec.cpp - StartMetabaseTransaction - RollbackMetabaseTransaction - CommitMetabaseTransaction - - WriteMetabaseChanges - - StartIIS7ConfigTransaction - RollbackIIS7ConfigTransaction - CommitIIS7ConfigTransaction - - WriteIIS7ConfigChanges -;scasched.cpp - ConfigureIIs - ConfigureIIsExec - ConfigureIIs7Exec diff --git a/src/ca/iisca.vcxproj b/src/ca/iisca.vcxproj deleted file mode 100644 index eb1174be..00000000 --- a/src/ca/iisca.vcxproj +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - Debug - ARM64 - - - Release - ARM64 - - - - - {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3} - DynamicLibrary - iisca - v142 - Unicode - iisca.def - WiX Toolset Iis CustomAction - - - - - - - crypt32.lib;msi.lib;Ws2_32.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}. - - - - - \ No newline at end of file diff --git a/src/ca/packages.config b/src/ca/packages.config deleted file mode 100644 index e3dc0e43..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 85ee0890..00000000 --- a/src/ca/precomp.h +++ /dev/null @@ -1,66 +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. - - -#if _WIN32_MSI < 150 -#define _WIN32_MSI 150 -#endif - -#include -#include -#include -#include - -#include // NetApi32.lib - -#include -#include -#include // IIS 7 config - -#define MAXUINT USHRT_MAX - -#include "wcautil.h" -#include "wcawow64.h" -#include "wcawrapquery.h" - -#include "certutil.h" -#include "cryputil.h" -#include "fileutil.h" -#include "iis7util.h" -#include "memutil.h" -#include "metautil.h" -#include "strutil.h" -#include "userutil.h" -#include "wiutil.h" - -#include "CustomMsiErrors.h" -#include "sca.h" -#include "scacost.h" -#include "scacert.h" -#include "scafilter.h" - -#include "scaiis.h" -#include "scaiis7.h" -#include "scaproperty.h" -#include "scaweb.h" -#include "scawebdir.h" -#include "scawebsvcext.h" -#include "scavdir.h" -#include "scaweb7.h" -#include "scaapppool7.h" -#include "scavdir7.h" -#include "scawebapp7.h" -#include "scawebappext7.h" -#include "scamimemap7.h" -#include "scawebprop7.h" -#include "scaweblog7.h" -#include "scafilter7.h" -#include "scahttpheader7.h" -#include "scaweberr7.h" -#include "scawebsvcext7.h" -#include "scaproperty7.h" -#include "scawebdir7.h" -#include "scassl7.h" -#include "scaexecIIS7.h" - -#include "caDecor.h" diff --git a/src/ca/sca.h b/src/ca/sca.h deleted file mode 100644 index 64567dcb..00000000 --- a/src/ca/sca.h +++ /dev/null @@ -1,124 +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 MAGIC_MULTISZ_CHAR 127 - -// Generic action enum. -enum SCA_ACTION -{ - SCA_ACTION_NONE, - SCA_ACTION_INSTALL, - SCA_ACTION_UNINSTALL -}; - - -// IIS Metabase actions -enum METABASE_ACTION -{ - MBA_UNKNOWNACTION = 0, - MBA_CREATEKEY, - MBA_DELETEKEY, - MBA_WRITEVALUE, - MBA_DELETEVALUE, - MBA_CREATEAPP, - MBA_DELETEAPP, -}; - -// IIS 7 Config actions -enum IIS_CONFIG_ACTION -{ - IIS_CREATE, - IIS_DELETE, - IIS_SITE, - IIS_APPLICATION, - IIS_APPPOOL, - IIS_APPPOOL_RECYCLE_MIN, - IIS_APPPOOL_RECYCLE_REQ, - IIS_APPPOOL_RECYCLE_TIMES, - IIS_APPPOOL_RECYCLE_VIRMEM, - IIS_APPPOOL_RECYCLE_PRIVMEM, - IIS_APPPOOL_RECYCLE_IDLTIMEOUT, - IIS_APPPOOL_RECYCLE_QUEUELIMIT, - IIS_APPPOOL_RECYCLE_CPU_PCT, - IIS_APPPOOL_RECYCLE_CPU_REFRESH, - IIS_APPPOOL_RECYCLE_CPU_ACTION, - IIS_APPPOOL_MAXPROCESS, - IIS_APPPOOL_IDENTITY, - IIS_APPPOOL_USER, - IIS_APPPOOL_PWD, - IIS_APPPOOL_32BIT, - IIS_APPPOOL_MANAGED_PIPELINE_MODE, - IIS_APPPOOL_MANAGED_RUNTIME_VERSION, - IIS_APPPOOL_END, - IIS_APPEXT_BEGIN, - IIS_APPEXT, - IIS_APPEXT_END, - IIS_VDIR, - IIS_BINDING, - IIS_MIMEMAP_BEGIN, - IIS_MIMEMAP, - IIS_MIMEMAP_END, - IIS_DIRPROP_BEGIN, - IIS_DIRPROP_ACCESS, - IIS_DIRPROP_AUTH, - IIS_DIRPROP_USER, - IIS_DIRPROP_PWD, - IIS_DIRPROP_PWDCTRL, - IIS_DIRPROP_LOG, - IIS_DIRPROP_DEFDOCS, - IIS_DIRPROP_SSLFLAGS, - IIS_DIRPROP_AUTHPROVID, - IIS_DIRPROP_ASPERROR, - IIS_DIRPROP_HTTPEXPIRES, - IIS_DIRPROP_MAXAGE, - IIS_DIRPROP_CACHECUST, - IIS_DIRPROP_NOCUSTERROR, - IIS_DIRPROP_LOGVISITS, - IIS_DIRPROP_END, - IIS_WEBLOG, - IIS_FILTER_BEGIN, - IIS_FILTER_GLOBAL_BEGIN, - IIS_FILTER, - IIS_FILTER_END, - IIS_HTTP_HEADER_BEGIN, - IIS_HTTP_HEADER, - IIS_HTTP_HEADER_END, - IIS_WEBERROR_BEGIN, - IIS_WEBERROR, - IIS_WEBERROR_END, - IIS_WEB_SVC_EXT, - IIS_PROPERTY, - IIS_PROPERTY_MAXBAND, - IIS_PROPERTY_LOGUTF8, - IIS_WEBDIR, - IIS_ASP_BEGIN, - IIS_ASP_SESSIONSTATE, - IIS_ASP_SESSIONTIMEOUT, - IIS_ASP_BUFFER, - IIS_ASP_PARENTPATHS, - IIS_ASP_SCRIPTLANG, - IIS_ASP_SCRIPTTIMEOUT, - IIS_ASP_SCRIPTSERVERDEBUG, - IIS_ASP_SCRIPTCLIENTDEBUG, - IIS_ASP_END, - IIS_SSL_BINDING -}; - - -// user creation attributes definitions -enum SCAU_ATTRIBUTES -{ - SCAU_DONT_EXPIRE_PASSWRD = 0x00000001, - SCAU_PASSWD_CANT_CHANGE = 0x00000002, - SCAU_PASSWD_CHANGE_REQD_ON_LOGIN = 0x00000004, - SCAU_DISABLE_ACCOUNT = 0x00000008, - SCAU_FAIL_IF_EXISTS = 0x00000010, - SCAU_UPDATE_IF_EXISTS = 0x00000020, - SCAU_ALLOW_LOGON_AS_SERVICE = 0x00000040, - SCAU_ALLOW_LOGON_AS_BATCH = 0x00000080, - - SCAU_DONT_REMOVE_ON_UNINSTALL = 0x00000100, - SCAU_DONT_CREATE_USER = 0x00000200, - SCAU_NON_VITAL = 0x00000400, -}; diff --git a/src/ca/scaapppool.cpp b/src/ca/scaapppool.cpp deleted file mode 100644 index 781c55ca..00000000 --- a/src/ca/scaapppool.cpp +++ /dev/null @@ -1,594 +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" - -/*------------------------------------------------------------------ -AppPool table: - -Column Type Nullable Example Value -AppPool s72 No TestPool -Name s72 No "TestPool" -Component_ s72 No ComponentName -Attributes i2 No 8 (APATTR_OTHERUSER) -User_ s72 Yes UserKey -RecycleMinutes i2 Yes 500 -RecycleRequests i2 Yes 5000 -RecycleTimes s72 Yes "1:45,13:30,22:00" -IdleTimeout i2 Yes 15 -QueueLimit i2 Yes 500 -CPUMon s72 Yes "65,500,1" (65% CPU usage, 500 minutes, Shutdown Action) -MaxProc i2 Yes 5 -ManagedRuntimeVersion s72 Yes "v2.0" -ManagedPipelineMode s72 Yes "Integrated" - -Notes: -RecycleTimes is a comma delimeted list of times. CPUMon is a -comma delimeted list of the following format: -,,. The values for -Action are 1 (Shutdown) and 0 (No Action). - -------------------------------------------------------------------*/ - -enum eAppPoolQuery { apqAppPool = 1, apqName, apqComponent, apqAttributes, apqUser, apqRecycleMinutes, apqRecycleRequests, apqRecycleTimes, apqVirtualMemory, apqPrivateMemory, apqIdleTimeout, apqQueueLimit, apqCpuMon, apqMaxProc, apqManagedRuntimeVersion, apqManagedPipelineMode, apqInstalled, apqAction }; - -enum eComponentAttrQuery { caqComponent = 1, caqAttributes }; - -// prototypes -static HRESULT AppPoolExists( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzAppPool - ); - -// functions - -void ScaAppPoolFreeList( - __in SCA_APPPOOL* psapList - ) -{ - SCA_APPPOOL* psapDelete = psapList; - while (psapList) - { - psapDelete = psapList; - psapList = psapList->psapNext; - - MemFree(psapDelete); - } -} - - -HRESULT ScaAppPoolRead( - __inout SCA_APPPOOL** ppsapList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(ppsapList); - - HRESULT hr = S_OK; - - MSIHANDLE hRec, hRecComp; - LPWSTR pwzData = NULL; - SCA_APPPOOL* psap = NULL; - WCA_WRAPQUERY_HANDLE hAppPoolQuery = NULL; - WCA_WRAPQUERY_HANDLE hComponentQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hAppPoolQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hAppPoolQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaAppPoolRead() - required table not present"); - ExitFunction1(hr = S_FALSE); - } - - hr = WcaBeginUnwrapQuery(&hComponentQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - // loop through all the AppPools - while (S_OK == (hr = WcaFetchWrappedRecord(hAppPoolQuery, &hRec))) - { - // Add this record's information into the list of things to process. - hr = AddAppPoolToList(ppsapList); - ExitOnFailure(hr, "failed to add app pool to app pool list"); - - psap = *ppsapList; - - hr = WcaGetRecordString(hRec, apqComponent, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.Component"); - - if (pwzData && *pwzData) - { - psap->fHasComponent = TRUE; - - hr = ::StringCchCopyW(psap->wzComponent, countof(psap->wzComponent), pwzData); - ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, apqInstalled, (int *)&psap->isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for app pool"); - - hr = WcaGetRecordInteger(hRec, apqAction, (int *)&psap->isAction); - ExitOnFailure(hr, "Failed to get Component action state for app pool"); - - WcaFetchWrappedReset(hComponentQuery); - hr = WcaFetchWrappedRecordWhereString(hComponentQuery, caqComponent, psap->wzComponent, &hRecComp); - ExitOnFailure(hr, "Failed to fetch Component.Attributes for Component '%ls'", psap->wzComponent); - - hr = WcaGetRecordInteger(hRecComp, caqAttributes, &psap->iCompAttributes); - ExitOnFailure(hr, "failed to get Component.Attributes"); - } - - hr = WcaGetRecordString(hRec, apqAppPool, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.AppPool"); - hr = ::StringCchCopyW(psap->wzAppPool, countof(psap->wzAppPool), pwzData); - ExitOnFailure(hr, "failed to copy AppPool name: %ls", pwzData); - - hr = WcaGetRecordString(hRec, apqName, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.Name"); - hr = ::StringCchCopyW(psap->wzName, countof(psap->wzName), pwzData); - ExitOnFailure(hr, "failed to copy app pool name: %ls", pwzData); - hr = ::StringCchPrintfW(psap->wzKey, countof(psap->wzKey), L"/LM/W3SVC/AppPools/%s", pwzData); - ExitOnFailure(hr, "failed to format app pool key name"); - - hr = WcaGetRecordInteger(hRec, apqAttributes, &psap->iAttributes); - ExitOnFailure(hr, "failed to get AppPool.Attributes"); - - hr = WcaGetRecordString(hRec, apqUser, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.User"); - hr = ScaGetUserDeferred(pwzData, hUserQuery, &psap->suUser); - ExitOnFailure(hr, "failed to get user: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, apqRecycleRequests, &psap->iRecycleRequests); - ExitOnFailure(hr, "failed to get AppPool.RecycleRequests"); - - hr = WcaGetRecordInteger(hRec, apqRecycleMinutes, &psap->iRecycleMinutes); - ExitOnFailure(hr, "failed to get AppPool.Minutes"); - - hr = WcaGetRecordString(hRec, apqRecycleTimes, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.RecycleTimes"); - hr = ::StringCchCopyW(psap->wzRecycleTimes, countof(psap->wzRecycleTimes), pwzData); - ExitOnFailure(hr, "failed to copy recycle value: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, apqVirtualMemory, &psap->iVirtualMemory); - ExitOnFailure(hr, "failed to get AppPool.VirtualMemory"); - - hr = WcaGetRecordInteger(hRec, apqPrivateMemory, &psap->iPrivateMemory); - ExitOnFailure(hr, "failed to get AppPool.PrivateMemory"); - - hr = WcaGetRecordInteger(hRec, apqIdleTimeout, &psap->iIdleTimeout); - ExitOnFailure(hr, "failed to get AppPool.IdleTimeout"); - - hr = WcaGetRecordInteger(hRec, apqQueueLimit, &psap->iQueueLimit); - ExitOnFailure(hr, "failed to get AppPool.QueueLimit"); - - hr = WcaGetRecordString(hRec, apqCpuMon, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.CPUMon"); - hr = ::StringCchCopyW(psap->wzCpuMon, countof(psap->wzCpuMon), pwzData); - ExitOnFailure(hr, "failed to copy cpu monitor value: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, apqMaxProc, &psap->iMaxProcesses); - ExitOnFailure(hr, "failed to get AppPool.MaxProc"); - - hr = WcaGetRecordString(hRec, apqManagedRuntimeVersion, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.ManagedRuntimeVersion"); - hr = ::StringCchCopyW(psap->wzManagedRuntimeVersion, countof(psap->wzManagedRuntimeVersion), pwzData); - ExitOnFailure(hr, "failed to copy ManagedRuntimeVersion value: %ls", pwzData); - - hr = WcaGetRecordString(hRec, apqManagedPipelineMode, &pwzData); - ExitOnFailure(hr, "failed to get AppPool.ManagedPipelineMode"); - hr = ::StringCchCopyW(psap->wzManagedPipelineMode, countof(psap->wzManagedPipelineMode), pwzData); - ExitOnFailure(hr, "failed to copy ManagedPipelineMode value: %ls", pwzData); - - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "failure while processing AppPools"); - -LExit: - WcaFinishUnwrapQuery(hAppPoolQuery); - WcaFinishUnwrapQuery(hComponentQuery); - - ReleaseStr(pwzData); - return hr; -} - - -HRESULT ScaFindAppPool( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzAppPool, - __out_ecount(cchName) LPWSTR wzName, - __in DWORD cchName, - __in SCA_APPPOOL *psapList - ) -{ - Assert(piMetabase && wzAppPool && *wzAppPool && wzName && *wzName); - - HRESULT hr = S_OK; - - // check memory first - SCA_APPPOOL* psap = psapList; - for (; psap; psap = psap->psapNext) - { - if (0 == lstrcmpW(psap->wzAppPool, wzAppPool)) - { - break; - } - } - ExitOnNull(psap, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Could not find the app pool: %ls", wzAppPool); - - // copy the web app pool name - hr = ::StringCchCopyW(wzName, cchName, psap->wzName); - ExitOnFailure(hr, "failed to copy app pool name while finding app pool: %ls", psap->wzName); - - // if it's not being installed now, check if it exists already - if (!psap->fHasComponent) - { - hr = AppPoolExists(piMetabase, psap->wzName); - ExitOnFailure(hr, "failed to check for existence of app pool: %ls", psap->wzName); - } - -LExit: - return hr; -} - - -static HRESULT AppPoolExists( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzAppPool - ) -{ - Assert(piMetabase && wzAppPool && *wzAppPool); - - HRESULT hr = S_OK; - WCHAR wzSubKey[METADATA_MAX_NAME_LEN]; - - for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex) - { - hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/AppPools", wzSubKey, dwIndex); - if (SUCCEEDED(hr) && 0 == lstrcmpW(wzSubKey, wzAppPool)) - { - hr = S_OK; - break; - } - } - - if (E_NOMOREITEMS == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - hr = S_FALSE; - } - - return hr; -} - - -HRESULT ScaAppPoolInstall( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psapList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - - for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) - { - // if we are installing the app pool - if (psap->fHasComponent && WcaIsInstalling(psap->isInstalled, psap->isAction)) - { - hr = ScaWriteAppPool(piMetabase, psap); - ExitOnFailure(hr, "failed to write AppPool '%ls' to metabase", psap->wzAppPool); - } - } - -LExit: - return hr; -} - - -HRESULT ScaAppPoolUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psapList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - - for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) - { - // if we are uninstalling the app pool - if (psap->fHasComponent && WcaIsUninstalling(psap->isInstalled, psap->isAction)) - { - hr = ScaRemoveAppPool(piMetabase, psap); - ExitOnFailure(hr, "Failed to remove AppPool '%ls' from metabase", psap->wzAppPool); - } - } - -LExit: - return hr; -} - - -HRESULT ScaWriteAppPool( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psap - ) -{ - Assert(piMetabase && psap); - - HRESULT hr = S_OK; - DWORD dwIdentity = 0xFFFFFFFF; - BOOL fExists = FALSE; - LPWSTR pwzValue = NULL; - LPWSTR wz = NULL; - - hr = AppPoolExists(piMetabase, psap->wzName); - ExitOnFailure(hr, "failed to check if app pool already exists"); - if (S_FALSE == hr) - { - // didn't find the AppPool key, so we need to create it - hr = ScaCreateMetabaseKey(piMetabase, psap->wzKey, L""); - ExitOnFailure(hr, "failed to create AppPool key: %ls", psap->wzKey); - - // mark it as an AppPool - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsApplicationPool"); - ExitOnFailure(hr, "failed to mark key as AppPool key: %ls", psap->wzKey); - - // TODO: Make this an Attribute? - // set autostart value - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_AUTO_START, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)1); - ExitOnFailure(hr, "failed to mark key as AppPool key: %ls", psap->wzKey); - } - else - { - fExists = TRUE; - } - - // - // Set the AppPool Recycling Tab - // - if (MSI_NULL_INTEGER != psap->iRecycleMinutes) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_TIME, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iRecycleMinutes)); - ExitOnFailure(hr, "failed to set periodic restart time"); - } - - if (MSI_NULL_INTEGER != psap->iRecycleRequests) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_REQUEST_COUNT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iRecycleRequests)); - ExitOnFailure(hr, "failed to set periodic restart request count"); - } - - if (*psap->wzRecycleTimes) - { - // Add another NULL' onto pwz since it's a 'MULTISZ' - hr = StrAllocString(&pwzValue, psap->wzRecycleTimes, 0); - ExitOnFailure(hr, "failed to allocate string for MULTISZ"); - hr = StrAllocConcat(&pwzValue, L"\0", 1); - ExitOnFailure(hr, "failed to add second null to RecycleTime multisz"); - - // Replace the commas with NULLs - wz = pwzValue; - while (NULL != (wz = wcschr(wz, L','))) - { - *wz = L'\0'; - ++wz; - } - - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_SCHEDULE, METADATA_INHERIT, IIS_MD_UT_SERVER, MULTISZ_METADATA, (LPVOID)pwzValue); - ExitOnFailure(hr, "failed to set periodic restart schedule"); - } - - if (MSI_NULL_INTEGER != psap->iVirtualMemory) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_MEMORY, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iVirtualMemory)); - ExitOnFailure(hr, "failed to set periodic restart memory count"); - } - - if (MSI_NULL_INTEGER != psap->iPrivateMemory) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_PRIVATE_MEMORY, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iPrivateMemory)); - ExitOnFailure(hr, "failed to set periodic restart private memory count"); - } - - - // - // Set AppPool Performance Tab - // - if (MSI_NULL_INTEGER != psap->iIdleTimeout) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_IDLE_TIMEOUT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iIdleTimeout)); - ExitOnFailure(hr, "failed to set idle timeout value"); - } - - if (MSI_NULL_INTEGER != psap->iQueueLimit) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_UL_APPPOOL_QUEUE_LENGTH, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iQueueLimit)); - ExitOnFailure(hr, "failed to set request queue limit value"); - } - - if (*psap->wzCpuMon) - { - hr = StrAllocString(&pwzValue, psap->wzCpuMon, 0); - ExitOnFailure(hr, "failed to allocate CPUMonitor string"); - - DWORD dwPercent = 0; - DWORD dwRefreshMinutes = 0; - DWORD dwAction = 0; - - dwPercent = wcstoul(pwzValue, &wz, 10); - if (100 < dwPercent) - { - ExitOnFailure(hr = E_INVALIDARG, "invalid maximum cpu percentage value: %d", dwPercent); - } - if (wz && L',' == *wz) - { - ++wz; - dwRefreshMinutes = wcstoul(wz, &wz, 10); - if (wz && L',' == *wz) - { - ++wz; - dwAction = wcstoul(wz, &wz, 10); - } - } - - if (dwPercent) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_LIMIT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)(dwPercent * 1000))); - ExitOnFailure(hr, "failed to set CPU percentage max"); - } - if (dwRefreshMinutes) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_RESET_INTERVAL, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwRefreshMinutes)); - ExitOnFailure(hr, "failed to set refresh CPU minutes"); - } - if (dwAction) - { - // 0 = No Action - // 1 = Shutdown - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_ACTION, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwAction)); - ExitOnFailure(hr, "failed to set CPU action"); - } - } - - if (MSI_NULL_INTEGER != psap->iMaxProcesses) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_MAX_PROCESS_COUNT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iMaxProcesses)); - ExitOnFailure(hr, "failed to set web garden maximum worker processes"); - } - - // TODO: Health Tab if anyone wants it? - - // - // Set the AppPool Identity tab - // - if (psap->iAttributes & APATTR_NETSERVICE) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE; - } - else if (psap->iAttributes & APATTR_LOCSERVICE) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE; - } - else if (psap->iAttributes & APATTR_LOCSYSTEM) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM; - } - else if (psap->iAttributes & APATTR_OTHERUSER) - { - if (!*psap->suUser.wzDomain || CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzDomain, -1, L".", -1)) - { - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"NetworkService", -1)) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE; - } - else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"LocalService", -1)) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE; - } - else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"LocalSystem", -1)) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM; - } - else - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER; - } - } - else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzDomain, -1, L"NT AUTHORITY", -1)) - { - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"NETWORK SERVICE", -1)) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE; - } - else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"SERVICE", -1)) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE; - } - else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"SYSTEM", -1)) - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM; - } - else - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER; - } - } - else - { - dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER; - } - } - - if (-1 != dwIdentity) - { - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_IDENTITY_TYPE, METADATA_INHERIT , IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwIdentity)); - ExitOnFailure(hr, "failed to set app pool identity"); - - if (MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER == dwIdentity) - { - if (*psap->suUser.wzDomain) - { - hr = StrAllocFormatted(&pwzValue, L"%s\\%s", psap->suUser.wzDomain, psap->suUser.wzName); - ExitOnFailure(hr, "failed to format user name: %ls domain: %ls", psap->suUser.wzName, psap->suUser.wzDomain); - } - else - { - hr = StrAllocFormatted(&pwzValue, L"%s", psap->suUser.wzName); - ExitOnFailure(hr, "failed to format user name: %ls", psap->suUser.wzName); - } - - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_WAM_USER_NAME, METADATA_INHERIT , IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pwzValue); - ExitOnFailure(hr, "failed to set app pool identity name"); - - hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_WAM_PWD, METADATA_INHERIT | METADATA_SECURE, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psap->suUser.wzPassword); - ExitOnFailure(hr, "failed to set app pool identity password"); - } - } - -LExit: - ReleaseStr(pwzValue); - - return hr; -} - - -HRESULT ScaRemoveAppPool( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psap - ) -{ - Assert(piMetabase && psap); - - HRESULT hr = S_OK; - - // simply remove the root key and everything else is pulled at the same time - if (0 != lstrlenW(psap->wzKey)) - { - hr = ScaDeleteMetabaseKey(piMetabase, psap->wzKey, L""); - ExitOnFailure(hr, "failed to delete AppPool key: %ls", psap->wzKey); - } - - // TODO: Maybe check to make sure any web sites that are using this AppPool are put back in the 'DefaultAppPool' - -LExit: - return hr; -} - - -HRESULT AddAppPoolToList( - __in SCA_APPPOOL** ppsapList - ) -{ - HRESULT hr = S_OK; - SCA_APPPOOL* psap = static_cast(MemAlloc(sizeof(SCA_APPPOOL), TRUE)); - ExitOnNull(psap, hr, E_OUTOFMEMORY, "failed to allocate memory for new element in app pool list"); - - psap->psapNext = *ppsapList; - *ppsapList = psap; - -LExit: - return hr; -} diff --git a/src/ca/scaapppool.h b/src/ca/scaapppool.h deleted file mode 100644 index 68575fcb..00000000 --- a/src/ca/scaapppool.h +++ /dev/null @@ -1,88 +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 "scauser.h" - -// Identity -#define APATTR_NETSERVICE 0x0001 // Network Service -#define APATTR_LOCSERVICE 0x0002 // Local Service -#define APATTR_LOCSYSTEM 0x0004 // Local System -#define APATTR_OTHERUSER 0x0008 // Other User - -struct SCA_APPPOOL -{ - // iis app pool configuation information - WCHAR wzAppPool[MAX_DARWIN_KEY + 1]; - WCHAR wzName[METADATA_MAX_NAME_LEN + 1]; - WCHAR wzKey[METADATA_MAX_NAME_LEN + 1]; - WCHAR wzComponent[METADATA_MAX_NAME_LEN + 1]; - BOOL fHasComponent; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - INT iAttributes; - - SCA_USER suUser; - - INT iRecycleRequests; - INT iRecycleMinutes; - WCHAR wzRecycleTimes[MAX_DARWIN_KEY + 1]; - INT iVirtualMemory; - INT iPrivateMemory; - - INT iIdleTimeout; - INT iQueueLimit; - WCHAR wzCpuMon[MAX_DARWIN_KEY + 1]; - INT iMaxProcesses; - WCHAR wzManagedPipelineMode[MAX_DARWIN_KEY + 1]; - WCHAR wzManagedRuntimeVersion[MAX_DARWIN_KEY + 1]; - - int iCompAttributes; - - SCA_APPPOOL *psapNext; -}; - - -// prototypes - -HRESULT ScaAppPoolRead( - __inout SCA_APPPOOL** ppsapList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __inout LPWSTR *ppwzCustomActionData - ); - -void ScaAppPoolFreeList( - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaFindAppPool( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzAppPool, - __out_ecount(cchName) LPWSTR wzName, - __in DWORD cchName, - __in SCA_APPPOOL *psapList - ); - -HRESULT ScaAppPoolInstall( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaAppPoolUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaWriteAppPool( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psap - ); - -HRESULT ScaRemoveAppPool( - __in IMSAdminBase* piMetabase, - __in SCA_APPPOOL* psap - ); - -HRESULT AddAppPoolToList( - __in SCA_APPPOOL** ppsapList - ); diff --git a/src/ca/scaapppool7.cpp b/src/ca/scaapppool7.cpp deleted file mode 100644 index 0fac4346..00000000 --- a/src/ca/scaapppool7.cpp +++ /dev/null @@ -1,401 +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" - -// prototypes -static HRESULT AppPoolExists( - __in LPCWSTR wzAppPool - ); - -// functions -HRESULT ScaFindAppPool7( - __in LPCWSTR wzAppPool, - __out_ecount(cchName) LPWSTR wzName, - __in DWORD cchName, - __in SCA_APPPOOL *psapList - ) -{ - Assert(wzAppPool && *wzAppPool && wzName && *wzName); - - HRESULT hr = S_OK; - - // check memory first - SCA_APPPOOL* psap = psapList; - for (; psap; psap = psap->psapNext) - { - if (0 == wcscmp(psap->wzAppPool, wzAppPool)) - { - break; - } - } - ExitOnNull(psap, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Could not find the app pool: %ls", wzAppPool); - - // copy the web app pool name -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ::StringCchCopyW(wzName, cchName, psap->wzName); - ExitOnFailure(hr, "failed to copy app pool name while finding app pool: %ls", psap->wzName); - - // if it's not being installed now, check if it exists already - if (!psap->fHasComponent) - { - hr = AppPoolExists(psap->wzName); - ExitOnFailure(hr, "failed to check for existence of app pool: %ls", psap->wzName); - } - -LExit: - return hr; -} - - -static HRESULT AppPoolExists( - __in LPCWSTR /*wzAppPool*/ - ) -{ - HRESULT hr = S_OK; - - //this function checks for existance of app pool in IIS7 config - //at schedule time, we will defer this to execute time. - - return hr; -} - - -HRESULT ScaAppPoolInstall7( - __in SCA_APPPOOL* psapList - ) -{ - HRESULT hr = S_OK; - - for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) - { - // if we are installing the app pool - if (psap->fHasComponent && WcaIsInstalling(psap->isInstalled, psap->isAction)) - { - hr = ScaWriteAppPool7(psap); - ExitOnFailure(hr, "failed to write AppPool '%ls' to metabase", psap->wzAppPool); - } - } - -LExit: - return hr; -} - - -HRESULT ScaAppPoolUninstall7( - __in SCA_APPPOOL* psapList - ) -{ - - HRESULT hr = S_OK; - - for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) - { - // if we are uninstalling the app pool - if (psap->fHasComponent && WcaIsUninstalling(psap->isInstalled, psap->isAction)) - { - hr = ScaRemoveAppPool7(psap); - ExitOnFailure(hr, "Failed to remove AppPool '%ls' from metabase", psap->wzAppPool); - } - } - -LExit: - return hr; -} - - -HRESULT ScaWriteAppPool7( - __in const SCA_APPPOOL* psap - ) -{ - Assert(psap); - - HRESULT hr = S_OK; - DWORD dwIdentity = 0xFFFFFFFF; - LPWSTR pwzValue = NULL; - LPWSTR wz = NULL; - - //create the app pool - hr = ScaWriteConfigID(IIS_APPPOOL); - ExitOnFailure(hr, "failed to write AppPool key."); - - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "failed to write AppPool create action."); - - hr = ScaWriteConfigString(psap->wzName); - ExitOnFailure(hr, "failed to write AppPool name: %ls", psap->wzName); - - // Now do all the optional stuff - - // Set the AppPool Recycling Tab - if (MSI_NULL_INTEGER != psap->iRecycleMinutes) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_MIN); - ExitOnFailure(hr, "failed to set periodic restart time id"); - hr = ScaWriteConfigInteger(psap->iRecycleMinutes); - ExitOnFailure(hr, "failed to set periodic restart time"); - } - - if (MSI_NULL_INTEGER != psap->iRecycleRequests) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_REQ); - ExitOnFailure(hr, "failed to set periodic restart request count id"); - hr = ScaWriteConfigInteger(psap->iRecycleRequests); - ExitOnFailure(hr, "failed to set periodic restart request count"); - } - - if (*psap->wzRecycleTimes) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_TIMES); - ExitOnFailure(hr, "failed to set periodic restart schedule id"); - hr = ScaWriteConfigString(psap->wzRecycleTimes); - ExitOnFailure(hr, "failed to set periodic restart schedule"); - } - - if (MSI_NULL_INTEGER != psap->iVirtualMemory) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_VIRMEM); - ExitOnFailure(hr, "failed to set periodic restart memory count id"); - hr = ScaWriteConfigInteger(psap->iVirtualMemory); - ExitOnFailure(hr, "failed to set periodic restart memory count"); - } - - if (MSI_NULL_INTEGER != psap->iPrivateMemory) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_PRIVMEM); - ExitOnFailure(hr, "failed to set periodic restart private memory count id"); - hr = ScaWriteConfigInteger(psap->iPrivateMemory); - ExitOnFailure(hr, "failed to set periodic restart private memory count"); - } - - // Set AppPool Performance Tab - if (MSI_NULL_INTEGER != psap->iIdleTimeout) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_IDLTIMEOUT); - ExitOnFailure(hr, "failed to set idle timeout value id"); - hr = ScaWriteConfigInteger(psap->iIdleTimeout); - ExitOnFailure(hr, "failed to set idle timeout value"); - } - - if (MSI_NULL_INTEGER != psap->iQueueLimit) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_QUEUELIMIT); - ExitOnFailure(hr, "failed to set request queue limit value id"); - hr = ScaWriteConfigInteger(psap->iQueueLimit); - ExitOnFailure(hr, "failed to set request queue limit value"); - } - if (*psap->wzCpuMon) - { -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ::StrAllocString(&pwzValue, psap->wzCpuMon, 0); - ExitOnFailure(hr, "failed to allocate CPUMonitor string"); - - DWORD dwPercent = 0; - DWORD dwRefreshMinutes = 0; - DWORD dwAction = 0; - - dwPercent = wcstoul(pwzValue, &wz, 10); - if (100 < dwPercent) - { - ExitOnFailure(hr = E_INVALIDARG, "invalid maximum cpu percentage value: %d", dwPercent); - } - if (wz && L',' == *wz) - { - ++wz; - dwRefreshMinutes = wcstoul(wz, &wz, 10); - if (wz && L',' == *wz) - { - ++wz; - dwAction = wcstoul(wz, &wz, 10); - } - } - if (dwPercent) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_CPU_PCT); - ExitOnFailure(hr, "failed to set recycle pct id"); - hr = ScaWriteConfigInteger(dwPercent); - ExitOnFailure(hr, "failed to set CPU percentage max"); - } - if (dwRefreshMinutes) - { - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_CPU_REFRESH); - ExitOnFailure(hr, "failed to set recycle refresh id"); - hr = ScaWriteConfigInteger(dwRefreshMinutes); - ExitOnFailure(hr, "failed to set refresh CPU minutes"); - } - if (dwAction) - { - // 0 = No Action - // 1 = Shutdown - hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_CPU_ACTION); - ExitOnFailure(hr, "failed to set recycle refresh id"); - hr = ScaWriteConfigInteger(dwAction); - ExitOnFailure(hr, "failed to set CPU action"); - } - } - - if (MSI_NULL_INTEGER != psap->iMaxProcesses) - { - hr = ScaWriteConfigID(IIS_APPPOOL_MAXPROCESS); - ExitOnFailure(hr, "Failed to write max processes config ID"); - - hr = ScaWriteConfigInteger(psap->iMaxProcesses); - ExitOnFailure(hr, "failed to set web garden maximum worker processes"); - } - - hr = ScaWriteConfigID(IIS_APPPOOL_32BIT); - ExitOnFailure(hr, "Failed to write 32 bit app pool config ID"); - hr = ScaWriteConfigInteger(psap->iCompAttributes & msidbComponentAttributes64bit ? 0 : 1); - ExitOnFailure(hr, "Failed to write 32 bit app pool config value"); - - // - // Set the AppPool Identity tab - // - if (psap->iAttributes & APATTR_APPPOOLIDENTITY) - { - dwIdentity = 4; - } - else if (psap->iAttributes & APATTR_NETSERVICE) - { - dwIdentity = 2; - } - else if (psap->iAttributes & APATTR_LOCSERVICE) - { - dwIdentity = 1; - } - else if (psap->iAttributes & APATTR_LOCSYSTEM) - { - dwIdentity = 0; - } - else if (psap->iAttributes & APATTR_OTHERUSER) - { - if (!*psap->suUser.wzDomain || 0 == _wcsicmp(psap->suUser.wzDomain, L".")) - { - if (0 == _wcsicmp(psap->suUser.wzName, L"NetworkService")) - { - dwIdentity = 2; - } - else if (0 == _wcsicmp(psap->suUser.wzName, L"LocalService")) - { - dwIdentity = 1; - } - else if (0 == _wcsicmp(psap->suUser.wzName, L"LocalSystem")) - { - dwIdentity = 0; - } - else - { - dwIdentity = 3; - } - } - else if (0 == _wcsicmp(psap->suUser.wzDomain, L"NT AUTHORITY")) - { - if (0 == _wcsicmp(psap->suUser.wzName, L"NETWORK SERVICE")) - { - dwIdentity = 2; - } - else if (0 == _wcsicmp(psap->suUser.wzName, L"SERVICE")) - { - dwIdentity = 1; - } - else if (0 == _wcsicmp(psap->suUser.wzName, L"SYSTEM")) - { - dwIdentity = 0; - } - else - { - dwIdentity = 3; - } - } - else - { - dwIdentity = 3; - } - } - - if (-1 != dwIdentity) - { - hr = ScaWriteConfigID(IIS_APPPOOL_IDENTITY); - ExitOnFailure(hr, "failed to set app pool identity id"); - hr = ScaWriteConfigInteger(dwIdentity); - ExitOnFailure(hr, "failed to set app pool identity"); - - if (3 == dwIdentity) - { - if (*psap->suUser.wzDomain) - { - hr = StrAllocFormatted(&pwzValue, L"%s\\%s", psap->suUser.wzDomain, psap->suUser.wzName); - ExitOnFailure(hr, "failed to format user name: %ls domain: %ls", psap->suUser.wzName, psap->suUser.wzDomain); - } - else - { - hr = StrAllocFormatted(&pwzValue, L"%s", psap->suUser.wzName); - ExitOnFailure(hr, "failed to format user name: %ls", psap->suUser.wzName); - } - - hr = ScaWriteConfigID(IIS_APPPOOL_USER); - ExitOnFailure(hr, "failed to set app pool identity name id"); - hr = ScaWriteConfigString(pwzValue); - ExitOnFailure(hr, "failed to set app pool identity name"); - - hr = ScaWriteConfigID(IIS_APPPOOL_PWD); - ExitOnFailure(hr, "failed to set app pool identity password id"); - hr = ScaWriteConfigString(psap->suUser.wzPassword); - ExitOnFailure(hr, "failed to set app pool identity password"); - } - } - - if (*psap->wzManagedPipelineMode) - { - hr = ScaWriteConfigID(IIS_APPPOOL_MANAGED_PIPELINE_MODE); - ExitOnFailure(hr, "failed to set app pool integrated mode"); - hr = ScaWriteConfigString(psap->wzManagedPipelineMode); - ExitOnFailure(hr, "failed to set app pool managed pipeline mode value"); - } - - if (*psap->wzManagedRuntimeVersion) - { - hr = ScaWriteConfigID(IIS_APPPOOL_MANAGED_RUNTIME_VERSION); - ExitOnFailure(hr, "failed to set app pool managed runtime version mode"); - hr = ScaWriteConfigString(psap->wzManagedRuntimeVersion); - ExitOnFailure(hr, "failed to set app pool managed runtime version value"); - } - - // - //The number of properties above is variable so we put an end tag in so the - //execute CA will know when to stop looking for AppPool properties - // - hr = ScaWriteConfigID(IIS_APPPOOL_END); - ExitOnFailure(hr, "failed to set app pool end of properties id"); - -LExit: - ReleaseStr(pwzValue); - - return hr; -} - - -HRESULT ScaRemoveAppPool7( - __in const SCA_APPPOOL* psap - ) -{ - Assert(psap); - - HRESULT hr = S_OK; - - //do not delete the default App Pool - if (0 != _wcsicmp(psap->wzAppPool, L"DefaultAppPool")) - { - //delete the app pool - hr = ScaWriteConfigID(IIS_APPPOOL); - ExitOnFailure(hr, "failed to write AppPool key."); - - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "failed to write AppPool delete action."); - - hr = ScaWriteConfigString(psap->wzName); - ExitOnFailure(hr, "failed to delete AppPool: %ls", psap->wzName); - } - -LExit: - return hr; -} diff --git a/src/ca/scaapppool7.h b/src/ca/scaapppool7.h deleted file mode 100644 index 1f49d899..00000000 --- a/src/ca/scaapppool7.h +++ /dev/null @@ -1,36 +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 "scauser.h" - -// Identity -#define APATTR_NETSERVICE 0x0001 // Network Service -#define APATTR_LOCSERVICE 0x0002 // Local Service -#define APATTR_LOCSYSTEM 0x0004 // Local System -#define APATTR_OTHERUSER 0x0008 // Other User -#define APATTR_APPPOOLIDENTITY 0x0010 // ApplicationPoolIdentity - -// prototypes -HRESULT ScaFindAppPool7( - __in LPCWSTR wzAppPool, - __out_ecount(cchName) LPWSTR wzName, - __in DWORD cchName, - __in SCA_APPPOOL *psapList - ); - -HRESULT ScaAppPoolInstall7( - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaAppPoolUninstall7( - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaWriteAppPool7( - __in const SCA_APPPOOL* psap - ); - -HRESULT ScaRemoveAppPool7( - __in const SCA_APPPOOL* psap - ); diff --git a/src/ca/scacert.cpp b/src/ca/scacert.cpp deleted file mode 100644 index 5eae905a..00000000 --- a/src/ca/scacert.cpp +++ /dev/null @@ -1,1482 +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" - -// prototypes -static HRESULT ConfigureCertificates( - __in SCA_ACTION saAction - ); - -static LPCWSTR StoreMapping( - __in int iStore - ); - -static HRESULT FindExistingCertificate( - __in LPCWSTR wzName, - __in DWORD dwStoreLocation, - __in LPCWSTR wzStore, - __out BYTE** prgbCertificate, - __out DWORD* pcbCertificate - ); - -static HRESULT ResolveCertificate( - __in LPCWSTR wzId, - __in LPCWSTR wzName, - __in DWORD dwStoreLocation, - __in LPCWSTR wzStoreName, - __in DWORD dwAttributess, - __in LPCWSTR wzData, - __in LPCWSTR wzPFXPassword, - __out BYTE** ppbCertificate, - __out DWORD* pcbCertificate - ); - -static HRESULT ReadCertificateFile( - __in LPCWSTR wzPath, - __out BYTE** prgbData, - __out DWORD* pcbData - ); - -static HRESULT CertificateToHash( - __in BYTE* pbCertificate, - __in DWORD cbCertificate, - __in DWORD dwStoreLocation, - __in LPCWSTR wzPFXPassword, - __in BYTE rgbHash[], - __in DWORD cbHash - ); - -/* -HRESULT ScaGetCertificateByPath(LPCWSTR pwzName, BOOL fIsInstalling, - BOOL fIsUninstalling, INT iStore, - INT iStoreLocation, LPCWSTR wzSslCertificate, - LPCWSTR wzPFXPassword, BSTR* pbstrCertificate, - DWORD* pcbCertificate, BYTE* pbaHashBuffer); - -HRESULT ScaGetCertificateByRequest(LPCWSTR pwzName, BOOL fIsInstalling, - BOOL fIsUninstalling, INT iStore, - INT iStoreLocation, LPCWSTR wzDistinguishedName, - LPCWSTR wzCA, BSTR* pbstrCertificate, - DWORD* pcbCertificate, BYTE* pbaHashBuffer); - -HRESULT ScaSslNewCertificate(LPCWSTR pwzName, INT iStore, - INT iStoreLocation, LPCWSTR wzComputerName, - LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthorityOrig, - BSTR* pbstrCertificate, DWORD* pcbCertificate, - BYTE* pbaHashBuffer); - -HRESULT ScaSslExistingCertificateByName(LPCWSTR pwzName, INT iStore, - INT iStoreLocation, BSTR* pbstrCertificate, - DWORD* pcbCertificate, BYTE* pbaHashBuffer); - -HRESULT ScaSslExistingCertificateByBinaryData(INT iStore, INT iStoreLocation, - BYTE* pwzData, DWORD cchData); - -HRESULT CreateEnroll(ICEnroll2 **hEnroll, INT iStore, - INT iStoreLocation); - -HRESULT RequestCertificate(LPCWSTR pwzName, INT iStore, - INT iStoreLocation, LPCWSTR wzComputerName, - LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthority, - BSTR *pbstrCertificate); - -VOID ParseCertificateAuthority(__in LPCWSTR wzCertificateAuthorityOrig, __out LPWSTR *pwzBuffer, - __out LPWSTR **hwzCAArray, __out int *piCAArray); -*/ - - -LPCWSTR vcsCertQuery = L"SELECT `Certificate`, `Name`, `Component_`, `StoreLocation`, `StoreName`, `Attributes`, `Binary_`, `CertificatePath`, `PFXPassword` FROM `Certificate`"; -enum eCertQuery { cqCertificate = 1, cqName, cqComponent, cqStoreLocation, cqStoreName, cqAttributes, cqCertificateBinary, cqCertificatePath, cqPFXPassword }; - - -/******************************************************************** -InstallCertificates - CUSTOM ACTION ENTRY POINT for installing - certificates - -********************************************************************/ -extern "C" UINT __stdcall InstallCertificates( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - // initialize - hr = WcaInitialize(hInstall, "InstallCertificates"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = ConfigureCertificates(SCA_ACTION_INSTALL); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/******************************************************************** -UninstallCertificates - CUSTOM ACTION ENTRY POINT for uninstalling - certificates - -********************************************************************/ -extern "C" UINT __stdcall UninstallCertificates( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - // initialize - hr = WcaInitialize(hInstall, "UninstallCertificates"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = ConfigureCertificates(SCA_ACTION_UNINSTALL); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -static HRESULT ConfigureCertificates( - __in SCA_ACTION saAction - ) -{ - //AssertSz(FALSE, "debug ConfigureCertificates()."); - - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - PMSIHANDLE hViewCertificate; - PMSIHANDLE hRecCertificate; - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - - WCHAR* pwzId = NULL; - WCHAR* pwzName = NULL; - WCHAR* pwzComponent = NULL; - int iData = 0; - DWORD dwStoreLocation = 0; - LPWSTR pwzStoreName = 0; - DWORD dwAttributes = 0; - WCHAR* pwzData = NULL; - WCHAR* pwzPFXPassword = NULL; - WCHAR* pwzCaData = NULL; - WCHAR* pwzRollbackCaData = NULL; - - BYTE* pbCertificate = NULL; - DWORD cbCertificate = 0; - DWORD_PTR cbPFXPassword = 0; - - // Bail quickly if the Certificate table isn't around. - if (S_OK != WcaTableExists(L"Certificate")) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ConfigureCertificates() - required table not present."); - ExitFunction1(hr = S_FALSE); - } - - // Process the Certificate table. - hr = WcaOpenExecuteView(vcsCertQuery, &hViewCertificate); - ExitOnFailure(hr, "failed to open view on Certificate table"); - - while (SUCCEEDED(hr = WcaFetchRecord(hViewCertificate, &hRecCertificate))) - { - hr = WcaGetRecordString(hRecCertificate, cqCertificate, &pwzId); // the id is just useful to have up front - ExitOnFailure(hr, "failed to get Certificate.Certificate"); - - hr = WcaGetRecordString(hRecCertificate, cqComponent, &pwzComponent); - ExitOnFailure(hr, "failed to get Certificate.Component_"); - - er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); - hr = HRESULT_FROM_WIN32(er); - ExitOnFailure(hr, "failed to get state for component: %ls", pwzComponent); - - if (!(WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL == saAction) && - !(WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL == saAction) && - !(WcaIsReInstalling(isInstalled, isAction))) - { - WcaLog(LOGMSG_VERBOSE, "Skipping non-action certificate: %ls", pwzId); - continue; - } - - // extract the rest of the data from the Certificate table - hr = WcaGetRecordFormattedString(hRecCertificate, cqName, &pwzName); - ExitOnFailure(hr, "failed to get Certificate.Name"); - - hr = WcaGetRecordInteger(hRecCertificate, cqStoreLocation, &iData); - ExitOnFailure(hr, "failed to get Certificate.StoreLocation"); - - switch (iData) - { - case SCA_CERTSYSTEMSTORE_CURRENTUSER: - dwStoreLocation = CERT_SYSTEM_STORE_CURRENT_USER; - break; - case SCA_CERTSYSTEMSTORE_LOCALMACHINE: - dwStoreLocation = CERT_SYSTEM_STORE_LOCAL_MACHINE; - break; - default: - hr = E_INVALIDARG; - ExitOnFailure(hr, "Invalid store location value: %d", iData); - } - - hr = WcaGetRecordString(hRecCertificate, cqStoreName, &pwzStoreName); - ExitOnFailure(hr, "failed to get Certificate.StoreName"); - - hr = WcaGetRecordInteger(hRecCertificate, cqAttributes, reinterpret_cast(&dwAttributes)); - ExitOnFailure(hr, "failed to get Certificate.Attributes"); - - if (dwAttributes & SCA_CERT_ATTRIBUTE_BINARYDATA) - { - hr = WcaGetRecordString(hRecCertificate, cqCertificateBinary, &pwzData); - ExitOnFailure(hr, "failed to get Certificate.Binary_"); - } - else - { - hr = WcaGetRecordFormattedString(hRecCertificate, cqCertificatePath, &pwzData); - ExitOnFailure(hr, "failed to get Certificate.CertificatePath"); - } - - hr = WcaGetRecordFormattedString(hRecCertificate, cqPFXPassword, &pwzPFXPassword); - ExitOnFailure(hr, "failed to get Certificate.PFXPassword"); - - // Write the common data (for both install and uninstall) to the CustomActionData - // to pass data to the deferred CustomAction. - hr = StrAllocString(&pwzCaData, pwzName, 0); - ExitOnFailure(hr, "Failed to pass Certificate.Certificate to deferred CustomAction."); - hr = WcaWriteStringToCaData(pwzStoreName, &pwzCaData); - ExitOnFailure(hr, "Failed to pass Certificate.StoreName to deferred CustomAction."); - hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCaData); - ExitOnFailure(hr, "Failed to pass Certificate.Attributes to deferred CustomAction."); - - // Copy the rollback data from the deferred data because it's the same up to this point. - hr = StrAllocString(&pwzRollbackCaData, pwzCaData, 0); - ExitOnFailure(hr, "Failed to allocate string for rollback CustomAction."); - - // Finally, schedule the correct deferred CustomAction to actually do work. - LPCWSTR wzAction = NULL; - LPCWSTR wzRollbackAction = NULL; - DWORD dwCost = 0; - if (SCA_ACTION_UNINSTALL == saAction) - { - // Find an existing certificate one (if there is one) to so we have it for rollback. - hr = FindExistingCertificate(pwzName, dwStoreLocation, pwzStoreName, &pbCertificate, &cbCertificate); - ExitOnFailure(hr, "Failed to search for existing certificate with friendly name: %ls", pwzName); - - if (pbCertificate) - { - hr = WcaWriteStreamToCaData(pbCertificate, cbCertificate, &pwzRollbackCaData); - ExitOnFailure(hr, "Failed to pass Certificate.Data to rollback CustomAction."); - - hr = WcaWriteStringToCaData(pwzPFXPassword, &pwzRollbackCaData); - ExitOnFailure(hr, "Failed to pass Certificate.PFXPassword to rollback CustomAction."); - - hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCaData); - ExitOnFailure(hr, "Failed to pass Certificate.Attributes to deferred CustomAction."); - } - - // Pick the right action to run based on what store we're uninstalling from. - if (CERT_SYSTEM_STORE_LOCAL_MACHINE == dwStoreLocation) - { - wzAction = CUSTOM_ACTION_DECORATION(L"DeleteMachineCertificate"); - if (pbCertificate) - { - wzRollbackAction = L"RollbackDeleteMachineCertificate"; - } - } - else - { - wzAction = CUSTOM_ACTION_DECORATION(L"DeleteUserCertificate"); - if (pbCertificate) - { - wzRollbackAction = L"RollbackDeleteUserCertificate"; - } - } - dwCost = COST_CERT_DELETE; - } - else - { - // Actually get the certificate, resolve it to a blob, and get the blob's hash. - hr = ResolveCertificate(pwzId, pwzName, dwStoreLocation, pwzStoreName, dwAttributes, pwzData, pwzPFXPassword, &pbCertificate, &cbCertificate); - ExitOnFailure(hr, "Failed to resolve certificate: %ls", pwzId); - - hr = WcaWriteStreamToCaData(pbCertificate, cbCertificate, &pwzCaData); - ExitOnFailure(hr, "Failed to pass Certificate.Data to deferred CustomAction."); - - hr = WcaWriteStringToCaData(pwzPFXPassword, &pwzCaData); - ExitOnFailure(hr, "Failed to pass Certificate.PFXPassword to deferred CustomAction."); - - // Pick the right action to run based on what store we're installing into. - if (CERT_SYSTEM_STORE_LOCAL_MACHINE == dwStoreLocation) - { - wzAction = CUSTOM_ACTION_DECORATION(L"AddMachineCertificate"); - wzRollbackAction = CUSTOM_ACTION_DECORATION(L"RollbackAddMachineCertificate"); - } - else - { - wzAction = CUSTOM_ACTION_DECORATION(L"AddUserCertificate"); - wzRollbackAction = CUSTOM_ACTION_DECORATION(L"RollbackAddUserCertificate"); - } - dwCost = COST_CERT_ADD; - } - - if (wzRollbackAction) - { - hr = WcaDoDeferredAction(wzRollbackAction, pwzRollbackCaData, dwCost); - ExitOnFailure(hr, "Failed to schedule rollback certificate action '%ls' for: %ls", wzRollbackAction, pwzId); - } - - hr = WcaDoDeferredAction(wzAction, pwzCaData, dwCost); - ExitOnFailure(hr, "Failed to schedule certificate action '%ls' for: %ls", wzAction, pwzId); - - // Clean up for the next certificate. - ReleaseNullMem(pbCertificate); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - -LExit: - if (NULL != pwzPFXPassword && SUCCEEDED(StrSize(pwzPFXPassword, &cbPFXPassword))) - { - SecureZeroMemory(pwzPFXPassword, cbPFXPassword); - } - - ReleaseMem(pbCertificate); - ReleaseStr(pwzCaData); - ReleaseStr(pwzPFXPassword); - ReleaseStr(pwzData); - ReleaseStr(pwzName); - ReleaseStr(pwzStoreName); - ReleaseStr(pwzComponent); - ReleaseStr(pwzId); - - return hr; -} - - -static HRESULT ResolveCertificate( - __in LPCWSTR wzId, - __in LPCWSTR /*wzName*/, - __in DWORD dwStoreLocation, - __in LPCWSTR /*wzStoreName*/, - __in DWORD dwAttributes, - __in LPCWSTR wzData, - __in LPCWSTR wzPFXPassword, - __out BYTE** ppbCertificate, - __out DWORD* pcbCertificate - ) -{ - HRESULT hr = S_OK; - - LPWSTR pwzSql = NULL; - PMSIHANDLE hView; - PMSIHANDLE hRec; - MSIHANDLE hCertificateHashView = NULL; - MSIHANDLE hCertificateHashColumns = NULL; - - BYTE rgbCertificateHash[CB_CERTIFICATE_HASH] = { 0 }; - WCHAR wzEncodedCertificateHash[CB_CERTIFICATE_HASH * 2 + 1] = { 0 }; - - PMSIHANDLE hViewCertificateRequest, hRecCertificateRequest; - - WCHAR* pwzDistinguishedName = NULL; - WCHAR* pwzCA = NULL; - - BYTE* pbData = NULL; - DWORD cbData = 0; - - if (dwAttributes & SCA_CERT_ATTRIBUTE_REQUEST) - { - hr = E_NOTIMPL; - ExitOnFailure(hr, "Installing certificates by requesting them from a certificate authority is not currently supported"); - //if (dwAttributes & SCA_CERT_ATTRIBUTE_OVERWRITE) - //{ - // // try to overwrite with the patch to a cert file - // WcaLog(LOGMSG_VERBOSE, "ConfigureCertificates - Overwrite with SSLCERTIFICATE"); - // hr = ScaGetCertificateByPath(pwzName, fIsInstalling, fIsUninstalling, - // iStore, iStoreLocation, pwzData, wzPFXPassword, pbstrCertificate, pcbCertificate, pbaHashBuffer); - //} - //if (hr != S_OK) - //{ - // if (fIsUninstalling && !fIsInstalling) - // { - // // for uninstall, we just want to find the existing certificate - // hr = ScaSslExistingCertificateByName(pwzName, iStore, iStoreLocation, pbstrCertificate, pcbCertificate, pbaHashBuffer); - // ExitOnFailure(hr, "Failed Retrieving existing certificate during uninstall"); - // // ok if no existing cert - // if (S_OK != hr) - // hr = S_OK; - // } - // else - // { - // // still no certificate - // // user has request this certificate, try to locate DistinguishedName and CA - // hr = WcaTableExists(L"CertificateRequest"); - // ExitOnFailure(hr, "CertificateRequest is referenced but not found"); - // WcaLog(LOGMSG_VERBOSE, "ConfigureCertificates - CertificateRequest table present"); - // cchSQLView = 255 + lstrlenW(pwzName); - // pwzSQLView = new WCHAR[cchSQLView]; - // if (pwzSQLView) - // { - // hr = ::StringCchPrintfW(pwzSQLView, cchSQLView, L"SELECT `DistinguishedName`, `CA` FROM `CertificateRequest` WHERE `Certificate_`=\'%s\'", pwzName); - // ExitOnFailure(hr, "::StringCchPrintfW failed"); - // hr = WcaOpenExecuteView(pwzSQLView, &hViewCertificateRequest); - // ExitOnFailure(hr, "failed to open view on CertificateRequest table"); - // hr = WcaFetchSingleRecord(hViewCertificateRequest, &hRecCertificateRequest); - // ExitOnFailure(hr, "failed to retrieve request from CertificateRequest table"); - // hr = WcaGetRecordString(hRecCertificateRequest, 1, &pwzDistinguishedName); - // ExitOnFailure(hr, "failed to get DistinguishedName"); - // hr = WcaGetRecordString(hRecCertificateRequest, 2, &pwzCA); - // ExitOnFailure(hr, "failed to get CA"); - // if (pwzDistinguishedName && pwzCA && *pwzDistinguishedName && *pwzCA) - // { - // hr = ScaGetCertificateByRequest(pwzName, fIsInstalling, fIsUninstalling, iStore, iStoreLocation, pwzDistinguishedName, pwzCA, pbstrCertificate, pcbCertificate, pbaHashBuffer); - // } - // else - // { - // hr = E_FAIL; - // ExitOnFailure(hr, "CertificateRequest entry is empty"); - // } - // } - // else - // { - // hr = E_FAIL; - // ExitOnFailure(hr, "Out of memory"); - // } - // } - //} - } - else if (dwAttributes & SCA_CERT_ATTRIBUTE_BINARYDATA) - { - // get the binary stream in Binary - hr = WcaTableExists(L"Binary"); - if (S_OK != hr) - { - if (SUCCEEDED(hr)) - { - hr = E_UNEXPECTED; - } - ExitOnFailure(hr, "Binary was referenced but there is no Binary table."); - } - - hr = StrAllocFormatted(&pwzSql, L"SELECT `Data` FROM `Binary` WHERE `Name`=\'%s\'", wzData); - ExitOnFailure(hr, "Failed to allocate Binary table query."); - - hr = WcaOpenExecuteView(pwzSql, &hView); - ExitOnFailure(hr, "Failed to open view on Binary table"); - - hr = WcaFetchSingleRecord(hView, &hRec); - ExitOnFailure(hr, "Failed to retrieve request from Binary table"); - - hr = WcaGetRecordStream(hRec, 1, &pbData, &cbData); - ExitOnFailure(hr, "Failed to ready Binary.Data for certificate."); - } - else if (dwAttributes == SCA_CERT_ATTRIBUTE_DEFAULT) - { - hr = ReadCertificateFile(wzData, &pbData, &cbData); - ExitOnFailure(hr, "Failed to read certificate from file path."); - } - else - { - hr = E_INVALIDARG; - ExitOnFailure(hr, "Invalid Certificate.Attributes."); - } - - // If we have loaded a certificate, update the Certificate.Hash column. - if (pbData) - { - hr = CertificateToHash(pbData, cbData, dwStoreLocation, wzPFXPassword, rgbCertificateHash, countof(rgbCertificateHash)); - ExitOnFailure(hr, "Failed to get SHA1 hash of certificate."); - - hr = StrHexEncode(rgbCertificateHash, countof(rgbCertificateHash), wzEncodedCertificateHash, countof(wzEncodedCertificateHash)); - ExitOnFailure(hr, "Failed to hex encode SHA1 hash of certificate."); - - // Update the CertificateHash table. - hr = WcaAddTempRecord(&hCertificateHashView, &hCertificateHashColumns, L"CertificateHash", NULL, 0, 2, wzId, wzEncodedCertificateHash); - ExitOnFailure(hr, "Failed to add encoded has for certificate: %ls", wzId); - } - - *ppbCertificate = pbData; - *pcbCertificate = cbData; - pbData = NULL; - -LExit: - if (hCertificateHashColumns) - { - ::MsiCloseHandle(hCertificateHashColumns); - } - - if (hCertificateHashView) - { - ::MsiCloseHandle(hCertificateHashView); - } - - ReleaseStr(pwzDistinguishedName); - ReleaseStr(pwzCA); - ReleaseMem(pbData); - ReleaseStr(pwzSql); - - return hr; -} - - -static HRESULT ReadCertificateFile( - __in LPCWSTR wzPath, - __out BYTE** prgbData, - __out DWORD* pcbData - ) -{ - HRESULT hr = S_OK; - - PCCERT_CONTEXT pCertContext = NULL; - DWORD dwContentType; - BYTE* pbData = NULL; - DWORD cbData = 0; - - if (!::CryptQueryObject(CERT_QUERY_OBJECT_FILE, reinterpret_cast(wzPath), CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &dwContentType, NULL, NULL, NULL, (LPCVOID*)&pCertContext)) - { - ExitOnFailure(hr, "Failed to read certificate from file: %ls", wzPath); - } - - if (pCertContext) - { - cbData = pCertContext->cbCertEncoded; - pbData = static_cast(MemAlloc(cbData, FALSE)); - ExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to allocate memory to read certificate from file: %ls", wzPath); - - CopyMemory(pbData, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded); - } - else - { - // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. - if (dwContentType & CERT_QUERY_CONTENT_PFX) - { - hr = FileRead(&pbData, &cbData, wzPath); - ExitOnFailure(hr, "Failed to read PFX file: %ls", wzPath); - } - else - { - hr = E_UNEXPECTED; - ExitOnFailure(hr, "Unexpected certificate type read from disk."); - } - } - - *pcbData = cbData; - *prgbData = pbData; - pbData = NULL; - -LExit: - ReleaseMem(pbData); - return hr; -} - - -static HRESULT CertificateToHash( - __in BYTE* pbCertificate, - __in DWORD cbCertificate, - __in DWORD dwStoreLocation, - __in LPCWSTR wzPFXPassword, - __in BYTE rgbHash[], - __in DWORD cbHash - ) -{ - HRESULT hr = S_OK; - - HCERTSTORE hPfxCertStore = NULL; - PCCERT_CONTEXT pCertContext = NULL; - PCCERT_CONTEXT pCertContextEnum = NULL; - CRYPT_DATA_BLOB blob = { 0 }; - CRYPT_KEY_PROV_INFO* pPfxInfo = NULL; - DWORD dwKeyset = (CERT_SYSTEM_STORE_CURRENT_USER == dwStoreLocation) ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; - DWORD dwEncodingType; - DWORD dwContentType; - DWORD dwFormatType; - - blob.pbData = pbCertificate; - blob.cbData = cbCertificate; - - if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) - { - ExitWithLastError(hr, "Failed to process certificate as a valid certificate."); - } - - if (!pCertContext) - { - // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. - if (dwContentType & CERT_QUERY_CONTENT_PFX) - { - // If we fail and our password is blank, also try passing in NULL for the password (according to the docs) - hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, dwKeyset); - if (NULL == hPfxCertStore && !*wzPFXPassword) - { - hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, NULL, dwKeyset); - } - ExitOnNullWithLastError(hPfxCertStore, hr, "Failed to open PFX file."); - - // Find the first cert with a private key, or just use the last one - for (pCertContextEnum = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContextEnum); - pCertContextEnum; - pCertContextEnum = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContextEnum)) - { - pCertContext = pCertContextEnum; - - if (pCertContext && CertHasPrivateKey(pCertContext, NULL)) - { - break; - } - } - - ExitOnNullWithLastError(pCertContext, hr, "Failed to read first certificate out of PFX file."); - - // Ignore failures, the worst that happens is some parts of the PFX get left behind. - CertReadProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, &pPfxInfo, NULL); - } - else - { - hr = E_UNEXPECTED; - ExitOnFailure(hr, "Unexpected certificate type processed."); - } - } - - DWORD cb = cbHash; - if (!::CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, static_cast(rgbHash), &cb)) - { - ExitWithLastError(hr, "Failed to get certificate SHA1 hash property."); - } - AssertSz(cb == cbHash, "Did not correctly read certificate SHA1 hash."); - -LExit: - if (pCertContext) - { - ::CertFreeCertificateContext(pCertContext); - } - - if (hPfxCertStore) - { - ::CertCloseStore(hPfxCertStore, 0); - } - - if (pPfxInfo) - { - HCRYPTPROV hProvIgnored = NULL; // ignored on deletes. - ::CryptAcquireContextW(&hProvIgnored, pPfxInfo->pwszContainerName, pPfxInfo->pwszProvName, pPfxInfo->dwProvType, dwKeyset | CRYPT_DELETEKEYSET | CRYPT_SILENT); - - MemFree(pPfxInfo); - } - - return hr; -} - - -static HRESULT FindExistingCertificate( - __in LPCWSTR wzName, - __in DWORD dwStoreLocation, - __in LPCWSTR wzStore, - __out BYTE** prgbCertificate, - __out DWORD* pcbCertificate - ) -{ - HRESULT hr = S_OK; - HCERTSTORE hCertStore = NULL; - PCCERT_CONTEXT pCertContext = NULL; - BYTE* pbCertificate = NULL; - DWORD cbCertificate = 0; - - hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation | CERT_STORE_READONLY_FLAG, wzStore); - MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store."); - - // Loop through the certificate, looking for certificates that match our friendly name. - pCertContext = CertFindCertificateInStore(hCertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL); - while (pCertContext) - { - WCHAR wzFriendlyName[256] = { 0 }; - DWORD cbFriendlyName = sizeof(wzFriendlyName); - - if (::CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, reinterpret_cast(wzFriendlyName), &cbFriendlyName) && - CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, wzName, -1, wzFriendlyName, -1)) - { - // If the certificate with matching friendly name is valid, let's use that. - long lVerify = ::CertVerifyTimeValidity(NULL, pCertContext->pCertInfo); - if (0 == lVerify) - { - cbCertificate = pCertContext->cbCertEncoded; - pbCertificate = static_cast(MemAlloc(cbCertificate, FALSE)); - ExitOnNull(pbCertificate, hr, E_OUTOFMEMORY, "Failed to allocate memory to copy out exist certificate."); - - CopyMemory(pbCertificate, pCertContext->pbCertEncoded, cbCertificate); - break; // found a matching certificate, no more searching necessary - } - } - - // Next certificate in the store. - PCCERT_CONTEXT pNext = ::CertFindCertificateInStore(hCertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pCertContext); - // old pCertContext is freed by CertFindCertificateInStore - pCertContext = pNext; - } - - *prgbCertificate = pbCertificate; - *pcbCertificate = cbCertificate; - pbCertificate = NULL; - -LExit: - ReleaseMem(pbCertificate); - - if (pCertContext) - { - ::CertFreeCertificateContext(pCertContext); - } - - if (hCertStore) - { - ::CertCloseStore(hCertStore, 0); - } - - return hr; -} - -/* -HRESULT CreateEnroll(ICEnroll2 **hEnroll, INT iStore, INT iStoreLocation) -{ - ICEnroll2 *pEnroll = NULL; - HRESULT hr = S_OK; - LONG lFlags; - DWORD dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; - - // create IEntroll - hr = CoCreateInstance( CLSID_CEnroll, NULL, CLSCTX_INPROC_SERVER, IID_ICEnroll2, (void **)&pEnroll ); - if (FAILED(hr)) - return hr; - - switch (iStore) - { - case SCA_CERT_STORENAME_MY: - pEnroll->get_MyStoreFlags(&lFlags); - lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; - lFlags |= dwFlags; - // following call will change Request store flags also - pEnroll->put_MyStoreFlags(lFlags); - break; - case SCA_CERT_STORENAME_CA: - pEnroll->get_CAStoreFlags(&lFlags); - lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; - lFlags |= dwFlags; - // following call will change Request store flags also - pEnroll->put_CAStoreFlags(lFlags); - break; - case SCA_CERT_STORENAME_REQUEST: - pEnroll->get_RequestStoreFlags(&lFlags); - lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; - lFlags |= dwFlags; - // following call will change Request store flags also - pEnroll->put_RequestStoreFlags(lFlags); - break; - case SCA_CERT_STORENAME_ROOT: - pEnroll->get_RootStoreFlags(&lFlags); - lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; - lFlags |= dwFlags; - // following call will change Request store flags also - pEnroll->put_RootStoreFlags(lFlags); - break; - default: - hr = E_FAIL; - return hr; - } - - pEnroll->get_GenKeyFlags(&lFlags); - lFlags |= CRYPT_EXPORTABLE; - pEnroll->put_GenKeyFlags(lFlags); - - pEnroll->put_KeySpec(AT_KEYEXCHANGE); - pEnroll->put_ProviderType(PROV_RSA_SCHANNEL); - pEnroll->put_DeleteRequestCert(TRUE); - - *hEnroll = pEnroll; - return hr; -} - - -HRESULT RequestCertificate(LPCWSTR pwzName, INT iStore, INT iStoreLocation, - LPCWSTR wzComputerName, LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthority, - BSTR *pbstrCertificate) -{ - if (pbstrCertificate == NULL) - return E_INVALIDARG; - - HRESULT hr; - ICEnroll2 *pEnroll = NULL; - ICertRequest *pCertRequest = NULL; - BSTR bstrRequest = NULL; - LONG nDisposition; - - BSTR bstrCertificateUsage = NULL; - BSTR bstrCertificateAttributes = NULL; - BSTR bstrCertificateAuthority = NULL; - - // equivalent to: sprintf(bstrDistinguishedName, L"%s,CN=%s", wzDistinguishedName, wzComputerName); - DWORD cchComputerName = lstrlenW(wzComputerName); - DWORD cchDistinguishedName = lstrlenW(wzDistinguishedName); - CONST DWORD cchbstrDistinguishedName = 5 + cchComputerName + cchDistinguishedName; - BSTR bstrDistinguishedName = SysAllocStringLen(NULL, cchbstrDistinguishedName); - ExitOnNull(bstrDistinguishedName, hr, E_OUTOFMEMORY, "Failed to allocate space for distinguished name."); - ::StringCchCopyW((WCHAR*) bstrDistinguishedName, cchbstrDistinguishedName, wzDistinguishedName); - ::StringCchCatW((WCHAR*) bstrDistinguishedName, cchbstrDistinguishedName, L",CN="); - ::StringCchCatW((WCHAR*) bstrDistinguishedName, cchbstrDistinguishedName, wzComputerName); - - bstrCertificateUsage = SysAllocString(WIDE(szOID_PKIX_KP_SERVER_AUTH)); - ExitOnNull(bstrCertificateUsage, hr, E_OUTOFMEMORY, "Failed to allocate space for Certificate Usage."); - bstrCertificateAttributes = SysAllocString(L"CertificateTemplate:WebServer"); - bstrCertificateAuthority = SysAllocString(wzCertificateAuthority); - ExitOnNull(bstrCertificateAuthority, hr, E_OUTOFMEMORY, "Failed to allocate space for Certificate Authority."); - - hr = CreateEnroll(&pEnroll, iStore, iStoreLocation); - ExitOnFailure(hr, "failed CoCreateInstance IEnroll"); - - hr = pEnroll->createPKCS10(bstrDistinguishedName, bstrCertificateUsage, &bstrRequest); - ExitOnFailure(hr, "failed createPKCS10"); - - hr = CoCreateInstance(CLSID_CCertRequest, NULL, CLSCTX_INPROC_SERVER, IID_ICertRequest, (void **)&pCertRequest); - ExitOnFailure(hr, "failed CoCreateInstance ICertRequest"); - - hr = pCertRequest->Submit(CR_IN_BASE64 | CR_IN_PKCS10, bstrRequest, bstrCertificateAttributes, bstrCertificateAuthority, &nDisposition); - ExitOnFailure(hr, "failed ICertRequest.Submit"); - - hr = (nDisposition == CR_DISP_ISSUED) ? S_OK : E_FAIL; - ExitOnFailure(hr, "failed CR_DISP_ISSUED"); - - hr = pCertRequest->GetCertificate(CR_OUT_BASE64, pbstrCertificate); - ExitOnFailure(hr, "failed ICertRequest.GetCertificate"); - - // save the certificate in place, cannot be passed to a deferred custom action - hr = pEnroll->acceptPKCS7(*pbstrCertificate); - ExitOnFailure(hr, "failed accept certificate into MY store"); - -LExit: - ReleaseObject(pCertRequest); - ReleaseBSTR(bstrRequest); - ReleaseObject(pEnroll); - ReleaseBSTR(bstrCertificateAuthority); - ReleaseBSTR(bstrCertificateAttributes); - ReleaseBSTR(bstrDistinguishedName); - - return hr; -} - - -VOID ParseCertificateAuthority(__in LPCWSTR wzCertificateAuthorityOrig, __out LPWSTR *pwzBuffer, __out LPWSTR **hwzCAArray, __out int *piCAArray) -{ - // @asAuthorities = split /;/, $sAuthority; - CONST WCHAR wchDelimiter = L';'; - - // copy constant into a buffer - Assert(wzCertificateAuthorityOrig); - - INT cchCA = lstrlenW(wzCertificateAuthorityOrig) + 1; - WCHAR* wzBuffer = new WCHAR[cchCA]; - if (!wzBuffer) - return; - - ::StringCchCopyW(wzBuffer, cchCA, wzCertificateAuthorityOrig); - - // determine the number of strings in the field - int iCAArray = 1; - int i; - for (i = 0; i < cchCA; ++i) - { - if (wzBuffer[i] == wchDelimiter) - ++iCAArray; - } - LPWSTR *pwzCAArray = (LPWSTR*) new BYTE[iCAArray * sizeof(LPWSTR)]; - if (!pwzCAArray) - { - return; - } - - pwzCAArray[0] = wzBuffer; - iCAArray = 0; - for (i = 0; i < cchCA; ++i) - { - if (wzBuffer[i] != wchDelimiter) - continue; - wzBuffer[i] = 0; // convert buffer into MULTISZ - pwzCAArray[iCAArray] = &wzBuffer[i+1]; - ++iCAArray; - } - - *pwzBuffer = wzBuffer; - *hwzCAArray = pwzCAArray; - *piCAArray = iCAArray; -} - - -HRESULT ScaSslExistingCertificateByBinaryData(INT iStore, INT iStoreLocation, BYTE* pwzData, DWORD cchData) -{ - HRESULT hr = S_FALSE; - HCERTSTORE hCertStore = NULL; - PCCERT_CONTEXT pCertCtx = NULL, pCertCtxExisting = NULL; - DWORD dwFlags = 0; - LPCWSTR wzStore = StoreMapping(iStore); - CERT_BLOB blob; - - dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; - hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwFlags, wzStore); - MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "failed to open certificate store, OK on uninstall"); - - blob.pbData = pwzData; - blob.cbData = cchData; - - if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, - 0, NULL, NULL, NULL, NULL, NULL, (LPCVOID*)&pCertCtx)) - ExitOnLastError(hr, "failed to parse the certificate blob, OK on uninstall"); - - pCertCtxExisting = CertFindCertificateInStore( - hCertStore, - PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, - 0, - CERT_FIND_EXISTING, - pCertCtx, - NULL); - - if (pCertCtxExisting) - { - hr = S_OK; - } - -LExit: - if (pCertCtx) - { - CertFreeCertificateContext(pCertCtx); - pCertCtx = NULL; - } - if (pCertCtxExisting) - { - CertFreeCertificateContext(pCertCtxExisting); - pCertCtxExisting = NULL; - } - if (hCertStore) - { - CertCloseStore(hCertStore, 0); - hCertStore = NULL; - } - - return hr; -} - - -HRESULT ScaSslExistingCertificateByName(LPCWSTR pwzName, INT iStore, INT iStoreLocation, - BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) -{ - HRESULT hr = S_FALSE; - HCERTSTORE hSystemStore = NULL; - PCCERT_CONTEXT pTargetCert = NULL; - WCHAR wzFriendlyName[MAX_PATH] = {0}; - DWORD dwFriendlyNameLen = sizeof(wzFriendlyName); - - // Call CertOpenStore to open the CA store. - hSystemStore = CertOpenStore( - CERT_STORE_PROV_SYSTEM_REGISTRY, - 0, - NULL, - (iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT) | CERT_STORE_OPEN_EXISTING_FLAG, - StoreMapping(iStore)); - if (hSystemStore == NULL) - ExitFunction(); - - // Get a particular certificate using CertFindCertificateInStore. - pTargetCert = CertFindCertificateInStore( - hSystemStore, - PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, - 0, - CERT_FIND_ANY, - NULL, - NULL); - while (pTargetCert != NULL) - { - if ((CertGetCertificateContextProperty(pTargetCert, CERT_FRIENDLY_NAME_PROP_ID, - (BYTE*)wzFriendlyName, &dwFriendlyNameLen)) && - lstrcmpW(wzFriendlyName, pwzName) == 0) - { - // pTargetCert is a pointer to the desired certificate. - // Check the certificate's validity. - switch (CertVerifyTimeValidity( - NULL, - pTargetCert->pCertInfo)) - { - case 1: - // Certificate is expired - WcaLog(LOGMSG_STANDARD, "The SSL certificate has expired"); - // always remove it - { - PCCERT_CONTEXT pDupCertContext = CertDuplicateCertificateContext(pTargetCert); - if (pDupCertContext && CertDeleteCertificateFromStore(pDupCertContext)) - { - WcaLog(LOGMSG_STANDARD, "A SSL certificate has removed"); - } - } - break; - case 0: - // Certificate is valid - WcaLog(LOGMSG_STANDARD, "The SSL certificate is valid"); - hr = S_OK; - if (pbaHashBuffer) - { - // if the certificate already exists and is valid, use that one - DWORD dwHashSize = CB_CERTIFICATE_HASH; - hr = CertGetCertificateContextProperty(pTargetCert, CERT_SHA1_HASH_PROP_ID, (VOID*)pbaHashBuffer, &dwHashSize) - ? S_OK : E_FAIL; - ExitOnFailure(hr, "failed CertGetCertificateContextProperty CERT_SHA1_HASH_PROP_ID"); - Assert(pbstrCertificate); - Assert(pcbCertificate); - ReleaseBSTR(*pbstrCertificate); - - *pbstrCertificate = SysAllocStringByteLen((LPCSTR)(pTargetCert->pbCertEncoded), pTargetCert->cbCertEncoded); - *pcbCertificate = pTargetCert->cbCertEncoded; - } - ExitFunction(); - break; - default: - // Certificate not valid yet, ignore it - WcaLog(LOGMSG_STANDARD, "The SSL certificate is not valid"); - break; - } - } - pTargetCert = CertFindCertificateInStore( - hSystemStore, - PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, - 0, - CERT_FIND_ANY, - NULL, - pTargetCert); - wzFriendlyName[0] = 0; - dwFriendlyNameLen = sizeof(wzFriendlyName); - } - -LExit: - // Clean up memory and quit. - if (pTargetCert) - { - CertFreeCertificateContext(pTargetCert); - pTargetCert = NULL; - } - if (hSystemStore) - { - CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG); - hSystemStore = NULL; - } - - return hr; -} - - -HRESULT ScaSslNewCertificate(LPCWSTR pwzName, INT iStore, INT iStoreLocation, LPCWSTR wzComputerName, LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthorityOrig, - BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) -{ - - if (pbstrCertificate == NULL) - return E_INVALIDARG; - - HRESULT hr = S_OK; - LPWSTR wzCABuffer = NULL; - LPWSTR *wzCAArray = NULL; - int iCAArray = 0; - - // otherwise call the CA for one - ParseCertificateAuthority(wzCertificateAuthorityOrig, &wzCABuffer, &wzCAArray, &iCAArray); - - // try each authority three times - for (int i = 0; i < 3 * iCAArray; ++i) - { - LPCWSTR wzCA = wzCAArray[i % iCAArray]; - if (NULL == wzCA || NULL == wzCA[0]) continue; - WcaLog(LOGMSG_STANDARD, "Requesting SSL certificate from %ls", wzCA); - hr = RequestCertificate(pwzName, iStore, iStoreLocation, wzComputerName, wzDistinguishedName, wzCA, pbstrCertificate); - if (hr == S_OK && pbstrCertificate) - { - // set the friendly name - CRYPT_HASH_BLOB hblob; - CERT_BLOB blob; - HCERTSTORE hCertStore = NULL; - PCCERT_CONTEXT pCertCtxExisting = NULL; - - blob.pbData = (BYTE*)pwzName; - blob.cbData = (lstrlenW(pwzName) + 1) * sizeof(pwzName[0]); // including terminating null - - *pcbCertificate = SysStringByteLen(*pbstrCertificate); - hr = CertificateToHash(*pbstrCertificate, pbaHashBuffer); - ExitOnFailure(hr, "failed to CertificateToHash for an existing certificate"); - - hblob.pbData = pbaHashBuffer; - hblob.cbData = CB_CERTIFICATE_HASH; - - hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, (iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT), StoreMapping(iStore)); - MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "failed to open certificate store"); - - pCertCtxExisting = CertFindCertificateInStore( - hCertStore, - PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, - 0, - CERT_FIND_HASH, - &hblob, - NULL); - - if (pCertCtxExisting) - { - CertSetCertificateContextProperty( - pCertCtxExisting, - CERT_FRIENDLY_NAME_PROP_ID, - 0, - &blob); - } - - if (pCertCtxExisting) - { - CertFreeCertificateContext(pCertCtxExisting); - pCertCtxExisting = NULL; - } - if (hCertStore) - { - CertCloseStore(hCertStore, 0); - hCertStore = NULL; - } - ExitFunction(); - } - if (pbstrCertificate && *pbstrCertificate) - { - SysFreeString(*pbstrCertificate); - pbstrCertificate = NULL; - } - } - hr = E_FAIL; - ExitOnFailure(hr, "failed to RequestCertificate"); - -LExit: - if (wzCABuffer) - { - delete wzCABuffer; - } - if (wzCAArray) - { - delete wzCAArray; - } - - return hr; -} - - -HRESULT ScaGetCertificateByRequest(LPCWSTR pwzName, BOOL fIsInstalling, BOOL fIsUninstalling, - INT iStore, INT iStoreLocation, - LPCWSTR wzDistinguishedName, LPCWSTR wzCA, - BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) -{ - HRESULT hr = S_OK; - WCHAR wzComputerName[MAX_COMPUTER_NAME] = {0}; - WCHAR* pwzData = NULL; - DWORD cchData = 0; - - // override %COMPUTERNAME% with DOMAINNAME property - hr = WcaGetProperty( L"DOMAINNAME", &pwzData); - ExitOnFailure(hr, "Failed to get Property DOMAINNAME"); - if (*pwzData) - { - // if DOMAINNAME is set, use it - ::StringCchCopyW(wzComputerName, MAX_COMPUTER_NAME, pwzData); - } - else - { - // otherwise get the intranet name given by %COMPUTERNAME% - GetEnvironmentVariableW(L"COMPUTERNAME", wzComputerName, MAX_COMPUTER_NAME); - } - - hr = ScaSslExistingCertificateByName(pwzName, iStore, iStoreLocation, pbstrCertificate, pcbCertificate, pbaHashBuffer); - ExitOnFailure(hr, "Failed ScaSslExistingCertificateByName"); - if (S_OK != hr) - { - if (!fIsUninstalling && fIsInstalling) - { - // if no existing cert and not on uninstall, hit the authority - WcaLog(LOGMSG_STANDARD, "Adding certificate: requested, %ls", wzDistinguishedName); - hr = ScaSslNewCertificate(pwzName, iStore, iStoreLocation, wzComputerName, wzDistinguishedName, wzCA, - pbstrCertificate, pcbCertificate, pbaHashBuffer); - ExitOnFailure(hr, "Failed ScaSslNewCertificate"); - } - else - { - // if no existing cert and uninstall - hr = S_OK; - } - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaInstallCertificateByContext(LPCWSTR pwzName, INT iStore, INT iStoreLocation, - PCCERT_CONTEXT pCertContext) -{ - HRESULT hr = S_OK; - HCERTSTORE hCertStore = NULL; - DWORD dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; - CERT_BLOB blob; - - hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwFlags, StoreMapping(iStore)); - if (hCertStore == NULL) - MessageExitOnLastError(hr, msierrCERTFailedOpen, "failed to open certificate store"); - - blob.pbData = (BYTE*)pwzName; - blob.cbData = (lstrlenW(pwzName) + 1) * sizeof(pwzName[0]); // including terminating null - CertSetCertificateContextProperty( - pCertContext, - CERT_FRIENDLY_NAME_PROP_ID, - 0, - &blob); - - if (!CertAddCertificateContextToStore( - hCertStore, - pCertContext, - CERT_STORE_ADD_REPLACE_EXISTING, - NULL)) - { - hr = E_FAIL; - MessageExitOnLastError(hr, msierrCERTFailedAdd, "failed to add certificate to the store"); - } - -LExit: - if (hCertStore) - { - CertCloseStore(hCertStore, 0); - hCertStore = NULL; - } - - return hr; -} - - -HRESULT ScaGetCertificateByPath(LPCWSTR pwzName, BOOL fIsInstalling, BOOL fIsUninstalling, - INT iStore, INT iStoreLocation, LPCWSTR wzSslCertificate, LPCWSTR wzPFXPassword, - BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) -{ - Assert(wzSslCertificate); - HRESULT hr = S_OK; - PCCERT_CONTEXT pCertContext = NULL; - DWORD dwEncodingType = 0; - DWORD dwContentType = 0; - DWORD dwFormatType = 0; - DWORD dwHashSize = CB_CERTIFICATE_HASH; - HANDLE hPfxFile = INVALID_HANDLE_VALUE; - CRYPT_DATA_BLOB blob; - - blob.pbData = NULL; - blob.cbData = 0; - - if (wzSslCertificate && wzSslCertificate[0] != 0) - { - if (!::CryptQueryObject(CERT_QUERY_OBJECT_FILE, (LPVOID)wzSslCertificate, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, - 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) - hr = fIsUninstalling ? S_FALSE : HRESULT_FROM_WIN32(::GetLastError()); // don't fail on uninstall - ExitOnFailure(hr, "failed CryptQueryObject"); - } - else - { - hr = S_FALSE; - ExitFunction(); - } - - if (!pCertContext) - { - // this is a pfx? - // make sure to exit this block of code properly for clean up blob.pbData - if (dwContentType & CERT_QUERY_CONTENT_PFX) - { - DWORD iSize = 0, iReadSize = 0; - HCERTSTORE hPfxCertStore = NULL; - - hPfxFile = ::CreateFileW(wzSslCertificate, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - hr = (hPfxFile != INVALID_HANDLE_VALUE) ? S_OK : E_FAIL; - ExitOnFailure(hr, "failed CryptQueryObject, file handle is null"); - iSize = ::GetFileSize(hPfxFile, NULL); - hr = (iSize > 0) ? S_OK : E_FAIL; - ExitOnFailure(hr, "failed CryptQueryObject, file size is 0"); - blob.pbData = new BYTE[iSize]; - blob.cbData = iSize; - hr = (blob.pbData) ? S_OK : E_FAIL; - ExitOnFailure(hr, "out of memory for blob"); - - if (::ReadFile(hPfxFile, (LPVOID)blob.pbData, iSize, &iReadSize, NULL)) - { - hPfxCertStore = PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, - (iStoreLocation == SCA_CERTSYSTEMSTORE_CURRENTUSER) ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET); - if (hPfxCertStore) - { - pCertContext = CertEnumCertificatesInStore(hPfxCertStore, NULL); - // work only with the first certificate in pfx - if (pCertContext) - { - hr = CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, (VOID*)pbaHashBuffer, &dwHashSize) - ? S_OK : E_FAIL; - ExitOnFailure(hr, "failed CertGetCertificateContextProperty CERT_SHA1_HASH_PROP_ID"); - ReleaseBSTR(*pbstrCertificate); - - *pbstrCertificate = SysAllocStringByteLen((LPCSTR)(pCertContext->pbCertEncoded), pCertContext->cbCertEncoded); - *pcbCertificate = pCertContext->cbCertEncoded; - if (fIsInstalling) - { - // install the certificate, cannot defer because the data required cannot be passed - hr = ScaInstallCertificateByContext(pwzName, iStore, iStoreLocation, pCertContext); - } - } - else - hr = E_FAIL; - } - else - hr = E_FAIL; - } - else - hr = E_FAIL; - } - else - { - ExitOnFailure(hr = E_FAIL, "failed CryptQueryObject, unknown data"); - } - } - else - { - // return cert and its hash - hr = CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, (VOID*)pbaHashBuffer, &dwHashSize) - ? S_OK : E_FAIL; - ExitOnFailure(hr, "failed CertGetCertificateContextProperty CERT_SHA1_HASH_PROP_ID"); - ReleaseBSTR(*pbstrCertificate); - - *pbstrCertificate = SysAllocStringByteLen((LPCSTR)(pCertContext->pbCertEncoded), pCertContext->cbCertEncoded); - *pcbCertificate = pCertContext->cbCertEncoded; - if (fIsInstalling) - { - // install the certificate, cannot defer because the data required cannot be passed - hr = ScaInstallCertificateByContext(pwzName, iStore, iStoreLocation, pCertContext); - } - } - -LExit: - if (pCertContext) - { - CertFreeCertificateContext(pCertContext); - pCertContext = NULL; - } - if (hPfxFile != INVALID_HANDLE_VALUE) - { - CloseHandle(hPfxFile); - hPfxFile = INVALID_HANDLE_VALUE; - } - if (blob.pbData) - { - delete [] blob.pbData; - blob.pbData = NULL; - blob.cbData = 0; - } - - return hr; -} - - -HRESULT ScaInstallCertificateByBinaryData(BOOL fAddCert, INT iStore, INT iStoreLocation, LPCWSTR wzName, BYTE* pwzData, DWORD cchData, - LPCWSTR wzPFXPassword) -{ - Assert(wzName); - Assert(pwzData); - Assert(cchData); - HRESULT hr = S_OK; - HCERTSTORE hCertStore = NULL, hPfxCertStore = NULL; - PCCERT_CONTEXT pCertCtx = NULL, pCertCtxExisting = NULL; - DWORD dwFlags, dwEncodingType, dwContentType, dwFormatType; - CERT_BLOB blob; - LPCWSTR wzStore = StoreMapping(iStore); - - dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; - hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwFlags, wzStore); - MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "failed to open certificate store"); - - blob.pbData = pwzData; - blob.cbData = cchData; - - if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, - 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertCtx)) - ExitOnLastError(hr, "failed to parse the certificate blob"); - ExitOnNull(pCertCtx, hr, E_UNEXPECTED, "failed to parse the certificate blob"); - - blob.pbData = (BYTE*)wzName; - blob.cbData = (lstrlenW(wzName) + 1) * sizeof(wzName[0]); // including terminating null - - CertSetCertificateContextProperty( - pCertCtx, - CERT_FRIENDLY_NAME_PROP_ID, - 0, - &blob); - - if (fAddCert) - { - // Add - WcaLog(LOGMSG_STANDARD, "Adding certificate: binary name, %ls", wzName); - if (!CertAddCertificateContextToStore( - hCertStore, - pCertCtx, - CERT_STORE_ADD_REPLACE_EXISTING, - NULL)) - { - hr = E_FAIL; - MessageExitOnLastError(hr, msierrCERTFailedAdd, "failed to add certificate to the store"); - } - } - else - { - // Delete - WcaLog(LOGMSG_STANDARD, "Deleting certificate provided: binary name, %ls", wzName); - pCertCtxExisting = CertFindCertificateInStore( - hCertStore, - PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, - 0, - CERT_FIND_EXISTING, - pCertCtx, - NULL); - - if (pCertCtxExisting) - { - if (!CertDeleteCertificateFromStore(pCertCtxExisting)) - { - ExitOnLastError(hr, "failed to delete certificate"); - } - else - { - pCertCtxExisting = NULL; - } - } - } - -LExit: - if (pCertCtx) - { - CertFreeCertificateContext(pCertCtx); - pCertCtx = NULL; - } - if (pCertCtxExisting) - { - CertFreeCertificateContext(pCertCtxExisting); - pCertCtxExisting = NULL; - } - // order is important for store - if (hCertStore) - { - CertCloseStore(hCertStore, 0); - hCertStore = NULL; - } - if (hPfxCertStore) - { - CertCloseStore(hPfxCertStore, 0); - hPfxCertStore = NULL; - } - - return hr; -} -*/ diff --git a/src/ca/scacert.h b/src/ca/scacert.h deleted file mode 100644 index 39b00d3d..00000000 --- a/src/ca/scacert.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. - - -#define CB_CERTIFICATE_HASH 20 - -// Certificate.Attribute -enum SCA_CERT_ATTRIBUTES -{ - SCA_CERT_ATTRIBUTE_DEFAULT = 0, - SCA_CERT_ATTRIBUTE_REQUEST = 1, - SCA_CERT_ATTRIBUTE_BINARYDATA = 2, - SCA_CERT_ATTRIBUTE_OVERWRITE = 4, - SCA_CERT_ATTRIBUTE_VITAL = 8, -}; - - -// Certificate.StoreLocation -enum SCA_CERTSYSTEMSTORE -{ - SCA_CERTSYSTEMSTORE_CURRENTUSER = 1, - SCA_CERTSYSTEMSTORE_LOCALMACHINE = 2, -}; diff --git a/src/ca/scacertexec.cpp b/src/ca/scacertexec.cpp deleted file mode 100644 index 95870c79..00000000 --- a/src/ca/scacertexec.cpp +++ /dev/null @@ -1,431 +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" - -#define SIXTY_FOUR_MEG 64 * 1024 * 1024 - -// prototypes -static HRESULT ExecuteCertificateOperation( - __in MSIHANDLE hInstall, - __in SCA_ACTION saAction, - __in DWORD dwStoreRoot - ); - -static HRESULT ReadCertificateFile( - __in LPCWSTR wzPath, - __out BYTE** prgbData, - __out DWORD* pcbData - ); - -static HRESULT InstallCertificatePackage( - __in HCERTSTORE hStore, - __in BOOL fUserCertificateStore, - __in LPCWSTR wzName, - __in_opt BYTE* rgbData, - __in DWORD cbData, - __in BOOL fVital, - __in_opt LPCWSTR wzPFXPassword - ); - -static HRESULT UninstallCertificatePackage( - __in HCERTSTORE hStore, - __in BOOL fUserCertificateStore, - __in LPCWSTR wzName - ); - -static HRESULT AddCertificate( - __in HCERTSTORE hStore, - __in PCCERT_CONTEXT pCertContext, - __in LPCWSTR wzCertificateUniqueName, - __in BOOL fVital -); - -/* **************************************************************** - AddUserCertificate - CUSTOM ACTION ENTRY POINT for adding per-user - certificates - - * ***************************************************************/ -extern "C" UINT __stdcall AddUserCertificate( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - hr = WcaInitialize(hInstall, "AddUserCertificate"); - ExitOnFailure(hr, "Failed to initialize AddUserCertificate."); - - hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_INSTALL, CERT_SYSTEM_STORE_CURRENT_USER); - ExitOnFailure(hr, "Failed to install per-user certificate."); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/* **************************************************************** - AddMachineCertificate - CUSTOM ACTION ENTRY POINT for adding - per-machine certificates - - * ***************************************************************/ -extern "C" UINT __stdcall AddMachineCertificate( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - hr = WcaInitialize(hInstall, "AddMachineCertificate"); - ExitOnFailure(hr, "Failed to initialize AddMachineCertificate."); - - hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_INSTALL, CERT_SYSTEM_STORE_LOCAL_MACHINE); - ExitOnFailure(hr, "Failed to install per-machine certificate."); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/* **************************************************************** - DeleteUserCertificate - CUSTOM ACTION ENTRY POINT for deleting - per-user certificates - - * ***************************************************************/ -extern "C" UINT __stdcall DeleteUserCertificate( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - hr = WcaInitialize(hInstall, "DeleteUserCertificate"); - ExitOnFailure(hr, "Failed to initialize DeleteUserCertificate."); - - hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_UNINSTALL, CERT_SYSTEM_STORE_CURRENT_USER); - ExitOnFailure(hr, "Failed to uninstall per-user certificate."); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/* **************************************************************** - DeleteMachineCertificate - CUSTOM ACTION ENTRY POINT for deleting - per-machine certificates - - * ***************************************************************/ -extern "C" UINT __stdcall DeleteMachineCertificate( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - hr = WcaInitialize(hInstall, "DeleteMachineCertificate"); - ExitOnFailure(hr, "Failed to initialize DeleteMachineCertificate."); - - hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_UNINSTALL, CERT_SYSTEM_STORE_LOCAL_MACHINE); - ExitOnFailure(hr, "Failed to uninstall per-machine certificate."); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -static HRESULT ExecuteCertificateOperation( - __in MSIHANDLE /*hInstall*/, - __in SCA_ACTION saAction, - __in DWORD dwStoreLocation - ) -{ - //AssertSz(FALSE, "Debug ExecuteCertificateOperation() here."); - Assert(saAction & SCA_ACTION_INSTALL || saAction & SCA_ACTION_UNINSTALL); - - HRESULT hr = S_OK; - LPWSTR pwzCaData = NULL; - LPWSTR pwz; - LPWSTR pwzName = NULL; - LPWSTR pwzStore = NULL; - int iAttributes = 0; - LPWSTR pwzPFXPassword = NULL; - LPWSTR pwzFilePath = NULL; - BYTE* pbData = NULL; - DWORD cbData = 0; - DWORD_PTR cbPFXPassword = 0; - - BOOL fUserStoreLocation = (CERT_SYSTEM_STORE_CURRENT_USER == dwStoreLocation); - HCERTSTORE hCertStore = NULL; - - hr = WcaGetProperty(L"CustomActionData", &pwzCaData); - ExitOnFailure(hr, "Failed to get CustomActionData"); - - WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCaData); - - pwz = pwzCaData; - hr = WcaReadStringFromCaData(&pwz, &pwzName); - ExitOnFailure(hr, "Failed to parse certificate name."); - hr = WcaReadStringFromCaData(&pwz, &pwzStore); - ExitOnFailure(hr, "Failed to parse CustomActionData, StoreName"); - hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); - ExitOnFailure(hr, "Failed to parse certificate attribute"); - if (SCA_ACTION_INSTALL == saAction) // install operations need more data - { - hr = WcaReadStreamFromCaData(&pwz, &pbData, (DWORD_PTR*)&cbData); - ExitOnFailure(hr, "Failed to parse certificate stream."); - - hr = WcaReadStringFromCaData(&pwz, &pwzPFXPassword); - ExitOnFailure(hr, "Failed to parse certificate password."); - } - - // Open the right store. - hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation | CERT_STORE_MAXIMUM_ALLOWED_FLAG, pwzStore); - MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store: %ls", pwzStore); - - if (SCA_ACTION_INSTALL == saAction) // install operations need more data - { - // Uninstall existing versions of this package. Ignore any failures - // This is needed to clean up the private key of a cert when we replace an existing cert - // CertAddCertificateContextToStore(CERT_STORE_ADD_REPLACE_EXISTING) does not remove the private key if the cert is replaced - UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName); - - hr = InstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName, pbData, cbData, iAttributes & SCA_CERT_ATTRIBUTE_VITAL, pwzPFXPassword); - ExitOnFailure(hr, "Failed to install certificate."); - } - else - { - Assert(SCA_ACTION_UNINSTALL == saAction); - - hr = UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName); - ExitOnFailure(hr, "Failed to uninstall certificate."); - } - -LExit: - if (NULL != pwzPFXPassword && SUCCEEDED(StrSize(pwzPFXPassword, &cbPFXPassword))) - { - SecureZeroMemory(pwzPFXPassword, cbPFXPassword); - } - - if (hCertStore) - { - if (!::CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG)) - { - WcaLog(LOGMSG_VERBOSE, "Cert store was closed but not all resources were freed. Error 0x%x", GetLastError()); - } - } - - ReleaseMem(pbData); - ReleaseStr(pwzFilePath); - ReleaseStr(pwzPFXPassword); - ReleaseStr(pwzStore); - ReleaseStr(pwzName); - ReleaseStr(pwzCaData); - return hr; -} - - -static HRESULT InstallCertificatePackage( - __in HCERTSTORE hStore, - __in BOOL fUserCertificateStore, - __in LPCWSTR wzName, - __in_opt BYTE* rgbData, - __in DWORD cbData, - __in BOOL fVital, - __in_opt LPCWSTR wzPFXPassword - ) -{ - HRESULT hr = S_OK; - - HCERTSTORE hPfxCertStore = NULL; - PCCERT_CONTEXT pCertContext = NULL; - CERT_BLOB blob = { 0 }; - DWORD dwKeyset = fUserCertificateStore ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; - DWORD dwEncodingType; - DWORD dwContentType; - DWORD dwFormatType; - LPWSTR pwzUniqueName = NULL; - int iUniqueId = 0; - - // Figure out what type of blob (certificate or PFX) we're dealing with here. - blob.pbData = rgbData; - blob.cbData = cbData; - - if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) - { - ExitWithLastError(hr, "Failed to parse the certificate blob: %ls", wzName); - } - - hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId); - ExitOnFailure(hr, "Failed to format unique name"); - - if (!pCertContext) - { - // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. - if (dwContentType & CERT_QUERY_CONTENT_PFX) - { - ExitOnNull(wzPFXPassword, hr, E_INVALIDARG, "Failed to import PFX blob because no password was provided"); - - // If we fail and our password is blank, also try passing in NULL for the password (according to the docs) - hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, dwKeyset); - if (NULL == hPfxCertStore && !*wzPFXPassword) - { - hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, NULL, dwKeyset); - } - ExitOnNullWithLastError(hPfxCertStore, hr, "Failed to open PFX file."); - - // Install all certificates in the PFX - for (pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext); - pCertContext; - pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext)) - { - hr = AddCertificate(hStore, pCertContext, pwzUniqueName, fVital); - MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store."); - - hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId); - ExitOnFailure(hr, "Failed to format unique name"); - } - } - else - { - hr = E_UNEXPECTED; - ExitOnFailure(hr, "Unexpected certificate type processed."); - } - } - else - { - hr = AddCertificate(hStore, pCertContext, pwzUniqueName, fVital); - MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store."); - } - - hr = WcaProgressMessage(COST_CERT_ADD, FALSE); - ExitOnFailure(hr, "Failed to send install progress message."); - -LExit: - ReleaseStr(pwzUniqueName); - - if (pCertContext) - { - ::CertFreeCertificateContext(pCertContext); - } - - // Close the stores after the context's are released. - if (hPfxCertStore) - { - if (!::CertCloseStore(hPfxCertStore, CERT_CLOSE_STORE_CHECK_FLAG)) - { - WcaLog(LOGMSG_VERBOSE, "PFX cert store was closed but not all resources were freed. Error 0x%x", GetLastError()); - } - } - - return hr; -} - - -static HRESULT UninstallCertificatePackage( - __in HCERTSTORE hStore, - __in BOOL fUserCertificateStore, - __in LPCWSTR wzName - ) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - PCCERT_CONTEXT pCertContext = NULL; - CRYPT_KEY_PROV_INFO* pPrivateKeyInfo = NULL; - LPWSTR pwzUniquePrefix = NULL; - int ccUniquePrefix = 0; - - hr = StrAllocFormatted(&pwzUniquePrefix, L"%s_wixCert_", wzName); - ExitOnFailure(hr, "Failed to format unique name"); - ccUniquePrefix = ::lstrlenW(pwzUniquePrefix); - - WcaLog(LOGMSG_STANDARD, "Deleting certificate that begin with friendly name: %ls", pwzUniquePrefix); - - // Loop through all certificates in the store, deleting the ones that begin with our prefix. - while (NULL != (pCertContext = ::CertFindCertificateInStore(hStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pCertContext))) - { - WCHAR wzFriendlyName[256] = { 0 }; - DWORD cbFriendlyName = sizeof(wzFriendlyName); - - if (::CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, reinterpret_cast(wzFriendlyName), &cbFriendlyName) && - lstrlenW(wzFriendlyName) >= ccUniquePrefix && - CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, pwzUniquePrefix, ccUniquePrefix, wzFriendlyName, ccUniquePrefix)) - { - PCCERT_CONTEXT pCertContextDelete = ::CertDuplicateCertificateContext(pCertContext); // duplicate the context so we can delete it with out disrupting the looping - if(pCertContextDelete) - { - // Delete the certificate and if successful delete the matching private key as well. - if (::CertDeleteCertificateFromStore(pCertContextDelete)) - { - // If we found private key info, delete it. - hr = CertReadProperty(pCertContextDelete, CERT_KEY_PROV_INFO_PROP_ID, &pPrivateKeyInfo, NULL); - if (SUCCEEDED(hr)) - { - HCRYPTPROV hProvIgnored = NULL; // ignored on deletes. - DWORD dwKeyset = fUserCertificateStore ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; - - if (!::CryptAcquireContextW(&hProvIgnored, pPrivateKeyInfo->pwszContainerName, pPrivateKeyInfo->pwszProvName, pPrivateKeyInfo->dwProvType, dwKeyset | CRYPT_DELETEKEYSET | CRYPT_SILENT)) - { - er = ::GetLastError(); - hr = HRESULT_FROM_WIN32(er); - } - - ReleaseNullMem(pPrivateKeyInfo); - } - else // don't worry about failures to delete private keys. - { - hr = S_OK; - } - } - else - { - er = ::GetLastError(); - hr = HRESULT_FROM_WIN32(er); - } - - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "Failed to delete certificate with friendly name: %ls, continuing anyway. Error: 0x%x", wzFriendlyName, hr); - } - - pCertContextDelete = NULL; - } - } - } - - hr = WcaProgressMessage(COST_CERT_DELETE, FALSE); - ExitOnFailure(hr, "Failed to send uninstall progress message."); - -LExit: - ReleaseStr(pwzUniquePrefix); - ReleaseMem(pPrivateKeyInfo); - if(pCertContext) - { - ::CertFreeCertificateContext(pCertContext); - } - - return hr; -} - -static HRESULT AddCertificate( - __in HCERTSTORE hStore, - __in PCCERT_CONTEXT pCertContext, - __in LPCWSTR wzCertificateUniqueName, - __in BOOL fVital -) -{ - HRESULT hr = S_OK; - - WcaLog(LOGMSG_STANDARD, "Adding certificate: %ls", wzCertificateUniqueName); - - hr = CertInstallSingleCertificate(hStore, pCertContext, wzCertificateUniqueName); - if (FAILED(hr) && !fVital) - { - WcaLog(LOGMSG_STANDARD, "Could not add non-vital certificate: %ls due to error: 0x%x, continuing...", wzCertificateUniqueName, hr); - hr = S_FALSE; - } - - return hr; -} diff --git a/src/ca/scacost.h b/src/ca/scacost.h deleted file mode 100644 index be92cf26..00000000 --- a/src/ca/scacost.h +++ /dev/null @@ -1,15 +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. - - -const UINT COST_IIS_TRANSACTIONS = 10000; - -const UINT COST_IIS_CREATEKEY = 5000; -const UINT COST_IIS_DELETEKEY = 5000; -const UINT COST_IIS_WRITEVALUE = 5000; -const UINT COST_IIS_DELETEVALUE = 5000; -const UINT COST_IIS_CREATEAPP = 5000; -const UINT COST_IIS_DELETEAPP = 5000; - -const UINT COST_CERT_ADD = 5000; -const UINT COST_CERT_DELETE = 5000; diff --git a/src/ca/scaexec.cpp b/src/ca/scaexec.cpp deleted file mode 100644 index df25e8db..00000000 --- a/src/ca/scaexec.cpp +++ /dev/null @@ -1,1184 +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" - - -/******************************************************************** - StartMetabaseTransaction - CUSTOM ACTION ENTRY POINT for backing up metabase - - Input: deferred CustomActionData - BackupName -********************************************************************/ -extern "C" UINT __stdcall StartMetabaseTransaction(MSIHANDLE hInstall) -{ -//AssertSz(FALSE, "debug StartMetabaseTransaction here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - IMSAdminBase* piMetabase = NULL; - LPWSTR pwzData = NULL; - BOOL fInitializedCom = FALSE; - - // initialize - hr = WcaInitialize(hInstall, "StartMetabaseTransaction"); - ExitOnFailure(hr, "failed to initialize StartMetabaseTransaction"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to initialize COM"); - fInitializedCom = TRUE; - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - if (hr == REGDB_E_CLASSNOTREG) - { - WcaLog(LOGMSG_STANDARD, "Failed to get IIMSAdminBase to backup - continuing"); - hr = S_OK; - } - else - { - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); - - hr = WcaGetProperty(L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - // back up the metabase - Assert(lstrlenW(pwzData) < MD_BACKUP_MAX_LEN); - - // MD_BACKUP_OVERWRITE = Overwrite if a backup of the same name and version exists in the backup location - hr = piMetabase->Backup(pwzData, MD_BACKUP_NEXT_VERSION, MD_BACKUP_OVERWRITE | MD_BACKUP_FORCE_BACKUP | MD_BACKUP_SAVE_FIRST); - if (MD_WARNING_SAVE_FAILED == hr) - { - WcaLog(LOGMSG_STANDARD, "Failed to save metabase before backing up - continuing"); - hr = S_OK; - } - MessageExitOnFailure(hr, msierrIISFailedStartTransaction, "failed to begin metabase transaction: '%ls'", pwzData); - } - hr = WcaProgressMessage(COST_IIS_TRANSACTIONS, FALSE); -LExit: - ReleaseStr(pwzData); - ReleaseObject(piMetabase); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - er = ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/******************************************************************** - RollbackMetabaseTransaction - CUSTOM ACTION ENTRY POINT for unbacking up metabase - - Input: deferred CustomActionData - BackupName -********************************************************************/ -extern "C" UINT __stdcall RollbackMetabaseTransaction(MSIHANDLE hInstall) -{ -//AssertSz(FALSE, "debug RollbackMetabaseTransaction here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - IMSAdminBase* piMetabase = NULL; - LPWSTR pwzData = NULL; - BOOL fInitializedCom = FALSE; - - hr = WcaInitialize(hInstall, "RollbackMetabaseTransaction"); - ExitOnFailure(hr, "failed to initialize"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to initialize COM"); - fInitializedCom = TRUE; - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - if (hr == REGDB_E_CLASSNOTREG) - { - WcaLog(LOGMSG_STANDARD, "Failed to get IIMSAdminBase to rollback - continuing"); - hr = S_OK; - ExitFunction(); - } - ExitOnFailure(hr, "failed to get IID_IIMSAdminBase object"); - - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - hr = piMetabase->Restore(pwzData, MD_BACKUP_HIGHEST_VERSION, 0); - ExitOnFailure(hr, "failed to rollback metabase transaction: '%ls'", pwzData); - - hr = piMetabase->DeleteBackup(pwzData, MD_BACKUP_HIGHEST_VERSION); - ExitOnFailure(hr, "failed to cleanup metabase transaction '%ls', continuing", pwzData); - -LExit: - ReleaseStr(pwzData); - ReleaseObject(piMetabase); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} - - -/******************************************************************** - CommitMetabaseTransaction - CUSTOM ACTION ENTRY POINT for unbacking up metabase - - Input: deferred CustomActionData - BackupName - * *****************************************************************/ -extern "C" UINT __stdcall CommitMetabaseTransaction(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - IMSAdminBase* piMetabase = NULL; - LPWSTR pwzData = NULL; - BOOL fInitializedCom = FALSE; - - hr = WcaInitialize(hInstall, "CommitMetabaseTransaction"); - ExitOnFailure(hr, "failed to initialize"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to initialize COM"); - fInitializedCom = TRUE; - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - if (hr == REGDB_E_CLASSNOTREG) - { - WcaLog(LOGMSG_STANDARD, "Failed to get IIMSAdminBase to commit - continuing"); - hr = S_OK; - ExitFunction(); - } - ExitOnFailure(hr, "failed to get IID_IIMSAdminBase object"); - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - hr = piMetabase->DeleteBackup(pwzData, MD_BACKUP_HIGHEST_VERSION); - ExitOnFailure(hr, "failed to cleanup metabase transaction: '%ls'", pwzData); - -LExit: - ReleaseStr(pwzData); - ReleaseObject(piMetabase); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} - - -/******************************************************************** - CreateMetabaseKey - Installs metabase keys - - Input: deferred CustomActionData - Key - * *****************************************************************/ -static HRESULT CreateMetabaseKey(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase) -{ -//AssertSz(FALSE, "debug CreateMetabaseKey here"); - HRESULT hr = S_OK; - METADATA_HANDLE mhRoot = 0; - LPWSTR pwzData = NULL; - LPCWSTR pwzKey; - - int i; - - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "failed to read key from custom action data"); - - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); - for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) - { - ::Sleep(1000); - WcaLog(LOGMSG_STANDARD, "failed to open root key, retrying %d time(s)...", i); - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); - } - MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", L"/LM"); - - pwzKey = pwzData + 3; - - WcaLog(LOGMSG_VERBOSE, "Creating Metabase Key: %ls", pwzKey); - - hr = piMetabase->AddKey(mhRoot, pwzKey); - if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr) - { - WcaLog(LOGMSG_VERBOSE, "Key `%ls` already existed, continuing.", pwzData); - hr = S_OK; - } - MessageExitOnFailure(hr, msierrIISFailedCreateKey, "failed to create metabase key: %ls", pwzKey); - - hr = WcaProgressMessage(COST_IIS_CREATEKEY, FALSE); - -LExit: - if (mhRoot) - { - piMetabase->CloseKey(mhRoot); - } - - return hr; -} - - -/******************************************************************** - WriteMetabaseValue -Installs metabase values - - Input: deferred CustomActionData - Key\tIdentifier\tAttributes\tUserType\tDataType\tData - * *****************************************************************/ -static HRESULT WriteMetabaseValue(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase) -{ - //AssertSz(FALSE, "debug WriteMetabaseValue here"); - HRESULT hr = S_OK; - - METADATA_HANDLE mhKey = 0; - - LPWSTR pwzKey = NULL; - LPWSTR pwzTemp = NULL; - DWORD dwData = 0; - DWORD dwTemp = 0; - BOOL fFreeData = FALSE; - METADATA_RECORD mr; - ::ZeroMemory((LPVOID)&mr, sizeof(mr)); - METADATA_RECORD mrGet; - ::ZeroMemory((LPVOID)&mrGet, sizeof(mrGet)); - - int i; - - // get the key first - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzKey); - ExitOnFailure(hr, "failed to read key"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDIdentifier)); - ExitOnFailure(hr, "failed to read identifier"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDAttributes)); - ExitOnFailure(hr, "failed to read attributes"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDUserType)); - ExitOnFailure(hr, "failed to read user type"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDDataType)); - ExitOnFailure(hr, "failed to read data type"); - - switch (mr.dwMDDataType) // data - { - case DWORD_METADATA: - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&dwData)); - mr.dwMDDataLen = sizeof(dwData); - mr.pbMDData = reinterpret_cast(&dwData); - break; - case STRING_METADATA: - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzTemp); - mr.dwMDDataLen = (lstrlenW(pwzTemp) + 1) * sizeof(WCHAR); - mr.pbMDData = reinterpret_cast(pwzTemp); - break; - case MULTISZ_METADATA: - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzTemp); - mr.dwMDDataLen = (lstrlenW(pwzTemp) + 1) * sizeof(WCHAR); - for (LPWSTR pwzT = pwzTemp; *pwzT; ++pwzT) - { - if (MAGIC_MULTISZ_CHAR == *pwzT) - { - *pwzT = L'\0'; - } - } - mr.pbMDData = reinterpret_cast(pwzTemp); - } - break; - case BINARY_METADATA: - hr = WcaReadStreamFromCaData(ppwzCustomActionData, &mr.pbMDData, reinterpret_cast(&mr.dwMDDataLen)); - fFreeData = TRUE; - break; - default: - hr = E_UNEXPECTED; - break; - } - ExitOnFailure(hr, "failed to parse CustomActionData into metabase record"); - - WcaLog(LOGMSG_VERBOSE, "Writing Metabase Value Under Key: %ls ID: %d", pwzKey, mr.dwMDIdentifier); - - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); - for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) - { - ::Sleep(1000); - WcaLog(LOGMSG_STANDARD, "failed to open '%ls' key, retrying %d time(s)...", pwzKey, i); - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); - } - MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", pwzKey); - - if (lstrlenW(pwzKey) < 3) - { - ExitOnFailure(hr = E_INVALIDARG, "Key didn't begin with \"/LM\" as expected - key value: %ls", pwzKey); - } - - hr = piMetabase->SetData(mhKey, pwzKey + 3, &mr); // pwzKey + 3 to skip "/LM" that was used to open the key. - - // This means we're trying to write to a secure key without the secure flag set - let's try again with the secure flag set - if (MD_ERROR_CANNOT_REMOVE_SECURE_ATTRIBUTE == hr) - { - mr.dwMDAttributes |= METADATA_SECURE; - hr = piMetabase->SetData(mhKey, pwzKey + 3, &mr); - } - - // If IIS6 returned failure, let's check if the correct value exists in the metabase before actually failing the CA - if (FAILED(hr)) - { - // Backup the original failure error, so we can log it below if necessary - HRESULT hrOldValue = hr; - - mrGet.dwMDIdentifier = mr.dwMDIdentifier; - mrGet.dwMDAttributes = METADATA_NO_ATTRIBUTES; - mrGet.dwMDUserType = mr.dwMDUserType; - mrGet.dwMDDataType = mr.dwMDDataType; - mrGet.dwMDDataLen = mr.dwMDDataLen; - mrGet.pbMDData = static_cast(MemAlloc(mr.dwMDDataLen, TRUE)); - - hr = piMetabase->GetData(mhKey, pwzKey + 3, &mrGet, &dwTemp); - if (SUCCEEDED(hr)) - { - if (mrGet.dwMDDataType == mr.dwMDDataType && mrGet.dwMDDataLen == mr.dwMDDataLen && 0 == memcmp(mrGet.pbMDData, mr.pbMDData, mr.dwMDDataLen)) - { - WcaLog(LOGMSG_VERBOSE, "Received error while writing metabase value under key: %ls ID: %d with error 0x%x, but the correct value is in the metabase - continuing", pwzKey, mr.dwMDIdentifier, hrOldValue); - hr = S_OK; - } - else - { - WcaLog(LOGMSG_VERBOSE, "Succeeded in checking metabase value after write value, but the values didn't match"); - hr = hrOldValue; - } - } - else - { - WcaLog(LOGMSG_VERBOSE, "Failed to check value after metabase write failure (error code 0x%x)", hr); - hr = hrOldValue; - } - } - MessageExitOnFailure(hr, msierrIISFailedWriteData, "failed to write data to metabase key: %ls", pwzKey); - - hr = WcaProgressMessage(COST_IIS_WRITEVALUE, FALSE); - -LExit: - ReleaseStr(pwzTemp); - ReleaseStr(pwzKey); - - if (mhKey) - { - piMetabase->CloseKey(mhKey); - } - - if (fFreeData && mr.pbMDData) - { - MemFree(mr.pbMDData); - } - - return hr; -} - - -/******************************************************************** - DeleteMetabaseValue -Installs metabase values - - Input: deferred CustomActionData - Key\tIdentifier\tAttributes\tUserType\tDataType\tData - * *****************************************************************/ -static HRESULT DeleteMetabaseValue(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase) -{ - //AssertSz(FALSE, "debug DeleteMetabaseValue here"); - HRESULT hr = S_OK; - - METADATA_HANDLE mhKey = 0; - - LPWSTR pwzKey = NULL; - DWORD dwIdentifier = 0; - DWORD dwDataType = 0; - - int i; - - // get the key first - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzKey); - ExitOnFailure(hr, "failed to read key"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&dwIdentifier)); - ExitOnFailure(hr, "failed to read identifier"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&dwDataType)); - ExitOnFailure(hr, "failed to read data type"); - - WcaLog(LOGMSG_VERBOSE, "Deleting Metabase Value Under Key: %ls ID: %d", pwzKey, dwIdentifier); - - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); - for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) - { - ::Sleep(1000); - WcaLog(LOGMSG_STANDARD, "failed to open '%ls' key, retrying %d time(s)...", pwzKey, i); - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); - } - MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", pwzKey); - - if (lstrlenW(pwzKey) < 3) - { - ExitOnFailure(hr = E_INVALIDARG, "Key didn't begin with \"/LM\" as expected - key value: %ls", pwzKey); - } - - hr = piMetabase->DeleteData(mhKey, pwzKey + 3, dwIdentifier, dwDataType); // pwzKey + 3 to skip "/LM" that was used to open the key. - if (MD_ERROR_DATA_NOT_FOUND == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) - { - hr = S_OK; - } - MessageExitOnFailure(hr, msierrIISFailedDeleteValue, "failed to delete value %d from metabase key: %ls", dwIdentifier, pwzKey); - - hr = WcaProgressMessage(COST_IIS_DELETEVALUE, FALSE); -LExit: - ReleaseStr(pwzKey); - - if (mhKey) - piMetabase->CloseKey(mhKey); - - return hr; -} - - -/******************************************************************** - DeleteAspApp - Deletes applications in IIS - - Input: deferred CustomActionData - MetabaseRoot\tRecursive - * *****************************************************************/ -static HRESULT DeleteAspApp(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase, __in ICatalogCollection* pApplicationCollection, __in IWamAdmin* piWam) -{ - const int BUFFER_BYTES = 512; - const BSTR bstrPropName = SysAllocString(L"Deleteable"); - - HRESULT hr = S_OK; - ICatalogObject* pApplication = NULL; - - LPWSTR pwzRoot = NULL; - DWORD dwActualBufferSize = 0; - long lSize = 0; - long lIndex = 0; - long lChanges = 0; - - VARIANT keyValue; - ::VariantInit(&keyValue); - VARIANT propValue; - propValue.vt = VT_BOOL; - propValue.boolVal = TRUE; - - METADATA_RECORD mr; - // Get current set of web service extensions. - ::ZeroMemory(&mr, sizeof(mr)); - mr.dwMDIdentifier = MD_APP_PACKAGE_ID; - mr.dwMDAttributes = 0; - mr.dwMDUserType = ASP_MD_UT_APP; - mr.dwMDDataType = STRING_METADATA; - mr.pbMDData = new unsigned char[BUFFER_BYTES]; - mr.dwMDDataLen = BUFFER_BYTES; - - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzRoot); // MetabaseRoot - ExitOnFailure(hr, "failed to get metabase root"); - - hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, pwzRoot, &mr, &dwActualBufferSize); - if (HRESULT_FROM_WIN32(MD_ERROR_DATA_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - // This one doesn't have an independent app GUID associated with it - it may have been already partially deleted, or a low isolation app - WcaLog(LOGMSG_VERBOSE, "No independent COM+ application found associated with %ls. It either doesn't exist, or was already removed - continuing", pwzRoot); - ExitFunction1(hr = S_OK); - } - MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get GUID for application at path: %ls", pwzRoot); - - WcaLog(LOGMSG_VERBOSE, "Deleting ASP App (used query: %ls) with GUID: %ls", pwzRoot, (LPWSTR)(mr.pbMDData)); - - // Delete the application association from IIS's point of view before it's obliterated from the application collection - hr = piWam->AppDelete(pwzRoot, FALSE); - if (FAILED(hr)) - { - // This isn't necessarily an error if we fail here, but let's log a failure if it happens - WcaLog(LOGMSG_VERBOSE, "error 0x%x: failed to call IWamAdmin::AppDelete() while removing web application - continuing"); - hr = S_OK; - } - - if (!pApplicationCollection) - { - WcaLog(LOGMSG_STANDARD, "Could not remove application with GUID %ls because the application collection could not be found", (LPWSTR)(mr.pbMDData)); - ExitFunction1(hr = S_OK); - } - - hr = pApplicationCollection->Populate(); - MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to populate Application collection"); - - hr = pApplicationCollection->get_Count(&lSize); - MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get size of Application collection"); - WcaLog(LOGMSG_TRACEONLY, "Found %u items in application collection", lSize); - - // No need to check this too early, as we may not even need this to have successfully allocated - ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "failed to allocate memory for \"Deleteable\" string"); - - for (lIndex = 0; lIndex < lSize; ++lIndex) - { - hr = pApplicationCollection->get_Item(lIndex, reinterpret_cast(&pApplication)); - MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get COM+ application while enumerating through COM+ applications"); - - hr = pApplication->get_Key(&keyValue); - MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get key of COM+ application while enumerating through COM+ applications"); - - WcaLog(LOGMSG_TRACEONLY, "While enumerating through COM+ applications, found an application with GUID: %ls", (LPWSTR)keyValue.bstrVal); - - if (VT_BSTR == keyValue.vt && 0 == lstrcmpW((LPWSTR)keyValue.bstrVal, (LPWSTR)(mr.pbMDData))) - { - hr = pApplication->put_Value(bstrPropName, propValue); - if (FAILED(hr)) - { - // This isn't necessarily a critical error unless we fail to actually delete it in the next step - WcaLog(LOGMSG_VERBOSE, "error 0x%x: failed to ensure COM+ application with guid %ls is deletable - continuing", hr, (LPWSTR)(mr.pbMDData)); - } - - hr = pApplicationCollection->SaveChanges(&lChanges); - if (FAILED(hr)) - { - // This isn't necessarily a critical error unless we fail to actually delete it in the next step - WcaLog(LOGMSG_VERBOSE, "error 0x%x: failed to save changes while ensuring COM+ application with guid %ls is deletable - continuing", hr, (LPWSTR)(mr.pbMDData)); - } - - hr = pApplicationCollection->Remove(lIndex); - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "error 0x%x: failed to remove COM+ application with guid %ls. The COM application will not be removed", hr, (LPWSTR)(mr.pbMDData)); - } - else - { - hr = pApplicationCollection->SaveChanges(&lChanges); - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "error 0x%x: failed to save changes when removing COM+ application with guid %ls. The COM application will not be removed - continuing", hr, (LPWSTR)(mr.pbMDData)); - } - else - { - WcaLog(LOGMSG_VERBOSE, "Found and removed application with GUID %ls", (LPWSTR)(mr.pbMDData)); - } - } - - // We've found the right key and successfully deleted the app - let's exit the loop now - lIndex = lSize; - } - } - // If we didn't find it, it isn't an error, because the application we want to delete doesn't seem to exist! - - hr = WcaProgressMessage(COST_IIS_DELETEAPP, FALSE); -LExit: - ReleaseBSTR(bstrPropName); - - ReleaseStr(pwzRoot); - // Don't release pApplication, because it points to an object within the collection - - delete [] mr.pbMDData; - - return hr; -} - - -/******************************************************************** - CreateAspApp - Creates applications in IIS - - Input: deferred CustomActionData - MetabaseRoot\tInProc - * ****************************************************************/ -static HRESULT CreateAspApp(__in LPWSTR* ppwzCustomActionData, __in IWamAdmin* piWam) -{ - HRESULT hr = S_OK; - - LPWSTR pwzRoot = NULL; - BOOL fInProc; - - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzRoot); // MetabaseRoot - ExitOnFailure(hr, "failed to get metabase root"); - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&fInProc)); // InProc - ExitOnFailure(hr, "failed to get in proc flag"); - - WcaLog(LOGMSG_VERBOSE, "Creating ASP App: %ls", pwzRoot); - - hr = piWam->AppCreate(pwzRoot, fInProc); - MessageExitOnFailure(hr, msierrIISFailedCreateApp, "failed to create web application: %ls", pwzRoot); - - hr = WcaProgressMessage(COST_IIS_CREATEAPP, FALSE); -LExit: - return hr; -} - - -/******************************************************************** - DeleteMetabaseKey - Deletes metabase keys - - Input: deferred CustomActionData - Key - ******************************************************************/ -static HRESULT DeleteMetabaseKey(__in LPWSTR *ppwzCustomActionData, __in IMSAdminBase* piMetabase) -{ - HRESULT hr = S_OK; - - METADATA_HANDLE mhRoot = 0; - - LPWSTR pwzData = NULL; - - LPCWSTR pwzKey; - int i; - - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "failed to read key to be deleted"); - - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); - for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) - { - ::Sleep(1000); - WcaLog(LOGMSG_STANDARD, "failed to open root key, retrying %d time(s)...", i); - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); - } - MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", L"/LM"); - - pwzKey = pwzData + 3; - - WcaLog(LOGMSG_VERBOSE, "Deleting Metabase Key: %ls", pwzKey); - - hr = piMetabase->DeleteKey(mhRoot, pwzKey); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) - { - WcaLog(LOGMSG_STANDARD, "Key `%ls` did not exist, continuing.", pwzData); - hr = S_OK; - } - MessageExitOnFailure(hr, msierrIISFailedDeleteKey, "failed to delete metabase key: %ls", pwzData); - - hr = WcaProgressMessage(COST_IIS_DELETEKEY, FALSE); -LExit: - if (mhRoot) - { - piMetabase->CloseKey(mhRoot); - } - - return hr; -} - - -/******************************************************************** - WriteMetabaseChanges - CUSTOM ACTION ENTRY POINT for IIS Metabase changes - - *******************************************************************/ -extern "C" UINT __stdcall WriteMetabaseChanges(MSIHANDLE hInstall) -{ -//AssertSz(FALSE, "debug WriteMetabaseChanges here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - IMSAdminBase* piMetabase = NULL; - IWamAdmin* piWam = NULL; - ICOMAdminCatalog* pCatalog = NULL; - ICatalogCollection* pApplicationCollection = NULL; - WCA_CASCRIPT_HANDLE hWriteMetabaseScript = NULL; - BSTR bstrApplications = SysAllocString(L"Applications"); - BOOL fInitializedCom = FALSE; - - LPWSTR pwzData = NULL; - LPWSTR pwz = NULL; - LPWSTR pwzScriptKey = NULL; - METABASE_ACTION maAction = MBA_UNKNOWNACTION; - - hr = WcaInitialize(hInstall, "WriteMetabaseChanges"); - ExitOnFailure(hr, "failed to initialize"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to initialize COM"); - fInitializedCom = TRUE; - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); - - // Get the CaScript key - hr = WcaReadStringFromCaData(&pwzData, &pwzScriptKey); - ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); - - hr = WcaCaScriptOpen(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzScriptKey, &hWriteMetabaseScript); - ExitOnFailure(hr, "Failed to open CaScript file"); - - // The rest of our existing custom action data string should be empty - go ahead and overwrite it - ReleaseNullStr(pwzData); - hr = WcaCaScriptReadAsCustomActionData(hWriteMetabaseScript, &pwzData); - ExitOnFailure(hr, "Failed to read script into CustomAction data."); - - pwz = pwzData; - - while (S_OK == (hr = WcaReadIntegerFromCaData(&pwz, (int *)&maAction))) - { - switch (maAction) - { - case MBA_CREATEAPP: - if (NULL == piWam) - { - hr = ::CoCreateInstance(CLSID_WamAdmin, NULL, CLSCTX_ALL, IID_IWamAdmin, reinterpret_cast(&piWam)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IWamAdmin object"); - } - - hr = CreateAspApp(&pwz, piWam); - ExitOnFailure(hr, "failed to create ASP App"); - break; - case MBA_DELETEAPP: - if (NULL == piMetabase) - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); - } - - if (NULL == pCatalog) - { - hr = CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pCatalog); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_ICOMAdmin object"); - - hr = pCatalog->GetCollection(bstrApplications, reinterpret_cast(&pApplicationCollection)); - if (FAILED(hr)) - { - hr = S_OK; - WcaLog(LOGMSG_STANDARD, "error 0x%x: failed to get ApplicationCollection object for list of COM+ applications - COM+ applications will not be able to be uninstalled - continuing", hr); - } - } - - if (NULL == piWam) - { - hr = ::CoCreateInstance(CLSID_WamAdmin, NULL, CLSCTX_ALL, IID_IWamAdmin, reinterpret_cast(&piWam)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IWamAdmin object"); - } - - hr = DeleteAspApp(&pwz, piMetabase, pApplicationCollection, piWam); - ExitOnFailure(hr, "failed to delete ASP App"); - break; - case MBA_CREATEKEY: - if (NULL == piMetabase) - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); - } - - hr = CreateMetabaseKey(&pwz, piMetabase); - ExitOnFailure(hr, "failed to create metabase key"); - break; - case MBA_DELETEKEY: - if (NULL == piMetabase) - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); - } - - hr = DeleteMetabaseKey(&pwz, piMetabase); - ExitOnFailure(hr, "failed to delete metabase key"); - break; - case MBA_WRITEVALUE: - if (NULL == piMetabase) - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); - } - - hr = WriteMetabaseValue(&pwz, piMetabase); - ExitOnFailure(hr, "failed to write metabase value"); - break; - case MBA_DELETEVALUE: - if (NULL == piMetabase) - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); - MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); - } - - hr = DeleteMetabaseValue(&pwz, piMetabase); - ExitOnFailure(hr, "failed to delete metabase value"); - break; - default: - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected metabase action specified: %d", maAction); - break; - } - } - if (E_NOMOREITEMS == hr) // If there are no more items, all is well - { - if (NULL != piMetabase) - { - hr = piMetabase->SaveData(); - for (int i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) - { - ::Sleep(1000); - WcaLog(LOGMSG_VERBOSE, "Failed to force save of metabase data, retrying %d time(s)...", i); - hr = piMetabase->SaveData(); - } - if (FAILED(hr)) - { - WcaLog(LOGMSG_VERBOSE, "Failed to force save of metabase data: 0x%x - continuing", hr); - } - hr = S_OK; - } - else - { - hr = S_OK; - } - } - -LExit: - WcaCaScriptClose(hWriteMetabaseScript, WCA_CASCRIPT_CLOSE_DELETE); - - ReleaseBSTR(bstrApplications); - ReleaseStr(pwzScriptKey); - ReleaseStr(pwzData); - ReleaseObject(piMetabase); - ReleaseObject(piWam); - ReleaseObject(pCatalog); - ReleaseObject(pApplicationCollection); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} -/******************************************************************** - WriteIIS7ConfigChanges - CUSTOM ACTION ENTRY POINT for IIS7 config changes - - *******************************************************************/ -extern "C" UINT __stdcall WriteIIS7ConfigChanges(MSIHANDLE hInstall) -{ - //AssertSz(FALSE, "debug WriteIIS7ConfigChanges here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR pwzData = NULL; - LPWSTR pwzScriptKey = NULL; - LPWSTR pwzHashString = NULL; - BYTE rgbActualHash[SHA1_HASH_LEN] = { }; - DWORD dwHashedBytes = SHA1_HASH_LEN; - - WCA_CASCRIPT_HANDLE hWriteIis7Script = NULL; - - hr = WcaInitialize(hInstall, "WriteIIS7ConfigChanges"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = WcaGetProperty( L"CustomActionData", &pwzScriptKey); - ExitOnFailure(hr, "Failed to get CustomActionData"); - WcaLog(LOGMSG_TRACEONLY, "Script WriteIIS7ConfigChanges: %ls", pwzScriptKey); - - hr = WcaCaScriptOpen(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzScriptKey, &hWriteIis7Script); - ExitOnFailure(hr, "Failed to open CaScript file"); - - hr = WcaCaScriptReadAsCustomActionData(hWriteIis7Script, &pwzData); - ExitOnFailure(hr, "Failed to read script into CustomAction data."); - - hr = CrypHashBuffer((BYTE*)pwzData, sizeof(pwzData) * sizeof(WCHAR), PROV_RSA_AES, CALG_SHA1, rgbActualHash, dwHashedBytes); - ExitOnFailure(hr, "Failed to calculate hash of CustomAction data."); - - hr = StrAlloc(&pwzHashString, ((dwHashedBytes * 2) + 1)); - ExitOnFailure(hr, "Failed to allocate string for script hash"); - - hr = StrHexEncode(rgbActualHash, dwHashedBytes, pwzHashString, ((dwHashedBytes * 2) + 1)); - ExitOnFailure(hr, "Failed to convert hash bytes to string."); - - WcaLog(LOGMSG_TRACEONLY, "CustomActionData WriteIIS7ConfigChanges: %ls", pwzData); - WcaLog(LOGMSG_VERBOSE, "Custom action data hash: %ls", pwzHashString); - WcaLog(LOGMSG_VERBOSE, "CustomActionData WriteIIS7ConfigChanges length: %d", wcslen(pwzData)); - - hr = IIS7ConfigChanges(hInstall, pwzData); - ExitOnFailure(hr, "WriteIIS7ConfigChanges Failed."); - -LExit: - WcaCaScriptClose(hWriteIis7Script, WCA_CASCRIPT_CLOSE_DELETE); - ReleaseStr(pwzScriptKey); - ReleaseStr(pwzData); - ReleaseStr(pwzHashString); - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - - return WcaFinalize(er); -} - - -/******************************************************************** - CommitIIS7ConfigTransaction - CUSTOM ACTION ENTRY POINT for unbacking up config - - Input: deferred CustomActionData - BackupName - * *****************************************************************/ -extern "C" UINT __stdcall CommitIIS7ConfigTransaction(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR pwzData = NULL; - WCHAR wzConfigCopy[MAX_PATH]; - DWORD dwSize = 0; - - BOOL fIsWow64Process = FALSE; - BOOL fIsFSRedirectDisabled = FALSE; - - hr = WcaInitialize(hInstall, "CommitIIS7ConfigTransaction"); - ExitOnFailure(hr, "failed to initialize IIS7 commit transaction"); - - WcaInitializeWow64(); - fIsWow64Process = WcaIsWow64Process(); - if (fIsWow64Process) - { - hr = WcaDisableWow64FSRedirection(); - if(FAILED(hr)) - { - //eat this error - hr = S_OK; - } - else - { - fIsFSRedirectDisabled = TRUE; - } - } - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - // Config AdminMgr changes already committed, just - // delete backup config file. - - dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", - wzConfigCopy, - MAX_PATH - ); - if ( dwSize == 0 ) - { - ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); - } - - hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, L"."); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of ."); - - hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, pwzData); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of extension"); - - if (!::DeleteFileW(wzConfigCopy)) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - WcaLog(LOGMSG_STANDARD, "Failed to delete backup applicationHost, not found - continuing"); - hr = S_OK; - } - else - { - ExitOnFailure(hr, "failed to delete config backup"); - } - } - -LExit: - ReleaseStr(pwzData); - - // Make sure we revert FS Redirection if necessary before exiting - if (fIsFSRedirectDisabled) - { - fIsFSRedirectDisabled = FALSE; - WcaRevertWow64FSRedirection(); - } - WcaFinalizeWow64(); - - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} -/******************************************************************** - StartIIS7Config Transaction - CUSTOM ACTION ENTRY POINT for backing up config - - Input: deferred CustomActionData - BackupName -********************************************************************/ -extern "C" UINT __stdcall StartIIS7ConfigTransaction(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR pwzData = NULL; - WCHAR wzConfigSource[MAX_PATH]; - WCHAR wzConfigCopy[MAX_PATH]; - DWORD dwSize = 0; - - - BOOL fIsWow64Process = FALSE; - BOOL fIsFSRedirectDisabled = FALSE; - - // initialize - hr = WcaInitialize(hInstall, "StartIIS7ConfigTransaction"); - ExitOnFailure(hr, "failed to initialize StartIIS7ConfigTransaction"); - - WcaInitializeWow64(); - fIsWow64Process = WcaIsWow64Process(); - if (fIsWow64Process) - { - hr = WcaDisableWow64FSRedirection(); - if(FAILED(hr)) - { - //eat this error - hr = S_OK; - } - else - { - fIsFSRedirectDisabled = TRUE; - } - } - - hr = WcaGetProperty(L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - - dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", - wzConfigSource, - MAX_PATH - ); - if ( dwSize == 0 ) - { - ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); - } - hr = ::StringCchCopyW(wzConfigCopy, MAX_PATH, wzConfigSource); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCopyW"); - - //add ca action as extension - - hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, L"."); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of ."); - - hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, pwzData); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of extension"); - - if ( !::CopyFileW(wzConfigSource, wzConfigCopy, FALSE) ) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - // IIS may not be installed on the machine, we'll fail later if we try to install anything - WcaLog(LOGMSG_STANDARD, "Failed to back up applicationHost, not found - continuing"); - hr = S_OK; - } - else - { - ExitOnFailure(hr, "Failed to copy config backup %ls -> %ls", wzConfigSource, wzConfigCopy); - } - } - - - hr = WcaProgressMessage(COST_IIS_TRANSACTIONS, FALSE); - - -LExit: - - ReleaseStr(pwzData); - - // Make sure we revert FS Redirection if necessary before exiting - if (fIsFSRedirectDisabled) - { - fIsFSRedirectDisabled = FALSE; - WcaRevertWow64FSRedirection(); - } - WcaFinalizeWow64(); - - if (FAILED(hr)) - er = ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/******************************************************************** - RollbackIIS7ConfigTransaction - CUSTOM ACTION ENTRY POINT for unbacking up config - - Input: deferred CustomActionData - BackupName -********************************************************************/ -extern "C" UINT __stdcall RollbackIIS7ConfigTransaction(MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR pwzData = NULL; - WCHAR wzConfigSource[MAX_PATH]; - WCHAR wzConfigCopy[MAX_PATH]; - DWORD dwSize = 0; - - BOOL fIsWow64Process = FALSE; - BOOL fIsFSRedirectDisabled = FALSE; - - hr = WcaInitialize(hInstall, "RollbackIIS7ConfigTransaction"); - ExitOnFailure(hr, "failed to initialize"); - - WcaInitializeWow64(); - fIsWow64Process = WcaIsWow64Process(); - if (fIsWow64Process) - { - hr = WcaDisableWow64FSRedirection(); - if(FAILED(hr)) - { - //eat this error - hr = S_OK; - } - else - { - fIsFSRedirectDisabled = TRUE; - } - } - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", - wzConfigSource, - MAX_PATH - ); - if ( dwSize == 0 ) - { - ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); - } - hr = ::StringCchCopyW(wzConfigCopy, MAX_PATH, wzConfigSource); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCopyW"); - - //add ca action as extension - - hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, L"."); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of ."); - - hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, pwzData); - ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of extension"); - - //copy is reverse of start transaction - if (!::CopyFileW(wzConfigCopy, wzConfigSource, FALSE)) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || - HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - WcaLog(LOGMSG_STANDARD, "Failed to restore applicationHost, not found - continuing"); - hr = S_OK; - } - else - { - ExitOnFailure(hr, "failed to restore config backup"); - } - } - - if (!::DeleteFileW(wzConfigCopy)) - { - ExitWithLastError(hr, "failed to delete config backup"); - } - - hr = WcaProgressMessage(COST_IIS_TRANSACTIONS, FALSE); - -LExit: - ReleaseStr(pwzData); - - // Make sure we revert FS Redirection if necessary before exiting - if (fIsFSRedirectDisabled) - { - fIsFSRedirectDisabled = FALSE; - WcaRevertWow64FSRedirection(); - } - WcaFinalizeWow64(); - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} diff --git a/src/ca/scaexecIIS7.cpp b/src/ca/scaexecIIS7.cpp deleted file mode 100644 index 108007a1..00000000 --- a/src/ca/scaexecIIS7.cpp +++ /dev/null @@ -1,4205 +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 "precomp.h" - -//local CAData action functions -HRESULT IIS7Site( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); - -HRESULT IIS7Application( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7VDir( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7Binding( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7AppPool( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7AppExtension( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7MimeMap( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7DirProperties( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7WebLog( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7FilterGlobal( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7FilterSite( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7HttpHeader( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7WebError( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7WebSvcExt( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7WebProperty( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7WebDir( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7AspProperty( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -HRESULT IIS7SslBinding( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ); -//local helper functions - -static HRESULT GetNextAvailableSiteId( - IAppHostWritableAdminManager *pAdminMgr, - DWORD *plSiteId - ); -static HRESULT GetSiteElement( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swSiteName, - IAppHostElement **pSiteElement, - BOOL* fFound - ); -static HRESULT GetApplicationElement( - IAppHostElement *pSiteElement, - LPCWSTR swAppPath, - IAppHostElement **pAppElement, - BOOL* fFound - ); -static HRESULT GetApplicationElementForVDir( - IAppHostElement *pSiteElement, - LPCWSTR swVDirPath, - IAppHostElement **ppAppElement, - LPCWSTR *ppwzVDirSubPath, - BOOL* fFound - ); - -static HRESULT CreateApplication( - IAppHostElement *pSiteElement, - LPCWSTR swAppPath, - IAppHostElement **pAppElement - ); -static HRESULT DeleteApplication( - IAppHostElement *pSiteElement, - LPCWSTR swAppPath - ); - -static HRESULT SetAppPool( - IAppHostElement *pAppElementpAppElement, - LPCWSTR pwzAppPool - ); -static HRESULT CreateVdir( - IAppHostElement *pAppElement, - LPCWSTR pwzVDirPath, - LPCWSTR pwzVDirPhyDir - ); -static HRESULT DeleteVdir( - IAppHostElement *pAppElement, - LPCWSTR pwzVDirPath - ); - -static HRESULT CreateBinding( - IAppHostElement *pSiteElem, - LPCWSTR pwzProtocol, - LPCWSTR pwzInfo - ); -static HRESULT DeleteBinding( - IAppHostElement *pSiteElem, - LPCWSTR pwzProtocol, - LPCWSTR pwzInfo - ); - -static HRESULT CreateSslBinding( - IAppHostElement *pSiteElem, - LPCWSTR pwzStoreName, - LPCWSTR pwzEncodedCertificateHash - ); -static HRESULT DeleteSslBinding( - IAppHostElement *pSiteElem, - LPCWSTR pwzStoreName, - LPCWSTR pwzEncodedCertificateHash - ); - -static HRESULT CreateSite( - IAppHostElementCollection *pAdminMgr, - LPCWSTR swSiteName, - IAppHostElement **pSiteElement - ); - -static HRESULT DeleteAppPool( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swAppPoolName - ); -static HRESULT CreateAppPool( - __inout LPWSTR *ppwzCustomActionData, - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swAppPoolName - ); - -static HRESULT SetDirPropAuthentications( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR wcConfigPath, - DWORD dwData - ); -static HRESULT SetDirPropAuthProvider( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR wszConfigPath, - __in LPWSTR wszData - ); -static HRESULT SetDirPropDefDoc( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR wszConfigPath, - __in LPWSTR wszData - ); - -static HRESULT ClearLocationTag( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swLocationPath - ); - -static HRESULT CreateWebLog( - IAppHostElement *pSiteElem, - LPCWSTR pwzFormat - ); - -static HRESULT CreateGlobalFilter( - __inout LPWSTR *ppwzCustomActionData, - IAppHostElement *pSection - ); -static HRESULT DeleteGlobalFilter( - __inout LPWSTR *ppwzCustomActionData, - IAppHostElement *pSection - ); - -static HRESULT CreateSiteFilter( - __inout LPWSTR *ppwzCustomActionData, - IAppHostWritableAdminManager *pAdminMgr - ); -static HRESULT DeleteSiteFilter( - __inout LPWSTR *ppwzCustomActionData, - IAppHostWritableAdminManager *pAdminMgr - ); - -static HRESULT DeleteCollectionElement( - __in IAppHostElementCollection *pCollection, - __in LPCWSTR pwzElementName, - __in LPCWSTR pwzAttributeName, - __in LPCWSTR pwzAttributeValue - ); - -struct SCA_WEB_ERROR_SERVER -{ - int iErrorCode; - int iSubCode; - WCHAR wzFile[MAX_PATH]; - WCHAR wzLangPath[MAX_PATH]; - int iResponseMode; - SCA_WEB_ERROR_SERVER *psweNext; -}; -static HRESULT AddWebErrorToList( - SCA_WEB_ERROR_SERVER** ppsweList - ); -static void ScaWebErrorFreeList7( - SCA_WEB_ERROR_SERVER *psweList - ); -static HRESULT PopulateHttpErrors( - IAppHostElement *pSection, - SCA_WEB_ERROR_SERVER **psweList - ); -static HRESULT GetErrorFromList( - const SCA_WEB_ERROR_SERVER & we, - SCA_WEB_ERROR_SERVER **ppsweList, - SCA_WEB_ERROR_SERVER **pswe, - BOOL *fFound - ); - -static void ConvSecToHMS( - int Sec, - __out_ecount(cchDest) LPWSTR wcTime, - size_t cchDest - ); -static void ConvSecToDHMS( - unsigned int Sec, - __out_ecount(cchDest) LPWSTR wcTime, - size_t cchDest - ); - -//////////////////////////////////////////////////////////////////// -// ScopeBSTR: Local helper class to construct & free BSTR from LPWSTR -// -///////////////////////////////////////////////////////////////////// -class ScopeBSTR -{ -public: - BSTR m_str; - - ScopeBSTR() - { - m_str = NULL; - } - - ScopeBSTR( __in LPCWSTR pSrc) - { - if (pSrc == NULL) - { - m_str = NULL; - } - else - { - m_str = ::SysAllocString(pSrc); - - } - } - - ~ScopeBSTR() - { - ::SysFreeString(m_str); - } - - operator BSTR() - { - return m_str; - } -}; - - -/******************************************************************** - IIS7ConfigChanges - Start of IIS7 config changes - - *******************************************************************/ -HRESULT IIS7ConfigChanges(MSIHANDLE /*hInstall*/, __inout LPWSTR pwzData) -{ - HRESULT hr = S_OK; - BOOL fInitializedCom = FALSE; - - IAppHostWritableAdminManager *pAdminMgr = NULL; - - LPWSTR pwz = NULL; - LPWSTR pwzLast = NULL; - LPWSTR pwzBackup = NULL; - DWORD cchData = lstrlenW(pwzData); - int iAction = -1; - - int iRetryCount = 0; - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "Failed to initialize COM"); - fInitializedCom = TRUE; - - pwz = pwzLast = pwzData; - - hr = StrAllocString(&pwzBackup, pwz, 0); - ExitOnFailure(hr, "Failed to backup custom action data"); - - while (S_OK == (hr = WcaReadIntegerFromCaData(&pwz, &iAction))) - { - if (NULL == pAdminMgr) - { - hr = ::CoCreateInstance( __uuidof(AppHostWritableAdminManager), - NULL, - CLSCTX_INPROC_SERVER, - __uuidof(IAppHostWritableAdminManager), - reinterpret_cast (&pAdminMgr)); - ExitOnFailure(hr , "Failed to open AppHostWritableAdminManager to configure IIS7"); - } - - switch (iAction) - { - case IIS_SITE: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7Site(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS site."); - break; - } - case IIS_APPLICATION: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7Application(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS application."); - break; - } - case IIS_VDIR: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7VDir(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS VDir."); - break; - } - case IIS_BINDING: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7Binding(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS site binding."); - break; - } - case IIS_APPPOOL: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7AppPool(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS appPool."); - break; - } - case IIS_APPEXT_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7AppExtension(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS AppExtension."); - break; - } - case IIS_MIMEMAP_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7MimeMap(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS MimeMap."); - break; - } - case IIS_DIRPROP_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7DirProperties(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS DirProperties."); - break; - } - case IIS_WEBLOG: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7WebLog(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS WebLog."); - break; - } - case IIS_FILTER_GLOBAL_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7FilterGlobal(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS filter global."); - break; - } - case IIS_FILTER_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7FilterSite(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS Filter."); - break; - } - case IIS_HTTP_HEADER_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7HttpHeader(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS http Header."); - break; - } - case IIS_WEBERROR_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7WebError(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS http Errors."); - break; - } - case IIS_WEB_SVC_EXT: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7WebSvcExt(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS web svc ext."); - break; - } - case IIS_PROPERTY: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7WebProperty(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS web property."); - break; - } - case IIS_WEBDIR: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7WebDir(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS web directory."); - break; - } - case IIS_ASP_BEGIN: - { -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7AspProperty(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS Asp property."); - break; - } - case IIS_SSL_BINDING: -#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") - hr = IIS7SslBinding(&pwz, pAdminMgr); - ExitOnFailure(hr, "Failed to configure IIS SSL binding."); - break; - - default: - ExitOnFailure(hr = E_UNEXPECTED, "IIS7ConfigChanges: Unexpected IIS Config action specified: %d", iAction); - break; - } - if (S_OK == hr) - { - // commit config changes now to close out IIS Admin changes, - // the Rollback or Commit defered CAs will determine final commit status. - hr = pAdminMgr->CommitChanges(); - - // Our transaction may have been interrupted. - if (hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) || hr == HRESULT_FROM_WIN32(ERROR_TRANSACTIONAL_CONFLICT)) - { - WcaLog(LOGMSG_VERBOSE, "Sharing violation or transactional conflict during attempt to save changes to applicationHost.config"); - if (++iRetryCount > 30) - { - if (IDRETRY == WcaErrorMessage(msierrIISFailedCommitInUse, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0)) - { - iRetryCount = 0; - } - else - { - ExitOnFailure(hr, "Failed to Commit IIS Config Changes, in silent mode or user has chosen to cancel"); - } - } - - // Throw away the changes since IIS has no way to remove uncommited changes from an AdminManager. - ReleaseNullObject(pAdminMgr); - - // Restore our CA data backup - pwz = pwzLast; - hr = ::StringCchCopyW(pwz, cchData - (pwz - pwzData) + 1, pwzBackup); - ExitOnFailure(hr , "Failed to restore custom action data backup"); - - } - else if (FAILED(hr)) - { - ExitOnFailure(hr , "Failed to Commit IIS Config Changes"); - } - else - { - // store a backup of CA data @ the last place that we successfully commited changes unless we are done. - if(NULL != pwz) - { - pwzLast = pwz; - hr = StrAllocString(&pwzBackup, pwz, 0); - ExitOnFailure(hr, "Failed to backup custom action data"); - } - } - } - } - if (E_NOMOREITEMS == hr) // If there are no more items, all is well - { - hr = S_OK; - } -LExit: - ReleaseObject(pAdminMgr); - ReleaseStr(pwzBackup); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - return hr; -} -//------------------------------------------------------------------------------------------------- -// IIS7AspProperty -// Called by WriteIIS7ConfigChanges -// Processes asp properties for WebApplication -// -//------------------------------------------------------------------------------------------------- - -HRESULT IIS7AspProperty( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - - int iAction = -1; - int iData = 0; - - LPWSTR pwzData = NULL; - LPWSTR pwzSiteName = NULL; - LPWSTR pwzPathName = NULL; - LPWSTR pwzLocationPath = NULL; - WCHAR wcTime[60]; - - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - - //read web site key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed read webDir webkey"); - - //read path key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzPathName); - ExitOnFailure(hr, "Failed read webDir path"); - - //Construct Location path - hr = StrAllocFormatted(&pwzLocationPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); - ExitOnFailure(hr, "failed to format webDir location"); - // - //Do not append trailing '/' for default vDir - // - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzPathName, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzLocationPath, L"/", 0); - ExitOnFailure(hr, "failed to copy location WebDir '/'"); - hr = StrAllocConcat(&pwzLocationPath, pwzPathName, 0); - ExitOnFailure(hr, "failed to copy location WebDir path"); - } - - //get asp section at config path location tag - hr = pAdminMgr->GetAdminSection( ScopeBSTR(IIS_CONFIG_ASP_SECTION), pwzLocationPath, &pSection); - ExitOnFailure(hr, "Failed get httpErrors section"); - - // Get action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read property action"); - - while (IIS_ASP_END != iAction) - { - switch (iAction) - { - case IIS_ASP_SESSIONSTATE: - { - //system.webServer/asp /session | allowSessionState - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp session state"); - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_SESSION), &pElement); - ExitOnFailure(hr, "Failed to get asp session element"); - hr = Iis7PutPropertyBool( pElement, IIS_CONFIG_ALLOWSTATE, iData); - ExitOnFailure(hr, "Failed to put asp session value"); - ReleaseNullObject(pElement); - break; - } - case IIS_ASP_SESSIONTIMEOUT: - { - //system.webServer/asp /session | timeout - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp session timeout"); - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_SESSION), &pElement); - ExitOnFailure(hr, "Failed to get asp session timeout"); - *wcTime = '\0'; - ConvSecToHMS(iData * 60, wcTime, countof( wcTime)); - hr = Iis7PutPropertyString( pElement, IIS_CONFIG_TIMEOUT, wcTime); - ExitOnFailure(hr, "Failed to put asp timeout value"); - ReleaseNullObject(pElement); - break; - } - case IIS_ASP_BUFFER: - { - //system.webServer/asp | bufferingOn - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp bufferingOn"); - hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_BUFFERING, iData); - ExitOnFailure(hr, "Failed to put asp bufferingOn value"); - break; - } - case IIS_ASP_PARENTPATHS: - { - //system.webServer/asp | enableParentPaths - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp ParentPaths"); - hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_PARENTPATHS, iData); - ExitOnFailure(hr, "Failed to put asp ParentPaths value"); - break; - } - case IIS_ASP_SCRIPTLANG: - { - //system.webServer/asp | scriptLanguage - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read asp scriptLanguage"); - hr = Iis7PutPropertyString( pSection, IIS_CONFIG_SCRIPTLANG, pwzData); - ExitOnFailure(hr, "Failed to put asp scriptLanguage value"); - break; - } - case IIS_ASP_SCRIPTTIMEOUT: - { - //system.webServer/asp /limits | scriptTimeout - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp scriptTimeout"); - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_LIMITS), &pElement); - ExitOnFailure(hr, "Failed to get asp session element"); - *wcTime = '\0'; - ConvSecToHMS(iData, wcTime, countof( wcTime)); - hr = Iis7PutPropertyString( pElement, IIS_CONFIG_SCRIPTTIMEOUT, wcTime); - ExitOnFailure(hr, "Failed to put asp scriptTimeout value"); - ReleaseNullObject(pElement); - break; - - } - case IIS_ASP_SCRIPTSERVERDEBUG: - { - //system.webServer/asp | appAllowDebugging - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp appAllowDebugging"); - hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_ALLOWDEBUG, iData); - ExitOnFailure(hr, "Failed to put asp appAllowDebugging value"); - break; - } - case IIS_ASP_SCRIPTCLIENTDEBUG: - { - //system.webServer/asp | appAllowClientDebug - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read asp appAllowClientDebug"); - hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_ALLOWCLIENTDEBUG, iData); - ExitOnFailure(hr, "Failed to put asp appAllowClientDebug value"); - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for asp properties"); - break; - } - } - // Get next action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read asp prop action"); - } - -LExit: - ReleaseStr(pwzData); - ReleaseStr(pwzSiteName); - ReleaseStr(pwzPathName); - ReleaseStr(pwzLocationPath); - ReleaseObject(pSection); - ReleaseObject(pElement); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7WebDir -// Called by WriteIIS7ConfigChanges -// Processes WebDir -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7WebDir( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - - int iAction = -1; - - LPWSTR pwzSiteName = NULL; - LPWSTR pwzPathName = NULL; - LPWSTR pwzLocationPath = NULL; - - // Get action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read property action"); - - //read web site key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed read webDir webkey"); - - //read path key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzPathName); - ExitOnFailure(hr, "Failed read webDir path"); - - switch (iAction) - { - case IIS_CREATE: - { - //no action needed for create since WebDir has a - //WebDirProperties element that will create and populate - //location tag - break; - } - case IIS_DELETE: - { - //Construct Location path - hr = StrAllocString(&pwzLocationPath, pwzSiteName, 0); - ExitOnFailure(hr, "failed to copy location WebDir web name"); - // - //Do not append trailing '/' for default vDir - // - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzPathName, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzLocationPath, L"/", 0); - ExitOnFailure(hr, "failed to copy location WebDir '/'"); - hr = StrAllocConcat(&pwzLocationPath, pwzPathName, 0); - ExitOnFailure(hr, "failed to copy location WebDir path"); - } - // and delete location tag for this application - hr = ClearLocationTag(pAdminMgr, pwzLocationPath); - ExitOnFailure(hr, "failed to clear location tag for %ls", pwzLocationPath) - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for WebDir"); - break; - } - } -LExit: - ReleaseStr(pwzSiteName); - ReleaseStr(pwzPathName); - ReleaseStr(pwzLocationPath); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7WebProperty -// Called by WriteIIS7ConfigChanges -// Processes isapiCgiRestriction -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7WebProperty( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - - int iAction = -1; - int iData = 0; - - IAppHostElement *pSection = NULL; - - // Get action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read property action"); - - switch (iAction) - { - case IIS_PROPERTY_MAXBAND: - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read property max band"); - //set value at system.applicationHost/webLimits | maxGlobalBandwidth - //Get IIS config section - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_WEBLIMITS_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); - ExitOnFailure(hr, "Failed get isapiCgiRestriction section"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get isapiCgiRestriction section object"); - } - hr = Iis7PutPropertyInteger(pSection, IIS_CONFIG_WEBLIMITS_MAXBAND, iData); - - break; - } - case IIS_PROPERTY_LOGUTF8: - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read property log"); - //set value at system.applicationHost/log | logInUTF8 - //Get IIS config section - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_LOG_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); - ExitOnFailure(hr, "Failed get isapiCgiRestriction section"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get isapiCgiRestriction section object"); - } - hr = Iis7PutPropertyBool(pSection, IIS_CONFIG_LOG_UTF8, iData); - - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for Web Property"); - break; - } - } - -LExit: - ReleaseObject(pSection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7WebSvcExt -// Called by WriteIIS7ConfigChanges -// Processes isapiCgiRestriction -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7WebSvcExt( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - - int iAction = -1; - int iData = 0; - BOOL fFound = FALSE; - LPWSTR pwzData = NULL; - LPWSTR pwzPath = NULL; - - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - // Get action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read WebSvcExt action"); - - //get path - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzPath); - ExitOnFailure(hr, "Failed to read WebSvcExt key"); - - //Get IIS config section - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_RESTRICTION_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); - ExitOnFailure(hr, "Failed get isapiCgiRestriction section"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get isapiCgiRestriction section object"); - } - //get collection - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get isapiCgiRestriction collection"); - - //find element - hr = Iis7FindAppHostElementPath(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_PATH, pwzPath, &pElement, NULL); - ExitOnFailure(hr, "Failed get isapiCgiRestriction element"); - fFound = (NULL != pElement); - - switch (iAction) - { - case IIS_CREATE: - { - if (!fFound) - { - //create a restriction element - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement); - ExitOnFailure(hr, "Failed create isapiCgiRestriction element"); - //put path - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzPath); - ExitOnFailure(hr, "Failed set isapiCgiRestriction path property"); - } - //update common properties - - //update allowed - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read WebSvcExt allowed"); - hr = Iis7PutPropertyBool(pElement, IIS_CONFIG_ALLOWED, iData); - ExitOnFailure(hr, "Failed set isapiCgiRestriction allowed property"); - - //update groupId - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read WebSvcExt group ID"); - if (*pwzData) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_GROUPID, pwzData); - ExitOnFailure(hr, "Failed set isapiCgiRestriction groupId property"); - } - //update description - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read WebSvcExt description"); - if (*pwzData) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_DESC, pwzData); - ExitOnFailure(hr, "Failed set isapiCgiRestriction description property"); - } - // add element if new - if (!fFound) - { - hr = pCollection->AddElement(pElement); - ExitOnFailure(hr, "Failed add isapiCgiRestriction element"); - } - - break; - } - case IIS_DELETE: - { - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_PATH, pwzPath); - ExitOnFailure(hr, "Failed delete isapiCgiRestriction element"); - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for WebSvcExt"); - break; - } - } - -LExit: - ReleaseStr(pwzPath); - ReleaseStr(pwzData); - ReleaseObject(pSection); - ReleaseObject(pElement); - ReleaseObject(pCollection); - - return hr; - -} - -//------------------------------------------------------------------------------------------------- -// IIS7WebError -// Called by WriteIIS7ConfigChanges -// Processes http header CA Data -// -//------------------------------------------------------------------------------------------------- - -HRESULT IIS7WebError( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - LPWSTR pwzConfigPath = NULL; - LPWSTR pwzSiteName = NULL; - LPWSTR pwzAppName = NULL; - - IAppHostElement *pElement = NULL; - IAppHostElement *pSection = NULL; - IAppHostElementCollection *pCollection = NULL; - - SCA_WEB_ERROR_SERVER *psweList = NULL; - SCA_WEB_ERROR_SERVER* pswe = NULL; - SCA_WEB_ERROR_SERVER we; - BOOL fFound = FALSE; - - int iAction = -1; - LPWSTR pwzData = NULL; - - //read web site key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed read web error site name"); - - //read app key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppName); - ExitOnFailure(hr, "Failed read web error app name"); - - //Construct config root path - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); - ExitOnFailure(hr, "failed to format web error config path"); - - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzAppName, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzConfigPath, L"/", 0); - ExitOnFailure(hr, "failed to copy web error config path delim"); - hr = StrAllocConcat(&pwzConfigPath, pwzAppName, 0); - ExitOnFailure(hr, "failed to app name to web error config path"); - } - - //get httpErrors section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPERRORS_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get httpErrors section"); - - //get existing httpErrors list & clear collection - hr = PopulateHttpErrors(pSection, &psweList); - ExitOnFailure(hr, "Failed to read httpErrors list"); - - //get collection - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get httpErrors collection"); - - DWORD cErrors = 0; - hr = pCollection->get_Count(&cErrors); - - // Get web error action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - while (IIS_WEBERROR_END != iAction) - { - //Process property action - if (IIS_WEBERROR == iAction) - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &(we.iErrorCode)); - ExitOnFailure(hr, "failed to get httpErrors ErrorCode"); - - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &(we.iSubCode)); - ExitOnFailure(hr, "failed to get httpErrors SubCode"); - //0 is the sub error code wild card for IIS6, change to -1 for IIS7 - if (we.iSubCode == 0) - { - we.iSubCode = -1; - } - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to get httpErrors File"); - hr = ::StringCchCopyW(we.wzFile, countof(we.wzFile), pwzData); - ExitOnFailure(hr, "Failed to copy httpErrors File"); - - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &(we.iResponseMode)); - ExitOnFailure(hr, "Failed to get httpErrors File code"); - - fFound = FALSE; - hr = GetErrorFromList( we, &psweList, &pswe, &fFound); - if (!fFound) - { - hr = AddWebErrorToList(&psweList); - ExitOnFailure(hr, "failed to add web error to list"); - pswe = psweList; - } - else - { - //if overwriting existing http errors element then clear lang path - hr = ::StringCchCopyW(pswe->wzLangPath, countof(pswe->wzLangPath), L""); - ExitOnFailure(hr, "Failed to copy httpErrors lang path value"); - } - pswe->iErrorCode = we.iErrorCode; - pswe->iSubCode = we.iSubCode; - hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), we.wzFile); - ExitOnFailure(hr, "Failed to copy httpErrors File value"); - pswe->iResponseMode = we.iResponseMode; - - } - else - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for http header"); - } - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - } - - //No inheritance - put a clear in at this loc tag - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pElement); - ExitOnFailure(hr, "Failed create httpErrors clear"); - hr = pCollection->AddElement(pElement); - ExitOnFailure(hr, "Failed add httpErrors clear"); - - //now we have merged new, from MSI, http errors with global list - //write this back out at location tag. - // Loop through the HTTP headers - for ( pswe = psweList; pswe; pswe = pswe->psweNext) - { - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ERROR), &pElement); - ExitOnFailure(hr, "Failed create httpErrors element"); - - // status code - hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_STATUSCODE, pswe->iErrorCode); - ExitOnFailure(hr, "Failed set httpErrors code value"); - - //sub status - hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_SUBSTATUS, pswe->iSubCode); - ExitOnFailure(hr, "Failed set httpErrors sub code value"); - - //lang path - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_LANGPATH, pswe->wzLangPath); - ExitOnFailure(hr, "Failed set httpErrors lang path value"); - - //path - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pswe->wzFile); - ExitOnFailure(hr, "Failed set httpErrors path value"); - - //response mode - hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_RESPMODE, pswe->iResponseMode); - ExitOnFailure(hr, "Failed set httpErrors resp mode value"); - - //add the element - hr = pCollection->AddElement(pElement); - ExitOnFailure(hr, "Failed add httpErrors element"); - ReleaseNullObject(pElement); - } - -LExit: - ScaWebErrorFreeList7(psweList); - - ReleaseStr(pwzConfigPath); - ReleaseStr(pwzSiteName); - ReleaseStr(pwzAppName); - ReleaseStr(pwzData); - ReleaseObject(pElement); - ReleaseObject(pSection); - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT PopulateHttpErrors(IAppHostElement *pSection, SCA_WEB_ERROR_SERVER **ppsweList) -{ - HRESULT hr = S_OK; - - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - IAppHostProperty *pProperty = NULL; - - DWORD cErrors = 0; - SCA_WEB_ERROR_SERVER *pswe = NULL; - - VARIANT vPropValue; - VARIANT vtIndex; - - VariantInit(&vPropValue); - VariantInit(&vtIndex); - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get httpErrors collection"); - - hr = pCollection->get_Count(&cErrors); - ExitOnFailure(hr, "Failed get sites collection count"); - - vtIndex.vt = VT_UI4; - for (DWORD i = 0; i < cErrors; ++i) - { - vtIndex.ulVal = i; - hr = pCollection->get_Item(vtIndex , &pElement); - ExitOnFailure(hr, "Failed get httpErrors collection item"); - - hr = AddWebErrorToList(ppsweList); - ExitOnFailure(hr, "Failed add web error list item"); - pswe = *ppsweList; - - //get all properties - // - // statusCode UINT - // subStatusCode INT - // prefixLanguageFilePath type="string" - // path type="string" - // responseMode type="enum" defaultValue="File"> - // - // - // - - // status code - hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_STATUSCODE), &pProperty); - ExitOnFailure(hr, "Failed get httpErrors code property"); - hr = pProperty->get_Value(&vPropValue); - ExitOnFailure(hr, "Failed get httpErrors code value"); - pswe->iErrorCode = vPropValue.uintVal; - ReleaseVariant(vPropValue); - - //sub status - hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_SUBSTATUS), &pProperty); - ExitOnFailure(hr, "Failed get httpErrors sub code property"); - hr = pProperty->get_Value(&vPropValue); - ExitOnFailure(hr, "Failed get httpErrors sub code value"); - pswe->iSubCode = vPropValue.intVal; - ReleaseVariant(vPropValue); - - //lang path - hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_LANGPATH), &pProperty); - ExitOnFailure(hr, "Failed get httpErrors lang path property"); - hr = pProperty->get_Value(&vPropValue); - ExitOnFailure(hr, "Failed get httpErrors lang path value"); - hr = ::StringCchCopyW(pswe->wzLangPath, countof(pswe->wzLangPath), vPropValue.bstrVal); - ExitOnFailure(hr, "Failed to copy httpErrors lang path"); - ReleaseVariant(vPropValue); - - //path - hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_PATH), &pProperty); - ExitOnFailure(hr, "Failed get httpErrors path property"); - hr = pProperty->get_Value(&vPropValue); - ExitOnFailure(hr, "Failed get httpErrors path value"); - hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), vPropValue.bstrVal); - ExitOnFailure(hr, "Failed to copy httpErrors File"); - ReleaseVariant(vPropValue); - - //response mode - hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_RESPMODE), &pProperty); - ExitOnFailure(hr, "Failed get httpErrors resp mode property"); - hr = pProperty->get_Value(&vPropValue); - ExitOnFailure(hr, "Failed get httpErrors resp mode value"); - pswe->iResponseMode = vPropValue.intVal; - ReleaseVariant(vPropValue); - - ReleaseNullObject(pElement); - ReleaseNullObject(pProperty); - } - - //remove the elements from connection so we can add back later - hr = pCollection->Clear(); - ExitOnFailure(hr, "Failed clear httpErrors collection"); - -LExit: - ReleaseVariant(vPropValue); - ReleaseObject(pProperty); - ReleaseObject(pElement); - ReleaseObject(pCollection); - - return hr; -} - -static void ScaWebErrorFreeList7(SCA_WEB_ERROR_SERVER *psweList) -{ - SCA_WEB_ERROR_SERVER *psweDelete = psweList; - while (psweList) - { - psweDelete = psweList; - psweList = psweList->psweNext; - - MemFree(psweDelete); - } -} -static HRESULT AddWebErrorToList(SCA_WEB_ERROR_SERVER **ppsweList) -{ - HRESULT hr = S_OK; - - SCA_WEB_ERROR_SERVER* pswe = static_cast(MemAlloc(sizeof(SCA_WEB_ERROR_SERVER), TRUE)); - - ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); - - pswe->psweNext = *ppsweList; - *ppsweList = pswe; - -LExit: - return hr; -} -static HRESULT GetErrorFromList( const SCA_WEB_ERROR_SERVER& we, - SCA_WEB_ERROR_SERVER **ppsweList, - SCA_WEB_ERROR_SERVER **ppswe, - BOOL *fFound) -{ - HRESULT hr = S_OK; - - *fFound = FALSE; - - SCA_WEB_ERROR_SERVER *pswe; - - for ( pswe = *ppsweList; pswe; pswe = pswe->psweNext) - { - if ((pswe->iErrorCode == we.iErrorCode) && (pswe->iSubCode == we.iSubCode)) - { - *fFound = TRUE; - *ppswe = pswe; - break; - } - } - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7HttpHeader -// Called by WriteIIS7ConfigChanges -// Processes http header CA Data -// -//------------------------------------------------------------------------------------------------- - -HRESULT IIS7HttpHeader( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - LPWSTR pwzConfigPath = NULL; - LPWSTR pwzSiteName = NULL; - LPWSTR pwzAppName = NULL; - - LPWSTR pwzHeaderName = NULL; - LPWSTR pwzHeaderValue = NULL; - - IAppHostElement *pElement = NULL; - IAppHostElement *pSection = NULL; - IAppHostElementCollection *pCollection = NULL; - IAppHostElement *pElementHeaders = NULL; - - int iAction = -1; - BOOL fFound = FALSE; - - //read web site key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed read header web site name"); - - //read app key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppName); - ExitOnFailure(hr, "Failed read header appkey"); - - //Construct config root path - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); - ExitOnFailure(hr, "failed to format web error config path"); - - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzAppName, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzConfigPath, L"/", 0); - ExitOnFailure(hr, "failed to copy web error config path delim"); - hr = StrAllocConcat(&pwzConfigPath, pwzAppName, 0); - ExitOnFailure(hr, "failed to app name to web error config path"); - } - - //get admin handlers section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPPROTO_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get http protocol section"); - - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_HEADERS), &pElementHeaders); - ExitOnFailure(hr, "Failed get http customHeaders section"); - - hr = pElementHeaders->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get http customHeaders collection"); - - // Get filter action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - while (IIS_HTTP_HEADER_END != iAction) - { - //Process property action - if (IIS_HTTP_HEADER == iAction) - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzHeaderName); - ExitOnFailure(hr, "Fail to read httpHeader name"); - - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzHeaderValue); - ExitOnFailure(hr, "Fail to read httpHeader value"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, pwzHeaderName, &pElement, NULL); - ExitOnFailure(hr, "Failed get isapiCgiRestriction element"); - fFound = (NULL != pElement); - - if (!fFound) - { - //make a new element - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement); - ExitOnFailure(hr, "Failed to create filter config element"); - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_NAME, pwzHeaderName); - ExitOnFailure(hr, "Failed to set header name"); - } - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_VALUE, pwzHeaderValue); - ExitOnFailure(hr, "Failed to set header Value"); - - if (!fFound) - { - hr = pCollection->AddElement(pElement); - ExitOnFailure(hr, "Failed add http header"); - } - - } - else - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for http header"); - } - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - } - -LExit: - ReleaseStr(pwzConfigPath); - ReleaseStr(pwzSiteName); - ReleaseStr(pwzAppName); - ReleaseStr(pwzHeaderName); - ReleaseStr(pwzHeaderValue); - ReleaseObject(pElementHeaders); - ReleaseObject(pElement); - ReleaseObject(pSection); - ReleaseObject(pCollection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7FilterGlobal -// Called by WriteIIS7ConfigChanges -// Processes Filter CA Data -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7FilterGlobal( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - int iAction = 0; - - IAppHostElement *pSection = NULL; - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ISAPI_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); - ExitOnFailure(hr, "Failed get sites section"); - - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get isapiFilters section object"); - } - - // Get filter action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - - while (IIS_FILTER_END != iAction) - { - //Process property action - switch (iAction) - { - case IIS_FILTER : - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - - if (iAction == IIS_CREATE) - { - hr = CreateGlobalFilter(ppwzCustomActionData, pSection); - } - else - { - hr = DeleteGlobalFilter(ppwzCustomActionData, pSection); - } - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for global filter"); - break; - } - } - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - - } - -LExit: - ReleaseObject(pSection); - - return hr; -} - -static HRESULT CreateGlobalFilter( __inout LPWSTR *ppwzCustomActionData, IAppHostElement *pSection) -{ - HRESULT hr = S_OK; - - LPWSTR pwzFilterName = NULL; - LPWSTR pwzSiteName = NULL; - LPWSTR pwzFilterPath = NULL; - int iLoadOrder = 0; - DWORD cFilters = 0; - - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get filter collection"); - - hr = pCollection->get_Count(&cFilters); - ExitOnFailure(hr, "Failed get filter collection count"); - - // Attempt to delete, we will we recreate with desired property values and order - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); - ExitOnFailure(hr, "Failed to delete filter"); - - //make a new element - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_FILTER), &pElement); - ExitOnFailure(hr, "Failed to create filter config element"); - - //filter Name key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); - ExitOnFailure(hr, "Failed to read filter name"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_NAME, pwzFilterName); - ExitOnFailure(hr, "Failed to set filter name"); - - //web site name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read filter site name"); - - // filter path - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterPath); - ExitOnFailure(hr, "Failed to read filter path"); - hr = Iis7PutPropertyString(pElement,IIS_CONFIG_PATH, pwzFilterPath); - ExitOnFailure(hr, "Failed to set filter path"); - - //filter load order - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iLoadOrder); - ExitOnFailure(hr, "Failed to read filter load order"); - - // put element in order in list - int iPosition = -1; - int icFilters = cFilters; - switch (iLoadOrder) - { - case 0 : - { - iPosition = -1; - break; - } - case -1 : - { - iPosition = icFilters; - break; - } - case MSI_NULL_INTEGER : - { - iPosition = icFilters; - break; - } - default: - { - if (iLoadOrder > icFilters) - { - iPosition = icFilters; - } - else - { - iPosition = iLoadOrder; - } - break; - } - } - hr = pCollection->AddElement(pElement, iPosition); - ExitOnFailure(hr, "Failed to add filter element"); - -LExit: - ReleaseStr(pwzFilterName); - ReleaseStr(pwzSiteName); - ReleaseStr(pwzFilterPath); - ReleaseObject(pCollection); - ReleaseObject(pElement); - - return hr; -} - -static HRESULT DeleteGlobalFilter( __inout LPWSTR *ppwzCustomActionData, IAppHostElement *pSection) -{ - HRESULT hr = S_OK; - - LPWSTR pwzFilterName = NULL; - LPWSTR pwzSiteName = NULL; - - IAppHostElementCollection *pCollection = NULL; - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get filter collection"); - - //filter Name key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); - ExitOnFailure(hr, "Failed to read filter name"); - - //web site name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); // TODO: unused? - ExitOnFailure(hr, "Failed to read filter site name"); - - DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); - ExitOnFailure(hr, "Failed to delete filter %ls", pwzFilterName); - -LExit: - ReleaseStr(pwzFilterName); - ReleaseStr(pwzSiteName); - ReleaseObject(pCollection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7FilterSite -// Called by WriteIIS7ConfigChanges -// Processes Filter CA Data -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7FilterSite( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - int iAction = 0; - - // Get filter action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - - while (IIS_FILTER_END != iAction) - { - //Process property action - switch (iAction) - { - case IIS_FILTER : - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - - if (iAction == IIS_CREATE) - { - hr = CreateSiteFilter(ppwzCustomActionData, pAdminMgr); - } - else - { - hr = DeleteSiteFilter(ppwzCustomActionData, pAdminMgr); - } - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for global filter"); - break; - } - } - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read filter action"); - } - -LExit: - return hr; - -} - -static HRESULT CreateSiteFilter(__inout LPWSTR *ppwzCustomActionData, IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - LPWSTR pwzFilterName = NULL; - LPWSTR pwzSiteName = NULL; - LPWSTR pwzFilterPath = NULL; - LPWSTR pwzConfigPath = NULL; - int iLoadOrder = 0; - DWORD cFilters; - - IAppHostElement *pElement = NULL; - IAppHostElement *pSection = NULL; - IAppHostElementCollection *pCollection = NULL; - - //filter Name key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); - ExitOnFailure(hr, "Failed to read filter name"); - - //web site name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read filter site name"); - - //Construct config root - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); - ExitOnFailure(hr, "failed to format filter config path"); - - //get admin isapiFilters section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ISAPI_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get isapiFilters section"); - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get filter collection"); - - hr = pCollection->get_Count(&cFilters); - ExitOnFailure(hr, "Failed get filter collection count"); - - // Attempt to delete, we will we recreate with desired property values and order - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); - ExitOnFailure(hr, "Failed to delete filter"); - - //make a new element - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_FILTER), &pElement); - ExitOnFailure(hr, "Failed to create filter config element"); - - hr = Iis7PutPropertyString(pElement,IIS_CONFIG_NAME, pwzFilterName); - ExitOnFailure(hr, "Failed to set filter name"); - - // filter path - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterPath); - ExitOnFailure(hr, "Failed to read filter path"); - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzFilterPath); - ExitOnFailure(hr, "Failed to set filter path"); - - //filter load order - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iLoadOrder); - ExitOnFailure(hr, "Failed to read filter load order"); - - // put element in order in list - int iPosition = -1; - int icFilters = cFilters; - switch (iLoadOrder) - { - case 0 : - { - iPosition = -1; - break; - } - case -1 : - { - iPosition = icFilters; - break; - } - case MSI_NULL_INTEGER : - { - iPosition = icFilters; - break; - } - default: - { - if (iLoadOrder > icFilters) - { - iPosition = icFilters; - } - else - { - iPosition = iLoadOrder; - } - break; - } - } - - hr = pCollection->AddElement(pElement, iPosition); - ExitOnFailure(hr, "Failed to add filter element"); - -LExit: - ReleaseStr(pwzFilterName); - ReleaseStr(pwzSiteName); - ReleaseStr(pwzFilterPath); - ReleaseStr(pwzConfigPath); - ReleaseObject(pElement); - ReleaseObject(pSection); - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT DeleteSiteFilter(__inout LPWSTR *ppwzCustomActionData, IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - LPWSTR pwzFilterName = NULL; - LPWSTR pwzSiteName = NULL; - LPWSTR pwzConfigPath = NULL; - - IAppHostElement *pSection = NULL; - IAppHostElementCollection *pCollection = NULL; - - //filter Name key - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); - ExitOnFailure(hr, "Failed to read filter name"); - - //web site name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read filter site name"); - - //Construct config root - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); - ExitOnFailure(hr, "failed to format filter config path"); - - //get admin isapiFilters section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ISAPI_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get isapiFilters section"); - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get filter collection"); - - DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); - ExitOnFailure(hr, "Failed to delete filter %ls", pwzFilterName); - -LExit: - ReleaseStr(pwzFilterName); - ReleaseStr(pwzSiteName); - ReleaseStr(pwzConfigPath); - ReleaseObject(pSection); - ReleaseObject(pCollection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7Site -// Called by WriteIIS7ConfigChanges -// Processes WebSite CA Data -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7Site( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - int iAction = -1; - int iData = 0; - BOOL fFound = FALSE; - - LPWSTR pwzSiteName = NULL; - IAppHostElement *pSites = NULL; - IAppHostElementCollection *pCollection = NULL; - IAppHostElement *pSiteElem = NULL; - IAppHostElement *pElement = NULL; - - // Get site action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read site action"); - - //get site name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read site key"); - - //Get site if it exists - hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fFound); - ExitOnFailure(hr, "Failed to read sites from config"); - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_SITES_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSites); - ExitOnFailure(hr, "Failed get sites section"); - ExitOnNull(pSites, hr, ERROR_FILE_NOT_FOUND, "Failed get sites section object"); - - hr = pSites->get_Collection( &pCollection); - ExitOnFailure(hr, "Failed get site collection"); - switch (iAction) - { - case IIS_DELETE : - { - if (fFound) - { - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_NAME, pwzSiteName); - ExitOnFailure(hr, "Failed to delete website"); - } - ExitFunction(); - break; - } - case IIS_CREATE : - { - if (!fFound) - { - //Create the site - hr = CreateSite(pCollection, pwzSiteName, &pSiteElem); - ExitOnFailure(hr, "Failed to create site"); - - } - } - } - // - //Set other Site properties - // - //set site Id - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read site Id"); - if (iData != MSI_NULL_INTEGER && -1 != iData) - { - hr = Iis7PutPropertyInteger(pSiteElem, IIS_CONFIG_SITE_ID, iData); - ExitOnFailure(hr, "Failed set site Id data"); - } - //Set Site AutoStart - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read site autostart"); - if (MSI_NULL_INTEGER != iData) - { - hr = Iis7PutPropertyBool(pSiteElem, IIS_CONFIG_AUTOSTART, iData); - ExitOnFailure(hr, "Failed set site config data"); - } - - //Set Site Connection timeout - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read site connection tomeout data"); - if (MSI_NULL_INTEGER != iData) - { - // get limits element, get connectionTimeout property - hr = pSiteElem->GetElementByName(ScopeBSTR(IIS_CONFIG_LIMITS), &pElement); - ExitOnFailure(hr, "Failed to read limits from config"); - //convert iData in seconds to timeSpan hh:mm:ss - WCHAR wcTime[60]; - *wcTime = '\0'; - ConvSecToHMS( iData, wcTime, countof( wcTime)); - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CONNECTTIMEOUT, wcTime); - ExitOnFailure(hr, "IIS: failed set connection timeout config data"); - } - -LExit: - ReleaseStr(pwzSiteName); - ReleaseObject(pSites); - ReleaseObject(pCollection); - ReleaseObject(pSiteElem); - ReleaseObject(pElement); - - return hr; -} -//------------------------------------------------------------------------------------------------- -// IIS7Application -// Processes Application CA Data -// -// -//------------------------------------------------------------------------------------------------- - -HRESULT IIS7Application( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - - int iAction = -1; - BOOL fSiteFound = FALSE; - BOOL fAppFound = FALSE; - - LPWSTR pwzSiteName = NULL; - LPWSTR pwzAppPath = NULL; - LPWSTR pwzAppPool = NULL; - LPWSTR pwzLocationPath = NULL; - IAppHostElement *pSiteElem = NULL; - IAppHostElement *pAppElement = NULL; - // Get Application action - hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read application action") - //get site key name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read app site key"); - //get application path - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppPath); - ExitOnFailure(hr, "Failed to read app path key"); - //get application Pool - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppPool); - ExitOnFailure(hr, "Failed to read app pool key"); - - //Get site if it exists - hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); - ExitOnFailure(hr, "Failed to read sites from config"); - - switch (iAction) - { - case IIS_CREATE : - { - if (fSiteFound) - { - //have site get application collection - hr = GetApplicationElement(pSiteElem, - pwzAppPath, - &pAppElement, - &fAppFound); - ExitOnFailure(hr, "Error reading application from config"); - - if (!fAppFound) - { - //Create Application - hr = CreateApplication(pSiteElem, pwzAppPath, &pAppElement); - ExitOnFailure(hr, "Error creating application in config"); - } - //Update application properties: - // - //Set appPool - hr = SetAppPool(pAppElement, pwzAppPool); - ExitOnFailure(hr, "Unable to set appPool for application"); - } - else - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Site not found for create application"); - } - break; - } - case IIS_DELETE : - { - if (fSiteFound) - { - //have site get application collection - hr = GetApplicationElement( pSiteElem, - pwzAppPath, - &pAppElement, - &fAppFound); - ExitOnFailure(hr, "Error reading application from config") - if (fAppFound) - { - //delete Application - hr = DeleteApplication(pSiteElem, pwzAppPath); - ExitOnFailure(hr, "Error deleating application from config") - //Construct Location path - // TODO: it seems odd that these are just - // jammed together, need to determine if this requires a '\' - hr = StrAllocString(&pwzLocationPath, pwzSiteName, 0); - ExitOnFailure(hr, "failed to copy location config path web name"); - hr = StrAllocConcat(&pwzLocationPath, pwzAppPath, 0); - ExitOnFailure(hr, "failed to copy location config path appPath "); - - // and delete location tag for this application - hr = ClearLocationTag(pAdminMgr, pwzLocationPath); - ExitOnFailure(hr, "failed to clear location tag for %ls", pwzLocationPath); - } - } - break; - } - default: - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for Application"); - break; - } - -LExit: - ReleaseStr(pwzSiteName); - ReleaseStr(pwzAppPath); - ReleaseStr(pwzAppPool); - ReleaseStr(pwzLocationPath); - ReleaseObject(pSiteElem); - ReleaseObject(pAppElement); - - return hr; -} -//------------------------------------------------------------------------------------------------- -// IIS7VDir -// Processes VDir CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7VDir( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - - int iAction = -1; - BOOL fSiteFound = FALSE; - BOOL fAppFound = FALSE; - - LPWSTR pwzSiteName = NULL; - LPWSTR pwzVDirPath = NULL; - LPWSTR pwzVDirPhyDir = NULL; - LPCWSTR pwzVDirSubPath = NULL; - - IAppHostElement *pSiteElem = NULL; - IAppHostElement *pAppElement = NULL; - IAppHostElementCollection *pElement = NULL; - - // Get Application action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read VDir action"); - - //get site key name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read site key"); - //get VDir path - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzVDirPath); - ExitOnFailure(hr, "Failed to read VDir key"); - //get physical dir path - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzVDirPhyDir); - ExitOnFailure(hr, "Failed to read VDirPath key"); - - //Get site if it exists - hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); - ExitOnFailure(hr, "Failed to read sites from config"); - - if (IIS_CREATE == iAction) - { - if (fSiteFound) - { - //have site get application - hr = GetApplicationElementForVDir( pSiteElem, - pwzVDirPath, - &pAppElement, - &pwzVDirSubPath, - &fAppFound); - ExitOnFailure(hr, "Error reading application element from config"); - - if (!fAppFound) - { - // need application to add vDir - hr = E_FILENOTFOUND; - ExitOnFailure(hr, "Error application not found for create VDir"); - } - // - // create the virDir - // - hr = CreateVdir(pAppElement, pwzVDirSubPath, pwzVDirPhyDir); - ExitOnFailure(hr, "Failed to create vdir for application"); - } - else - { - hr = E_FILENOTFOUND; - ExitOnFailure(hr, "IIS: site not found for create VDir"); - } - } - else if (IIS_DELETE == iAction) - { - if (fSiteFound) - { - //have site get application - hr = GetApplicationElementForVDir( pSiteElem, - pwzVDirPath, - &pAppElement, - &pwzVDirSubPath, - &fAppFound); - ExitOnFailure(hr, "Error reading application from config") - if (fAppFound) - { - //delete vdir - hr = DeleteVdir(pAppElement, pwzVDirSubPath); - ExitOnFailure(hr, "Unable to delete vdir for application"); - } - } - } - - LExit: - ReleaseStr(pwzSiteName); - ReleaseStr(pwzVDirPath); - ReleaseStr(pwzVDirPhyDir); - ReleaseObject(pSiteElem); - ReleaseObject(pAppElement); - ReleaseObject(pElement); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7Binding -// Processes Bindings CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7Binding( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - - int iAction = -1; - BOOL fSiteFound = FALSE; - - LPWSTR pwzSiteName = NULL; - LPWSTR pwzProtocol = NULL; - LPWSTR pwzInfo = NULL; - - IAppHostElement *pSiteElem = NULL; - - // Get Application action - hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read binding action"); - - //get site key name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read binding site name key"); - - //get binding protocol - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzProtocol); - ExitOnFailure(hr, "Failed to read binding protocol"); - - //get binding info - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzInfo); - ExitOnFailure(hr, "Failed to read binding info"); - - //Get site if it exists - hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); - ExitOnFailure(hr, "Failed to read sites from config"); - - if (IIS_CREATE == iAction) - { - if (fSiteFound) - { - //add binding - hr = CreateBinding(pSiteElem, pwzProtocol, pwzInfo); - ExitOnFailure(hr, "Failed to create site binding"); - } - else - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Site not found for create binding"); - } - } - else if (IIS_DELETE == iAction) - { - if (fSiteFound) - { - //delete binding - hr = DeleteBinding(pSiteElem, pwzProtocol, pwzInfo); - ExitOnFailure(hr, "Failed to delete binding"); - } - } - - LExit: - ReleaseStr(pwzSiteName); - ReleaseStr(pwzProtocol); - ReleaseStr(pwzInfo); - ReleaseObject(pSiteElem); - - return hr; -} -//------------------------------------------------------------------------------------------------- -// IIS7Binding -// Processes WebLog CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7WebLog( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - - BOOL fSiteFound = FALSE; - - LPWSTR pwzSiteName = NULL; - LPWSTR pwzLogFormat = NULL; - - IAppHostElement *pSiteElem = NULL; - - //get site key name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read web log site name key"); - - //get log format - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzLogFormat); - ExitOnFailure(hr, "Failed to read web log protocol"); - - //Get site if it exists - hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); - ExitOnFailure(hr, "Failed to read web log sites from config"); - - if (fSiteFound) - { - //add log format - hr = CreateWebLog(pSiteElem, pwzLogFormat); - ExitOnFailure(hr, "Failed to create weblog file format"); - } - else - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Site not found for create weblog file format"); - } - - LExit: - ReleaseStr(pwzSiteName); - ReleaseStr(pwzLogFormat); - ReleaseObject(pSiteElem); - - return hr; -} -//------------------------------------------------------------------------------------------------- -// IIS7AppPool -// Processes AppPool CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7AppPool( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - - int iAction = -1; - - LPWSTR pwzAppPoolName = NULL; - - // Get AppPool action - hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read AppPool action"); - - //get appPool name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppPoolName); - ExitOnFailure(hr, "Failed to read AppPool name key"); - - switch (iAction) - { - case IIS_CREATE : - { - hr = CreateAppPool(ppwzCustomActionData, pAdminMgr, pwzAppPoolName); - break; - } - case IIS_DELETE: - { - hr = DeleteAppPool(pAdminMgr, pwzAppPoolName); - break; - } - default: - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for appPool"); - break; - } - -LExit: - ReleaseStr(pwzAppPoolName); - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7AppExtension -// Processes AppExtension (config handlers) CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7AppExtension( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr) -{ - HRESULT hr = S_OK; - - LPWSTR pwzWebName = NULL; - LPWSTR pwzWebRoot = NULL; - LPWSTR pwzData = NULL; - LPWSTR pwzConfigPath = NULL; - LPWSTR pwzHandlerName = NULL; - LPWSTR pwzPath = NULL; - int iAction = -1; - - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - BOOL fFound = FALSE; - DWORD cHandlers = 1000; - - //get web name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebName); - ExitOnFailure(hr, "Failed to read appExt Web name key"); - - //get root name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebRoot); - ExitOnFailure(hr, "Failed to read appExt Web name key"); - - //Construct config root - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzWebName); - ExitOnFailure(hr, "failed to format appext config path"); - // - //Do not append trailing '/' for default vDir - // - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzWebRoot, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzConfigPath, L"/", 0); - ExitOnFailure(hr, "failed to copy appext config path delim"); - hr = StrAllocConcat(&pwzConfigPath, pwzWebRoot, 0); - ExitOnFailure(hr, "failed to copy appext config path root name"); - } - //get admin handlers section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HANDLERS_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get appext section"); - - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get appext section object"); - } - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read appExt action"); - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get handlers collection for appext"); - - while (IIS_APPEXT_END != iAction) - { - fFound = FALSE; - - //Process property action - switch (iAction) - { - case IIS_APPEXT : - { - // These IDs aren't really stable but this is stable enough to support repair since the MSI won't change - hr = StrAllocFormatted(&pwzHandlerName, L"MsiCustom-%u", ++cHandlers); - ExitOnFailure(hr, "Failed increment handler name"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, pwzHandlerName, &pElement, NULL); - ExitOnFailure(hr, "Failed to find mimemap extension"); - - fFound = (NULL != pElement); - if (!fFound) - { - //create new handler element - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement); - ExitOnFailure(hr, "Failed get create handler element for appext"); - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_NAME, pwzHandlerName); - ExitOnFailure(hr, "Failed set appext name property"); - } - - //BUGBUG: For compat we are assuming these are all ISAPI MODULES so we are - //setting the modules property to IsapiModule. - //Currently can't deal with handlers of different module types. - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_MODULES, L"IsapiModule"); - ExitOnFailure(hr, "Failed set site appExt path property"); - - //get extension (path) - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read appExt extension"); - hr = StrAllocFormatted(&pwzPath, L"*.%s", pwzData); - ExitOnFailure(hr, "Failed decorate appExt path"); - //put property - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzPath); - ExitOnFailure(hr, "Failed set site appExt path property"); - - //get executable - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read appExt executable"); - //put property - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_EXECUTABLE, pwzData); - ExitOnFailure(hr, "Failed set site appExt executable property"); - - //get verbs - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read appExt verbs"); - //put property - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_VERBS, pwzData); - ExitOnFailure(hr, "Failed set site appExt verbs property"); - - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for AppExt"); - break; - } - } - - if (!fFound) - { - // put handler element at beginning of list - hr = pCollection->AddElement(pElement, 0); - ExitOnFailure(hr, "Failed add handler element for appext"); - } - - ReleaseNullObject(pElement); - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read AppPool Property action"); - } - -LExit: - ReleaseStr(pwzWebName); - ReleaseStr(pwzWebRoot); - ReleaseStr(pwzData); - ReleaseStr(pwzConfigPath); - ReleaseStr(pwzHandlerName); - ReleaseStr(pwzPath); - ReleaseObject(pSection); - ReleaseObject(pElement); - ReleaseObject(pCollection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7MimeMap -// Processes Mime Map (config handlers) CA Data -// -// -//------------------------------------------------------------------------------------------------- - HRESULT IIS7MimeMap( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - LPWSTR pwzConfigPath = NULL; - LPWSTR pwzWebName = NULL; - LPWSTR pwzWebRoot = NULL; - LPWSTR pwzData = NULL; - int iAction = -1; - - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - BOOL fFound = FALSE; - - //get web name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebName); - ExitOnFailure(hr, "Failed to read mime map Web name key"); - - //get vdir root name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebRoot); - ExitOnFailure(hr, "Failed to read vdir root name key"); - - //Construct config root - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzWebName); - ExitOnFailure(hr, "failed to format mime map config path web name"); - // - //Do not append trailing '/' for default vDir - // - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzWebRoot, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzConfigPath, L"/", 0); - ExitOnFailure(hr, "failed to copy appext config path delim"); - hr = StrAllocConcat(&pwzConfigPath, pwzWebRoot, 0); - ExitOnFailure(hr, "failed to copy appext config path root name"); - } - - //get admin section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get staticContent section for mimemap"); - - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get staticContent section object"); - } - - // Get mimemap action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read mimemap action"); - - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get staticContent collection for mimemap"); - - while (IIS_MIMEMAP_END != iAction) - { - //Process property action - switch (iAction) - { - case IIS_MIMEMAP : - { - //get extension - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read mimemap extension"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_MIMEMAP, IIS_CONFIG_FILEEXT, pwzData, &pElement, NULL); - ExitOnFailure(hr, "Failed to find mimemap extension"); - fFound = (NULL != pElement); - - if (!fFound) - { - //create new mimeMap element - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_MIMEMAP), &pElement); - ExitOnFailure(hr, "Failed get create MimeMap element"); - } - - //put property - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_FILEEXT, pwzData); - ExitOnFailure(hr, "Failed set mimemap extension property"); - - //get type - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read mimemap type"); - //put property - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_MIMETYPE, pwzData); - ExitOnFailure(hr, "Failed set mimemap type property"); - - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for mimeMap"); - break; - } - } - - if (!fFound) - { - // put mimeMap element at beginning of list - hr = pCollection->AddElement(pElement, -1); - ExitOnFailure(hr, "Failed add mimemap"); - } - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read mimemap action"); - - ReleaseNullObject(pElement); - } - -LExit: - ReleaseStr(pwzConfigPath); - ReleaseStr(pwzWebName); - ReleaseStr(pwzWebRoot); - ReleaseStr(pwzData); - ReleaseObject(pSection); - ReleaseObject(pElement); - ReleaseObject(pCollection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7DirProperties -// ProcessesVdir Properties CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7DirProperties( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - WCHAR wcTime[60]; - LPWSTR pwzConfigPath = NULL; - LPWSTR pwzWebName = NULL; - LPWSTR pwzWebRoot = NULL; - LPWSTR pwzData = NULL; - int iAction = -1; - int iData = 0; - DWORD dwData = 0; - - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - //get web name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebName); - ExitOnFailure(hr, "Failed to read DirProp Web name key"); - - //get vdir root name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebRoot); - ExitOnFailure(hr, "Failed to read DirProp Web name key"); - - //Construct config root - hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzWebName); - ExitOnFailure(hr, "failed to format mime map config path web name"); - // - //Do not append trailing '/' for default vDir - // - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzWebRoot, -1, L"/", -1)) - { - hr = StrAllocConcat(&pwzConfigPath, L"/", 0); - ExitOnFailure(hr, "failed to copy appext config path delim"); - hr = StrAllocConcat(&pwzConfigPath, pwzWebRoot, 0); - ExitOnFailure(hr, "failed to copy appext config path root name"); - } - - // Get DirProps action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read DirProps action"); - - while (IIS_DIRPROP_END != iAction) - { - //Process property action - switch (iAction) - { - case IIS_DIRPROP_ACCESS : - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read DirProps access"); - //iData contains bit flags for - //no translation required - //get admin section at config path location tag - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HANDLERS_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get handlers section for DirProp"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get handlers section object for DirProps"); - } - dwData = iData; - hr = Iis7PutPropertyInteger( pSection, L"accessPolicy", dwData); - ExitOnFailure(hr, "Failed set accessPolicy for DirProps"); - ReleaseNullObject(pSection); - break; - } - case IIS_DIRPROP_USER : - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read DirProps user"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/anonymousAuthentication"), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get AnonymousAuthentication section for DirProp"); - hr = Iis7PutPropertyString( pSection, IIS_CONFIG_USERNAME, pwzData); - ExitOnFailure(hr, "Failed set accessPolicy for DirProps"); - ReleaseNullObject(pSection); - break; - } - case IIS_DIRPROP_PWD : - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read DirProps pwd"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/anonymousAuthentication"), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get AnonymousAuthentication section for DirProp"); - hr = Iis7PutPropertyString( pSection, IIS_CONFIG_PASSWORD, pwzData); - ExitOnFailure(hr, "Failed set accessPolicy for DirProps"); - ReleaseNullObject(pSection); - break; - } - case IIS_DIRPROP_DEFDOCS : - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read DirProps def doc"); - hr = SetDirPropDefDoc(pAdminMgr, pwzConfigPath, pwzData); - ExitOnFailure(hr, "Failed to set DirProps Default Documents"); - break; - } - case IIS_DIRPROP_AUTH : - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read DirProps auth"); - //iData contains bit flags for /security/authentication/<...> - // Anonymous = 1 - // Basic = 2 - // Windows = 4 - // Digest =16 - // Passport =64 *not supported - //translation required from bit map to section - // E.G security/authentication/windowsAuthentication [property enabled true|false] - dwData= iData; - hr = SetDirPropAuthentications(pAdminMgr, pwzConfigPath, dwData); - ExitOnFailure(hr, "Failed set Authentication for DirProps"); - break; - } - case IIS_DIRPROP_SSLFLAGS : - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read DirProps sslFlags"); - //iData contains bit flags for /security/access sslFlags - //no translation required - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/access"), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get security/access section for DirProp"); - dwData = iData; - hr = Iis7PutPropertyInteger( pSection, L"sslFlags", dwData); - ExitOnFailure(hr, "Failed set security/access for DirProps"); - ReleaseNullObject(pSection); - break; - } - case IIS_DIRPROP_AUTHPROVID : - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read DirProps auth provider"); - hr = SetDirPropAuthProvider(pAdminMgr, pwzConfigPath, pwzData); - ExitOnFailure(hr, "Failed to set DirProps auth provider"); - break; - } - case IIS_DIRPROP_ASPERROR: - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read DirProps aspDetailedError"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ASP_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get asp section for DirProp"); - hr = Iis7PutPropertyBool(pSection, IIS_CONFIG_SCRIPTERROR, iData); - ExitOnFailure(hr, "Failed to set DirProps aspDetailedError"); - ReleaseNullObject(pSection); - break; - } - case IIS_DIRPROP_HTTPEXPIRES: - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read DirProps httpExpires provider"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get staticContent section for DirProp"); - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_CLIENTCACHE), &pElement); - ExitOnFailure(hr, "Failed to get clientCache element"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_HTTPEXPIRES, pwzData); - ExitOnFailure(hr, "Failed to set clientCache httpExpires value"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CACHECONTROLMODE, IIS_CONFIG_USEEXPIRES); - ExitOnFailure(hr, "Failed to set clientCache cacheControlMode value"); - ReleaseNullObject(pSection); - ReleaseNullObject(pElement); - break; - } - case IIS_DIRPROP_MAXAGE: - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read DirProps httpExpires provider"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get staticContent section for DirProp"); - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_CLIENTCACHE), &pElement); - ExitOnFailure(hr, "Failed to get clientCache element"); - *wcTime = '\0'; - ConvSecToDHMS(iData, wcTime, countof(wcTime)); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_MAXAGE, wcTime); - ExitOnFailure(hr, "Failed to set clientCache maxAge value"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CACHECONTROLMODE, IIS_CONFIG_USEMAXAGE); - ExitOnFailure(hr, "Failed to set clientCache cacheControlMode value"); - ReleaseNullObject(pSection); - ReleaseNullObject(pElement); - break; - } - case IIS_DIRPROP_CACHECUST: - { - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read DirProps cacheControlCustom"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get staticContent section for DirProp"); - hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_CLIENTCACHE), &pElement); - ExitOnFailure(hr, "Failed to get clientCache element"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CACHECUST, pwzData); - ExitOnFailure(hr, "Failed to set clientCache cacheControlCustom value"); - ReleaseNullObject(pSection); - ReleaseNullObject(pElement); - break; - } - case IIS_DIRPROP_NOCUSTERROR: - { - //no value, if have ID tag write clear to system.webServer/httpErrors - //error collection - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPERRORS_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get httperrors section for DirProp"); - hr = pSection->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get error collection for DirProp"); - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pElement); - ExitOnFailure(hr, "Failed to create clear element for error collection for DirProp"); - hr = pCollection->AddElement(pElement); - ExitOnFailure(hr, "Failed to add lear element for error collection for DirProp"); - ReleaseNullObject(pSection); - ReleaseNullObject(pElement); - break; - } - case IIS_DIRPROP_LOGVISITS: - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read DirProps logVisits"); - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPLOGGING_SECTION), pwzConfigPath, &pSection); - ExitOnFailure(hr, "Failed get httpLogging section for DirProp"); - hr = Iis7PutPropertyBool(pSection, IIS_CONFIG_DONTLOG, iData); - ExitOnFailure(hr, "Failed to set DirProps aspDetailedError"); - ReleaseNullObject(pSection); - break; - } - default: - { - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for WebDirProperties"); - break; - } - } - - // Get AppExt action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read DirProps Property action"); - } -LExit: - ReleaseStr(pwzConfigPath); - ReleaseStr(pwzWebName); - ReleaseStr(pwzWebRoot); - ReleaseStr(pwzData); - ReleaseObject(pSection); - ReleaseObject(pElement); - ReleaseObject(pCollection); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// IIS7SslBinding -// ProcessesVdir Properties CA Data -// -// -//------------------------------------------------------------------------------------------------- -HRESULT IIS7SslBinding( - __inout LPWSTR *ppwzCustomActionData, - __in IAppHostWritableAdminManager *pAdminMgr - ) -{ - HRESULT hr = S_OK; - int iAction = -1; - BOOL fSiteFound = FALSE; - - LPWSTR pwzSiteName = NULL; - LPWSTR pwzStoreName = NULL; - LPWSTR pwzEncodedCertificateHash = NULL; - - IAppHostElement *pSiteElem = NULL; - - // Get Application action - hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read binding action"); - - //get site key name - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); - ExitOnFailure(hr, "Failed to read binding site name key"); - - //get binding protocol - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzStoreName); - ExitOnFailure(hr, "Failed to read binding protocol"); - - //get binding info - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzEncodedCertificateHash); - ExitOnFailure(hr, "Failed to read binding info"); - - //Get site if it exists - hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); - ExitOnFailure(hr, "Failed to read sites from config"); - - if (IIS_CREATE == iAction) - { - if (fSiteFound) - { - //add SSL cert to binding - hr = CreateSslBinding(pSiteElem, pwzStoreName, pwzEncodedCertificateHash); - ExitOnFailure(hr, "Failed to create site binding"); - } - else - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Site not found for create binding"); - } - } - else if (IIS_DELETE == iAction) - { - if (fSiteFound) - { - //delete binding - hr = DeleteSslBinding(pSiteElem, pwzStoreName, pwzEncodedCertificateHash); - ExitOnFailure(hr, "Failed to delete binding"); - } - } - - LExit: - ReleaseStr(pwzSiteName); - ReleaseStr(pwzStoreName); - ReleaseStr(pwzEncodedCertificateHash); - ReleaseObject(pSiteElem); - - return hr; -} - -//------------------------------------------------------------------------------------------------- -// Helper Functions -// -// -// -//------------------------------------------------------------------------------------------------- - -static HRESULT GetNextAvailableSiteId( - IAppHostElementCollection *pCollection, - DWORD *plSiteId - ) -{ - HRESULT hr = S_OK; - IAppHostElement *pElement = NULL; - IAppHostProperty *pProperty = NULL; - - DWORD cSites; - DWORD plNextAvailSite = 0; - VARIANT vPropValue; - VARIANT vtIndex; - - VariantInit(&vPropValue); - VariantInit(&vtIndex); - - *plSiteId = 0; - - hr = pCollection->get_Count(&cSites); - ExitOnFailure(hr, "Failed get sites collection count"); - - vtIndex.vt = VT_UI4; - for (DWORD i = 0; i < cSites; ++i) - { - vtIndex.ulVal = i; - hr = pCollection->get_Item(vtIndex , &pElement); - ExitOnFailure(hr, "Failed get sites collection item"); - - hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_ID), &pProperty); - ExitOnFailure(hr, "Failed get site property"); - - hr = pProperty->get_Value(&vPropValue); - ExitOnFailure(hr, "Failed get site property value"); - - *plSiteId = vPropValue.lVal; - if (*plSiteId > plNextAvailSite) - { - plNextAvailSite = *plSiteId; - } - ReleaseNullObject(pElement); - ReleaseNullObject(pProperty); - } - *plSiteId = ++plNextAvailSite; - -LExit: - ReleaseVariant(vPropValue); - ReleaseVariant(vtIndex); - - ReleaseObject(pElement); - ReleaseObject(pProperty); - - return hr; -} - -static HRESULT GetSiteElement( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swSiteName, - IAppHostElement **ppSiteElement, - BOOL* fFound - ) -{ - HRESULT hr = S_OK; - IAppHostElement *pSites = NULL; - IAppHostElementCollection *pCollection = NULL; - - *fFound = FALSE; - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_SITES_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSites); - ExitOnFailure(hr, "Failed get sites section"); - ExitOnNull(pSites, hr, ERROR_FILE_NOT_FOUND, "Failed get sites section object"); - - hr = pSites->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get sites collection"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_NAME, swSiteName, ppSiteElement, NULL); - ExitOnFailure(hr, "Failed to find site %ls", swSiteName); - - *fFound = ppSiteElement != NULL && *ppSiteElement != NULL; - -LExit: - ReleaseObject(pSites); - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT GetApplicationElement( IAppHostElement *pSiteElement, - LPCWSTR swAppPath, - IAppHostElement **ppAppElement, - BOOL* fFound) -{ - HRESULT hr = S_OK; - IAppHostElementCollection *pCollection = NULL; - - *fFound = FALSE; - - hr = pSiteElement->get_Collection( &pCollection); - ExitOnFailure(hr, "Failed get site app collection"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_APPLICATION, IIS_CONFIG_PATH, swAppPath, ppAppElement, NULL); - ExitOnFailure(hr, "Failed to find app %ls", swAppPath); - - *fFound = ppAppElement != NULL && *ppAppElement != NULL; - -LExit: - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT GetApplicationElementForVDir( IAppHostElement *pSiteElement, - LPCWSTR pwzVDirPath, - IAppHostElement **ppAppElement, - LPCWSTR *ppwzVDirSubPath, - BOOL* fFound) -{ - HRESULT hr = S_OK; - IAppHostElementCollection *pCollection = NULL; - LPWSTR pwzAppPath = NULL; - *fFound = FALSE; - *ppwzVDirSubPath = NULL; - - hr = pSiteElement->get_Collection( &pCollection); - ExitOnFailure(hr, "Failed get site app collection"); - - // Start with full path - int iLastPathIndex = lstrlenW(pwzVDirPath) - 1; - hr = StrAllocString(&pwzAppPath, pwzVDirPath, 0); - ExitOnFailure(hr, "Failed allocate application path"); - - for (int iSubPathIndex = iLastPathIndex; (iSubPathIndex >= 0) && (!*fFound); --iSubPathIndex) - { - // We are looking at the full path, or at a directory boundary, or at the root - if (iSubPathIndex == iLastPathIndex || - '/' == pwzAppPath[iSubPathIndex] || - 0 == iSubPathIndex) - { - // break the path if needed - if ('/' == pwzAppPath[iSubPathIndex]) - { - pwzAppPath[iSubPathIndex] = '\0'; - } - - // Special case for root path, need an empty app path - LPCWSTR pwzAppSearchPath = 0 == iSubPathIndex ? L"/" : pwzAppPath; - - // Try to find an app with the specified path - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_APPLICATION, IIS_CONFIG_PATH, pwzAppSearchPath, ppAppElement, NULL); - ExitOnFailure(hr, "Failed to search for app %ls", pwzAppSearchPath); - *fFound = ppAppElement != NULL && *ppAppElement != NULL; - - if (*fFound) - { - // set return value for sub path - // special case for app path == vdir path, need an empty subpath. - *ppwzVDirSubPath = (iSubPathIndex == iLastPathIndex) ? L"/" : pwzVDirPath + iSubPathIndex; - } - } - } - -LExit: - ReleaseObject(pCollection); - ReleaseStr(pwzAppPath); - - return hr; -} - -static HRESULT CreateSite( - __in IAppHostElementCollection *pCollection, - __in LPCWSTR swSiteName, - __out IAppHostElement **pSiteElement - ) -{ - HRESULT hr = S_OK; - IAppHostElement *pNewElement = NULL; - - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_SITE), &pNewElement); - ExitOnFailure(hr, "Failed create site element"); - - hr = Iis7PutPropertyString(pNewElement, IIS_CONFIG_NAME, swSiteName); - ExitOnFailure(hr, "Failed set site name property"); - - DWORD lSiteId = 0; - hr = GetNextAvailableSiteId(pCollection, &lSiteId); - ExitOnFailure(hr, "Failed get next site id"); - - Iis7PutPropertyInteger(pNewElement, IIS_CONFIG_ID, lSiteId); - ExitOnFailure(hr, "Failed set site id property"); - - hr = pCollection->AddElement(pNewElement); - ExitOnFailure(hr, "Failed add site element"); - - *pSiteElement = pNewElement; - pNewElement = NULL; - -LExit: - ReleaseObject(pNewElement); - - return hr; -} - -static HRESULT CreateApplication( - IAppHostElement *pSiteElement, - LPCWSTR swAppPath, - IAppHostElement **pAppElement - ) -{ - HRESULT hr = S_OK; - IAppHostElement *pNewElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - hr = pSiteElement->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get application collection"); - - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_APPLICATION), &pNewElement); - ExitOnFailure(hr, "Failed get application element"); - - hr = Iis7PutPropertyString(pNewElement, IIS_CONFIG_PATH, swAppPath); - ExitOnFailure(hr, "Failed set application path property"); - - hr = pCollection->AddElement(pNewElement); - ExitOnFailure(hr, "Failed add application to collection"); - - *pAppElement = pNewElement; - pNewElement = NULL; - -LExit: - ReleaseObject(pCollection); - ReleaseObject(pNewElement); - - return hr; -} - -static HRESULT DeleteApplication( - IAppHostElement *pSiteElement, - LPCWSTR swAppPath - ) -{ - HRESULT hr = S_OK; - IAppHostElementCollection *pCollection = NULL; - - hr = pSiteElement->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get application collection"); - - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_APPLICATION, IIS_CONFIG_PATH, swAppPath); - ExitOnFailure(hr, "Failed to delete website"); - -LExit: - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT SetAppPool( - IAppHostElement *pAppElement, - LPCWSTR pwzAppPool - ) -{ - HRESULT hr = S_OK; - - if (*pwzAppPool != 0) - { - hr = Iis7PutPropertyString(pAppElement, IIS_CONFIG_APPPOOL, pwzAppPool); - ExitOnFailure(hr, "Failed set application appPool property"); - } -LExit: - return hr; -} - -static HRESULT CreateVdir( - IAppHostElement *pAppElement, - LPCWSTR pwzVDirPath, - LPCWSTR pwzVDirPhyDir - ) -{ - HRESULT hr = S_OK; - IAppHostElement *pElement = NULL; - IAppHostElementCollection *pCollection = NULL; - BOOL fFound; - - hr = pAppElement->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get application VDir collection"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_VDIR, IIS_CONFIG_PATH, pwzVDirPath, &pElement, NULL); - ExitOnFailure(hr, "Failed while finding virtualDir"); - fFound = (NULL != pElement); - - if (!fFound) - { - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_VDIR), &pElement); - ExitOnFailure(hr, "Failed create application VDir collection"); - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzVDirPath); - ExitOnFailure(hr, "Failed set VDir path property"); - } - - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PHYSPATH, pwzVDirPhyDir); - ExitOnFailure(hr, "Failed set VDir phys path property"); - - if (!fFound) - { - hr = pCollection->AddElement(pElement); - ExitOnFailure(hr, "Failed add application VDir element"); - } - -LExit: - ReleaseObject(pCollection); - ReleaseObject(pElement); - - return hr; -} - -static HRESULT DeleteVdir( - IAppHostElement *pAppElement, - LPCWSTR pwzVDirPath - ) -{ - HRESULT hr = S_OK; - IAppHostElementCollection *pCollection = NULL; - - hr = pAppElement->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get application VDir collection"); - - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_VDIR, IIS_CONFIG_PATH, pwzVDirPath); - ExitOnFailure(hr, "Failed to delete vdir"); - -LExit: - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT CreateBinding( - IAppHostElement *pSiteElem, - LPCWSTR pwzProtocol, - LPCWSTR pwzInfo - ) -{ - HRESULT hr = S_OK; - IAppHostChildElementCollection *pChildElems = NULL; - IAppHostElement *pBindings = NULL; - IAppHostElement *pBindingElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - VARIANT vtProp; - - VariantInit(&vtProp); - - hr = pSiteElem->get_ChildElements(&pChildElems); - ExitOnFailure(hr, "Failed get site child elements collection"); - - vtProp.vt = VT_BSTR; - vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_BINDINGS); - hr = pChildElems->get_Item(vtProp, &pBindings); - ExitOnFailure(hr, "Failed get bindings element"); - ReleaseVariant(vtProp); - - hr = pBindings->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get bindings collection"); - - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_BINDING), &pBindingElement); - ExitOnFailure(hr, "Failed get binding element"); - - hr = Iis7PutPropertyString(pBindingElement, IIS_CONFIG_PROTOCOL, pwzProtocol); - ExitOnFailure(hr, "Failed set binding protocol property"); - - hr = Iis7PutPropertyString(pBindingElement, IIS_CONFIG_BINDINGINFO, pwzInfo); - ExitOnFailure(hr, "Failed set binding information property"); - - hr = pCollection->AddElement(pBindingElement); - if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) - { - //Eat this error. Binding is there and nothing to repair since - //identity == protocol + info so all is OK - hr = S_OK; - } - else - { - ExitOnFailure(hr, "Failed add binding to site"); - } - -LExit: - ReleaseVariant(vtProp); - - ReleaseObject(pCollection); - ReleaseObject(pChildElems); - ReleaseObject(pBindingElement); - ReleaseObject(pBindings); - - return hr; -} -static HRESULT CreateWebLog( - IAppHostElement *pSiteElem, - LPCWSTR pwzFormat - ) -{ - HRESULT hr = S_OK; - IAppHostChildElementCollection *pChildElems = NULL; - IAppHostElement *pLogFile = NULL; - - VARIANT vtProp; - - VariantInit(&vtProp); - - hr = pSiteElem->get_ChildElements(&pChildElems); - ExitOnFailure(hr, "Failed get site child elements collection"); - - vtProp.vt = VT_BSTR; - vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_WEBLOG); - hr = pChildElems->get_Item(vtProp, &pLogFile); - ExitOnFailure(hr, "Failed get logfile element"); - ReleaseVariant(vtProp); - - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzFormat, -1, L"none", -1)) - { - hr = Iis7PutPropertyString(pLogFile, IIS_CONFIG_LOGFORMAT, pwzFormat); - ExitOnFailure(hr, "Failed set logfile format property"); - hr = Iis7PutPropertyString(pLogFile, IIS_CONFIG_ENABLED, IIS_CONFIG_TRUE); - ExitOnFailure(hr, "Failed set logfile enabled property"); - } - else - { - hr = Iis7PutPropertyString(pLogFile, IIS_CONFIG_ENABLED, IIS_CONFIG_FALSE); - ExitOnFailure(hr, "Failed set logfile enabled property"); - } - -LExit: - ReleaseVariant(vtProp); - - ReleaseObject(pLogFile); - ReleaseObject(pChildElems); - - return hr; -} - -static HRESULT DeleteBinding( - IAppHostElement* /*pSiteElem*/, - LPCWSTR /*pwzProtocol*/, - LPCWSTR /*pwzInfo*/ - ) -{ - HRESULT hr = S_OK; - // - //this isn't supported right now, we should support this for the SiteSearch scenario - return hr; -} - -struct SCA_SSLBINDINGINFO -{ - IIS7_APPHOSTELEMENTCOMPARISON comparison; - LPCWSTR pwzStoreName; - LPCWSTR pwzEncodedCertificateHash; - HRESULT hr; -}; - -static BOOL AddSslCertificateToBindingCallback(IAppHostElement *pBindingElement, LPVOID pContext) -{ - HRESULT hr = S_OK; - VARIANT vtProp; - VariantInit(&vtProp); - SCA_SSLBINDINGINFO* pBindingInfo = (SCA_SSLBINDINGINFO*)pContext; - IAppHostMethodCollection *pAppHostMethodCollection = NULL; - IAppHostMethod *pAddSslMethod = NULL; - IAppHostMethodInstance *pAddSslMethodInstance = NULL; - IAppHostElement *pAddSslInput = NULL; - int iWsaError = 0; - WSADATA wsaData = {}; - BOOL fWsaInitialized = FALSE; - - // IIS's AddSslCertificate doesn't initialize WinSock on 2008 before using it to parse the IP - // Initialize before calling to workaround the failure. - iWsaError = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (0 != iWsaError) - { - ExitOnWin32Error(iWsaError, hr, "Failed to initialize WinSock"); - } - - fWsaInitialized = TRUE; - - if (Iis7IsMatchingAppHostElement(pBindingElement, &pBindingInfo->comparison)) - { - hr = pBindingElement->get_Methods(&pAppHostMethodCollection); - ExitOnFailure(hr, "failed to get binding method collection"); - - hr = Iis7FindAppHostMethod(pAppHostMethodCollection, L"AddSslCertificate", &pAddSslMethod, NULL); - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "The AddSslCertificate method is not supported by the binding element, SSL certificate will not be associated with the website"); - ExitFunction(); - } - - pAddSslMethod->CreateInstance(&pAddSslMethodInstance); - ExitOnFailure(hr, "failed to create an instance of AddSslCertificate method"); - - pAddSslMethodInstance->get_Input(&pAddSslInput); - ExitOnFailure(hr, "failed to get input element of AddSslCertificate method"); - - Iis7PutPropertyString(pAddSslInput, IIS_CONFIG_CERTIFICATESTORENAME, pBindingInfo->pwzStoreName); - ExitOnFailure(hr, "failed to set certificateStoreName input parameter of AddSslCertificate method"); - - Iis7PutPropertyString(pAddSslInput, IIS_CONFIG_CERTIFICATEHASH, pBindingInfo->pwzEncodedCertificateHash); - ExitOnFailure(hr, "failed to set certificateHash input parameter of AddSslCertificate method"); - - hr = pAddSslMethodInstance->Execute(); - ExitOnFailure(hr, "failed to execute AddSslCertificate method"); - } -LExit: - pBindingInfo->hr = hr; - ReleaseObject(pAppHostMethodCollection); - ReleaseObject(pAddSslMethod); - ReleaseObject(pAddSslMethodInstance); - ReleaseObject(pAddSslInput); - if (fWsaInitialized) - { - WSACleanup(); - } - - return FAILED(hr); -} - -static HRESULT CreateSslBinding( IAppHostElement *pSiteElem, LPCWSTR pwzStoreName, LPCWSTR pwzEncodedCertificateHash) -{ - HRESULT hr = S_OK; - IAppHostChildElementCollection *pChildElems = NULL; - IAppHostElement *pBindingsElement = NULL; - IAppHostElementCollection *pBindingsCollection = NULL; - SCA_SSLBINDINGINFO bindingInfo = {}; - VARIANT vtProp; - VariantInit(&vtProp); - - hr = pSiteElem->get_ChildElements(&pChildElems); - ExitOnFailure(hr, "Failed get site child elements collection"); - - vtProp.vt = VT_BSTR; - vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_BINDINGS); - hr = pChildElems->get_Item(vtProp, &pBindingsElement); - ExitOnFailure(hr, "Failed get bindings element"); - ReleaseVariant(vtProp); - - hr = pBindingsElement->get_Collection(&pBindingsCollection); - ExitOnFailure(hr, "Failed get bindings collection"); - - bindingInfo.comparison.sczElementName = IIS_CONFIG_BINDING; - bindingInfo.comparison.sczAttributeName = IIS_CONFIG_PROTOCOL; - vtProp.vt = VT_BSTR; - vtProp.bstrVal = ::SysAllocString(L"https"); - bindingInfo.comparison.pvAttributeValue = &vtProp; - bindingInfo.pwzStoreName = pwzStoreName; - bindingInfo.pwzEncodedCertificateHash = pwzEncodedCertificateHash; - - // Our current IISWebSiteCertificates schema does not allow specification of the website binding - // to associate the certificate with. For now just associate it with all secure bindings. - - hr = Iis7EnumAppHostElements(pBindingsCollection, AddSslCertificateToBindingCallback, &bindingInfo, NULL, NULL); - ExitOnFailure(hr, "Failed to enumerate bindings collection"); - hr = bindingInfo.hr; - ExitOnFailure(hr, "Failed to add ssl binding"); - -LExit: - ReleaseVariant(vtProp); - - ReleaseObject(pChildElems); - ReleaseObject(pBindingsElement); - ReleaseObject(pBindingsCollection); - - return hr; -} - -static HRESULT DeleteSslBinding( - IAppHostElement * /*pSiteElem*/, - LPCWSTR /*pwzStoreName*/, - LPCWSTR /*pwzEncodedCertificateHash*/ - ) -{ - HRESULT hr = S_OK; - // - //this isn't supported right now, we should support this for the SiteSearch scenario - return hr; -} - -static HRESULT DeleteAppPool( IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swAppPoolName) -{ - HRESULT hr = S_OK; - IAppHostElement *pAppPools = NULL; - IAppHostElementCollection *pCollection = NULL; - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_APPPOOL_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pAppPools); - ExitOnFailure(hr, "Failed get AppPools section"); - ExitOnNull(pAppPools, hr, E_UNEXPECTED, "Failed get appPools section object"); - - hr = pAppPools->get_Collection( &pCollection); - ExitOnFailure(hr, "Failed get AppPools collection"); - - hr = DeleteCollectionElement(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, swAppPoolName); - ExitOnFailure(hr, "Failed to delete app pool %ls", swAppPoolName); - -LExit: - ReleaseObject(pAppPools); - ReleaseObject(pCollection); - - return hr; -} - -static HRESULT CreateAppPool( - __inout LPWSTR *ppwzCustomActionData, - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swAppPoolName - ) -{ - HRESULT hr = S_OK; - IAppHostElement *pAppPools = NULL; - IAppHostElement *pAppPoolElement = NULL; - IAppHostElement *pElement = NULL; - IAppHostElement *pElement2 = NULL; - IAppHostElement *pElement3 = NULL; - IAppHostElementCollection *pCollection = NULL; - IAppHostElementCollection *pCollection2 = NULL; - int iAction = -1; - int iData = 0; - LPWSTR pwzData = NULL; - WCHAR wcData[512]; - WCHAR wcTime[60]; - BOOL fFound = FALSE; - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_APPPOOL_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pAppPools); - ExitOnFailure(hr, "Failed get AppPools section"); - ExitOnNull(pAppPools, hr, ERROR_FILE_NOT_FOUND, "Failed get AppPools section object"); - - hr = pAppPools->get_Collection( &pCollection); - ExitOnFailure(hr, "Failed get AppPools collection"); - - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, swAppPoolName, &pAppPoolElement, NULL); - ExitOnFailure(hr, "Failed find AppPool element"); - fFound = (NULL != pAppPoolElement); - - if (!fFound) - { - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pAppPoolElement); - ExitOnFailure(hr, "Failed create AppPool element"); - } - - hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_NAME, swAppPoolName); - ExitOnFailure(hr, "Failed set AppPool name property"); - - //For WiX II6 /ABO compat we will default managedPipelineMode="Classic" - hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_PIPELINEMODE, L"Classic"); - ExitOnFailure(hr, "Failed set AppPool managedPipelineMode property"); - //For WiX II6 /ABO compat we will be hardcoding autostart="true" - hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_APPPOOL_AUTO, L"true"); - ExitOnFailure(hr, "Failed set AppPool autoStart property"); - - if (!fFound) - { - hr = pCollection->AddElement(pAppPoolElement); - ExitOnFailure(hr, "Failed to add appPool element"); - } - - // Get AppPool Property action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read AppPool Property action"); - while (IIS_APPPOOL_END != iAction) - { - //Process property action - switch (iAction) - { - case IIS_APPPOOL_RECYCLE_MIN : - { - // /recycling / periodicRestart | time - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool recycle min"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); - ExitOnFailure(hr, "Failed to get AppPool recycling element"); - hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); - ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); - *wcTime = '\0'; - ConvSecToHMS(iData * 60, wcTime, countof(wcTime)); - hr = Iis7PutPropertyString(pElement2, IIS_CONFIG_TIME, wcTime); - ExitOnFailure(hr, "Failed to set AppPool periodicRestart time value"); - ReleaseNullObject(pElement); - ReleaseNullObject(pElement2); - break; - } - case IIS_APPPOOL_RECYCLE_REQ : - { - // /recycling / periodicRestart | requests - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool recycle req"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); - ExitOnFailure(hr, "Failed to get AppPool recycling element"); - hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); - ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); - hr = Iis7PutPropertyInteger(pElement2, IIS_CONFIG_REQUESTS, iData); - ExitOnFailure(hr, "Failed to set AppPool periodicRestart time value"); - ReleaseNullObject(pElement); - ReleaseNullObject(pElement2); - break; - } - case IIS_APPPOOL_RECYCLE_TIMES : - { - // /recycling / periodicRestart | schedule - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read AppPool recycle times"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); - ExitOnFailure(hr, "Failed to get AppPool recycling element"); - hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); - ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); - hr = pElement2->GetElementByName(ScopeBSTR(IIS_CONFIG_SCHEDULE), &pElement3); - ExitOnFailure(hr, "Failed to get AppPool schedule element"); - hr = pElement3->get_Collection(&pCollection2); - ExitOnFailure(hr, "Failed to get AppPool schedule collection"); - - WCHAR wcDelim[] = L","; - const WCHAR *wszToken = NULL; - WCHAR *wszNextToken = NULL; - wszToken = wcstok_s( pwzData, wcDelim, &wszNextToken); - - while (wszToken) - { - *wcData = '\0'; - hr = ::StringCchCopyW(wcData, countof(wcData), wszToken); - ExitOnFailure(hr, "failed to copy AppPool schedule"); - hr = ::StringCchCatW(wcData, countof(wcData), L":00"); - ExitOnFailure(hr, "failed to append AppPool schedule"); - - hr = pCollection2->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement3); - ExitOnFailure(hr, "Failed to create AppPool schedule element"); - - hr = Iis7PutPropertyString(pElement3, IIS_CONFIG_VALUE, wcData); - ExitOnFailure(hr, "Failed to set AppPool schedule value"); - - hr = pCollection2->AddElement(pElement3); - if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) - { - //Eat this error, recycle time already exists NBD - hr = S_OK; - } - ExitOnFailure(hr, "Failed to add win auth providers element"); - ReleaseNullObject(pElement3); - wszToken = wcstok_s( NULL, wcDelim, &wszNextToken); - } - ReleaseNullObject(pElement); - ReleaseNullObject(pElement2); - ReleaseNullObject(pElement3); - ReleaseNullObject(pCollection2); - break; - } - case IIS_APPPOOL_RECYCLE_VIRMEM : - { - // /recycling / periodicRestart | memory - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool recycle vir memory"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); - ExitOnFailure(hr, "Failed to get AppPool recycling element"); - hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); - ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); - hr = Iis7PutPropertyInteger(pElement2, IIS_CONFIG_MEMORY, iData); - ExitOnFailure(hr, "Failed to set AppPool periodicRestart memory"); - ReleaseNullObject(pElement); - ReleaseNullObject(pElement2); - break; - } - case IIS_APPPOOL_RECYCLE_PRIVMEM : - { - // /recycling / periodicRestart | privateMemory - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool recycle priv mem"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); - ExitOnFailure(hr, "Failed to get AppPool recycling element"); - hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); - ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); - hr = Iis7PutPropertyInteger(pElement2, IIS_CONFIG_PRIVMEMORY, iData); - ExitOnFailure(hr, "Failed to set AppPool periodicRestart private memory"); - ReleaseNullObject(pElement); - ReleaseNullObject(pElement2); - break; - } - case IIS_APPPOOL_RECYCLE_IDLTIMEOUT : - { - // /processModel | idleTimeout - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool idle timeout"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); - ExitOnFailure(hr, "Failed to get AppPool processModel element"); - *wcTime = '\0'; - ConvSecToHMS(iData * 60, wcTime, countof(wcTime)); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDLETIMEOUT, wcTime); - ExitOnFailure(hr, "Failed to set AppPool processModel idle timeout value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_RECYCLE_QUEUELIMIT : - { - // /applicationPools | queueLength - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool recycle queue limit"); - hr = Iis7PutPropertyInteger(pAppPoolElement, IIS_CONFIG_QUEUELENGTH, iData); - ExitOnFailure(hr, "Failed to set AppPool recycle queue limit value"); - break; - } - case IIS_APPPOOL_MAXPROCESS : - { - // /processModel | maxProcesses - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool max processes"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); - ExitOnFailure(hr, "Failed to get AppPool processModel element"); - hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_MAXWRKPROCESSES, iData); - ExitOnFailure(hr, "Failed to set AppPool processModel maxProcesses value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_IDENTITY : - { - //"LocalSystem" 0 - //"LocalService" 1 - //"NetworkService" 2 - //"SpecificUser" 3 - //"ApplicationPoolIdentity" 4 - // /processModel | identityType - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read AppPool identity"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); - ExitOnFailure(hr, "Failed to get AppPool processModel element"); - if (iData == 0) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_LOCALSYSTEM); - } - else if (iData == 1) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_LOCALSERVICE); - } - else if (iData == 2) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_NETWORKSERVICE); - } - else if (iData == 3) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_SPECIFICUSER); - } - else if (iData == 4) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_APPLICATIONPOOLIDENTITY); - } - ExitOnFailure(hr, "Failed to set AppPool processModel identityType value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_USER : - { - // /processModel | userName - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read AppPool user"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); - ExitOnFailure(hr, "Failed to get AppPool processModel element"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_USERNAME, pwzData); - ExitOnFailure(hr, "Failed to set AppPool processModel username value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_PWD : - { - // /processModel | password - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read AppPool pwd"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); - ExitOnFailure(hr, "Failed to get AppPool processModel element"); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PASSWORD, pwzData); - ExitOnFailure(hr, "Failed to set AppPool processModel password value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_RECYCLE_CPU_PCT: - { - // /cpu | limit - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read cpu pct"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_CPU), &pElement); - ExitOnFailure(hr, "Failed to get AppPool cpu element"); - // limit is maximum percentage of CPU time (in 1/1000ths of one percent) - hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_LIMIT, iData * 1000); - ExitOnFailure(hr, "Failed to set AppPool cpu limit"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_RECYCLE_CPU_REFRESH: - { - // /cpu | resetInterval - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read cpu refresh pwd"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_CPU), &pElement); - ExitOnFailure(hr, "Failed to get AppPool cpu element"); - *wcTime = '\0'; - ConvSecToHMS(iData * 60, wcTime, countof(wcTime)); - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_RESETINTERVAL, wcTime); - ExitOnFailure(hr, "Failed to set AppPool cpu resetInterval value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_RECYCLE_CPU_ACTION: - { - // /cpu | action - //"NoAction" 0 - //"KillW3wp" 1 - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read cpu action"); - hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_CPU), &pElement); - ExitOnFailure(hr, "Failed to get AppPool cpu element"); - if (iData) - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CPU_ACTION, IIS_CONFIG_KILLW3WP); - } - else - { - hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CPU_ACTION, IIS_CONFIG_NOACTION); - } - ExitOnFailure(hr, "Failed to set AppPool cpu action value"); - ReleaseNullObject(pElement); - break; - } - case IIS_APPPOOL_32BIT: - { - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); - ExitOnFailure(hr, "Failed to read enable32BitAppOnWin64 value"); - // enable32BitAppOnWin64 - hr = Iis7PutPropertyBool(pAppPoolElement, IIS_CONFIG_ENABLE32, iData ? TRUE : FALSE); - ExitOnFailure(hr, "Failed to set AppPool enable32BitAppOnWin64 value"); - break; - } - case IIS_APPPOOL_MANAGED_PIPELINE_MODE: - { - // managedPipelineMode - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read AppPool managedRuntimeVersion"); - hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_PIPELINEMODE, pwzData); - ExitOnFailure(hr, "Failed set AppPool managedPipelineMode property"); - break; - } - case IIS_APPPOOL_MANAGED_RUNTIME_VERSION: - { - // managedRuntimeVersion - hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); - ExitOnFailure(hr, "Failed to read AppPool managedRuntimeVersion"); - hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_MANAGEDRUNTIMEVERSION, pwzData); - ExitOnFailure(hr, "Failed set AppPool managedRuntimeVersion property"); - break; - } - - default: - ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for AppPool"); - break; - - } - // Get AppPool property action - hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); - ExitOnFailure(hr, "Failed to read AppPool Property action"); - } - -LExit: - ReleaseObject(pAppPools); - ReleaseObject(pCollection); - ReleaseObject(pCollection2); - ReleaseObject(pAppPoolElement); - ReleaseObject(pElement); - ReleaseObject(pElement2); - ReleaseObject(pElement3); - - return hr; -} - -static HRESULT SetDirPropAuthentications(IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR wszConfigPath, - DWORD dwData) -{ - HRESULT hr = S_OK; - IAppHostElement *pSection = NULL; - - //dwData contains bit flags for /security/authentication/<...> - // Anonymous = 1 - // Basic = 2 - // Windows = 4 - // Digest =16 - // Passport =64 *not supported - //translation required from bit map to section name - // E.G security/authentication/windowsAuthentication [property enabled true|false] - - // AnonymousAuthentication = 1 - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/anonymousAuthentication"), ScopeBSTR(wszConfigPath), &pSection); - ExitOnFailure(hr, "Failed get AnonymousAuthentication section for DirProp"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get AnonymousAuthentication section object for DirProps"); - } - - hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x1)); - ExitOnFailure(hr, "Failed set AnonymousAuthentication enabled for DirProps"); - ReleaseNullObject(pSection); - - // basicAuthentication = 2 - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/basicAuthentication"), ScopeBSTR(wszConfigPath), &pSection); - ExitOnFailure(hr, "Failed get basicAuthentication section for DirProp"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get basicAuthentication section object for DirProps"); - } - - hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x2)); - ExitOnFailure(hr, "Failed set basicAuthentication enabled for DirProps"); - ReleaseNullObject(pSection); - - // WindowsAuthentication = 4 - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/windowsAuthentication"), ScopeBSTR(wszConfigPath), &pSection); - ExitOnFailure(hr, "Failed get windowsAuthentication section for DirProp"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get windowsAuthentication section object for DirProps"); - } - - hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x4)); - ExitOnFailure(hr, "Failed set windowsAuthentication enabled for DirProps"); - ReleaseNullObject(pSection); - - // digestAuthentication = 16 - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/digestAuthentication"), ScopeBSTR(wszConfigPath), &pSection); - ExitOnFailure(hr, "Failed get digestAuthentication section for DirProp"); - if (!pSection) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed get digestAuthentication section object for DirProps"); - } - - hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x10)); - ExitOnFailure(hr, "Failed set digestAuthentication enabled for DirProps"); - ReleaseNullObject(pSection); - -LExit: - ReleaseObject(pSection); - - return hr; -} - -static HRESULT SetDirPropAuthProvider(IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR wszConfigPath, - __in LPWSTR wszData) -{ - HRESULT hr = S_OK; - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - IAppHostElement *pNewElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - WCHAR wcDelim[] = L","; - const WCHAR *wszToken = NULL; - WCHAR *wszNextToken = NULL; - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/windowsAuthentication"), ScopeBSTR(wszConfigPath), &pSection); - ExitOnFailure(hr, "Failed get windowsAuthentication section for DirProp providers"); - - hr = pSection->GetElementByName(ScopeBSTR(L"providers"), &pElement); - ExitOnFailure(hr, "Failed get win auth providers section"); - - hr = pElement->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get win auth providers collection"); - - hr = pCollection->Clear(); - ExitOnFailure(hr, "Failed to clear win auth providers collection"); - - //Clear out inherited items - add clear - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pNewElement); - ExitOnFailure(hr, "Failed to create win auth providers clear element"); - hr = pCollection->AddElement(pNewElement); - ExitOnFailure(hr, "Failed to add win auth providers clear element"); - ReleaseNullObject(pNewElement); - - wszToken = wcstok_s( wszData, wcDelim, &wszNextToken); - for (int i = 0; (wszToken); ++i) - { - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pNewElement); - ExitOnFailure(hr, "Failed to create win auth providers element"); - - hr = Iis7PutPropertyString( pNewElement, IIS_CONFIG_VALUE, wszToken); - ExitOnFailure(hr, "Failed to set win auth providers value"); - - hr = pCollection->AddElement(pNewElement, i); - ExitOnFailure(hr, "Failed to add win auth providers element"); - ReleaseNullObject(pNewElement); - - wszToken = wcstok_s( NULL, wcDelim, &wszNextToken); - } - -LExit: - ReleaseObject(pSection); - ReleaseObject(pCollection); - ReleaseObject(pElement); - ReleaseObject(pNewElement); - - return hr; -} - -static HRESULT SetDirPropDefDoc( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR wszConfigPath, - __in LPWSTR wszData) -{ - HRESULT hr = S_OK; - IAppHostElement *pSection = NULL; - IAppHostElement *pElement = NULL; - IAppHostElement *pNewElement = NULL; - IAppHostElementCollection *pCollection = NULL; - - WCHAR wcDelim[] = L","; - const WCHAR *wszToken = NULL; - WCHAR *wszNextToken = NULL; - - hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_DEFAULTDOC_SECTION), ScopeBSTR(wszConfigPath), &pSection); - ExitOnFailure(hr, "Failed get defaultDocument section for DirProp"); - - hr = pSection->GetElementByName(ScopeBSTR(L"files"), &pElement); - ExitOnFailure(hr, "Failed get win files section"); - - hr = pElement->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get files collection"); - - hr = pCollection->Clear(); - ExitOnFailure(hr, "Failed clear files collection"); - - //Clear out inherited items - add clear - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pNewElement); - ExitOnFailure(hr, "Failed to create files clear element"); - hr = pCollection->AddElement(pNewElement); - ExitOnFailure(hr, "Failed to add files clear element"); - - wszToken = wcstok_s( wszData, wcDelim, &wszNextToken); - for (int i = 0; (wszToken); ++i) - { - hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pNewElement); - ExitOnFailure(hr, "Failed to create win auth providers element"); - - hr = Iis7PutPropertyString( pNewElement, IIS_CONFIG_VALUE, wszToken); - ExitOnFailure(hr, "Failed to set win auth providers value"); - - hr = pCollection->AddElement(pNewElement, i); - ExitOnFailure(hr, "Failed to add defaultDocument Files element"); - ReleaseNullObject(pNewElement); - - wszToken = wcstok_s( NULL, wcDelim, &wszNextToken); - } - -LExit: - ReleaseObject(pSection); - ReleaseObject(pCollection); - ReleaseObject(pNewElement); - - return hr; -} - -static HRESULT ClearLocationTag( - IAppHostWritableAdminManager *pAdminMgr, - LPCWSTR swLocationPath - ) -{ - HRESULT hr = S_OK; - IAppHostConfigManager *pConfigMgr = NULL; - IAppHostConfigFile *pConfigFile = NULL; - IAppHostConfigLocationCollection *pLocationCollection = NULL; - IAppHostConfigLocation *pLocation = NULL; - - DWORD dwCount = 0; - BSTR bstrLocationPath = NULL; - - hr = pAdminMgr->get_ConfigManager(&pConfigMgr); - ExitOnFailure(hr, "Failed to get IIS ConfigManager interface"); - - hr = pConfigMgr->GetConfigFile(ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pConfigFile); - ExitOnFailure(hr, "Failed to get IIS ConfigFile interface"); - - hr = pConfigFile->get_Locations(&pLocationCollection); - ExitOnFailure(hr, "Failed to get IIS location tag collection"); - - hr = pLocationCollection->get_Count(&dwCount); - ExitOnFailure(hr, "Failed to get IIS location collection count"); - - VARIANT vtIndex; - vtIndex.vt = VT_UI4; - for (DWORD i = 0; i < dwCount; ++i) - { - vtIndex.ulVal = i; - hr = pLocationCollection->get_Item(vtIndex, &pLocation); - ExitOnFailure(hr, "Failed to get IIS location collection count"); - - hr = pLocation->get_Path(&bstrLocationPath); - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, swLocationPath, -1, bstrLocationPath, -1)) - { - hr = pLocationCollection->DeleteLocation(vtIndex); - ExitOnFailure(hr, "Failed to delete IIS location tag %ls",swLocationPath); - break; - } - - ReleaseNullObject(pLocation); - ::SysFreeString(bstrLocationPath); - bstrLocationPath = NULL; - } -LExit: - ReleaseObject(pConfigMgr); - ReleaseObject(pConfigFile); - ReleaseObject(pLocationCollection); - ReleaseObject(pLocation); - ReleaseBSTR(bstrLocationPath); - - return hr; - -} - -static HRESULT DeleteCollectionElement( - __in IAppHostElementCollection *pCollection, - __in LPCWSTR pwzElementName, - __in LPCWSTR pwzAttributeName, - __in LPCWSTR pwzAttributeValue - ) -{ - HRESULT hr = S_OK; - - DWORD dwIndex; - VARIANT vtIndex; - VariantInit(&vtIndex); - - hr = Iis7FindAppHostElementString(pCollection, pwzElementName, pwzAttributeName, pwzAttributeValue, NULL, &dwIndex); - ExitOnFailure(hr, "Failed while finding IAppHostElement %ls/@%ls=%ls", pwzElementName, pwzAttributeName, pwzAttributeValue); - - if (MAXDWORD != dwIndex) - { - vtIndex.vt = VT_UI4; - vtIndex.ulVal = dwIndex; - hr = pCollection->DeleteElement(vtIndex); - ExitOnFailure(hr, "Failed to delete IAppHostElement %ls/@%ls=%ls", pwzElementName, pwzAttributeName, pwzAttributeValue); - } - // else : nothing to do, already deleted -LExit: - ReleaseVariant(vtIndex); - - return hr; -} -static void ConvSecToHMS( int Sec, __out_ecount(cchDest) LPWSTR wcTime, size_t cchDest) -{ - int ZH, ZM, ZS = 0; - - ZH = (Sec / 3600); - Sec = Sec - ZH * 3600; - ZM = (Sec / 60) ; - Sec = Sec - ZM * 60; - ZS = Sec ; - - HRESULT hr = ::StringCchPrintfW(wcTime, cchDest, L"%02d:%02d:%02d", ZH, ZM, ZS); - if (S_OK != hr) - { - *wcTime = '\0'; - } -} -static void ConvSecToDHMS( unsigned int Sec, __out_ecount(cchDest) LPWSTR wcTime, size_t cchDest) -{ - int ZD, ZH, ZM, ZS = 0; - - ZD = Sec / 86400; - Sec = Sec - ZD * 86400; - ZH = (Sec / 3600); - Sec = Sec - ZH * 3600; - ZM = (Sec / 60) ; - Sec = Sec - ZM * 60; - ZS = Sec ; - - HRESULT hr = ::StringCchPrintfW(wcTime, cchDest, L"%d.%02d:%02d:%02d", ZD, ZH, ZM, ZS); - if (S_OK != hr) - { - *wcTime = '\0'; - } -} diff --git a/src/ca/scaexecIIS7.h b/src/ca/scaexecIIS7.h deleted file mode 100644 index ec31f202..00000000 --- a/src/ca/scaexecIIS7.h +++ /dev/null @@ -1,5 +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 IIS7ConfigChanges(MSIHANDLE hInstall, __inout LPWSTR pwzData); diff --git a/src/ca/scafilter.cpp b/src/ca/scafilter.cpp deleted file mode 100644 index 9d9014fd..00000000 --- a/src/ca/scafilter.cpp +++ /dev/null @@ -1,510 +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" - -// prototypes -static HRESULT ReadFilterLoadOrder( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzFilterRoot, - __out LPWSTR *ppwzLoadOrder - ); -static HRESULT AddFilterToLoadOrder( - __in LPCWSTR wzFilter, - __in int iLoadOrder, - __inout LPWSTR *ppwzLoadOrder - ); -static HRESULT RemoveFilterFromLoadOrder( - __in LPCWSTR wzFilter, - __inout LPWSTR *ppwzLoadOrder - ); - - -UINT __stdcall ScaFiltersRead( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __inout SCA_FILTER** ppsfList, - __inout LPWSTR *ppwzCustomActionData - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - - LPWSTR pwzData = NULL; - - SCA_FILTER* psf = NULL; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaFiltersRead() - no IIsFilter table"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the filters - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - // Get the Component first. If the component is not being modified during - // this transaction, skip processing this whole record. - hr = WcaGetRecordString(hRec, fqComponent, &pwzData); - ExitOnFailure(hr, "failed to get IIsFilter.Component"); - - hr = WcaGetRecordInteger(hRec, fqInstalled, (int *)&isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for IIs filter"); - - hr = WcaGetRecordInteger(hRec, fqAction, (int *)&isAction); - ExitOnFailure(hr, "Failed to get Component action state for IIs filter"); - - if (!WcaIsInstalling(isInstalled, isAction) && - !WcaIsReInstalling(isInstalled, isAction) && - !WcaIsUninstalling(isInstalled, isAction)) - { - continue; // skip this record. - } - - hr = AddFilterToList(ppsfList); - ExitOnFailure(hr, "failed to add filter to list"); - - psf = *ppsfList; - - hr = ::StringCchCopyW(psf->wzComponent, countof(psf->wzComponent), pwzData); - ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); - - psf->isInstalled = isInstalled; - psf->isAction = isAction; - - hr = WcaGetRecordString(hRec, fqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web for VirtualDir"); - - if (*pwzData) - { - hr = ScaWebsGetBase(piMetabase, pswList, pwzData, psf->wzWebBase, countof(psf->wzWebBase), hWebBaseQuery); - if (FAILED(hr) && WcaIsUninstalling(isInstalled, isAction)) - { - // If we're uninstalling, don't bother finding the existing web, just leave the filter root empty - hr = S_OK; - } - ExitOnFailure(hr, "Failed to get base of web for Filter"); - - if (0 != lstrlenW(psf->wzWebBase)) - { - hr = ::StringCchPrintfW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"%s/Filters", psf->wzWebBase); - ExitOnFailure(hr, "Failed to allocate filter base string"); - } - } - else - { - hr = ::StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/LM/W3SVC/Filters"); - ExitOnFailure(hr, "Failed to allocate global filter base string"); - } - - // filter key - hr = WcaGetRecordString(hRec, fqFilter, &pwzData); - ExitOnFailure(hr, "Failed to get Filter.Filter"); - hr = ::StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to filter object"); - - // filter path - hr = WcaGetRecordString(hRec, fqPath, &pwzData); - ExitOnFailure(hr, "Failed to get Filter.Path"); - hr = ::StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData); - ExitOnFailure(hr, "Failed to copy path string to filter object"); - - // filter description - hr = WcaGetRecordString(hRec, fqDescription, &pwzData); - ExitOnFailure(hr, "Failed to get Filter.Description"); - hr = ::StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData); - ExitOnFailure(hr, "Failed to copy description string to filter object"); - - // filter flags - hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags); - ExitOnFailure(hr, "Failed to get Filter.Flags"); - - // filter load order - hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder); - ExitOnFailure(hr, "Failed to get Filter.LoadOrder"); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing filters"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - return hr; -} - - -HRESULT ScaFiltersInstall( - __in IMSAdminBase* piMetabase, - __in SCA_FILTER* psfList - ) -{ - HRESULT hr = S_OK; - SCA_FILTER* psf = psfList; - LPCWSTR wzPreviousFilterRoot = NULL; - LPWSTR pwzLoadOrder = NULL; - - while (psf) - { - if (WcaIsInstalling(psf->isInstalled, psf->isAction)) - { - if (!wzPreviousFilterRoot || CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, wzPreviousFilterRoot, -1, psf->wzFilterRoot, -1)) - { - if (pwzLoadOrder) - { - hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); - ExitOnFailure(hr, "Failed to write filter load order to metabase"); - - ReleaseNullStr(pwzLoadOrder); - } - - hr = ReadFilterLoadOrder(piMetabase, psf->wzFilterRoot, &pwzLoadOrder); - ExitOnFailure(hr, "Failed to read filter load order."); - - wzPreviousFilterRoot = psf->wzFilterRoot; - } - - hr = ScaCreateMetabaseKey(piMetabase, psf->wzFilterRoot, psf->wzKey); - ExitOnFailure(hr, "Failed to create key for filter '%ls'", psf->wzKey); - - hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsFilter"); - ExitOnFailure(hr, "Failed to write key type for filter '%ls'", psf->wzKey); - - // filter path - hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_IMAGE_PATH, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)psf->wzPath); - ExitOnFailure(hr, "Failed to write Path for filter '%ls'", psf->wzKey); - - // filter description - hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_DESCRIPTION, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)psf->wzDescription); - ExitOnFailure(hr, "Failed to write Description for filter '%ls'", psf->wzKey); - - // filter flags - if (MSI_NULL_INTEGER != psf->iFlags) - { - hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_FLAGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psf->iFlags)); - ExitOnFailure(hr, "Failed to write Flags for filter '%ls'", psf->wzKey); - } - - // filter load order - if (MSI_NULL_INTEGER != psf->iLoadOrder) - { - hr = AddFilterToLoadOrder(psf->wzKey, psf->iLoadOrder, &pwzLoadOrder); - ExitOnFailure(hr, "Failed to add filter '%ls' to load order.", psf->wzKey); - } - } - - psf = psf->psfNext; - } - - if (pwzLoadOrder) - { - Assert(wzPreviousFilterRoot && *wzPreviousFilterRoot); - - hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); - ExitOnFailure(hr, "Failed to write filter load order to metabase"); - } - -LExit: - ReleaseStr(pwzLoadOrder); - return hr; -} - - -HRESULT ScaFiltersUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_FILTER* psfList - ) -{ - HRESULT hr = S_OK; - SCA_FILTER* psf = psfList; - LPCWSTR wzPreviousFilterRoot = NULL; - LPWSTR pwzLoadOrder = NULL; - - while (psf) - { - if (WcaIsUninstalling(psf->isInstalled, psf->isAction)) - { - if (!wzPreviousFilterRoot || CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, wzPreviousFilterRoot, -1, psf->wzFilterRoot, -1)) - { - if (pwzLoadOrder) - { - hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); - ExitOnFailure(hr, "Failed to write filter load order to metabase"); - - ReleaseNullStr(pwzLoadOrder); - } - - hr = ReadFilterLoadOrder(piMetabase, psf->wzFilterRoot, &pwzLoadOrder); - ExitOnFailure(hr, "Failed to read filter load order."); - - wzPreviousFilterRoot = psf->wzFilterRoot; - } - - hr = RemoveFilterFromLoadOrder(psf->wzKey, &pwzLoadOrder); - ExitOnFailure(hr, "Failed to remove filter '%ls' from load order", psf->wzKey); - - // remove the filter from the load order and remove the filter's key - if (0 != lstrlenW(psf->wzFilterRoot)) - { - hr = ScaDeleteMetabaseKey(piMetabase, psf->wzFilterRoot, psf->wzKey); - ExitOnFailure(hr, "Failed to remove web '%ls' from metabase", psf->wzKey); - } - } - - psf = psf->psfNext; - } - - if (pwzLoadOrder) - { - Assert(wzPreviousFilterRoot && *wzPreviousFilterRoot); - - hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); - ExitOnFailure(hr, "Failed to write filter load order to metabase"); - } - -LExit: - return hr; -} - - -void ScaFiltersFreeList( - __in SCA_FILTER* psfList - ) -{ - SCA_FILTER* psfDelete = psfList; - while (psfList) - { - psfDelete = psfList; - psfList = psfList->psfNext; - - MemFree(psfDelete); - } -} - -HRESULT AddFilterToList( - __inout SCA_FILTER** ppsfList) -{ - HRESULT hr = S_OK; - SCA_FILTER* psf = static_cast(MemAlloc(sizeof(SCA_FILTER), TRUE)); - ExitOnNull(psf, hr, E_OUTOFMEMORY, "failed to add filter to filter list"); - - psf->psfNext = *ppsfList; - *ppsfList = psf; - -LExit: - return hr; -} - -// private helper functions - - -static HRESULT ReadFilterLoadOrder( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzFilterRoot, - __out LPWSTR *ppwzLoadOrder - ) -{ - HRESULT hr = S_OK; - METADATA_HANDLE mhRoot = NULL; - - METADATA_RECORD mr; - DWORD dwRequired = 0; - DWORD cchData = 255; - - ::ZeroMemory(&mr, sizeof(mr)); - mr.dwMDIdentifier = MD_FILTER_LOAD_ORDER; - mr.dwMDAttributes = METADATA_NO_ATTRIBUTES; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = ALL_METADATA; - mr.dwMDDataLen = cchData; - mr.pbMDData = static_cast(MemAlloc(mr.dwMDDataLen * sizeof(WCHAR), TRUE)); - ExitOnNull(mr.pbMDData, hr, E_OUTOFMEMORY, "failed to allocate memory for MDData in metadata record"); - - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, wzFilterRoot, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10, &mhRoot); - for (int i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) - { - ::Sleep(1000); - WcaLog(LOGMSG_STANDARD, "Failed to open root key, retrying %d time(s)...", i); - hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, wzFilterRoot, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10, &mhRoot); - } - - if (SUCCEEDED(hr)) - { - hr = piMetabase->GetData(mhRoot, L"", &mr, &dwRequired); - if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) - { - mr.dwMDDataLen = cchData = dwRequired; - - LPVOID pv = MemReAlloc(mr.pbMDData, mr.dwMDDataLen * sizeof(WCHAR), TRUE); - ExitOnNull(pv, hr, E_OUTOFMEMORY, "failed to allocate memory for MDData in metadata record"); - mr.pbMDData = static_cast(pv); - - hr = piMetabase->GetData(mhRoot, L"", &mr, &dwRequired); - } - } - - // The /Filters node or /Filters/FilterLoadOrder property might not exist (yet). - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failed to get filter load order."); - - hr = StrAllocString(ppwzLoadOrder, reinterpret_cast(mr.pbMDData), 0); - ExitOnFailure(hr, "Failed to allocate string for filter load order."); - -LExit: - ReleaseMem(mr.pbMDData); - - if (mhRoot) - { - piMetabase->CloseKey(mhRoot); - } - - return hr; -} - - -static HRESULT AddFilterToLoadOrder( - __in LPCWSTR wzFilter, - __in int iLoadOrder, - __inout LPWSTR *ppwzLoadOrder - ) -{ - HRESULT hr = S_OK; - LPCWSTR wzLoadOrder = *ppwzLoadOrder; - int cchFilter = lstrlenW(wzFilter); - LPWSTR pwzTemp = NULL; - - // If the filter name ends with '\0' or ',' and - // the filter name begins at the beginning of the list or with ',' - // Then we've found the exact filter by name. - // - // If the filter isn't already in the load order, add it - if (wzLoadOrder && *wzLoadOrder) - { - LPCWSTR pwz = wcsstr(wzLoadOrder, wzFilter); - - if (NULL != pwz && - (L'\0' == *(pwz + cchFilter) || L',' == *(pwz + cchFilter)) && - (pwz == wzLoadOrder || L',' == *(pwz - 1))) - { - // Filter already in the load order, no work to do. - } - else - { - pwz = NULL; - if (0 <= iLoadOrder) - { - pwz = wzLoadOrder; - for (int i = 0; i < iLoadOrder && pwz; ++i) - { - pwz = wcsstr(pwz, L","); - } - } - - if (NULL == pwz) // put the filter at the end of the order - { - Assert(wzLoadOrder && *wzLoadOrder); - - // tack on a comma since there are other filters in the order - hr = StrAllocConcat(ppwzLoadOrder, L",", 1); - ExitOnFailure(hr, "Failed to append a comma to filter load order."); - - hr = StrAllocConcat(ppwzLoadOrder, wzFilter, cchFilter); - ExitOnFailure(hr, "Failed to append the filter on to the load order."); - } - else if (L',' == *pwz) // put the filter in the middle of the order - { - hr = StrAllocString(&pwzTemp, wzLoadOrder, pwz - wzLoadOrder + 1); - ExitOnFailure(hr, "Failed to copy first half of filter load order to temp string."); - - hr = StrAllocConcat(&pwzTemp, wzFilter, 0); - ExitOnFailure(hr, "Failed to copy filter into load order."); - - hr = StrAllocConcat(&pwzTemp, pwz, 0); - ExitOnFailure(hr, "Failed to copy remaining filter load order back onto load order."); - - hr = StrAllocString(ppwzLoadOrder, pwzTemp, 0); - ExitOnFailure(hr, "Failed to copy temp string to load order string."); - } - else // put the filter at the beginning of the order - { - hr = StrAllocPrefix(ppwzLoadOrder, L",", 1); - ExitOnFailure(hr, "Failed to prepend a comma to filter load order."); - - hr = StrAllocPrefix(ppwzLoadOrder, wzFilter, cchFilter); - ExitOnFailure(hr, "Failed to prepend the filter on to the load order."); - } - } - } - else - { - hr = StrAllocString(ppwzLoadOrder, wzFilter, cchFilter); - ExitOnFailure(hr, "Failed to add filter to load order."); - } - -LExit: - ReleaseStr(pwzTemp); - return hr; -} - - -static HRESULT RemoveFilterFromLoadOrder( - __in LPCWSTR wzFilter, - __inout LPWSTR *ppwzLoadOrder - ) -{ - HRESULT hr = S_OK; - int cchFilter = lstrlenW(wzFilter); - - LPCWSTR pwzStart = NULL; - LPWSTR pwzFind = NULL; - - pwzStart = pwzFind = *ppwzLoadOrder; - while (NULL != (pwzFind = wcsstr(pwzFind, wzFilter))) - { - // Make sure to only match [wzFilter] and NOT foo[wzFilter]bar - if (pwzFind == pwzStart || L',' == *(pwzFind - 1)) - { - int cchRemainder = lstrlenW(pwzFind) - cchFilter + 1; // add one to include the null terminator - - if (L'\0' == *(pwzFind + cchFilter)) - { - if (pwzFind == pwzStart) - { - memmove(pwzFind, pwzFind + cchFilter, cchRemainder * sizeof(WCHAR)); // copy down the null terminator - } - else - { - memmove(pwzFind - 1, pwzFind + cchFilter, cchRemainder * sizeof(WCHAR)); // copy down the null terminator over top the trailing "," - } - } - else if (L',' == *(pwzFind + cchFilter)) - { - memmove(pwzFind, pwzFind + cchFilter + 1, (cchRemainder - 1) * sizeof(WCHAR)); // skip copying the "," - } - else // skip past the partial match - { - pwzFind = pwzFind + cchFilter; - } - } - else // skip past the partial match - { - pwzFind = pwzFind + cchFilter; - } - } - -//LExit: - return hr; -} diff --git a/src/ca/scafilter.h b/src/ca/scafilter.h deleted file mode 100644 index d072bf22..00000000 --- a/src/ca/scafilter.h +++ /dev/null @@ -1,46 +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 "scaweb.h" - -enum eFilterQuery { fqWeb = 1, fqFilter, fqComponent , fqPath, fqDescription, fqFlags, fqLoadOrder, fqInstalled, fqAction }; - -struct SCA_FILTER -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - // metabase information - WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; - WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; - WCHAR wzFilterRoot[METADATA_MAX_NAME_LEN + 1]; - - // iis configuation information - WCHAR wzPath[MAX_PATH]; - WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; - int iFlags; - int iLoadOrder; - - SCA_FILTER* psfNext; -}; - - -// prototypes -HRESULT AddFilterToList( - __in SCA_FILTER** ppsfList - ); - -UINT __stdcall ScaFiltersRead(IMSAdminBase* piMetabase, - SCA_WEB* pswList, __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, SCA_FILTER** ppsfList, - __inout LPWSTR *ppwzCustomActionData); - -HRESULT ScaFiltersInstall(IMSAdminBase* piMetabase, SCA_FILTER* psfList); - -HRESULT ScaFiltersUninstall(IMSAdminBase* piMetabase, SCA_FILTER* psfList); - -void ScaFiltersFreeList(SCA_FILTER* psfList); - diff --git a/src/ca/scafilter7.cpp b/src/ca/scafilter7.cpp deleted file mode 100644 index dda91c4d..00000000 --- a/src/ca/scafilter7.cpp +++ /dev/null @@ -1,284 +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" - -static HRESULT WriteFilter(const SCA_FILTER* psf); - -UINT __stdcall ScaFiltersRead7( - __in SCA_WEB7* pswList, - __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, - __inout SCA_FILTER** ppsfList, - __inout LPWSTR *ppwzCustomActionData - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - SCA_FILTER* psf; - - LPWSTR pwzData = NULL; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaFiltersRead() - no IIsFilter table"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the filters - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - // Get the Component first. If the component is not being modified during - // this transaction, skip processing this whole record. - // get the darwin information - hr = WcaGetRecordString(hRec, fqComponent, &pwzData); - ExitOnFailure(hr, "failed to get IIsFilter.Component"); - - hr = WcaGetRecordInteger(hRec, fqInstalled, (int *)&isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for IIs filter"); - - hr = WcaGetRecordInteger(hRec, fqAction, (int *)&isAction); - ExitOnFailure(hr, "Failed to get Component action state for IIs filter"); - - if (!WcaIsInstalling(isInstalled, isAction) && - !WcaIsReInstalling(isInstalled, isAction) && - !WcaIsUninstalling(isInstalled, isAction)) - { - continue; // skip this record. - } - - hr = AddFilterToList(ppsfList); - ExitOnFailure(hr, "failed to add filter to list"); - - psf = *ppsfList; - - hr = ::StringCchCopyW(psf->wzComponent, countof(psf->wzComponent), pwzData); - ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); - - psf->isInstalled = isInstalled; - psf->isAction = isAction; - - hr = WcaGetRecordString(hRec, fqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web for VirtualDir"); - - if (*pwzData) - { - hr = ScaWebsGetBase7(pswList, pwzData, psf->wzFilterRoot, countof(psf->wzFilterRoot)); - if (FAILED(hr)) - { - WcaLog(LOGMSG_VERBOSE, "Could not find site for filter: %ls. Result 0x%x ", psf->wzFilterRoot, hr); - hr = S_OK; - } - } - else - { - hr = ::StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/"); - ExitOnFailure(hr, "Failed to allocate global filter base string"); - } - - // filter Name key - hr = WcaGetRecordString(hRec, fqFilter, &pwzData); - ExitOnFailure(hr, "Failed to get Filter.Filter"); - hr = ::StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to filter object"); - - // filter path - hr = WcaGetRecordString(hRec, fqPath, &pwzData); - ExitOnFailure(hr, "Failed to get Filter.Path"); - hr = ::StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData); - ExitOnFailure(hr, "Failed to copy path string to filter object"); - - // filter description -- not supported in iis 7 - hr = WcaGetRecordString(hRec, fqDescription, &pwzData); - ExitOnFailure(hr, "Failed to get Filter.Description"); - hr = ::StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData); - ExitOnFailure(hr, "Failed to copy description string to filter object"); - - // filter flags - //What are these - hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags); - ExitOnFailure(hr, "Failed to get Filter.Flags"); - - // filter load order - hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder); - ExitOnFailure(hr, "Failed to get Filter.LoadOrder"); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing filters"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaFiltersInstall7( - __in SCA_FILTER* psfList - ) -{ - HRESULT hr = S_OK; - SCA_FILTER* psf = psfList; - - if (!psf) - { - ExitFunction(); - } - //write global filters - hr = ScaWriteConfigID(IIS_FILTER_GLOBAL_BEGIN); - ExitOnFailure(hr, "Failed to write filter begin ID"); - while (psf) - { - if (WcaIsInstalling(psf->isInstalled, psf->isAction)) - { - if (0 == wcscmp(psf->wzFilterRoot, L"/")) - { - hr = WriteFilter(psf); - } - } - psf = psf->psfNext; - } - hr = ScaWriteConfigID(IIS_FILTER_END); - ExitOnFailure(hr, "Failed to write filter ID"); - - psf = psfList; - - //Write Web Site Filters - hr = ScaWriteConfigID(IIS_FILTER_BEGIN); - ExitOnFailure(hr, "Failed to write filter begin ID"); - while (psf) - { - if (WcaIsInstalling(psf->isInstalled, psf->isAction)) - { - if (0 != wcscmp(psf->wzFilterRoot, L"/")) - { - hr = WriteFilter(psf); - } - } - psf = psf->psfNext; - } - hr = ScaWriteConfigID(IIS_FILTER_END); - ExitOnFailure(hr, "Failed to write filter ID"); - -LExit: - - return hr; -} -static HRESULT WriteFilter(const SCA_FILTER* psf) -{ - HRESULT hr = S_OK; - - hr = ScaWriteConfigID(IIS_FILTER); - ExitOnFailure(hr, "Failed to write filter begin ID"); - - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed to write filter create ID"); - - //filter Name key - hr = ScaWriteConfigString(psf->wzKey); - ExitOnFailure(hr, "Failed to write key name for filter '%ls'", psf->wzKey); - - //web site name - hr = ScaWriteConfigString(psf->wzFilterRoot); - ExitOnFailure(hr, "Failed to write filter web root "); - - // filter path - hr = ScaWriteConfigString(psf->wzPath); - ExitOnFailure(hr, "Failed to write Path for filter '%ls'", psf->wzKey); - - //filter load order - hr = ScaWriteConfigInteger(psf->iLoadOrder); - ExitOnFailure(hr, "Failed to write load order for filter '%ls'", psf->wzKey); - -LExit: - return hr; -} - - -HRESULT ScaFiltersUninstall7( - __in SCA_FILTER* psfList - ) -{ - HRESULT hr = S_OK; - SCA_FILTER* psf = psfList; - - if (!psf) - { - ExitFunction1(hr = S_OK); - } - - //Uninstall global filters - hr = ScaWriteConfigID(IIS_FILTER_GLOBAL_BEGIN); - ExitOnFailure(hr, "Failed to write filter begin ID"); - - while (psf) - { - if (WcaIsUninstalling(psf->isInstalled, psf->isAction)) - { - if (0 == wcscmp(psf->wzFilterRoot, L"/")) - { - hr = ScaWriteConfigID(IIS_FILTER); - ExitOnFailure(hr, "Failed to write filter begin ID"); - - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "Failed to write filter create ID"); - - //filter Name key - hr = ScaWriteConfigString(psf->wzKey); - ExitOnFailure(hr, "Failed to write key name for filter '%ls'", psf->wzKey); - - //web site name - hr = ScaWriteConfigString(psf->wzFilterRoot); - ExitOnFailure(hr, "Failed to write filter web root "); - - } - } - psf = psf->psfNext; - } - - hr = ScaWriteConfigID(IIS_FILTER_END); - ExitOnFailure(hr, "Failed to write filter ID"); - - psf = psfList; - - //Uninstall website filters - hr = ScaWriteConfigID(IIS_FILTER_BEGIN); - ExitOnFailure(hr, "Failed to write filter begin ID"); - while (psf) - { - if (WcaIsUninstalling(psf->isInstalled, psf->isAction)) - { - if (0 != wcscmp(psf->wzFilterRoot, L"/")) - { - hr = ScaWriteConfigID(IIS_FILTER); - ExitOnFailure(hr, "Failed to write filter begin ID"); - - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "Failed to write filter create ID"); - - //filter Name key - hr = ScaWriteConfigString(psf->wzKey); - ExitOnFailure(hr, "Failed to write key name for filter '%ls'", psf->wzKey); - - //web site name - hr = ScaWriteConfigString(psf->wzFilterRoot); - ExitOnFailure(hr, "Failed to write filter web root "); - } - } - psf = psf->psfNext; - } - hr = ScaWriteConfigID(IIS_FILTER_END); - ExitOnFailure(hr, "Failed to write filter ID"); - -LExit: - return hr; -} diff --git a/src/ca/scafilter7.h b/src/ca/scafilter7.h deleted file mode 100644 index 50ff6652..00000000 --- a/src/ca/scafilter7.h +++ /dev/null @@ -1,21 +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 "scaweb.h" - -// prototypes -UINT __stdcall ScaFiltersRead7( - __in SCA_WEB7* pswList, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __inout SCA_FILTER** ppsfList, - __inout LPWSTR *ppwzCustomActionData - ); - -HRESULT ScaFiltersInstall7( - SCA_FILTER* psfList - ); - -HRESULT ScaFiltersUninstall7( - SCA_FILTER* psfList - ); diff --git a/src/ca/scahttpheader.cpp b/src/ca/scahttpheader.cpp deleted file mode 100644 index 1e134cea..00000000 --- a/src/ca/scahttpheader.cpp +++ /dev/null @@ -1,323 +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" - -enum eHttpHeaderQuery { hhqName = 1, hhqParentType, hhqParentValue, hhqValue, hhqAttributes}; - -static HRESULT AddHttpHeaderToList( - __in SCA_HTTP_HEADER** ppshhList - ); - - -void ScaHttpHeaderFreeList( - __in SCA_HTTP_HEADER* pshhList - ) -{ - SCA_HTTP_HEADER* pshhDelete = pshhList; - while (pshhList) - { - pshhDelete = pshhList; - pshhList = pshhList->pshhNext; - - MemFree(pshhDelete); - } -} - - -HRESULT ScaHttpHeaderRead( - __in SCA_HTTP_HEADER** ppshhList, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(ppshhList); - - HRESULT hr = S_OK; - MSIHANDLE hRec; - LPWSTR pwzData = NULL; - SCA_HTTP_HEADER* pshh = NULL; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaHttpHeaderRead() - required tables not present."); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the HTTP headers - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - hr = AddHttpHeaderToList(ppshhList); - ExitOnFailure(hr, "failed to add http header to list"); - - pshh = *ppshhList; - - hr = WcaGetRecordInteger(hRec, hhqParentType, &(pshh->iParentType)); - ExitOnFailure(hr, "failed to get IIsHttpHeader.ParentType"); - - hr = WcaGetRecordString(hRec, hhqParentValue, &pwzData); - ExitOnFailure(hr, "Failed to get IIsHttpHeader.ParentValue"); - hr = ::StringCchCopyW(pshh->wzParentValue, countof(pshh->wzParentValue), pwzData); - ExitOnFailure(hr, "Failed to copy IIsHttpHeader.ParentValue"); - - hr = WcaGetRecordString(hRec, hhqName, &pwzData); - ExitOnFailure(hr, "Failed to get IIsHttpHeader.Name"); - hr = ::StringCchCopyW(pshh->wzName, countof(pshh->wzName), pwzData); - ExitOnFailure(hr, "Failed to copy IIsHttpHeader.Name"); - - hr = WcaGetRecordString(hRec, hhqValue, &pwzData); - ExitOnFailure(hr, "Failed to get IIsHttpHeader.Value"); - hr = ::StringCchCopyW(pshh->wzValue, countof(pshh->wzValue), pwzData); - ExitOnFailure(hr, "Failed to copy IIsHttpHeader.Value"); - - hr = WcaGetRecordInteger(hRec, hhqAttributes, &(pshh->iAttributes)); - ExitOnFailure(hr, "failed to get IIsHttpHeader.Attributes"); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing web errors"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaGetHttpHeader( - __in int iParentType, - __in LPCWSTR wzParentValue, - __in SCA_HTTP_HEADER** ppshhList, - __out SCA_HTTP_HEADER** ppshhOut - ) -{ - HRESULT hr = S_OK; - SCA_HTTP_HEADER* pshhAdd = NULL; - SCA_HTTP_HEADER* pshhLast = NULL; - - *ppshhOut = NULL; - - if (!*ppshhList) - { - return hr; - } - - SCA_HTTP_HEADER* pshh = *ppshhList; - while (pshh) - { - if (iParentType == pshh->iParentType && CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, wzParentValue, -1, pshh->wzParentValue, -1)) - { - // Found a match, take this one out of the list and add it to the matched out list - pshhAdd = pshh; - - if (pshhLast) - { - // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) - pshhLast->pshhNext = pshhAdd->pshhNext; - } - else - { - // If we are at the beginning (no pshhLast) update the beginning (since we're taking it) - *ppshhList = pshh->pshhNext; - } - pshh = pshh->pshhNext; // move on - - // Add the one we've removed to the beginning of the out list - pshhAdd->pshhNext = *ppshhOut; - *ppshhOut = pshhAdd; - } - else - { - pshhLast = pshh; // remember the last we that didn't match - pshh = pshh->pshhNext; // move on - } - } - - return hr; -} - - -HRESULT ScaWriteHttpHeader( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzRoot, - __in SCA_HTTP_HEADER* pshhList - ) -{ - Assert(piMetabase && pshhList); - - HRESULT hr = S_OK; - METADATA_RECORD mr = { 0 }; - DWORD cchData = 0; - LPWSTR pwzSearchKey = NULL; - LPWSTR pwz = NULL; - LPWSTR pwzHeaders = NULL; - LPWSTR pwzNewHeader = NULL; - DWORD_PTR dwFoundHeaderIndex = 0; - LPCWSTR wzFoundHeader = NULL; - BOOL fOldValueFound = FALSE; - - ExitOnNull(wzRoot, hr, E_INVALIDARG, "Failed to write HTTP header, because no root was provided"); - - Assert(*wzRoot); - - // Check if HTTP header already exist here. - mr.dwMDIdentifier = MD_HTTP_CUSTOM; - mr.dwMDAttributes = METADATA_INHERIT; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = ALL_METADATA; - mr.dwMDDataLen = cchData = 0; - mr.pbMDData = NULL; - - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzRoot, &mr); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) - { - // - // If we don't have any HTTP Headers already, move up to get the parent headers. - // TODO: Make it configurable to not inherit HTTP Headers - // - hr = StrAllocConcat(&pwzSearchKey, wzRoot, 0); - ExitOnFailure(hr, "Failed to copy root string: %ls", wzRoot); - - pwz = pwzSearchKey + lstrlenW(pwzSearchKey); - while (NULL == pwzHeaders) - { - // find the last slash - while (*pwz != '/' && pwz != pwzSearchKey) - { - --pwz; - } - - if (pwz == pwzSearchKey) - { - break; - } - - *pwz = L'\0'; - - // Try here. If it's not found, keep walking up the path - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, pwzSearchKey, &mr); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) - { - hr = S_FALSE; - } - ExitOnFailure(hr, "Failed to find search for HTTP headers for web root: %ls while walking up the tree", wzRoot); - - if (S_OK == hr) - { - hr = StrAllocString(&pwzHeaders, reinterpret_cast(mr.pbMDData), 0); - ExitOnFailure(hr, "Failed to allocate parent HTTP header string"); - break; - } - } - } - else - { - hr = StrAllocString(&pwzHeaders, reinterpret_cast(mr.pbMDData), 0); - ExitOnFailure(hr, "Failed to allocate HTTP header string"); - } - ExitOnFailure(hr, "Failed while searching for default HTTP headers to start with for web root: %ls", wzRoot); - - // Loop through the HTTP headers - for (SCA_HTTP_HEADER* pshh = pshhList; pshh; pshh = pshh->pshhNext) - { - fOldValueFound = FALSE; // assume a HTTP Header match will not be found - - hr = StrAllocFormatted(&pwzNewHeader, L"%s: ", pshh->wzName); - ExitOnFailure(hr, "Failed to allocate header name"); - - if (NULL != pwzHeaders && *pwzHeaders) - { - // Try to find a matching header already in the list - hr = MultiSzFindSubstring(pwzHeaders, pwzNewHeader, &dwFoundHeaderIndex, &wzFoundHeader); - ExitOnFailure(hr, "Failed while searching for existing HTTP header."); - - // If there was a substring HTTP header match, make sure the match was at the beginning - // of the string because that is the HTTP header name. - if (S_OK == hr) - { - DWORD cchMatch = lstrlenW(pwzNewHeader); - if (CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pwzNewHeader, cchMatch, wzFoundHeader, cchMatch)) - { - fOldValueFound = TRUE; - break; - } - } - } - - // Add the value on to the header name now. - hr = StrAllocConcat(&pwzNewHeader, pshh->wzValue, 0); - ExitOnFailure(hr, "Failed to add value on to HTTP header name."); - - // If we have something to replace, replace it, otherwise, put it at the beginning (order shouldn't matter) - if (fOldValueFound) - { - if (NULL == pwzHeaders) - { - ExitOnFailure(hr = E_INVALIDARG, "While attempting to replace old HTTP header with new HTTP header, it was discovered that the old HTTP header was NULL!"); - } - hr = MultiSzReplaceString(&pwzHeaders, dwFoundHeaderIndex, pwzNewHeader); - ExitOnFailure(hr, "Failed to replace old HTTP header with new HTTP header"); - } - else - { - hr = MultiSzPrepend(&pwzHeaders, NULL, pwzNewHeader); - ExitOnFailure(hr, "Failed to prepend new HTTP header"); - } - } - - // now write the HttpCustom to the metabase - hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_HTTP_CUSTOM, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzHeaders); - ExitOnFailure(hr, "Failed to write HTTP Headers to metabase"); - -LExit: - MetaFreeValue(&mr); - - ReleaseStr(pwzNewHeader); - ReleaseStr(pwzHeaders); - ReleaseStr(pwzSearchKey); - - return hr; -} - - -HRESULT ScaHttpHeaderCheckList( - __in SCA_HTTP_HEADER* pshhList - ) -{ - if (!pshhList) - { - return S_OK; - } - - while (pshhList) - { - WcaLog(LOGMSG_STANDARD, "Http Header: %ls for parent: %ls not used!", pshhList->wzName, pshhList->wzParentValue); - pshhList = pshhList->pshhNext; - } - - return E_FAIL; -} - - -static HRESULT AddHttpHeaderToList( - __in SCA_HTTP_HEADER** ppshhList - ) -{ - HRESULT hr = S_OK; - - SCA_HTTP_HEADER* pshh = static_cast(MemAlloc(sizeof(SCA_HTTP_HEADER), TRUE)); - ExitOnNull(pshh, hr, E_OUTOFMEMORY, "failed to allocate memory for new http header list element"); - - pshh->pshhNext = *ppshhList; - *ppshhList = pshh; - -LExit: - return hr; -} diff --git a/src/ca/scahttpheader.h b/src/ca/scahttpheader.h deleted file mode 100644 index a4c407a4..00000000 --- a/src/ca/scahttpheader.h +++ /dev/null @@ -1,40 +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. - - -enum eHttpHeaderParentType { hhptVDir = 1, hhptWeb }; - -struct SCA_HTTP_HEADER -{ - int iParentType; - WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; - - WCHAR wzName[MAX_PATH]; - WCHAR wzValue[MAX_PATH]; - int iAttributes; - - SCA_HTTP_HEADER* pshhNext; -}; - -// prototypes -HRESULT ScaHttpHeaderRead( - __in SCA_HTTP_HEADER **ppshhList, - __inout LPWSTR *ppwzCustomActionData - ); -void ScaHttpHeaderFreeList( - __in SCA_HTTP_HEADER *pshhList - ); -HRESULT ScaHttpHeaderCheckList( - __in SCA_HTTP_HEADER* pshhList - ); -HRESULT ScaGetHttpHeader( - __in int iParentType, - __in LPCWSTR wzParentValue, - __in SCA_HTTP_HEADER** ppshhList, - __out SCA_HTTP_HEADER** ppshhOut - ); -HRESULT ScaWriteHttpHeader( - __in IMSAdminBase* piMetabase, - LPCWSTR wzRoot, - SCA_HTTP_HEADER* pshhList - ); diff --git a/src/ca/scahttpheader7.cpp b/src/ca/scahttpheader7.cpp deleted file mode 100644 index 645dd8d4..00000000 --- a/src/ca/scahttpheader7.cpp +++ /dev/null @@ -1,130 +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" - -HRESULT ScaGetHttpHeader7( - __in int iParentType, - __in_z LPCWSTR wzParentValue, - __in SCA_HTTP_HEADER** ppshhList, - __out SCA_HTTP_HEADER** ppshhOut - ) -{ - HRESULT hr = S_OK; - SCA_HTTP_HEADER* pshhAdd = NULL; - SCA_HTTP_HEADER* pshhLast = NULL; - - *ppshhOut = NULL; - - if (!*ppshhList) - { - return hr; - } - - SCA_HTTP_HEADER* pshh = *ppshhList; - while (pshh) - { - if (iParentType == pshh->iParentType && 0 == wcscmp(wzParentValue, pshh->wzParentValue)) - { - // Found a match, take this one out of the list and add it to the matched out list - pshhAdd = pshh; - - if (pshhLast) - { - // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) - pshhLast->pshhNext = pshhAdd->pshhNext; - } - else - { - // If we are at the beginning (no pshhLast) update the beginning (since we're taking it) - *ppshhList = pshh->pshhNext; - } - pshh = pshh->pshhNext; // move on - - // Add the one we've removed to the beginning of the out list - pshhAdd->pshhNext = *ppshhOut; - *ppshhOut = pshhAdd; - } - else - { - pshhLast = pshh; // remember the last we that didn't match - pshh = pshh->pshhNext; // move on - } - } - - return hr; -} - - -HRESULT ScaWriteHttpHeader7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRoot, - SCA_HTTP_HEADER* pshhList - ) -{ - - HRESULT hr = S_OK; - - hr = ScaWriteConfigID(IIS_HTTP_HEADER_BEGIN); - ExitOnFailure(hr, "Fail to write httpHeader begin ID"); - - hr = ScaWriteConfigString(wzWebName); - ExitOnFailure(hr, "Fail to write httpHeader Web Key"); - - hr = ScaWriteConfigString(wzRoot); - ExitOnFailure(hr, "Fail to write httpHeader Vdir key"); - - // Loop through the HTTP headers - for (SCA_HTTP_HEADER* pshh = pshhList; pshh; pshh = pshh->pshhNext) - { - hr = ScaWriteConfigID(IIS_HTTP_HEADER); - ExitOnFailure(hr, "Fail to write httpHeader ID"); - - hr = ScaWriteConfigString(pshh->wzName); - ExitOnFailure(hr, "Fail to write httpHeader name"); - - hr = ScaWriteConfigString(pshh->wzValue); - ExitOnFailure(hr, "Fail to write httpHeader value"); - } - - hr = ScaWriteConfigID(IIS_HTTP_HEADER_END); - ExitOnFailure(hr, "Fail to write httpHeader end ID"); - -LExit: - return hr; -} - - -HRESULT ScaHttpHeaderCheckList7( - __in SCA_HTTP_HEADER* pshhList - ) -{ - if (!pshhList) - { - return S_OK; - } - - while (pshhList) - { - WcaLog(LOGMSG_STANDARD, "Http Header: %ls for parent: %ls not used!", pshhList->wzName, pshhList->wzParentValue); - pshhList = pshhList->pshhNext; - } - - return E_FAIL; -} - - -//static HRESULT AddHttpHeaderToList( -// __in SCA_HTTP_HEADER** ppshhList -// ) -//{ -// HRESULT hr = S_OK; -// -// SCA_HTTP_HEADER* pshh = static_cast(MemAlloc(sizeof(SCA_HTTP_HEADER), TRUE)); -// ExitOnNull(pshh, hr, E_OUTOFMEMORY, "failed to allocate memory for new http header list element"); -// -// pshh->pshhNext = *ppshhList; -// *ppshhList = pshh; -// -//LExit: -// return hr; -//} diff --git a/src/ca/scahttpheader7.h b/src/ca/scahttpheader7.h deleted file mode 100644 index 7a873c16..00000000 --- a/src/ca/scahttpheader7.h +++ /dev/null @@ -1,15 +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 ScaGetHttpHeader7( - __in int iParentType, - __in_z LPCWSTR wzParentValue, - __in SCA_HTTP_HEADER** ppshhList, - __out SCA_HTTP_HEADER** ppshhOut - ); -HRESULT ScaWriteHttpHeader7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRoot, - SCA_HTTP_HEADER* pshhList - ); diff --git a/src/ca/scaiis.cpp b/src/ca/scaiis.cpp deleted file mode 100644 index 958051ed..00000000 --- a/src/ca/scaiis.cpp +++ /dev/null @@ -1,481 +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" - -// globals -LPWSTR vpwzCustomActionData = NULL; -DWORD vdwCustomActionCost = 0; - -HRESULT ScaMetabaseTransaction(__in_z LPCWSTR wzBackup) -{ - HRESULT hr = S_OK; - - // TODO: These functions have been reported to hang IIS (O11:51709). They may have been fixed in IIS6, but if not, need to be re-written the hard way - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"StartMetabaseTransaction"), wzBackup, COST_IIS_TRANSACTIONS); - ExitOnFailure(hr, "Failed to schedule StartMetabaseTransaction"); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackMetabaseTransaction"), wzBackup, 0); // rollback cost is irrelevant - ExitOnFailure(hr, "Failed to schedule RollbackMetabaseTransaction"); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CommitMetabaseTransaction"), wzBackup, 0); // commit is free - ExitOnFailure(hr, "Failed to schedule StartMetabaseTransaction"); - -LExit: - return hr; -} - - -HRESULT ScaCreateWeb(IMSAdminBase* piMetabase, LPCWSTR /*wzWeb*/, LPCWSTR wzWebBase) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - UINT ui = 0; - - hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L""); - ExitOnFailure(hr, "Failed to create web"); - - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebServer"); - ExitOnFailure(hr, "Failed to set key type for web"); - - hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L"Root"); - ExitOnFailure(hr, "Failed to create web root"); - - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Root", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); - ExitOnFailure(hr, "Failed to set key type for web root"); - - ui = 0x4000003e; // 1073741886; // default directory browsing rights - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Root", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); - ExitOnFailure(hr, "Failed to set directory browsing for web"); - - hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L"Filters"); - ExitOnFailure(hr, "Failed to create web filters root"); - - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Filters", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsFilters"); - ExitOnFailure(hr, "Failed to set key for web filters root"); - - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Filters", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L""); - ExitOnFailure(hr, "Failed to set empty load order for web"); - -LExit: - return hr; -} - - -HRESULT ScaDeleteApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot) -{ - Assert(piMetabase); - Unused(piMetabase); - - HRESULT hr = S_OK; - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteIntegerToCaData(MBA_DELETEAPP, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase delete app directive to CustomActionData"); - - hr = ::StringCchCopyW(wzKey, countof(wzKey), wzWebRoot); - ExitOnFailure(hr, "Failed to copy webroot string to key"); - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEAPP); - ExitOnFailure(hr, "Failed to add ScaDeleteApp action data: %ls cost: %d", pwzCustomActionData, COST_IIS_DELETEAPP); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - - -HRESULT ScaCreateApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot, - DWORD dwIsolation) -{ - Assert(piMetabase); - Unused(piMetabase); - - HRESULT hr = S_OK; - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - BOOL fInProc = FALSE; - - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteIntegerToCaData(MBA_CREATEAPP, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase create app directive to CustomActionData"); - - hr = ::StringCchCopyW(wzKey, countof(wzKey), wzWebRoot); - ExitOnFailure(hr, "Failed to copy webroot string to key"); - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); - - if (0 == dwIsolation) - fInProc = TRUE; - else - fInProc = FALSE; - - hr = WcaWriteIntegerToCaData(fInProc, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add isolation value to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_CREATEAPP); - ExitOnFailure(hr, "Failed to add ScaCreateApp action data: %ls cost: %d", pwzCustomActionData, COST_IIS_CREATEAPP); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - - -HRESULT ScaCreateMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey) -{ - Assert(piMetabase); - Unused(piMetabase); - - HRESULT hr = S_OK; - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - WCHAR* pwzCustomActionData = NULL; - - hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); - ExitOnFailure(hr, "Failed to copy root key string to key"); - if (L'/' != *(wzKey + lstrlenW(wzRootKey))) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); - ExitOnFailure(hr, "Failed to concatenate / to key string"); - } - if (wzSubKey && *wzSubKey) - { - if (L'/' == *wzSubKey) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); - ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); - } - else - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); - ExitOnFailure(hr, "Failed to concatenate subkey to key string"); - } - } - - hr = WcaWriteIntegerToCaData(MBA_CREATEKEY, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); - - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_CREATEKEY); - ExitOnFailure(hr, "Failed to add ScaCreateMetabaseKey action data: %ls cost: %d", pwzCustomActionData, COST_IIS_CREATEKEY); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - - -HRESULT ScaDeleteMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey) -{ - Assert(piMetabase); - Unused(piMetabase); - - HRESULT hr = S_OK; - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - WCHAR* pwzCustomActionData = NULL; - - hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); - ExitOnFailure(hr, "Failed to copy root key string to key"); - if (L'/' != *(wzKey + lstrlenW(wzRootKey))) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); - ExitOnFailure(hr, "Failed to concatenate / to key string"); - } - if (*wzSubKey) - { - if (L'/' == *wzSubKey) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); - ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); - } - else - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); - ExitOnFailure(hr, "Failed to concatenate subkey to key string"); - } - } - - hr = WcaWriteIntegerToCaData(MBA_DELETEKEY, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); - - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEKEY); - ExitOnFailure(hr, "Failed to add ScaDeleteMetabaseKey action data: %ls cost: %d", pwzCustomActionData, COST_IIS_DELETEKEY); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - - -HRESULT ScaDeleteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey, DWORD dwIdentifier, - DWORD dwDataType) -{ - Assert(piMetabase); - Unused(piMetabase); - - HRESULT hr = S_OK; - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - WCHAR* pwzCustomActionData = NULL; - - hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); - ExitOnFailure(hr, "Failed to copy root key string to key"); - if (L'/' != *(wzKey + lstrlenW(wzRootKey))) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); - ExitOnFailure(hr, "Failed to concatenate / to key string"); - } - - if (wzSubKey && *wzSubKey) - { - if (L'/' == *wzSubKey) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); - ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); - } - else - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); - ExitOnFailure(hr, "Failed to concatenate subkey to key string"); - } - } - - hr = WcaWriteIntegerToCaData(MBA_DELETEVALUE, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase write value directive to CustomActionData"); - - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); - - hr = WcaWriteIntegerToCaData(dwIdentifier, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase identifier to CustomActionData"); - - hr = WcaWriteIntegerToCaData(dwDataType, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase data type to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEVALUE); - ExitOnFailure(hr, "Failed to add ScaDeleteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_DELETEVALUE); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - - -#pragma prefast(push) -#pragma prefast(disable:25120) // Disable "requires count parameter" warning - we do have a way to distinguish buffer sizes in all situations, - // it just depends on the dwDataType, and there's no way to annotate the situation in SAL -HRESULT ScaWriteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey, DWORD dwIdentifier, - DWORD dwAttributes, DWORD dwUserType, - DWORD dwDataType, LPVOID pvData) -#pragma prefast(pop) -{ - Assert(piMetabase && (pvData || (DWORD_METADATA == dwDataType))); // pvData may be 0 if it is DWORD data - Unused(piMetabase); - - HRESULT hr = S_OK; - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - WCHAR* pwzCustomActionData = NULL; - - if (BINARY_METADATA == dwDataType) - { - ExitOnNull(pvData, hr, E_INVALIDARG, "Failed to write binary metadata - no data available to write"); - } - - hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); - ExitOnFailure(hr, "Failed to copy root key string to key"); - if (L'/' != *(wzKey + lstrlenW(wzRootKey))) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); - ExitOnFailure(hr, "Failed to concatenate / to key string"); - } - if (wzSubKey && *wzSubKey) - { - if (L'/' == *wzSubKey) - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); - ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); - } - else - { - hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); - ExitOnFailure(hr, "Failed to concatenate subkey to key string"); - } - } - - hr = WcaWriteIntegerToCaData(MBA_WRITEVALUE, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase write value directive to CustomActionData"); - - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); - - hr = WcaWriteIntegerToCaData(dwIdentifier, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase identifier to CustomActionData"); - - hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase attributes to CustomActionData"); - - hr = WcaWriteIntegerToCaData(dwUserType, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase user type to CustomActionData"); - - hr = WcaWriteIntegerToCaData(dwDataType, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase data type to CustomActionData"); - - switch (dwDataType) - { - case DWORD_METADATA: - hr = WcaWriteIntegerToCaData((DWORD)((DWORD_PTR)pvData), &pwzCustomActionData); - break; - case STRING_METADATA: - hr = WcaWriteStringToCaData((LPCWSTR)pvData, &pwzCustomActionData); - break; - case MULTISZ_METADATA: - { - // change NULLs to unprintable character to create a 'safe' MULTISZ string - LPWSTR pwz = (LPWSTR)pvData; - for (;;) - { - if ('\0' == *pwz) - { - *pwz = MAGIC_MULTISZ_CHAR; - if ('\0' == *(pwz + 1)) // second null back to back means end of string - break; - } - - ++pwz; - } - - hr = WcaWriteStringToCaData((LPCWSTR)pvData, &pwzCustomActionData); - } - break; - case BINARY_METADATA: - hr = WcaWriteStreamToCaData(((BLOB*) pvData)->pBlobData, ((BLOB*) pvData)->cbSize, &pwzCustomActionData); - break; - default: - hr = E_UNEXPECTED; - } - ExitOnFailure(hr, "Failed to add metabase data to CustomActionData"); - - // TODO: maybe look the key up and make sure we're not just writing the same value that already there - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEVALUE); - ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEVALUE); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - - -HRESULT ScaAddToIisConfiguration(LPCWSTR pwzData, DWORD dwCost) -{ - HRESULT hr = S_OK; - - hr = WcaWriteStringToCaData(pwzData, &vpwzCustomActionData); - ExitOnFailure(hr, "failed to add to metabase configuration data string: %ls", pwzData); - - vdwCustomActionCost += dwCost; - -LExit: - return hr; -} - - -HRESULT ScaWriteConfigurationScript(__in LPCWSTR pwzCaScriptKey) -{ - HRESULT hr = S_OK; - WCA_CASCRIPT_HANDLE hScript = NULL; - LPWSTR pwzHashString = NULL; - BYTE rgbActualHash[SHA1_HASH_LEN] = { }; - DWORD dwHashedBytes = SHA1_HASH_LEN; - - // Create CaScript for communication with WriteMetabaseChanges - hr = WcaCaScriptCreate(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzCaScriptKey, FALSE, &hScript); - ExitOnFailure(hr, "Failed to write ca script for WriteMetabaseChanges script."); - - if (vpwzCustomActionData && *vpwzCustomActionData) - { - // Write the actual custom action data to the ca script - WcaCaScriptWriteString(hScript, vpwzCustomActionData); - - hr = CrypHashBuffer((BYTE*)vpwzCustomActionData, sizeof(vpwzCustomActionData) * sizeof(WCHAR), PROV_RSA_AES, CALG_SHA1, rgbActualHash, dwHashedBytes); - ExitOnFailure(hr, "Failed to calculate hash of CustomAction data."); - - hr = StrAlloc(&pwzHashString, ((dwHashedBytes * 2) + 1)); - ExitOnFailure(hr, "Failed to allocate string for script hash"); - - hr = StrHexEncode(rgbActualHash, dwHashedBytes, pwzHashString, ((dwHashedBytes * 2) + 1)); - ExitOnFailure(hr, "Failed to convert hash bytes to string."); - - WcaLog(LOGMSG_VERBOSE, "Custom action data hash: %ls", pwzHashString); - WcaLog(LOGMSG_TRACEONLY, "Custom action data being written to ca script: %ls", vpwzCustomActionData); - } - else - hr = S_FALSE; - -LExit: - // Release the string - ReleaseStr(vpwzCustomActionData); - ReleaseStr(pwzHashString); - - // Flush the ca script to disk as best we can - WcaCaScriptFlush(hScript); - - WcaCaScriptClose(hScript, WCA_CASCRIPT_CLOSE_PRESERVE); - - return hr; -} - - -HRESULT ScaLoadMetabase(IMSAdminBase** ppiMetabase) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the - // user to still uninstall this package by clicking "Ignore" - do - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)ppiMetabase); - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object"); - er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); - switch (er) - { - case IDABORT: - ExitFunction(); // bail with the error result from the CoCreate to kick off a rollback - case IDRETRY: - hr = S_FALSE; // hit me, baby, one more time - break; - case IDIGNORE: - hr = S_OK; // pretend everything is okay and bail - break; - default: // For failure on uninstall continue - hr = S_OK; - break; - } - } - } while (S_FALSE == hr); - -LExit: - return hr; -} diff --git a/src/ca/scaiis.h b/src/ca/scaiis.h deleted file mode 100644 index 4c743edf..00000000 --- a/src/ca/scaiis.h +++ /dev/null @@ -1,33 +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 ScaMetabaseTransaction(__in_z LPCWSTR wzBackup); - -HRESULT ScaCreateWeb(IMSAdminBase* piMetabase, LPCWSTR wzWeb, LPCWSTR wzWebBase); - -HRESULT ScaDeleteApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot); - -HRESULT ScaCreateApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot, - DWORD dwIsolation); - -HRESULT ScaCreateMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey); - -HRESULT ScaDeleteMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey); - -HRESULT ScaWriteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey, DWORD dwIdentifier, - DWORD dwAttributes, DWORD dwUserType, - DWORD dwDataType, LPVOID pvData); - -HRESULT ScaDeleteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, - LPCWSTR wzSubKey, DWORD dwIdentifier, - DWORD dwDataType); - -HRESULT ScaWriteConfigurationScript(LPCWSTR pwzCaScriptKey); - -HRESULT ScaAddToIisConfiguration(LPCWSTR pwzData, DWORD dwCost); - -HRESULT ScaLoadMetabase(IMSAdminBase** piMetabase); diff --git a/src/ca/scaiis7.cpp b/src/ca/scaiis7.cpp deleted file mode 100644 index aaf307d7..00000000 --- a/src/ca/scaiis7.cpp +++ /dev/null @@ -1,74 +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" - -#define COST_IIS_WRITEKEY 10 - -HRESULT ScaIIS7ConfigTransaction(LPCWSTR wzBackup) -{ - HRESULT hr = S_OK; - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"StartIIS7ConfigTransaction"), wzBackup, COST_IIS_TRANSACTIONS); - ExitOnFailure(hr, "Failed to schedule StartIIS7ConfigTransaction"); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackIIS7ConfigTransaction"), wzBackup, 0); // rollback cost is irrelevant - ExitOnFailure(hr, "Failed to schedule RollbackIIS7ConfigTransaction"); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CommitIIS7ConfigTransaction"), wzBackup, 0); // commit is free - ExitOnFailure(hr, "Failed to schedule StartIIS7ConfigTransaction"); - -LExit: - return hr; -} - -HRESULT ScaWriteConfigString(const LPCWSTR wzValue) -{ - HRESULT hr = S_OK; - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteStringToCaData(wzValue, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEKEY); - ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEKEY); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - -HRESULT ScaWriteConfigInteger(DWORD dwValue) -{ - HRESULT hr = S_OK; - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteIntegerToCaData(dwValue, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEKEY); - ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEKEY); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - -HRESULT ScaWriteConfigID(IIS_CONFIG_ACTION emID) -{ - HRESULT hr = S_OK; - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteIntegerToCaData(emID, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); - - hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEKEY); - ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEKEY); - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} - diff --git a/src/ca/scaiis7.h b/src/ca/scaiis7.h deleted file mode 100644 index f398deca..00000000 --- a/src/ca/scaiis7.h +++ /dev/null @@ -1,17 +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 ScaScheduleIIS7Configuration(); - -HRESULT ScaIIS7ConfigTransaction(__in_z LPCWSTR wzBackup); - -HRESULT ScaCreateApp7(__in_z LPCWSTR wzWebRoot, DWORD dwIsolation); - -HRESULT ScaDeleteConfigElement(IIS_CONFIG_ACTION emElement, LPCWSTR wzSubKey); - -HRESULT ScaWriteConfigString(__in_z const LPCWSTR wzValue); - -HRESULT ScaWriteConfigID(IIS_CONFIG_ACTION emID); - -HRESULT ScaWriteConfigInteger(DWORD dwValue); diff --git a/src/ca/scamimemap.cpp b/src/ca/scamimemap.cpp deleted file mode 100644 index 8afe99f9..00000000 --- a/src/ca/scamimemap.cpp +++ /dev/null @@ -1,200 +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" - -enum eMimeMapQuery { mmqMimeMap = 1, mmqParentType, mmqParentValue, - mmqMimeType, mmqExtension}; - -// prototypes -static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList); - - -void ScaMimeMapFreeList(SCA_MIMEMAP* psmmList) -{ - SCA_MIMEMAP* psmmDelete = psmmList; - while (psmmList) - { - psmmDelete = psmmList; - psmmList = psmmList->psmmNext; - - MemFree(psmmDelete); - } -} - - -HRESULT __stdcall ScaMimeMapRead( - SCA_MIMEMAP** ppsmmList, - __inout LPWSTR *ppwzCustomActionData - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - LPWSTR pwzData = NULL; - SCA_MIMEMAP* psmm; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaMimeMapRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaMimeMapRead() - required table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the mimemappings - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - hr = AddMimeMapToList(ppsmmList); - ExitOnFailure(hr, "failed to add mime map to list"); - - psmm = *ppsmmList; - - hr = WcaGetRecordString(hRec, mmqMimeMap, &pwzData); - ExitOnFailure(hr, "Failed to get MimeMap.MimeMap"); - hr = ::StringCchCopyW(psmm->wzMimeMap, countof(psmm->wzMimeMap), pwzData); - ExitOnFailure(hr, "Failed to copy mimemap string to mimemap object"); - - hr = WcaGetRecordInteger(hRec, mmqParentType, &psmm->iParentType); - ExitOnFailure(hr, "Failed to get MimeMap.iParentType"); - - hr = WcaGetRecordString(hRec, mmqParentValue, &pwzData); - ExitOnFailure(hr, "Failed to get MimeMap.ParentValue"); - hr = ::StringCchCopyW(psmm->wzParentValue, countof(psmm->wzParentValue), pwzData); - ExitOnFailure(hr, "Failed to copy parent value string to mimemap object"); - - hr = WcaGetRecordString(hRec, mmqExtension, &pwzData); - ExitOnFailure(hr, "Failed to get MimeMap.Extension"); - hr = ::StringCchCopyW(psmm->wzExtension, countof(psmm->wzExtension), pwzData); - ExitOnFailure(hr, "Failed to copy extension string to mimemap object"); - - hr = WcaGetRecordString(hRec, mmqMimeType, &pwzData); - ExitOnFailure(hr, "Failed to get MimeMap.MimeType"); - hr = ::StringCchCopyW(psmm->wzMimeType, countof(psmm->wzMimeType), pwzData); - ExitOnFailure(hr, "Failed to copy mimetype string to mimemap object"); - } - - if (E_NOMOREITEMS == hr) - hr = S_OK; - ExitOnFailure(hr, "Failure while processing mimemappings"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaGetMimeMap(int iParentType, LPCWSTR wzParentValue, SCA_MIMEMAP **ppsmmList, SCA_MIMEMAP **ppsmmOut) -{ - HRESULT hr = S_OK; - SCA_MIMEMAP* psmmAdd = NULL; - SCA_MIMEMAP* psmmLast = NULL; - - *ppsmmOut = NULL; - - if (!*ppsmmList) - return hr; - - SCA_MIMEMAP* psmm = *ppsmmList; - while (psmm) - { - if (iParentType == psmm->iParentType && 0 == lstrcmpW(wzParentValue, psmm->wzParentValue)) - { - // Found a match, take this one out of the list and add it to the matched out list - psmmAdd = psmm; - - if (psmmLast) - { - // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) - psmmLast->psmmNext = psmmAdd->psmmNext; - } - else - { - // If we are at the beginning (no psmmLast) update the beginning (since we're taking it) - *ppsmmList = psmm->psmmNext; - } - psmm = psmm->psmmNext; // move on - - // Add the one we've removed to the beginning of the out list - psmmAdd->psmmNext = *ppsmmOut; - *ppsmmOut = psmmAdd; - } - else - { - psmmLast = psmm; // remember the last we that didn't match - psmm = psmm->psmmNext; // move on - } - } - - return hr; -} - -HRESULT ScaMimeMapCheckList(SCA_MIMEMAP* psmmList) -{ - if (!psmmList) - return S_OK; - - while (psmmList) - { - WcaLog(LOGMSG_STANDARD, "MimeMapping of %ls with ParentType=%d and ParentValue=%ls not used!", psmmList->wzMimeMap, psmmList->iParentType, psmmList->wzParentValue); - psmmList = psmmList->psmmNext; - } - - return E_FAIL; -} - - -HRESULT ScaWriteMimeMap(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, - SCA_MIMEMAP* psmmList) -{ - HRESULT hr = S_OK; - - WCHAR wzMimeMap[8192]; - WCHAR *pwzNext = wzMimeMap; - const WCHAR *pwzMac = wzMimeMap + countof(wzMimeMap); // used to properly create the MULTI_SZ - - // fill the MULTI_SZ wzMimeMap buffer for the MimeMap attribute - ::ZeroMemory(wzMimeMap, sizeof(wzMimeMap)); - - for (SCA_MIMEMAP* psmm = psmmList; psmm; psmm = psmm->psmmNext) - { - hr = ::StringCchPrintfW(pwzNext, max(0, pwzMac - pwzNext), L"%s,%s", psmm->wzExtension, psmm->wzMimeType); - ExitOnFailure(hr, "Failed to set MimeMap string"); - - pwzNext += lstrlenW(pwzNext) + 1; // reserve space for null - Assert(pwzNext <= pwzMac); - } - - if (pwzNext != wzMimeMap) - { - // now write the CustomErrors to the metabase - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_MIME_MAP, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzMimeMap); - ExitOnFailure(hr, "Failed to write MimeMap"); - } - else - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaWriteMimeMap() - no mappings found."); - ExitFunction1(hr = S_FALSE); - } - -LExit: - return hr; -} - - -static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList) -{ - HRESULT hr = S_OK; - - SCA_MIMEMAP* psmm = static_cast(MemAlloc(sizeof(SCA_MIMEMAP), TRUE)); - ExitOnNull(psmm, hr, E_OUTOFMEMORY, "failed to allocate memory for new mime map list element"); - - psmm->psmmNext = *ppsmmList; - *ppsmmList = psmm; - -LExit: - return hr; -} diff --git a/src/ca/scamimemap.h b/src/ca/scamimemap.h deleted file mode 100644 index b50e82e9..00000000 --- a/src/ca/scamimemap.h +++ /dev/null @@ -1,33 +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. - - -enum eMimeMapParentType { mmptVDir = 1, mmptWeb = 2 }; - -struct SCA_MIMEMAP -{ - // iis configuation information - WCHAR wzMimeMap[MAX_DARWIN_KEY + 1]; - int iParentType; - WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; - WCHAR wzMimeType[MAX_DARWIN_KEY + 1]; - WCHAR wzExtension[MAX_DARWIN_KEY + 1]; - - - SCA_MIMEMAP* psmmNext; -}; - - -// prototypes - -HRESULT __stdcall ScaMimeMapRead(SCA_MIMEMAP** ppsmmList, __inout LPWSTR *ppwzCustomActionData); - -HRESULT ScaGetMimeMap(int iParentType, LPCWSTR wzParentValue, SCA_MIMEMAP **psmmList, SCA_MIMEMAP **ppsmmOut); - -HRESULT ScaMimeMapCheckList(SCA_MIMEMAP* psmmList); - -void ScaMimeMapFreeList(SCA_MIMEMAP* psmmList); - -HRESULT ScaWriteMimeMap(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, - SCA_MIMEMAP* psmmList); - diff --git a/src/ca/scamimemap7.cpp b/src/ca/scamimemap7.cpp deleted file mode 100644 index f6689720..00000000 --- a/src/ca/scamimemap7.cpp +++ /dev/null @@ -1,68 +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" - -// prototypes -HRESULT ScaWriteMimeMap7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - SCA_MIMEMAP* psmmList - ) -{ - HRESULT hr = S_OK; - SCA_MIMEMAP* psmm; - - //create the mimemap list for this vdir application - //all go to same web/root location tag - hr = ScaWriteConfigID(IIS_MIMEMAP_BEGIN); - ExitOnFailure(hr, "Failed to write mimemap begin id"); - hr = ScaWriteConfigString(wzWebName); //site name key - ExitOnFailure(hr, "Failed to write mimemap web key"); - hr = ScaWriteConfigString(wzRootOfWeb); //app path key - ExitOnFailure(hr, "Failed to write mimemap app key"); - - psmm = psmmList; - - while (psmm) - { - //create the Extension for this vdir application - hr = ScaWriteConfigID(IIS_MIMEMAP); - ExitOnFailure(hr, "Failed to write mimemap id"); - - if (*psmm->wzExtension) - { - hr = ScaWriteConfigString(psmm->wzExtension); - } - else // blank means "*" (all) - { - hr = ScaWriteConfigString(L"*"); - } - ExitOnFailure(hr, "Failed to write mimemap extension"); - - hr = ScaWriteConfigString(psmm->wzMimeType); - ExitOnFailure(hr, "Failed to write mimemap type"); - - psmm = psmm->psmmNext; - } - - hr = ScaWriteConfigID(IIS_MIMEMAP_END); - ExitOnFailure(hr, "Failed to write mimemap end id"); - -LExit: - return hr; -} - - -//static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList) -//{ -// HRESULT hr = S_OK; -// -// SCA_MIMEMAP* psmm = static_cast(MemAlloc(sizeof(SCA_MIMEMAP), TRUE)); -// ExitOnNull(psmm, hr, E_OUTOFMEMORY, "failed to allocate memory for new mime map list element"); -// -// psmm->psmmNext = *ppsmmList; -// *ppsmmList = psmm; -// -//LExit: -// return hr; -//} diff --git a/src/ca/scamimemap7.h b/src/ca/scamimemap7.h deleted file mode 100644 index 88fcdc39..00000000 --- a/src/ca/scamimemap7.h +++ /dev/null @@ -1,10 +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 ScaWriteMimeMap7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - SCA_MIMEMAP* psmmList - ); - diff --git a/src/ca/scaproperty.cpp b/src/ca/scaproperty.cpp deleted file mode 100644 index d0e0d8a4..00000000 --- a/src/ca/scaproperty.cpp +++ /dev/null @@ -1,252 +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" - -/*------------------------------------------------------------------ -IIsProperty table: - -Property Component_ Attributes Value -s72 s72 i4 s255 -------------------------------------------------------------------*/ - -// sql queries -enum ePropertyQuery { pqProperty = 1, pqComponent, pqAttributes, pqValue, pqInstalled, pqAction }; - - -// prototypes -static HRESULT AddPropertyToList( - SCA_PROPERTY** ppspList - ); - - -// functions -void ScaPropertyFreeList( - SCA_PROPERTY* pspList - ) -{ - SCA_PROPERTY* pspDelete = pspList; - while (pspList) - { - pspDelete = pspList; - pspList = pspList->pspNext; - - MemFree(pspDelete); - } -} - - -HRESULT ScaPropertyRead( - SCA_PROPERTY** ppspList, - __inout LPWSTR *ppwzCustomActionData - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - - LPWSTR pwzData = NULL; - SCA_PROPERTY* pss; - - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - ExitOnNull(ppspList, hr, E_INVALIDARG, "Failed to read property, because no property to read was provided"); - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallProperty() - required table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the Settings - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - hr = AddPropertyToList(ppspList); - ExitOnFailure(hr, "failed to add property to list"); - - pss = *ppspList; - - hr = WcaGetRecordString(hRec, pqProperty, &pwzData); - ExitOnFailure(hr, "failed to get IIsProperty.Property"); - hr = ::StringCchCopyW(pss->wzProperty, countof(pss->wzProperty), pwzData); - ExitOnFailure(hr, "failed to copy Property name: %ls", pwzData); - - hr = WcaGetRecordString(hRec, pqValue, &pwzData); - ExitOnFailure(hr, "failed to get IIsProperty.Value"); - hr = ::StringCchCopyW(pss->wzValue, countof(pss->wzValue), pwzData); - ExitOnFailure(hr, "failed to copy Property value: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, pqAttributes, &pss->iAttributes); - ExitOnFailure(hr, "failed to get IIsProperty.Attributes"); - - hr = WcaGetRecordString(hRec, pqComponent, &pwzData); - ExitOnFailure(hr, "failed to get IIsProperty.Component"); - hr = ::StringCchCopyW(pss->wzComponent, countof(pss->wzComponent), pwzData); - ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, pqInstalled, (int *)&pss->isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for filter"); - - hr = WcaGetRecordInteger(hRec, pqAction, (int *)&pss->isAction); - ExitOnFailure(hr, "Failed to get Component action state for filter"); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "failure while processing IIsProperty table"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaPropertyInstall( - IMSAdminBase* piMetabase, - SCA_PROPERTY* pspList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - - for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) - { - // if we are installing the web site - if (WcaIsInstalling(psp->isInstalled, psp->isAction)) - { - hr = ScaWriteProperty(piMetabase, psp); - ExitOnFailure(hr, "failed to write Property '%ls' to metabase", psp->wzProperty); - } - } - -LExit: - return hr; -} - - -HRESULT ScaPropertyUninstall( - IMSAdminBase* piMetabase, - SCA_PROPERTY* pspList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - - for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) - { - // if we are uninstalling the web site - if (WcaIsUninstalling(psp->isInstalled, psp->isAction)) - { - hr = ScaRemoveProperty(piMetabase, psp); - ExitOnFailure(hr, "Failed to remove Property '%ls' from metabase", psp->wzProperty); - } - } - -LExit: - return hr; -} - - -HRESULT ScaWriteProperty( - IMSAdminBase* piMetabase, - SCA_PROPERTY* psp - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - DWORD dwValue; - LPWSTR wz = NULL; - - ExitOnNull(psp, hr, E_INVALIDARG, "Failed to write property because no property to write was given"); - - // - // Figure out what setting we're writing and write it - // - if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) - { - dwValue = 1; - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_STANDARD_APP_MODE_ENABLED, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to set IIs5IsolationMode"); - } - else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) - { - dwValue = wcstoul(psp->wzValue, &wz, 10) * 1024; // remember, the value shown is in kilobytes, the value saved is in bytes - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_MAX_GLOBAL_BANDWIDTH, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to set MaxGlobalBandwidth"); - } - else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) - { - dwValue = 1; - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_LOG_IN_UTF_8, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to set LogInUTF8"); - } - else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_ETAG_CHANGENUMBER)) - { - dwValue = wcstoul(psp->wzValue, &wz, 10); - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, /*MD_ETAG_CHANGENUMBER*/ 2039, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to set EtagChangenumber"); - } -LExit: - return hr; -} - - -HRESULT ScaRemoveProperty( - IMSAdminBase* piMetabase, - SCA_PROPERTY* psp - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - DWORD dwValue; - - ExitOnNull(psp, hr, E_INVALIDARG, "Failed to remove property because no property to remove was given"); - - if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) - { - dwValue = 0; - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_STANDARD_APP_MODE_ENABLED, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to clear IIs5IsolationMode"); - } - else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) - { - dwValue = 0xFFFFFFFF; // This unchecks the box - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_MAX_GLOBAL_BANDWIDTH, METADATA_NO_ATTRIBUTES , IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to clear MaxGlobalBandwidth"); - } - else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) - { - dwValue = 0; - hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_LOG_IN_UTF_8, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); - ExitOnFailure(hr, "failed to clear LogInUTF8"); - } - -LExit: - return hr; -} - - -static HRESULT AddPropertyToList( - SCA_PROPERTY** ppspList - ) -{ - HRESULT hr = S_OK; - SCA_PROPERTY* psp = static_cast(MemAlloc(sizeof(SCA_PROPERTY), TRUE)); - ExitOnNull(psp, hr, E_OUTOFMEMORY, "failed to allocate memory for new property list element"); - - psp->pspNext = *ppspList; - *ppspList = psp; - -LExit: - return hr; -} diff --git a/src/ca/scaproperty.h b/src/ca/scaproperty.h deleted file mode 100644 index 21e7cfc7..00000000 --- a/src/ca/scaproperty.h +++ /dev/null @@ -1,54 +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 wzIISPROPERTY_IIS5_ISOLATION_MODE L"IIs5IsolationMode" -#define wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH L"MaxGlobalBandwidth" -#define wzIISPROPERTY_LOG_IN_UTF8 L"LogInUTF8" -#define wzIISPROPERTY_ETAG_CHANGENUMBER L"ETagChangeNumber" - -struct SCA_PROPERTY -{ - // iis configuation information - WCHAR wzProperty[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - INT iAttributes; - WCHAR wzValue[MAX_DARWIN_COLUMN + 1]; - - SCA_PROPERTY *pspNext; -}; - - -// prototypes - -HRESULT ScaPropertyRead( - SCA_PROPERTY** ppspList, - __inout LPWSTR *ppwzCustomActionData - ); - -void ScaPropertyFreeList( - SCA_PROPERTY* pspList - ); - -HRESULT ScaPropertyInstall( - IMSAdminBase* piMetabase, - SCA_PROPERTY* pspList - ); - -HRESULT ScaPropertyUninstall( - IMSAdminBase* piMetabase, - SCA_PROPERTY* pspList - ); - -HRESULT ScaWriteProperty( - IMSAdminBase* piMetabase, - SCA_PROPERTY* psp - ); - -HRESULT ScaRemoveProperty( - IMSAdminBase* piMetabase, - SCA_PROPERTY* psp - ); - diff --git a/src/ca/scaproperty7.cpp b/src/ca/scaproperty7.cpp deleted file mode 100644 index d17eeb68..00000000 --- a/src/ca/scaproperty7.cpp +++ /dev/null @@ -1,108 +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" - -HRESULT ScaPropertyInstall7( - SCA_PROPERTY* pspList - ) -{ - HRESULT hr = S_OK; - - for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) - { - // if we are installing the web site - if (WcaIsInstalling(psp->isInstalled, psp->isAction)) - { - hr = ScaWriteProperty7(psp); - ExitOnFailure(hr, "failed to write Property '%ls' ", psp->wzProperty); - } - } - -LExit: - return hr; -} - - -HRESULT ScaPropertyUninstall7( - SCA_PROPERTY* pspList - ) -{ - HRESULT hr = S_OK; - - for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) - { - // if we are uninstalling the web site - if (WcaIsUninstalling(psp->isInstalled, psp->isAction)) - { - hr = ScaRemoveProperty7(psp); - ExitOnFailure(hr, "Failed to remove Property '%ls'", psp->wzProperty); - } - } - -LExit: - return hr; -} - - -HRESULT ScaWriteProperty7( - const SCA_PROPERTY* psp - ) -{ - HRESULT hr = S_OK; - DWORD dwValue; - LPWSTR wz = NULL; - - ExitOnNull(psp, hr, E_INVALIDARG, "Failed to write property because no property to write was given"); - // - // Figure out what setting we're writing and write it - // - if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) - { - // IIs5IsolationMode not supported - WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: IIs5IsolationMode, ignoring"); - } - else if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) - { - dwValue = wcstoul(psp->wzValue, &wz, 10) * 1024; // remember, the value shown is in kilobytes, the value saved is in bytes - hr = ScaWriteConfigID(IIS_PROPERTY); - ExitOnFailure(hr, "failed to set Property ID"); - hr = ScaWriteConfigID(IIS_PROPERTY_MAXBAND); - ExitOnFailure(hr, "failed to set Property MSXBAND ID"); - hr = ScaWriteConfigInteger(dwValue); - ExitOnFailure(hr, "failed to set Property MSXBAND value"); - } - else if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) - { - dwValue = 1; - hr = ScaWriteConfigID(IIS_PROPERTY); - ExitOnFailure(hr, "failed to set Property ID"); - hr = ScaWriteConfigID(IIS_PROPERTY_LOGUTF8); - ExitOnFailure(hr, "failed to set Property LOG ID"); - hr = ScaWriteConfigInteger(dwValue); - ExitOnFailure(hr, "failed to set Property Log value"); - } - else if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_ETAG_CHANGENUMBER)) - { - //EtagChangenumber not supported - WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: EtagChangenumber, ignoring"); - } - -LExit: - return hr; -} - -HRESULT ScaRemoveProperty7( - __in SCA_PROPERTY* /*psp*/ - ) -{ - - // NOP function for now - //The two global values being set by WebProperty: - // - // - // should should not be removed on uninstall. - - HRESULT hr = S_OK; - - return hr; -} diff --git a/src/ca/scaproperty7.h b/src/ca/scaproperty7.h deleted file mode 100644 index bbf811e8..00000000 --- a/src/ca/scaproperty7.h +++ /dev/null @@ -1,26 +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 wzIISPROPERTY_IIS5_ISOLATION_MODE L"IIs5IsolationMode" -#define wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH L"MaxGlobalBandwidth" -#define wzIISPROPERTY_LOG_IN_UTF8 L"LogInUTF8" -#define wzIISPROPERTY_ETAG_CHANGENUMBER L"ETagChangeNumber" - -// prototypes -HRESULT ScaPropertyInstall7( - SCA_PROPERTY* pspList - ); - -HRESULT ScaPropertyUninstall7( - SCA_PROPERTY* pspList - ); - -HRESULT ScaWriteProperty7( - const SCA_PROPERTY* psp - ); - -HRESULT ScaRemoveProperty7( - SCA_PROPERTY* psp - ); - diff --git a/src/ca/scasched.cpp b/src/ca/scasched.cpp deleted file mode 100644 index de021275..00000000 --- a/src/ca/scasched.cpp +++ /dev/null @@ -1,823 +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" - -const int ConfigureIIsCost = 8; -const int WriteMetabaseChangesCost = 20; -const int WriteIIS7ConfigChangesCost = 20; - -// sql queries -LPCWSTR vcsUserDeferredQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `User`"; - -LPCWSTR vcsWebSvcExtQuery = L"SELECT `Component_`, `File`, `Description`, `Group`, `Attributes` FROM `IIsWebServiceExtension`"; - -LPCWSTR vcsAppPoolQuery = L"SELECT `AppPool`, `Name`, `Component_`, `Attributes`, `User_`, `RecycleMinutes`, `RecycleRequests`, `RecycleTimes`, `VirtualMemory`, `PrivateMemory`, `IdleTimeout`, `QueueLimit`, `CPUMon`, `MaxProc`, `ManagedRuntimeVersion`, `ManagedPipelineMode` FROM `IIsAppPool`"; - -LPCWSTR vcsComponentAttrQuery = L"SELECT `Component`,`Attributes` FROM `Component`"; - -LPCWSTR vcsMimeMapQuery = L"SELECT `MimeMap`, `ParentType`, `ParentValue`, `MimeType`, `Extension` FROM `IIsMimeMap`"; - -LPCWSTR vcsHttpHeaderQuery = L"SELECT `Name`, `ParentType`, `ParentValue`, `Value`, `Attributes` FROM `IIsHttpHeader` ORDER BY `Sequence`"; - -LPCWSTR vcsWebErrorQuery = - L"SELECT `ErrorCode`, `SubCode`, `ParentType`, `ParentValue`, `File`, `URL` " - L"FROM `IIsWebError` ORDER BY `ErrorCode`, `SubCode`"; - -LPCWSTR vcsWebDirPropertiesQuery = L"SELECT `DirProperties`, `Access`, `Authorization`, `AnonymousUser_`, `IIsControlledPassword`, `LogVisits`, `Index`, `DefaultDoc`, `AspDetailedError`, `HttpExpires`, `CacheControlMaxAge`, `CacheControlCustom`, `NoCustomError`, `AccessSSLFlags`, `AuthenticationProviders` " - L"FROM `IIsWebDirProperties`"; - -LPCWSTR vcsSslCertificateQuery = L"SELECT `Certificate`.`StoreName`, `CertificateHash`.`Hash`, `IIsWebSiteCertificates`.`Web_` FROM `Certificate`, `CertificateHash`, `IIsWebSiteCertificates` WHERE `Certificate`.`Certificate`=`CertificateHash`.`Certificate_` AND `CertificateHash`.`Certificate_`=`IIsWebSiteCertificates`.`Certificate_`"; - -LPCWSTR vcsWebLogQuery = L"SELECT `Log`, `Format` " - L"FROM `IIsWebLog`"; - -LPCWSTR vcsWebApplicationQuery = L"SELECT `Name`, `Isolation`, `AllowSessions`, `SessionTimeout`, " - L"`Buffer`, `ParentPaths`, `DefaultScript`, `ScriptTimeout`, " - L"`ServerDebugging`, `ClientDebugging`, `AppPool_`, `Application` " - L"FROM `IIsWebApplication`"; - -LPCWSTR vcsWebAppExtensionQuery = L"SELECT `Extension`, `Verbs`, `Executable`, `Attributes`, `Application_` FROM `IIsWebApplicationExtension`"; - -LPCWSTR vcsWebQuery = L"SELECT `Web`, `Component_`, `Id`, `Description`, `ConnectionTimeout`, `Directory_`, `State`, `Attributes`, `DirProperties_`, `Application_`, " - L"`Address`, `IP`, `Port`, `Header`, `Secure`, `Log_` FROM `IIsWebSite`, `IIsWebAddress` " - L"WHERE `KeyAddress_`=`Address` ORDER BY `Sequence`"; - -LPCWSTR vcsWebAddressQuery = L"SELECT `Address`, `Web_`, `IP`, `Port`, `Header`, `Secure` " - L"FROM `IIsWebAddress`"; - -LPCWSTR vcsWebBaseQuery = L"SELECT `Web`, `Id`, `IP`, `Port`, `Header`, `Secure`, `Description` " - L"FROM `IIsWebSite`, `IIsWebAddress` " - L"WHERE `KeyAddress_`=`Address`"; - -LPCWSTR vcsWebDirQuery = L"SELECT `Web_`, `WebDir`, `Component_`, `Path`, `DirProperties_`, `Application_` " - L"FROM `IIsWebDir`"; - -LPCWSTR vcsVDirQuery = L"SELECT `Web_`, `VirtualDir`, `Component_`, `Alias`, `Directory_`, `DirProperties_`, `Application_` " - L"FROM `IIsWebVirtualDir`"; - -LPCWSTR vcsFilterQuery = L"SELECT `Web_`, `Name`, `Component_`, `Path`, `Description`, `Flags`, `LoadOrder` FROM `IIsFilter` ORDER BY `Web_`"; - -LPCWSTR vcsPropertyQuery = L"SELECT `Property`, `Component_`, `Attributes`, `Value` " - L"FROM `IIsProperty`"; - -#define IIS7CONDITION L"VersionNT >= 600" -#define USEIIS7CONDITION IIS7CONDITION L"AND NOT UseIis6Compatibility" - -/******************************************************************** -ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings - -********************************************************************/ -extern "C" UINT __stdcall ConfigureIIs( - __in MSIHANDLE hInstall - ) -{ - //AssertSz(FALSE, "debug ConfigureIIs here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - LPWSTR pwzScriptKey = NULL; - LPWSTR pwzBackupId = NULL; - LPWSTR pwzCustomActionData = NULL; // CustomActionData for ConfigureIIs custom action - - // initialize - hr = WcaInitialize(hInstall, "ConfigureIIs"); - ExitOnFailure(hr, "Failed to initialize"); - - // check for the prerequsite tables - if (S_OK != WcaTableExists(L"IIsWebSite") && S_OK != WcaTableExists(L"IIsFilter") && S_OK != WcaTableExists(L"IIsProperty") && - S_OK != WcaTableExists(L"IIsWebServiceExtension") && S_OK != WcaTableExists(L"IIsAppPool")) - { - WcaLog(LOGMSG_VERBOSE, "skipping IIs CustomAction, no IIsWebSite table, no IIsFilter table, no IIsProperty table, no IIsWebServiceExtension, and no IIsAppPool table"); - ExitFunction1(hr = S_FALSE); - } - - // Get a CaScript key - hr = WcaCaScriptCreateKey(&pwzScriptKey); - ExitOnFailure(hr, "Failed to get encoding key."); - - // Generate a unique string to be used for this product's transaction - // This prevents a name collision when doing a major upgrade - hr = WcaGetProperty(L"ProductCode", &pwzBackupId); - ExitOnFailure(hr, "failed to get ProductCode"); - - hr = StrAllocConcat(&pwzBackupId, L"ScaConfigureIIs", 0); - ExitOnFailure(hr, "failed to concat ScaConfigureIIs"); - - // make sure the operations below are wrapped in a "transaction" - // use IIS7 transaction logic even if using Iis6 compat because Backup/Restore don't work with metabase compatibility - if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, IIS7CONDITION)) - { - hr = ScaIIS7ConfigTransaction(pwzBackupId); - MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS7 transaction"); - } - else - { - hr = ScaMetabaseTransaction(pwzBackupId); - MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS transaction"); - } - - // Write the CaScript key to the ConfigureIIS custom action data - hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add encoding key to CustomActionData."); - - // Wrap vcsUserDeferredQuery to send to deferred CA - if (S_OK == WcaTableExists(L"User")) - { - hr = WcaWrapQuery(vcsUserDeferredQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap User query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap User empty query"); - } - - // Wrap vcsWebSvcExtQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebServiceExtension")) - { - hr = WcaWrapQuery(vcsWebSvcExtQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4, 1, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension empty query"); - } - - // Wrap vcsAppPoolQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsAppPool")) - { - hr = WcaWrapQuery(vcsAppPoolQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn15 | efmcColumn16, 3, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsAppPool query"); - - hr = WcaWrapQuery(vcsComponentAttrQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap Component query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsAppPool empty query"); - } - - // Wrap vcsMimeMapQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsMimeMap")) - { - hr = WcaWrapQuery(vcsMimeMapQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsMimeMap query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsMimeMap empty query"); - } - - // Wrap vcsHttpHeaderQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsHttpHeader")) - { - hr = WcaWrapQuery(vcsHttpHeaderQuery, &pwzCustomActionData, efmcColumn1 | efmcColumn4, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsHttpHeader query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsHttpHeader empty query"); - } - - // Wrap vcsWebErrorQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebError")) - { - hr = WcaWrapQuery(vcsWebErrorQuery, &pwzCustomActionData, efmcColumn5 | efmcColumn6, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebError query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebError empty query"); - } - - // Wrap vcsWebDirPropertiesQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebDirProperties")) - { - hr = WcaWrapQuery(vcsWebDirPropertiesQuery, &pwzCustomActionData, efmcColumn8 | efmcColumn10 | efmcColumn12 | efmcColumn15, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties empty query"); - } - - // Wrap vcsSslCertificateQuery to send to deferred CA - if (S_OK == WcaTableExists(L"Certificate") && S_OK == WcaTableExists(L"CertificateHash") && S_OK == WcaTableExists(L"IIsWebSiteCertificates")) - { - hr = WcaWrapQuery(vcsSslCertificateQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap SslCertificate query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap SslCertificate empty query"); - } - - // Wrap vcsWebLogQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebLog")) - { - hr = WcaWrapQuery(vcsWebLogQuery, &pwzCustomActionData, efmcColumn2, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebLog query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebLog empty query"); - } - - // Wrap vcsWebApplicationQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebApplication")) - { - hr = WcaWrapQuery(vcsWebApplicationQuery, &pwzCustomActionData, efmcColumn1, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebApplication query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebApplication empty query"); - } - - // Wrap vcsWebAppExtensionQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebApplicationExtension")) - { - hr = WcaWrapQuery(vcsWebAppExtensionQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension empty query"); - } - - // Wrap vcsWebQuery, vcsWebAddressQuery, and vcsWebBaseQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebAddress") && S_OK == WcaTableExists(L"IIsWebSite")) - { - hr = WcaWrapQuery(vcsWebQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn12 | efmcColumn13 | efmcColumn14, 2, 6); - ExitOnFailure(hr, "Failed to wrap IIsWebSite query"); - - hr = WcaWrapQuery(vcsWebAddressQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebAddress query"); - - hr = WcaWrapQuery(vcsWebBaseQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4 | efmcColumn5 | efmcColumn7, 0xFFFFFFFF, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebBase query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebSite empty query"); - - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebAddress empty query"); - - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebBase empty query"); - } - - // Wrap vcsWebDirQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebDir")) - { - hr = WcaWrapQuery(vcsWebDirQuery, &pwzCustomActionData, efmcColumn4, 3, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsWebDir query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebDir empty query"); - } - - // Wrap vcsVDirQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsWebVirtualDir")) - { - hr = WcaWrapQuery(vcsVDirQuery, &pwzCustomActionData, efmcColumn4, 3, 5); - ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir empty query"); - } - - // Wrap vcsFilterQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsFilter")) - { - hr = WcaWrapQuery(vcsFilterQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 3, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsFilter query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsFilter empty query"); - } - - // Wrap vcsPropertyQuery to send to deferred CA - if (S_OK == WcaTableExists(L"IIsProperty")) - { - hr = WcaWrapQuery(vcsPropertyQuery, &pwzCustomActionData, efmcColumn4, 2, 0xFFFFFFFF); - ExitOnFailure(hr, "Failed to wrap IIsProperty query"); - } - else - { - hr = WcaWrapEmptyQuery(&pwzCustomActionData); - ExitOnFailure(hr, "Failed to wrap IIsProperty empty query"); - } - - if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, USEIIS7CONDITION)) - { - // This must remain trace only, CA data may contain password - WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIIS7Exec will be: %ls", pwzCustomActionData); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ConfigureIIs7Exec"), pwzCustomActionData, ConfigureIIsCost); - ExitOnFailure(hr, "Failed to schedule ConfigureIIs7Exec custom action"); - - ReleaseNullStr(pwzCustomActionData); - - // Write the CaScript key to the ConfigureIIS custom action data - hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add script key to CustomActionData."); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WriteIIS7ConfigChanges"), pwzCustomActionData, WriteIIS7ConfigChangesCost); - ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action"); - } - else - { - // This must remain trace only, CA data may contain password - WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIISExec will be: %ls", pwzCustomActionData); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ConfigureIIsExec"), pwzCustomActionData, ConfigureIIsCost); - ExitOnFailure(hr, "Failed to schedule ConfigureIISExec custom action"); - - ReleaseNullStr(pwzCustomActionData); - - // Write the CaScript key to the ConfigureIIS custom action data - hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add script key to CustomActionData."); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WriteMetabaseChanges"), pwzCustomActionData, WriteMetabaseChangesCost); - ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action"); - } - -LExit: - ReleaseStr(pwzScriptKey); - ReleaseStr(pwzBackupId); - ReleaseStr(pwzCustomActionData); - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - -/******************************************************************** -ConfigureIIsExec - custom action for installing IIs settings - table -data will be wrapped and passed in from immediate CA -ReadIIsTables - -********************************************************************/ -extern "C" UINT __stdcall ConfigureIIsExec( - __in MSIHANDLE hInstall - ) -{ - //AssertSz(FALSE, "debug ConfigureIIsExec here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - BOOL fInitializedCom = FALSE; - IMSAdminBase* piMetabase = NULL; - - SCA_WEB* pswList = NULL; - SCA_WEBDIR* pswdList = NULL; - SCA_VDIR* psvdList = NULL; - SCA_FILTER* psfList = NULL; - SCA_APPPOOL *psapList = NULL; - SCA_MIMEMAP* psmmList = NULL; - SCA_HTTP_HEADER* pshhList = NULL; - SCA_PROPERTY *pspList = NULL; - SCA_WEBSVCEXT* psWseList = NULL; - SCA_WEB_ERROR* psweList = NULL; - - LPWSTR pwzScriptKey = NULL; - LPWSTR pwzCustomActionData = NULL; - - WCA_WRAPQUERY_HANDLE hUserQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL; - WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL; - - // initialize - hr = WcaInitialize(hInstall, "ConfigureIIsExec"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - // Get the CaScript key - hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey); - ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to initialize COM"); - fInitializedCom = TRUE; - - // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the - // user to still uninstall this package by clicking "Ignore" - do - { - hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)&piMetabase); - if (FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object"); - er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); - switch (er) - { - case IDABORT: - ExitFunction(); // bail with the error result from the CoCreate to kick off a rollback - case IDRETRY: - hr = S_FALSE; // hit me, baby, one more time - break; - case IDIGNORE: - __fallthrough; - default: - WcaLog(LOGMSG_STANDARD, "ignoring absent IIS"); - // We need to write the empty script to communicate to other deferred CA that there is noting to do. - hr = ScaWriteConfigurationScript(pwzScriptKey); - ExitOnFailure(hr, "failed to schedule metabase configuration"); - - ExitFunction1(hr = S_OK); // pretend everything is okay - break; - } - } - } while (S_FALSE == hr); - - // read the msi tables - hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap user query"); - - hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions"); - - hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools"); - - // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read - hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps"); - - hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders"); - - hr = ScaWebErrorRead(&psweList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors"); - - hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web dir properties query"); - - hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap ssl certificate query"); - - hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web log query"); - - hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web application query"); - - hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web application extension query"); - - hr = ScaWebsRead(piMetabase, &psmmList, &pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites"); - - hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web base query"); - - hr = ScaWebDirsRead(piMetabase, pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList); - MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs"); - - hr = ScaVirtualDirsRead(piMetabase, pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs"); - - hr = ScaFiltersRead(piMetabase, pswList, hWebBaseQuery, &psfList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters"); - - hr = ScaPropertyRead(&pspList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties"); - - // do uninstall actions (order is important!) - hr = ScaPropertyUninstall(piMetabase, pspList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties"); - - hr = ScaFiltersUninstall(piMetabase, psfList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters"); - - hr = ScaVirtualDirsUninstall(piMetabase, psvdList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories"); - - hr = ScaWebDirsUninstall(piMetabase, pswdList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories"); - - hr = ScaWebsUninstall(piMetabase, pswList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs"); - - hr = ScaAppPoolUninstall(piMetabase, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools"); - - - // do install actions (order is important!) - // ScaWebSvcExtCommit contains both uninstall and install actions. - hr = ScaWebSvcExtCommit(piMetabase, psWseList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt"); - - hr = ScaAppPoolInstall(piMetabase, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools"); - - hr = ScaWebsInstall(piMetabase, pswList, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs"); - - hr = ScaWebDirsInstall(piMetabase, pswdList, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories"); - - hr = ScaVirtualDirsInstall(piMetabase, psvdList, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories"); - - hr = ScaFiltersInstall(piMetabase, psfList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters"); - - hr = ScaPropertyInstall(piMetabase, pspList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties"); - - hr = ScaWriteConfigurationScript(pwzScriptKey); - ExitOnFailure(hr, "failed to schedule metabase configuration"); - -LExit: - ReleaseStr(pwzScriptKey); - ReleaseStr(pwzCustomActionData); - - WcaFinishUnwrapQuery(hUserQuery); - WcaFinishUnwrapQuery(hWebBaseQuery); - WcaFinishUnwrapQuery(hWebDirPropQuery); - WcaFinishUnwrapQuery(hSslCertQuery); - WcaFinishUnwrapQuery(hWebLogQuery); - WcaFinishUnwrapQuery(hWebAppQuery); - WcaFinishUnwrapQuery(hWebAppExtQuery); - - if (psWseList) - { - ScaWebSvcExtFreeList(psWseList); - } - - if (psfList) - { - ScaFiltersFreeList(psfList); - } - - if (psvdList) - { - ScaVirtualDirsFreeList(psvdList); - } - - if (pswdList) - { - ScaWebDirsFreeList(pswdList); - } - - if (pswList) - { - ScaWebsFreeList(pswList); - } - - if (psmmList) - { - ScaMimeMapCheckList(psmmList); - ScaMimeMapFreeList(psmmList); - } - - if (pshhList) - { - ScaHttpHeaderCheckList(pshhList); - ScaHttpHeaderFreeList(pshhList); - } - - if (psweList) - { - ScaWebErrorCheckList(psweList); - ScaWebErrorFreeList(psweList); - } - - ReleaseObject(piMetabase); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/******************************************************************** -ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings - -********************************************************************/ -extern "C" UINT __stdcall ConfigureIIs7Exec( - __in MSIHANDLE hInstall - ) -{ - //AssertSz(FALSE, "debug ConfigureIIs7Exec here"); - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - LPWSTR pwzScriptKey = NULL; - LPWSTR pwzCustomActionData = NULL; - - SCA_WEB7* pswList = NULL; - SCA_WEBDIR7* pswdList = NULL; - SCA_VDIR7* psvdList = NULL; - SCA_FILTER* psfList = NULL; - SCA_APPPOOL *psapList = NULL; - SCA_MIMEMAP* psmmList = NULL; - SCA_HTTP_HEADER* pshhList = NULL; - SCA_PROPERTY *pspList = NULL; - SCA_WEBSVCEXT* psWseList = NULL; - SCA_WEB_ERROR* psweList = NULL; - - WCA_WRAPQUERY_HANDLE hUserQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL; - WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL; - WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL; - - // initialize - hr = WcaInitialize(hInstall, "ConfigureIIs7Exec"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - // Get the CaScript key - hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey); - ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); - - // read the msi tables - hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap user query"); - - hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions"); - - hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools"); - - // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read - hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps"); - - hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders"); - - hr = ScaWebErrorRead(&psweList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors"); - - hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web dir properties query"); - - hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap ssl certificate query"); - - hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web log query"); - - hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web application query"); - - hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web application extension query"); - - hr = ScaWebsRead7(&pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites"); - - hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap web base query"); - - hr = ScaWebDirsRead7(pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList); - MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs"); - - hr = ScaVirtualDirsRead7(pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs"); - - hr = ScaFiltersRead7(pswList, hWebBaseQuery, &psfList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters"); - - hr = ScaPropertyRead(&pspList, &pwzCustomActionData); - MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties"); - - // do uninstall actions (order is important!) - hr = ScaPropertyUninstall7(pspList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties"); - - hr = ScaFiltersUninstall7(psfList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters"); - - hr = ScaVirtualDirsUninstall7(psvdList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories"); - - hr = ScaWebDirsUninstall7(pswdList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories"); - - hr = ScaWebsUninstall7(pswList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs"); - - hr = ScaAppPoolUninstall7(psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools"); - - - // do install actions (order is important!) - // ScaWebSvcExtCommit contains both uninstall and install actions. - hr = ScaWebSvcExtCommit7(psWseList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt"); - - hr = ScaAppPoolInstall7(psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools"); - - hr = ScaWebsInstall7(pswList, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs"); - - hr = ScaWebDirsInstall7(pswdList, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories"); - - hr = ScaVirtualDirsInstall7(psvdList, psapList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories"); - - hr = ScaFiltersInstall7(psfList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters"); - - hr = ScaPropertyInstall7(pspList); - MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties"); - - hr = ScaWriteConfigurationScript(pwzScriptKey); - ExitOnFailure(hr, "failed to schedule metabase configuration"); - -LExit: - ReleaseNullStr(pwzScriptKey); - ReleaseNullStr(pwzCustomActionData); - - WcaFinishUnwrapQuery(hUserQuery); - WcaFinishUnwrapQuery(hWebBaseQuery); - WcaFinishUnwrapQuery(hWebDirPropQuery); - WcaFinishUnwrapQuery(hSslCertQuery); - WcaFinishUnwrapQuery(hWebLogQuery); - WcaFinishUnwrapQuery(hWebAppQuery); - WcaFinishUnwrapQuery(hWebAppExtQuery); - - if (psWseList) - { - ScaWebSvcExtFreeList(psWseList); - } - - if (psfList) - { - ScaFiltersFreeList(psfList); - } - - if (psvdList) - { - ScaVirtualDirsFreeList7(psvdList); - } - - if (pswdList) - { - ScaWebDirsFreeList7(pswdList); - } - - if (pswList) - { - ScaWebsFreeList7(pswList); - } - - if (psmmList) - { - ScaMimeMapFreeList(psmmList); - } - - if (pshhList) - { - ScaHttpHeaderCheckList(pshhList); - ScaHttpHeaderFreeList(pshhList); - } - - if (psweList) - { - ScaWebErrorCheckList(psweList); - ScaWebErrorFreeList(psweList); - } - - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} diff --git a/src/ca/scassl.cpp b/src/ca/scassl.cpp deleted file mode 100644 index 4a06b77e..00000000 --- a/src/ca/scassl.cpp +++ /dev/null @@ -1,115 +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" - -enum eSslCertificateQuery { scqStoreName = 1, scqHash, scqWeb }; - -static HRESULT AddSslCertificateToList( - __in SCA_WEB_SSL_CERTIFICATE** ppswscList - ); - - -HRESULT ScaSslCertificateRead( - __in LPCWSTR wzWebId, - __in WCA_WRAPQUERY_HANDLE hSslCertQuery, - __inout SCA_WEB_SSL_CERTIFICATE** ppswscList - ) -{ - HRESULT hr = S_OK; - - MSIHANDLE hRec; - SCA_WEB_SSL_CERTIFICATE* pswsc = NULL; - LPWSTR pwzData = NULL; - - WcaFetchWrappedReset(hSslCertQuery); - - // Get the certificate information. - while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hSslCertQuery, scqWeb, wzWebId, &hRec))) - { - hr = AddSslCertificateToList(ppswscList); - ExitOnFailure(hr, "failed to add ssl certificate to list"); - - pswsc = *ppswscList; - - hr = WcaGetRecordString(hRec, scqStoreName, &pwzData); - ExitOnFailure(hr, "Failed to get web ssl certificate store name."); - - hr = ::StringCchCopyW(pswsc->wzStoreName, countof(pswsc->wzStoreName), pwzData); - ExitOnFailure(hr, "Failed to copy web ssl certificate store name."); - - hr = WcaGetRecordString(hRec, scqHash, &pwzData); - ExitOnFailure(hr, "Failed to get hash for web ssl certificate."); - - hr = StrHexDecode(pwzData, pswsc->rgbSHA1Hash, countof(pswsc->rgbSHA1Hash)); - ExitOnFailure(hr, "Failed to decode certificate hash for web: %ls, data: %ls", wzWebId, pwzData); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failed to read IIsWebSiteCertificates table."); - -LExit: - ReleaseStr(pwzData); - return hr; -} - - -HRESULT ScaSslCertificateWriteMetabase( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzWebBase, - __in SCA_WEB_SSL_CERTIFICATE* pswscList - ) -{ - HRESULT hr = S_OK; - BLOB blob; - - for (SCA_WEB_SSL_CERTIFICATE* pswsc = pswscList; pswsc; pswsc = pswsc->pNext) - { - // Write: /W3SVC/1:SslCertStoreName = "MY", "CA", "Root", etc. - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_SSL_CERT_STORE_NAME, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, static_cast(pswsc->wzStoreName)); - ExitOnFailure(hr, "Failed to write SslCertStoreName"); - - // Write: /W3SVC/1:SslCertHash = - blob.pBlobData = pswsc->rgbSHA1Hash; - blob.cbSize = countof(pswsc->rgbSHA1Hash); - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_SSL_CERT_HASH, METADATA_INHERIT, IIS_MD_UT_SERVER, BINARY_METADATA, static_cast(&blob)); - ExitOnFailure(hr, "Failed to write SslCertHash"); - } - -LExit: - return hr; -} - - -void ScaSslCertificateFreeList( - __in SCA_WEB_SSL_CERTIFICATE* pswscList - ) -{ - SCA_WEB_SSL_CERTIFICATE* pswscDelete = pswscList; - while (pswscList) - { - pswscDelete = pswscList; - pswscList = pswscList->pNext; - - MemFree(pswscDelete); - } -} - - -static HRESULT AddSslCertificateToList( - __in SCA_WEB_SSL_CERTIFICATE** ppswscList - ) -{ - HRESULT hr = S_OK; - - SCA_WEB_SSL_CERTIFICATE* pswsc = static_cast(MemAlloc(sizeof(SCA_WEB_SSL_CERTIFICATE), TRUE)); - ExitOnNull(pswsc, hr, E_OUTOFMEMORY, "failed to allocate memory for new SSL certificate list element"); - - pswsc->pNext = *ppswscList; - *ppswscList = pswsc; - -LExit: - return hr; -} diff --git a/src/ca/scassl.h b/src/ca/scassl.h deleted file mode 100644 index df7c473d..00000000 --- a/src/ca/scassl.h +++ /dev/null @@ -1,36 +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 MD_SSL_CERT_HASH ( IIS_MD_SSL_BASE+6 ) -#define MD_SSL_CERT_STORE_NAME ( IIS_MD_SSL_BASE+11 ) -//#define WIDE(x) WIDE2(x) -//#define WIDE2(x) L ## x - - -// structs -struct SCA_WEB_SSL_CERTIFICATE -{ - WCHAR wzStoreName[65]; - BYTE rgbSHA1Hash[CB_CERTIFICATE_HASH]; - - SCA_WEB_SSL_CERTIFICATE* pNext; -}; - - -// prototypes -HRESULT ScaSslCertificateRead( - __in LPCWSTR wzWebId, - __in WCA_WRAPQUERY_HANDLE hSslCertQuery, - __inout SCA_WEB_SSL_CERTIFICATE** ppswscList - ); - -HRESULT ScaSslCertificateWriteMetabase( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzWebBase, - __in SCA_WEB_SSL_CERTIFICATE* pswscList - ); - -void ScaSslCertificateFreeList( - __in SCA_WEB_SSL_CERTIFICATE* pswscList - ); diff --git a/src/ca/scassl7.cpp b/src/ca/scassl7.cpp deleted file mode 100644 index 47c16a9d..00000000 --- a/src/ca/scassl7.cpp +++ /dev/null @@ -1,34 +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" - -HRESULT ScaSslCertificateWrite7( - __in_z LPCWSTR wzWebBase, - __in SCA_WEB_SSL_CERTIFICATE* pswscList - ) -{ - HRESULT hr = S_OK; - WCHAR wzEncodedCertificateHash[CB_CERTIFICATE_HASH * 2 + 1] = { 0 }; - - for (SCA_WEB_SSL_CERTIFICATE* pswsc = pswscList; pswsc; pswsc = pswsc->pNext) - { - hr = ScaWriteConfigID(IIS_SSL_BINDING); - ExitOnFailure(hr, "Failed write SSL binding ID"); - hr = ScaWriteConfigID(IIS_CREATE); // Need to determine site action - ExitOnFailure(hr, "Failed write binding action"); - - hr = ScaWriteConfigString(wzWebBase); //site name key - ExitOnFailure(hr, "Failed to write SSL website"); - hr = ScaWriteConfigString(pswsc->wzStoreName); //ssl store name - ExitOnFailure(hr, "Failed to write SSL store name"); - - hr = StrHexEncode(pswsc->rgbSHA1Hash, countof(pswsc->rgbSHA1Hash), wzEncodedCertificateHash, countof(wzEncodedCertificateHash)); - ExitOnFailure(hr, "Failed to encode SSL hash"); - - hr = ScaWriteConfigString(wzEncodedCertificateHash); //ssl hash - ExitOnFailure(hr, "Failed to write SSL hash"); - } -LExit: - - return hr; -} diff --git a/src/ca/scassl7.h b/src/ca/scassl7.h deleted file mode 100644 index 1a4b09af..00000000 --- a/src/ca/scassl7.h +++ /dev/null @@ -1,8 +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 ScaSslCertificateWrite7( - __in_z LPCWSTR wzWebBase, - __in SCA_WEB_SSL_CERTIFICATE* pswscList - ); diff --git a/src/ca/scauser.cpp b/src/ca/scauser.cpp deleted file mode 100644 index 0b99edff..00000000 --- a/src/ca/scauser.cpp +++ /dev/null @@ -1,91 +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" - -LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `User` WHERE `User`=?"; -enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqPassword }; - -LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Group` WHERE `Group`=?"; -enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; - -LPCWSTR vcsUserGroupQuery = L"SELECT `User_`, `Group_` FROM `UserGroup` WHERE `User_`=?"; -enum eUserGroupQuery { vugqUser = 1, vugqGroup }; - -LPCWSTR vActionableQuery = L"SELECT `User`,`Component_`,`Name`,`Domain`,`Password`,`Attributes` FROM `User` WHERE `Component_` IS NOT NULL"; -enum eActionableQuery { vaqUser = 1, vaqComponent, vaqName, vaqDomain, vaqPassword, vaqAttributes }; - -HRESULT __stdcall ScaGetUserDeferred( - __in LPCWSTR wzUser, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __out SCA_USER* pscau - ) -{ - if (!wzUser || !pscau) - { - return E_INVALIDARG; - } - - HRESULT hr = S_OK; - MSIHANDLE hRec, hRecTest; - - LPWSTR pwzData = NULL; - - // clear struct and bail right away if no user key was passed to search for - ::ZeroMemory(pscau, sizeof(*pscau)); - if (!*wzUser) - { - ExitFunction1(hr = S_OK); - } - - // Reset back to the first record - WcaFetchWrappedReset(hUserQuery); - - hr = WcaFetchWrappedRecordWhereString(hUserQuery, vuqUser, wzUser, &hRec); - if (S_OK == hr) - { - hr = WcaFetchWrappedRecordWhereString(hUserQuery, vuqUser, wzUser, &hRecTest); - if (S_OK == hr) - { - AssertSz(FALSE, "Found multiple matching User rows"); - } - - hr = WcaGetRecordString(hRec, vuqUser, &pwzData); - ExitOnFailure(hr, "Failed to get User.User"); - hr = ::StringCchCopyW(pscau->wzKey, countof(pscau->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to user object (in deferred CA)"); - - hr = WcaGetRecordString(hRec, vuqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get User.Component_"); - hr = ::StringCchCopyW(pscau->wzComponent, countof(pscau->wzComponent), pwzData); - ExitOnFailure(hr, "Failed to copy component string to user object (in deferred CA)"); - - hr = WcaGetRecordString(hRec, vuqName, &pwzData); - ExitOnFailure(hr, "Failed to get User.Name"); - hr = ::StringCchCopyW(pscau->wzName, countof(pscau->wzName), pwzData); - ExitOnFailure(hr, "Failed to copy name string to user object (in deferred CA)"); - - hr = WcaGetRecordString(hRec, vuqDomain, &pwzData); - ExitOnFailure(hr, "Failed to get User.Domain"); - hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); - ExitOnFailure(hr, "Failed to copy domain string to user object (in deferred CA)"); - - hr = WcaGetRecordString(hRec, vuqPassword, &pwzData); - ExitOnFailure(hr, "Failed to get User.Password"); - hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); - ExitOnFailure(hr, "Failed to copy password string to user object (in deferred CA)"); - } - else if (E_NOMOREITEMS == hr) - { - WcaLog(LOGMSG_STANDARD, "Error: Cannot locate User.User='%ls'", wzUser); - hr = E_FAIL; - } - else - { - ExitOnFailure(hr, "Error fetching single User row"); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} diff --git a/src/ca/scauser.h b/src/ca/scauser.h deleted file mode 100644 index b2b94650..00000000 --- a/src/ca/scauser.h +++ /dev/null @@ -1,39 +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. - -// structs -struct SCA_GROUP -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - - WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; - WCHAR wzName[MAX_DARWIN_COLUMN + 1]; - - SCA_GROUP *psgNext; -}; - -struct SCA_USER -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; - WCHAR wzName[MAX_DARWIN_COLUMN + 1]; - WCHAR wzPassword[MAX_DARWIN_COLUMN + 1]; - INT iAttributes; - - SCA_GROUP *psgGroups; - - SCA_USER *psuNext; -}; - - -// prototypes -HRESULT __stdcall ScaGetUserDeferred( - __in LPCWSTR wzUser, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __out SCA_USER* pscau - ); diff --git a/src/ca/scavdir.cpp b/src/ca/scavdir.cpp deleted file mode 100644 index d388ce97..00000000 --- a/src/ca/scavdir.cpp +++ /dev/null @@ -1,331 +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" - -// prototypes -static HRESULT AddVirtualDirToList( - __in SCA_VDIR** psvdList - ); - - -HRESULT __stdcall ScaVirtualDirsRead( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in SCA_VDIR** ppsvdList, - __in SCA_MIMEMAP** ppsmmList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(piMetabase && ppsvdList); - - HRESULT hr = S_OK; - MSIHANDLE hRec; - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - - SCA_VDIR* pvdir = NULL; - LPWSTR pwzData = NULL; - - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the vdirs - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - // Get the Component first. If there is a Component and it is not being modified during - // this transaction, skip processing this whole record. - hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); - ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); - - hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); - - hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&isAction); - ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); - - if (!WcaIsInstalling(isInstalled, isAction) && - !WcaIsReInstalling(isInstalled, isAction) && - !WcaIsUninstalling(isInstalled, isAction)) - { - continue; // skip this record. - } - - hr = AddVirtualDirToList(ppsvdList); - ExitOnFailure(hr, "failed to add virtual dir to list"); - - pvdir = *ppsvdList; - - hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); - ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); - - pvdir->isInstalled = isInstalled; - pvdir->isAction = isAction; - - // get the web key - hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web for VirtualDir"); - - hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pvdir->wzWebBase, countof(pvdir->wzWebBase), hWebBaseQuery); - if (WcaIsUninstalling(isInstalled, isAction)) - { - // If we're uninstalling, ignore any failure to find the existing web - hr = S_OK; - } - ExitOnFailure(hr, "Failed to get base of web: %ls for VirtualDir", pwzData); - - hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); - ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); - - if (0 != lstrlenW(pvdir->wzWebBase)) - { - hr = ::StringCchPrintfW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), L"%s/Root/%s", pvdir->wzWebBase, pwzData); - ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); - } - - // get the vdir's directory - hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); - ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); - - // get the web's directory - if (INSTALLSTATE_SOURCE == pvdir->isAction) - { - hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); - } - else - { - hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); - } - ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); - - // remove trailing backslash(es) - while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') - { - pwzData[lstrlenW(pwzData)-1] = 0; - } - hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); - ExitOnFailure(hr, "Failed to copy directory string to vdir object"); - - // get the security information for this web - hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); - if (*pwzData) - { - hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); - ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); - - pvdir->fHasProperties = TRUE; - } - - // get the application information for this web - hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); - ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); - if (*pwzData) - { - hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); - ExitOnFailure(hr, "Failed to get application for VirtualDir"); - - pvdir->fHasApplication = TRUE; - } - - hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); - ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); - - if (*pwzData && *ppsmmList) - { - hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); - ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); - } - - if (*pwzData && *ppshhList) - { - hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); - ExitOnFailure(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); - } - - if (*pwzData && *ppsweList) - { - hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); - ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); - } - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing VirtualDirs"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - return hr; -} - - -HRESULT ScaVirtualDirsInstall( - __in IMSAdminBase* piMetabase, - __in SCA_VDIR* psvdList, - __in SCA_APPPOOL * psapList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - SCA_VDIR* psvd = psvdList; - int i; - - while (psvd) - { - // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created - if (WcaIsReInstalling(psvd->isInstalled, psvd->isAction)) - { - if (psvd->fHasApplication) - { - hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); - ExitOnFailure(hr, "Failed to remove application for WebVDir as part of a reinstall"); - } - } - - if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) - { - hr = ScaCreateMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); - ExitOnFailure(hr, "Failed to create key for VirtualDir"); - hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); - ExitOnFailure(hr, "Failed to write key type for for VirtualDir"); - i = 0x4000003e; // 1073741886; // default directory browsing rights - hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); - ExitOnFailure(hr, "Failed to set directory browsing for VirtualDir"); - - hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psvd->wzDirectory); - ExitOnFailure(hr, "Failed to write Directory for VirtualDir"); - - if (psvd->fHasProperties) - { - ScaWriteWebDirProperties(piMetabase, psvd->wzVDirRoot, &psvd->swp); - ExitOnFailure(hr, "Failed to write directory properties for VirtualDir"); - } - - if (psvd->fHasApplication) - { - hr = ScaWriteWebApplication(piMetabase, psvd->wzVDirRoot, &psvd->swapp, psapList); - ExitOnFailure(hr, "Failed to write application for VirtualDir"); - } - - if (psvd->psmm) - { - hr = ScaWriteMimeMap(piMetabase, psvd->wzVDirRoot, psvd->psmm); - ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); - } - - if (psvd->pshh) - { - hr = ScaWriteHttpHeader(piMetabase, psvd->wzVDirRoot, psvd->pshh); - ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir"); - } - - if (psvd->pswe) - { - hr = ScaWriteWebError(piMetabase, weptVDir, psvd->wzVDirRoot, psvd->pswe); - ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); - } - } - - psvd = psvd->psvdNext; - } - -LExit: - return hr; -} - - -HRESULT ScaVirtualDirsUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_VDIR* psvdList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - SCA_VDIR* psvd = psvdList; - - while (psvd) - { - if (WcaIsUninstalling(psvd->isInstalled, psvd->isAction)) - { - // delete the application for this virtual directory - if (psvd->fHasApplication) - { - hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); - ExitOnFailure(hr, "Failed to remove application for WebVDir"); - } - - if (0 != lstrlenW(psvd->wzVDirRoot)) - { - hr = ScaDeleteMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); - ExitOnFailure(hr, "Failed to remove VirtualDir '%ls' from metabase", psvd->wzKey); - } - } - - psvd = psvd->psvdNext; - } - -LExit: - return hr; -} - - -void ScaVirtualDirsFreeList( - __in SCA_VDIR* psvdList - ) -{ - SCA_VDIR* psvdDelete = psvdList; - while (psvdList) - { - psvdDelete = psvdList; - psvdList = psvdList->psvdNext; - - if (psvdDelete->psmm) - { - ScaMimeMapFreeList(psvdDelete->psmm); - } - - if (psvdDelete->pswe) - { - ScaWebErrorFreeList(psvdDelete->pswe); - } - - MemFree(psvdDelete); - } -} - - -static HRESULT AddVirtualDirToList( - __in SCA_VDIR** ppsvdList - ) -{ - HRESULT hr = S_OK; - SCA_VDIR* psvd = static_cast(MemAlloc(sizeof(SCA_VDIR), TRUE)); - ExitOnNull(psvd, hr, E_OUTOFMEMORY, "failed to allocate memory for new vdir list element"); - - psvd->psvdNext= *ppsvdList; - *ppsvdList = psvd; - -LExit: - return hr; -} diff --git a/src/ca/scavdir.h b/src/ca/scavdir.h deleted file mode 100644 index c7e9661b..00000000 --- a/src/ca/scavdir.h +++ /dev/null @@ -1,71 +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 "scawebprop.h" -#include "scawebapp.h" -#include "scamimemap.h" -#include "scaapppool.h" - -enum eVDirQuery { vdqWeb = 1, vdqVDir, vdqComponent , vdqAlias, vdqDirectory, vdqProperties, vdqApplication, vdqInstalled, vdqAction, vdqSourcePath, vdqTargetPath }; - -struct SCA_VDIR -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - // metabase information - WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; - WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; - WCHAR wzVDirRoot[METADATA_MAX_NAME_LEN + 1]; - - // iis configuation information - WCHAR wzDirectory[MAX_PATH]; - - BOOL fHasProperties; - SCA_WEB_PROPERTIES swp; - - BOOL fHasApplication; - SCA_WEB_APPLICATION swapp; - - SCA_MIMEMAP* psmm; // mime mappings - SCA_HTTP_HEADER* pshh; // custom web errors - SCA_WEB_ERROR* pswe; // custom web errors - - SCA_VDIR* psvdNext; -}; - - -// prototypes -HRESULT __stdcall ScaVirtualDirsRead( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in SCA_VDIR** ppsvdList, - __in SCA_MIMEMAP** ppsmmList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ); - -HRESULT ScaVirtualDirsInstall( - __in IMSAdminBase* piMetabase, - __in SCA_VDIR* psvdList, - __in SCA_APPPOOL * psapList - ); - -HRESULT ScaVirtualDirsUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_VDIR* psvdList - ); - -void ScaVirtualDirsFreeList( - __in SCA_VDIR* psvdList - ); diff --git a/src/ca/scavdir7.cpp b/src/ca/scavdir7.cpp deleted file mode 100644 index 3f675357..00000000 --- a/src/ca/scavdir7.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" - -// prototypes -static HRESULT AddVirtualDirToList7( - __in SCA_VDIR7** psvdList - ); - - -HRESULT __stdcall ScaVirtualDirsRead7( - __in SCA_WEB7* pswList, - __in SCA_VDIR7** ppsvdList, - __in SCA_MIMEMAP** ppsmmList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(ppsvdList); - - HRESULT hr = S_OK; - MSIHANDLE hRec; - - SCA_VDIR7* pvdir = NULL; - LPWSTR pwzData = NULL; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the vdirs - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - // Add this record's information into the list of things to process. - hr = AddVirtualDirToList7(ppsvdList); - ExitOnFailure(hr, "failed to add vdir to vdir list"); - - pvdir = *ppsvdList; - - // get the darwin information - hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); - ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); - - hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&pvdir->isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); - - hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&pvdir->isAction); - ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); - - // get vdir properties - hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); - ExitOnFailure(hr, "failed to copy vdir component name: %ls", pwzData); - - hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web for VirtualDir"); - - hr = ScaWebsGetBase7(pswList, pwzData, pvdir->wzWebName , countof(pvdir->wzWebName)); - if (S_FALSE == hr) - { - hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); - ExitOnFailure(hr, "Failed to get Web Base for VirtualDir"); - } - if (WcaIsUninstalling(pvdir->isInstalled, pvdir->isAction)) - { - // If we're uninstalling, ignore any failure to find the existing web - hr = S_OK; - } - - hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); - ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); - - hr = ::StringCchCopyW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), pwzData); - ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); - - // get the vdir's directory - hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); - ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); - - // get the web's directory - if (INSTALLSTATE_SOURCE == pvdir->isAction) - { - hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); - } - else - { - hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); - } - ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); - - // remove trailing backslash(es) - while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') - { - pwzData[lstrlenW(pwzData)-1] = 0; - } - hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); - ExitOnFailure(hr, "Failed to copy directory string to vdir object"); - - // get the security information for this web - hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); - if (*pwzData) - { - hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); - ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); - - pvdir->fHasProperties = TRUE; - } - - // get the application information for this web - hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); - ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); - if (*pwzData) - { - hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); - ExitOnFailure(hr, "Failed to get application for VirtualDir"); - - pvdir->fHasApplication = TRUE; - } - - hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); - ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); - - if (*pwzData && *ppsmmList) - { - hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); - ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); - } - - if (*pwzData && *ppshhList) - { - hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); - ExitOnFailure(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); - } - - if (*pwzData && *ppsweList) - { - hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); - ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); - } - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing VirtualDirs"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaVirtualDirsInstall7( - __in SCA_VDIR7* psvdList, - __in SCA_APPPOOL * psapList - ) -{ - HRESULT hr = S_OK; - SCA_VDIR7* psvd = psvdList; - LPWSTR wzPath = NULL; - WCHAR wzAppPoolName[MAX_PATH]; - while (psvd) - { - if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) - { - // First write all applications, this is necessary since vdirs must be nested under the applications. - if (psvd->fHasApplication) - { - //create the application for this vdir application - hr = ScaWriteConfigID(IIS_APPLICATION); - ExitOnFailure(hr, "Failed to write app ID"); - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed to write app action"); -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaWriteConfigString(psvd->wzWebName); //site name key - ExitOnFailure(hr, "Failed to write app web key"); - hr = StrAllocFormatted(&wzPath, L"/%s", psvd->wzVDirRoot); - ExitOnFailure(hr, "Failed to create app path"); - hr = ScaWriteConfigString(wzPath); // App Path - ExitOnFailure(hr, "Failed to write app path root "); - - if (!*psvd->swapp.wzAppPool) - { - //This Application goes in default appPool - hr = ScaWriteConfigString(L""); // App Pool - } - else - { - //get apppool from WebApplication -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaFindAppPool7(psvd->swapp.wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); - ExitOnFailure(hr, "Failed to read app pool from application"); - hr = ScaWriteConfigString(wzAppPoolName); // App Pool - ExitOnFailure(hr, "Failed to write appPool for vdir"); - - } - } - } - - psvd = psvd->psvdNext; - } - - // Reset our linked list and write all the VDirs - psvd = psvdList; - while (psvd) - { - if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) - { - //create the Vdir - hr = ScaWriteConfigID(IIS_VDIR); - ExitOnFailure(hr, "Failed write VirDir ID") - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed write VirDir action") -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaWriteConfigString(psvd->wzWebName); //site name key - ExitOnFailure(hr, "Failed write VirDir web name"); - hr = StrAllocFormatted(&wzPath, L"/%s", psvd->wzVDirRoot); - ExitOnFailure(hr, "Failed to create vdir path"); - hr = ScaWriteConfigString(wzPath); //vdir path - ExitOnFailure(hr, "Failed write VirDir path") -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaWriteConfigString(psvd->wzDirectory); //physical dir - ExitOnFailure(hr, "Failed write VirDir dir"); - - if (psvd->fHasProperties) - { - ScaWriteWebDirProperties7(psvd->wzWebName, psvd->wzVDirRoot, &psvd->swp); - ExitOnFailure(hr, "Failed to write directory properties for VirtualDir"); - } - - if (psvd->fHasApplication) - { - hr = ScaWriteWebApplication7(psvd->wzWebName, psvd->wzVDirRoot, &psvd->swapp, psapList); - ExitOnFailure(hr, "Failed to write application for VirtualDir"); - } - - if (psvd->psmm) - { - hr = ScaWriteMimeMap7(psvd->wzWebName, psvd->wzVDirRoot, psvd->psmm); - ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); - } - - if (psvd->pshh) - { - hr = ScaWriteHttpHeader7(psvd->wzWebName, psvd->wzVDirRoot, psvd->pshh); - ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir"); - } - - if (psvd->pswe) - { - hr = ScaWriteWebError7(psvd->wzWebName, psvd->wzVDirRoot, psvd->pswe); - ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); - } - } - - psvd = psvd->psvdNext; - } - -LExit: - ReleaseStr(wzPath); - return hr; -} - - -HRESULT ScaVirtualDirsUninstall7( - __in SCA_VDIR7* psvdList - ) -{ - - HRESULT hr = S_OK; - SCA_VDIR7* psvd = psvdList; - LPWSTR wzPath = NULL; - - while (psvd) - { - if (WcaIsUninstalling(psvd->isInstalled, psvd->isAction)) - { - //init path - hr = StrAllocFormatted(&wzPath, L"/%s", psvd->wzVDirRoot); - ExitOnFailure(hr, "Failed to create vdir path"); - - if (psvd->fHasApplication) - { - //delete Application - hr = ScaWriteConfigID(IIS_APPLICATION); - ExitOnFailure(hr, "Failed to write app ID "); - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "Failed to write delete app ID "); -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaWriteConfigString(psvd->wzWebName); //site name key - ExitOnFailure(hr, "Failed to write App site Name"); -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaWriteConfigString(wzPath); // App Path - ExitOnFailure(hr, "Failed to write app path root "); - hr = ScaWriteConfigString(L"NOP"); // App pool - ExitOnFailure(hr, "Failed to write app path app pool "); - } - else - { - //delete VDir - hr = ScaWriteConfigID(IIS_VDIR); - ExitOnFailure(hr, "Failed to write vDir ID "); - hr = ScaWriteConfigID(IIS_DELETE); -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ScaWriteConfigString(psvd->wzWebName); //site name key - ExitOnFailure(hr, "Failed to write App site Name"); - hr = ScaWriteConfigString(wzPath); // Vdir Path - ExitOnFailure(hr, "Failed to write app vdir "); - hr = ScaWriteConfigString(L"NOP"); // Phy Path - ExitOnFailure(hr, "Failed to write vdir path"); - } - - ExitOnFailure(hr, "Failed to remove VirtualDir '%ls' from config", psvd->wzKey); - } - - psvd = psvd->psvdNext; - } - -LExit: - ReleaseStr(wzPath); - return hr; -} - - -void ScaVirtualDirsFreeList7( - __in SCA_VDIR7* psvdList - ) -{ - SCA_VDIR7* psvdDelete = psvdList; - while (psvdList) - { - psvdDelete = psvdList; - psvdList = psvdList->psvdNext; - - if (psvdDelete->psmm) - { - ScaMimeMapFreeList(psvdDelete->psmm); - } - - if (psvdDelete->pswe) - { - ScaWebErrorFreeList(psvdDelete->pswe); - } - - MemFree(psvdDelete); - } -} - - -static HRESULT AddVirtualDirToList7( - __in SCA_VDIR7** ppsvdList - ) -{ - HRESULT hr = S_OK; - - SCA_VDIR7* psvd = static_cast(MemAlloc(sizeof(SCA_VDIR7), TRUE)); - ExitOnNull(psvd, hr, E_OUTOFMEMORY, "failed to allocate memory for new vdir list element"); - - psvd->psvdNext= *ppsvdList; - *ppsvdList = psvd; - -LExit: - return hr; -} diff --git a/src/ca/scavdir7.h b/src/ca/scavdir7.h deleted file mode 100644 index dba25431..00000000 --- a/src/ca/scavdir7.h +++ /dev/null @@ -1,66 +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 "scawebprop.h" -#include "scawebapp.h" -#include "scamimemap.h" -#include "scaapppool.h" - -struct SCA_VDIR7 -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - // metabase information - WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; - WCHAR wzWebName[METADATA_MAX_NAME_LEN + 1]; - WCHAR wzVDirRoot[METADATA_MAX_NAME_LEN + 1]; - - // iis configuation information - WCHAR wzDirectory[MAX_PATH]; - - BOOL fHasProperties; - SCA_WEB_PROPERTIES swp; - - BOOL fHasApplication; - SCA_WEB_APPLICATION swapp; - - SCA_MIMEMAP* psmm; // mime mappings - SCA_HTTP_HEADER* pshh; // custom web errors - SCA_WEB_ERROR* pswe; // custom web errors - - SCA_VDIR7* psvdNext; -}; - - -// prototypes -HRESULT __stdcall ScaVirtualDirsRead7( - __in SCA_WEB7* pswList, - __in SCA_VDIR7** ppsvdList, - __in SCA_MIMEMAP** ppsmmList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ); - -HRESULT ScaVirtualDirsInstall7( - __in SCA_VDIR7* psvdList, - __in SCA_APPPOOL * psapList - ); - -HRESULT ScaVirtualDirsUninstall7( - __in SCA_VDIR7* psvdList - ); - -void ScaVirtualDirsFreeList7( - __in SCA_VDIR7* psvdList - ); diff --git a/src/ca/scaweb.cpp b/src/ca/scaweb.cpp deleted file mode 100644 index 0452fb0b..00000000 --- a/src/ca/scaweb.cpp +++ /dev/null @@ -1,1187 +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" - -//Adding this because delivery doesn't have the updated specstrings.h that windows build does -#ifndef __in_xcount -#define __in_xcount(size) -#endif - -// sql queries - -enum eWebBaseQuery { wbqWeb = 1, wbqId, wbqIP, wbqPort, wbqHeader, wbqSecure, wbqDescription }; - - -// prototypes for private helper functions -static SCA_WEB* NewWeb(); -static void FreeWeb(SCA_WEB *pswDelete); -static SCA_WEB* AddWebToList( - __in SCA_WEB* pswList, - __in SCA_WEB* psw - ); -static HRESULT ScaWebFindBase( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in_z LPCWSTR wzWeb, - __in int iSiteId, - __in_z LPCWSTR wzIP, - __in int iPort, - __in_z LPCWSTR wzHeader, - __in BOOL fSecure, - __in_z LPCWSTR wzDescription, - __out_ecount(cchWebBase) LPWSTR wzWebBase, - __in DWORD cchWebBase - ); -static HRESULT ScaWebFindFreeBase( - __in IMSAdminBase* piMetabase, - __in_xcount(unknown) SCA_WEB* pswList, - __in int iSiteId, - __in_z LPCWSTR wzDescription, - __out_ecount(cchWebBase) LPWSTR wzWebBase, - __in DWORD cchWebBase - ); -static HRESULT ScaWebWrite( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* psw, - __in SCA_APPPOOL * psapList - ); -static HRESULT ScaWebRemove( - __in IMSAdminBase* piMetabase, - __in const SCA_WEB* psw); -static DWORD SiteIdFromDescription( - __in_z LPCWSTR wzDescription - ); -static void Sort( - __in_ecount(cArray) DWORD dwArray[], - __in int cArray - ); - - -HRESULT ScaWebsRead( - __in IMSAdminBase* piMetabase, - __in SCA_MIMEMAP** ppsmmList, - __in SCA_WEB** ppswList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hSslCertQuery, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(piMetabase && ppswList); - - HRESULT hr = S_OK; - - MSIHANDLE hRec; - MSIHANDLE hRecAddresses; - - SCA_WEB* psw = NULL; - LPWSTR pwzData = NULL; - int iSiteId; - - DWORD dwLen = 0; - WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL; - WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL; - - hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); - - hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); - - if (0 == WcaGetQueryRecords(hQueryWebSite)) - { - WcaLog(LOGMSG_VERBOSE, "Required tables not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the webs - while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec))) - { - psw = NewWeb(); - ExitOnNull(psw, hr, E_OUTOFMEMORY, "Failed to allocate memory for web object in memory"); - - // get the darwin information - hr = WcaGetRecordString(hRec, wqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web"); - hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to web object"); - - if (*pwzData && *ppsmmList) - { - hr = ScaGetMimeMap(mmptWeb, pwzData, ppsmmList, &psw->psmm); - ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); - } - - // get component install state - hr = WcaGetRecordString(hRec, wqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get Component for Web"); - hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); - ExitOnFailure(hr, "Failed to copy component string to web object"); - if (*(psw->wzComponent)) - { - psw->fHasComponent = TRUE; - - hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled); - ExitOnFailure(hr, "Failed to get web Component's installed state"); - - WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction); - ExitOnFailure(hr, "Failed to get web Component's action state"); - - if (!WcaIsInstalling(psw->isInstalled, psw->isAction) && !WcaIsUninstalling(psw->isInstalled, psw->isAction) - && !WcaIsReInstalling(psw->isInstalled, psw->isAction)) - { - FreeWeb(psw); - psw = NULL; - - continue; // If we aren't acting on this component, skip it - } - } - - hr = WcaGetRecordInteger(hRec, wqId, &iSiteId); - ExitOnFailure(hr, "Failed to get SiteId for Web"); - - // Get the web's key address. - hr = WcaGetRecordString(hRec, wqAddress, &pwzData); - ExitOnFailure(hr, "Failed to get Address for Web"); - hr = ::StringCchCopyW(psw->swaKey.wzKey, countof(psw->swaKey.wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to web object"); - - hr = WcaGetRecordString(hRec, wqIP, &pwzData); - ExitOnFailure(hr, "Failed to get IP for Web"); - hr = ::StringCchCopyW(psw->swaKey.wzIP, countof(psw->swaKey.wzIP), pwzData); - ExitOnFailure(hr, "Failed to copy IP string to web object"); - - hr = WcaGetRecordString(hRec, wqPort, &pwzData); - ExitOnFailure(hr, "Failed to get Web Address port"); - psw->swaKey.iPort = wcstol(pwzData, NULL, 10); - - hr = WcaGetRecordString(hRec, wqHeader, &pwzData); - ExitOnFailure(hr, "Failed to get Header for Web"); - hr = ::StringCchCopyW(psw->swaKey.wzHeader, countof(psw->swaKey.wzHeader), pwzData); - ExitOnFailure(hr, "Failed to copy header string to web object"); - - hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaKey.fSecure); - ExitOnFailure(hr, "Failed to get if Web is secure"); - if (S_FALSE == hr) - { - psw->swaKey.fSecure = FALSE; - } - - // Get the web's description. - hr = WcaGetRecordString(hRec, wqDescription, &pwzData); - ExitOnFailure(hr, "Failed to get Description for Web"); - hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); - ExitOnFailure(hr, "Failed to copy description string to web object"); - - // Try to find the web root in case it already exists. - dwLen = METADATA_MAX_NAME_LEN; - hr = ScaWebFindBase(piMetabase, *ppswList, - psw->wzKey, - iSiteId, - psw->swaKey.wzIP, - psw->swaKey.iPort, - psw->swaKey.wzHeader, - psw->swaKey.fSecure, - psw->wzDescription, - psw->wzWebBase, dwLen); - if (S_OK == hr) - { - psw->fBaseExists = TRUE; - } - else if (S_FALSE == hr) // didn't find the web site. - { - psw->fBaseExists = FALSE; - - // If we're actually configuring the web site. - if (psw->fHasComponent) - { - if (WcaIsInstalling(psw->isInstalled, psw->isAction)) - { - hr = ScaWebFindFreeBase(piMetabase, *ppswList, iSiteId, psw->wzDescription, psw->wzWebBase, countof(psw->wzWebBase)); - ExitOnFailure(hr, "Failed to find free web root."); - } - else if (WcaIsUninstalling(psw->isInstalled, psw->isAction)) - { - WcaLog(LOGMSG_VERBOSE, "Web site: '%ls' was already removed, skipping.", psw->wzKey); - - hr = S_OK; - continue; - } - } - } - ExitOnFailure(hr, "Failed to find web root"); - - // get any extra web addresses - WcaFetchWrappedReset(hQueryWebAddress); - while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses))) - { - if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) - { - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); - } - - hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); - ExitOnFailure(hr, "Failed to get extra web Address"); - - // if this isn't the key address add it - if (0 != lstrcmpW(pwzData, psw->swaKey.wzKey)) - { - hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy extra addresses key string to web object"); - - hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData); - ExitOnFailure(hr, "Failed to get extra web IP"); - hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); - ExitOnFailure(hr, "Failed to copy extra addresses IP string to web object"); - - hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData); - ExitOnFailure(hr, "Failed to get port for extra web IP"); - psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); - - hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData); - ExitOnFailure(hr, "Failed to get header for extra web IP"); - hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); - ExitOnFailure(hr, "Failed to copy extra addresses header string to web object"); - - hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); - ExitOnFailure(hr, "Failed to get if secure extra web IP"); - if (S_FALSE == hr) - psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; - - ++psw->cExtraAddresses; - } - } - - if (E_NOMOREITEMS == hr) - hr = S_OK; - ExitOnFailure(hr, "Failure occured while getting extra web addresses"); - - hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); - ExitOnFailure(hr, "Failed to get connection timeout for Web"); - - if (psw->fHasComponent) // If we're installing it, it needs a dir - { - // get the web's directory - if (INSTALLSTATE_SOURCE == psw->isAction) - { - hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData); - } - else - { - hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData); - } - ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); - - // remove trailing backslashes - while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') - { - pwzData[lstrlenW(pwzData)-1] = 0; - } - hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData); - ExitOnFailure(hr, "Failed to copy directory string to web object"); - } - - hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); - ExitOnFailure(hr, "Failed to get state for Web"); - - hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); - ExitOnFailure(hr, "Failed to get attributes for Web"); - - // get the dir properties for this web - hr = WcaGetRecordString(hRec, wqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get directory property record for Web"); - if (*pwzData) - { - hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp); - ExitOnFailure(hr, "Failed to get directory properties for Web"); - - psw->fHasProperties = TRUE; - } - - // get the application information for this web - hr = WcaGetRecordString(hRec, wqApplication, &pwzData); - ExitOnFailure(hr, "Failed to get application identifier for Web"); - if (*pwzData) - { - hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp); - ExitOnFailure(hr, "Failed to get application for Web"); - - psw->fHasApplication = TRUE; - } - - // get the SSL certificates - hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList)); - ExitOnFailure(hr, "Failed to get SSL Certificates."); - - // get the custom headers - if (*ppshhList) - { - hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); - ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); - } - - // get the errors - if (*ppsweList) - { - hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); - ExitOnFailure(hr, "Failed to get Custom Errors"); - } - - // get the log information for this web - hr = WcaGetRecordString(hRec, wqLog, &pwzData); - ExitOnFailure(hr, "Failed to get log identifier for Web"); - if (*pwzData) - { - hr = ScaGetWebLog(piMetabase, pwzData, hWebLogQuery, &psw->swl); - ExitOnFailure(hr, "Failed to get Log for Web."); - - psw->fHasLog = TRUE; - } - - *ppswList = AddWebToList(*ppswList, psw); - psw = NULL; // set the web NULL so it doesn't accidentally get freed below - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - -LExit: - // if anything was left over after an error clean it all up - WcaFinishUnwrapQuery(hQueryWebSite); - WcaFinishUnwrapQuery(hQueryWebAddress); - - if (psw) - { - ScaWebsFreeList(psw); - } - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaWebsGetBase( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in LPCWSTR wzWeb, - __out_ecount(cchWebBase) LPWSTR wzWebBase, - __in DWORD cchWebBase, - __in WCA_WRAPQUERY_HANDLE hWrapQuery - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - - int iSiteId; - WCHAR wzIP[MAX_PATH]; - int iPort = -1; - WCHAR wzHeader[MAX_PATH]; - BOOL fSecure = FALSE; - - LPWSTR pwzData = NULL; - - // get the web information - WcaFetchWrappedReset(hWrapQuery); - - hr = WcaFetchWrappedRecordWhereString(hWrapQuery, 1, wzWeb, &hRec); - if (S_OK == hr) - { - // get the data to search for - hr = WcaGetRecordInteger(hRec, wbqId, &iSiteId); - ExitOnFailure(hr, "Failed to get SiteId for Web for VirtualDir"); - - hr = WcaGetRecordString(hRec, wbqIP, &pwzData); - ExitOnFailure(hr, "Failed to get IP for Web for VirtualDir"); - hr = ::StringCchCopyW(wzIP, countof(wzIP), pwzData); - ExitOnFailure(hr, "Failed to copy IP for Web for VirtualDir"); - - hr = WcaGetRecordString(hRec, wbqPort, &pwzData); - ExitOnFailure(hr, "Failed to get port for extra web IP"); - iPort = wcstol(pwzData, NULL, 10); - - hr = WcaGetRecordString(hRec, wbqHeader, &pwzData); - ExitOnFailure(hr, "Failed to get Header for Web for VirtualDir"); - hr = ::StringCchCopyW(wzHeader, countof(wzHeader), pwzData); - ExitOnFailure(hr, "Failed to copy Header for Web for VirtualDir"); - - hr = WcaGetRecordInteger(hRec, wbqSecure, &fSecure); - if (S_FALSE == hr) - fSecure = FALSE; - - hr = WcaGetRecordString(hRec, wbqDescription, &pwzData); - ExitOnFailure(hr, "Failed to get Description for Web"); - - // find the web or find the next free web location - hr = ScaWebFindBase(piMetabase, pswList, wzWeb, iSiteId, wzIP, iPort, wzHeader, fSecure, pwzData, wzWebBase, cchWebBase); - if (S_FALSE == hr) - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - ExitOnFailure(hr, "Failed to find Web base"); - } - else if (S_FALSE == hr) - hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); - - // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would - HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWrapQuery, 1, wzWeb, &hRec); - if (SUCCEEDED(hrTemp)) - { - AssertSz(E_NOMOREITEMS == hrTemp, "ScaWebsGetBase found more than one record"); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaWebsInstall( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in SCA_APPPOOL * psapList - ) -{ - HRESULT hr = S_OK; - SCA_WEB* psw = pswList; - - while (psw) - { - // if we are installing the web site - if (psw->fHasComponent && WcaIsInstalling(psw->isInstalled, psw->isAction)) - { - hr = ScaWebWrite(piMetabase, psw, psapList); - ExitOnFailure(hr, "failed to write web '%ls' to metabase", psw->wzKey); - } - - psw = psw->pswNext; - } - -LExit: - return hr; -} - - -HRESULT ScaWebsUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList - ) -{ - HRESULT hr = S_OK; - SCA_WEB* psw = pswList; - - while (psw) - { - // if we are uninstalling the web site - if (psw->fHasComponent && WcaIsUninstalling(psw->isInstalled, psw->isAction)) - { - hr = ScaWebRemove(piMetabase, psw); - ExitOnFailure(hr, "Failed to remove web '%ls' from metabase", psw->wzKey); - } - - psw = psw->pswNext; - } - -LExit: - return hr; -} - - -void ScaWebsFreeList( - __in SCA_WEB* pswList - ) -{ - SCA_WEB* pswDelete = pswList; - while (pswList) - { - pswDelete = pswList; - pswList = pswList->pswNext; - - // Free the SSL, headers and errors list first - FreeWeb(pswDelete); - } -} - - -// private helper functions - -static void FreeWeb(SCA_WEB *pswDelete) -{ - ScaSslCertificateFreeList(pswDelete->pswscList); - ScaHttpHeaderFreeList(pswDelete->pshhList); - ScaWebErrorFreeList(pswDelete->psweList); - MemFree(pswDelete); -} - -static SCA_WEB* NewWeb() -{ - SCA_WEB* psw = static_cast(MemAlloc(sizeof(SCA_WEB), TRUE)); - Assert(psw); - return psw; -} - - -static SCA_WEB* AddWebToList( - __in SCA_WEB* pswList, - __in SCA_WEB* psw - ) -{ - if (pswList) - { - SCA_WEB* pswTemp = pswList; - while (pswTemp->pswNext) - { - pswTemp = pswTemp->pswNext; - } - - pswTemp->pswNext = psw; - } - else - { - pswList = psw; - } - - return pswList; -} - - -static HRESULT ScaWebFindBase( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in_z LPCWSTR wzWeb, - __in int iSiteId, - __in_z LPCWSTR wzIP, - __in int iPort, - __in_z LPCWSTR wzHeader, - __in BOOL fSecure, - __in_z LPCWSTR wzDescription, - __out_ecount(cchWebBase) LPWSTR wzWebBase, - __in DWORD cchWebBase - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - WCHAR wzSubkey[METADATA_MAX_NAME_LEN]; - LPWSTR wzFoundKey = NULL; - - METADATA_RECORD mr; - ::ZeroMemory(&mr, sizeof(mr)); - - METADATA_RECORD mrCompare; - ::ZeroMemory(&mrCompare, sizeof(mrCompare)); - - // try to find the web in memory first - for (SCA_WEB* psw = pswList; psw; psw = psw->pswNext) - { - if (0 == lstrcmpW(wzWeb, psw->wzKey)) - { - if ((0 == lstrcmpW(wzIP, psw->swaKey.wzIP) || 0 == lstrcmpW(wzIP, L"*") || 0 == lstrcmpW(psw->swaKey.wzIP, L"*")) && - iPort == psw->swaKey.iPort && - 0 == lstrcmpW(wzHeader, psw->swaKey.wzHeader) && - fSecure == psw->swaKey.fSecure) - { - if (0 == lstrlenW(psw->wzWebBase)) - { - WcaLog(LOGMSG_STANDARD, "A matching web object in memory was found, but the web object in memory has no associated base"); - ExitFunction1(hr = S_FALSE); - } - - hr = ::StringCchCopyW(wzKey, countof(wzKey), psw->wzWebBase); - ExitOnFailure(hr, "Failed to copy web base into key."); - - wzFoundKey = wzKey; - break; - } - else - { - WcaLog(LOGMSG_STANDARD, "Found web `%ls` but data did not match.", wzWeb); - hr = E_UNEXPECTED; - break; - } - } - } - ExitOnFailure(hr, "Failure occured while searching for web in memory"); - - // If we didn't find a web in memory matching look in the metabase. - if (!wzFoundKey) - { - mr.dwMDIdentifier = MD_KEY_TYPE; - mr.dwMDAttributes = METADATA_INHERIT; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = ALL_METADATA; - mr.dwMDDataLen = 0; - mr.pbMDData = NULL; - - // If we're looking based on the old WebAddress detection (NULL) or the new - // Web description detection (-1) - if (MSI_NULL_INTEGER == iSiteId || -1 == iSiteId) - { - if (MSI_NULL_INTEGER == iSiteId) - { - mrCompare.dwMDIdentifier = (fSecure) ? MD_SECURE_BINDINGS : MD_SERVER_BINDINGS; - } - else - { - mrCompare.dwMDIdentifier = MD_SERVER_COMMENT; - } - mrCompare.dwMDAttributes = METADATA_INHERIT; - mrCompare.dwMDUserType = IIS_MD_UT_SERVER; - mrCompare.dwMDDataType = ALL_METADATA; - mrCompare.dwMDDataLen = 0; - mrCompare.pbMDData = NULL; - - // Loop through the "web keys" looking for the "IIsWebServer" key that matches our search criteria. - for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex) - { - hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC", wzSubkey, dwIndex); - if (SUCCEEDED(hr)) - { - hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/W3SVC/%s", wzSubkey); - ExitOnFailure(hr, "Failed to copy web subkey."); - - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mr); - if (MD_ERROR_DATA_NOT_FOUND == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) - { - hr = S_FALSE; // didn't find anything, try next one - continue; - } - ExitOnFailure(hr, "Failed to get key from metabase while searching for web servers"); - - // If we have an IIsWebServer check to see if this is the site we are searching for. - if (0 == lstrcmpW(L"IIsWebServer", (LPCWSTR)mr.pbMDData)) - { - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrCompare); - if (MD_ERROR_DATA_NOT_FOUND == hr || NULL == mrCompare.pbMDData) - { - hr = S_FALSE; - continue; - } - ExitOnFailure(hr, "Failed to get address/description from metabase while searching for web servers"); - - LPWSTR pwzExists = (LPWSTR)mrCompare.pbMDData; - if (MSI_NULL_INTEGER == iSiteId) - { - // Break down the address into its constituent parts (IP:Port:Header). - while (S_OK == hr && *pwzExists) - { - LPCWSTR pwzIPExists = pwzExists; - pwzExists = const_cast(wcsstr(pwzIPExists, L":")); - ExitOnNull(pwzExists, hr, E_INVALIDARG, "Invalid web address. IP was not separated by a colon."); - *pwzExists = L'\0'; - - LPCWSTR pwzPortExists = pwzExists + 1; - pwzExists = const_cast(wcsstr(pwzPortExists, L":")); - ExitOnNull(pwzExists, hr, E_INVALIDARG, "Invalid web address. Port was not separated by a colon."); - *pwzExists = L'\0'; - int iPortExists = wcstol(pwzPortExists, NULL, 10); - - LPCWSTR pwzHeaderExists = pwzExists + 1; - - // compare the passed in address with the address listed for this web - if ((0 == lstrcmpW(wzIP, pwzIPExists) || 0 == lstrcmpW(wzIP, L"*")) && - iPort == iPortExists && - 0 == lstrcmpW(wzHeader, pwzHeaderExists)) - { - wzFoundKey = wzKey; - break; - } - - // move to the next block of data, this may move beyond the available - // data and exit the while loop above. - pwzExists = const_cast(pwzHeaderExists + lstrlenW(pwzHeaderExists) + 1); - } - } - else - { - if (0 == lstrcmpW(wzDescription, pwzExists)) - { - wzFoundKey = wzKey; - } - } - - // If we found the key we were looking for, no point in continuing to search. - if (wzFoundKey) - { - break; - } - } - } - } - - if (E_NOMOREITEMS == hr) - { - Assert(!wzFoundKey); - hr = S_FALSE; - } - } - else // we're looking a specific SiteId - { - hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/W3SVC/%d", iSiteId); - ExitOnFailure(hr, "Failed to allocate metabase key string."); - - // if we have an IIsWebServer store the key - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mr); - - if (SUCCEEDED(hr) && NULL != mr.pbMDData && 0 == lstrcmpW(L"IIsWebServer", (LPCWSTR)mr.pbMDData)) - { - wzFoundKey = wzKey; - } - else if (MD_ERROR_DATA_NOT_FOUND == hr || NULL == mrCompare.pbMDData || NULL == mr.pbMDData) - { - hr = S_FALSE; - } - } - } - - if (wzFoundKey) - { - Assert(S_OK == hr); - - hr = ::StringCchCopyW(wzWebBase, cchWebBase, wzFoundKey); - ExitOnFailure(hr, "Buffer not larger enough for found base key."); - } - -LExit: - MetaFreeValue(&mr); - MetaFreeValue(&mrCompare); - - if (!wzFoundKey && SUCCEEDED(hr)) - { - hr = S_FALSE; - } - - return hr; -} - - -static HRESULT ScaWebFindFreeBase( - __in IMSAdminBase* piMetabase, - __in_xcount(unknown) SCA_WEB* pswList, - __in int iSiteId, - __in_z LPCWSTR wzDescription, - __out_ecount(cchWebBase) LPWSTR wzWebBase, - __in DWORD cchWebBase - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - WCHAR wzSubkey[METADATA_MAX_NAME_LEN]; - DWORD* prgdwSubKeys = NULL; - DWORD cSubKeys = 128; - DWORD cSubKeysFilled = 0; - - DWORD dwKey; - - METADATA_RECORD mr; - ::ZeroMemory(&mr, sizeof(METADATA_RECORD)); - mr.dwMDIdentifier = MD_KEY_TYPE; - mr.dwMDAttributes = 0; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = STRING_METADATA; - mr.dwMDDataLen = 0; - mr.pbMDData = NULL; - - if (MSI_NULL_INTEGER == iSiteId || -1 == iSiteId) - { - prgdwSubKeys = static_cast(MemAlloc(cSubKeys * sizeof(DWORD), TRUE)); - ExitOnNull(prgdwSubKeys, hr, E_OUTOFMEMORY, "failed to allocate space for web site keys"); - - // loop through the "web keys" looking for the "IIsWebServer" key that matches wzWeb - for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex) - { - hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC", wzSubkey, dwIndex); - if (SUCCEEDED(hr)) - { - hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/W3SVC/%s", wzSubkey); - ExitOnFailure(hr, "Failed remember key."); - - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mr); - if (MD_ERROR_DATA_NOT_FOUND == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) - { - hr = S_FALSE; // didn't find anything, try next one - continue; - } - ExitOnFailure(hr, "Failed to get key from metabase while searching for free web root"); - - // if we have a IIsWebServer get the address information - if (0 == lstrcmpW(L"IIsWebServer", (LPCWSTR)mr.pbMDData)) - { - if (cSubKeysFilled >= cSubKeys) - { - cSubKeys = cSubKeys * 2; - prgdwSubKeys = static_cast(MemReAlloc(prgdwSubKeys, cSubKeys * sizeof(DWORD), FALSE)); - ExitOnNull(prgdwSubKeys, hr, E_OUTOFMEMORY, "failed to allocate space for web site keys"); - } - - prgdwSubKeys[cSubKeysFilled] = wcstol(wzSubkey, NULL, 10); - ++cSubKeysFilled; - Sort(prgdwSubKeys, cSubKeysFilled); - } - } - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failed to find free web root"); - - // Add all the webs created in memory. - CONST WCHAR *pcchSlash; - for (SCA_WEB* psw = pswList; psw; psw = psw->pswNext) - { - // Don't process webs that don't have a base - if (!*psw->wzWebBase) - { - continue; - } - - // find the last slash in the web root because the root # is after it - pcchSlash = NULL; - for (CONST WCHAR *pcch = psw->wzWebBase; pcch && *pcch; ++pcch) - { - if (L'/' == *pcch) - { - pcchSlash = pcch; - } - } - // In case we don't find a slash, error out - ExitOnNull(pcchSlash, hr, E_INVALIDARG, "Failed to find a slash in the web root: %ls", psw->wzWebBase); - - prgdwSubKeys[cSubKeysFilled] = wcstol(pcchSlash + 1, NULL, 10); - ++cSubKeysFilled; - Sort(prgdwSubKeys, cSubKeysFilled); - - if (cSubKeysFilled >= cSubKeys) - { - cSubKeys = cSubKeys * 2; - prgdwSubKeys = static_cast(MemReAlloc(prgdwSubKeys, cSubKeys * sizeof(DWORD), FALSE)); - ExitOnNull(prgdwSubKeys, hr, E_OUTOFMEMORY, "failed to allocate space for web site keys"); - } - } - - // Find the lowest free web root. - dwKey = (-1 == iSiteId) ? SiteIdFromDescription(wzDescription) : 1; - for (DWORD i = 0; i < cSubKeysFilled; ++i) - { - if (dwKey == prgdwSubKeys[i]) - { - ++dwKey; - } - else if (dwKey < prgdwSubKeys[i]) - { - break; - } - } - } - else - { - dwKey = iSiteId; - } - - hr = ::StringCchPrintfW(wzWebBase, cchWebBase, L"/LM/W3SVC/%u", dwKey); - ExitOnFailure(hr, "failed to format web base with key: %u", dwKey); - -LExit: - MetaFreeValue(&mr); - - if (prgdwSubKeys) - { - MemFree(prgdwSubKeys); - } - - return hr; -} - - -static HRESULT ScaWebWrite( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* psw, - __in SCA_APPPOOL * psapList) -{ - HRESULT hr = S_OK; - - UINT ui = 0; - WCHAR wzIP[64]; - WCHAR wzBindings[1024]; - WCHAR wzSecureBindings[1024]; - WCHAR* pcchNext; // used to properly create the MULTI_SZ - DWORD cchPcchNext; - WCHAR* pcchSecureNext ; // used to properly create the MULTI_SZ - DWORD cchPcchSecureNext; - - // if the web root doesn't exist create it - if (!psw->fBaseExists) - { - hr = ScaCreateWeb(piMetabase, psw->wzKey, psw->wzWebBase); - ExitOnFailure(hr, "Failed to create web"); - } - else if (psw->iAttributes & SWATTRIB_NOCONFIGUREIFEXISTS) // if we're not supposed to configure existing webs, bail - { - Assert(psw->fBaseExists); - - hr = S_FALSE; - WcaLog(LOGMSG_VERBOSE, "Skipping configuration of existing web: %ls", psw->wzKey); - ExitFunction(); - } - - // put the secure and non-secure bindings together as MULTI_SZs - ::ZeroMemory(wzBindings, sizeof(wzBindings)); - pcchNext = wzBindings; - cchPcchNext = countof(wzBindings); - ::ZeroMemory(wzSecureBindings, sizeof(wzSecureBindings)); - pcchSecureNext = wzSecureBindings; - cchPcchSecureNext = countof(wzSecureBindings); - - // set the IP address appropriately - if (0 == lstrcmpW(psw->swaKey.wzIP, L"*")) - { - ::ZeroMemory(wzIP, sizeof(wzIP)); - } - else - { - hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaKey.wzIP); - ExitOnFailure(hr, "Failed to copy IP string"); - } - - WCHAR wzBinding[256]; - hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaKey.iPort, psw->swaKey.wzHeader); - ExitOnFailure(hr, "Failed to format IP:Port:Header binding string"); - if (psw->swaKey.fSecure) - { - hr = ::StringCchCopyW(pcchSecureNext, cchPcchSecureNext, wzBinding); - ExitOnFailure(hr, "Failed to copy binding string to securenext string"); - pcchSecureNext += lstrlenW(wzBinding) + 1; - cchPcchSecureNext -= lstrlenW(wzBinding) + 1; - } - else - { - hr = ::StringCchCopyW(pcchNext, cchPcchNext, wzBinding); - ExitOnFailure(hr, "Failed to copy binding string to next string"); - pcchNext += lstrlenW(wzBinding) + 1; - cchPcchNext -= lstrlenW(wzBinding) + 1; - } - - for (ui = 0; ui < psw->cExtraAddresses; ++ui) - { - // set the IP address appropriately - if (0 == lstrcmpW(psw->swaExtraAddresses[ui].wzIP, L"*")) - { - ::ZeroMemory(wzIP, sizeof(wzIP)); - } - else - { - hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaExtraAddresses[ui].wzIP); - ExitOnFailure(hr, "Failed to copy extra addresses IP to IP string"); - } - - hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaExtraAddresses[ui].iPort, psw->swaExtraAddresses[ui].wzHeader); - ExitOnFailure(hr, "Failed to format IP:Port:Header binding string for extra address"); - if (psw->swaExtraAddresses[ui].fSecure) - { - hr = ::StringCchCopyW(pcchSecureNext, cchPcchSecureNext, wzBinding); - ExitOnFailure(hr, "Failed to copy binding string to securenext string for extra address"); - pcchSecureNext += lstrlenW(wzBinding) + 1; - cchPcchSecureNext -= lstrlenW(wzBinding) + 1; - } - else - { - hr = ::StringCchCopyW(pcchNext, cchPcchNext, wzBinding); - ExitOnFailure(hr, "Failed to copy binding string to next string for extra address"); - pcchNext += lstrlenW(wzBinding) + 1; - cchPcchNext -= lstrlenW(wzBinding) + 1; - } - } - - // Delete the existing secure bindings metabase value, as having one while SSLCertHash and SSLStoreName aren't both set correctly can result in - // 0x80070520 (ERROR_NO_SUCH_LOGON_SESSION) errors in some situations on IIS7. Clearing this value first and then setting it after the install has completed - // allows the two aforementioned properties to exist in an intermediate state without errors - hr = ScaDeleteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SECURE_BINDINGS, MULTISZ_METADATA); - ExitOnFailure(hr, "Failed to temporarily delete secure bindings for Web"); - - // now write the bindings to the metabase - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_BINDINGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, MULTISZ_METADATA, wzBindings); - ExitOnFailure(hr, "Failed to write server bindings for Web"); - - // write the target path for the web's directory to the metabase - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"/Root", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, psw->wzDirectory); - ExitOnFailure(hr, "Failed to write virtual root path for Web"); - - // write the description for the web to the metabase - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_COMMENT, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, psw->wzDescription); - ExitOnFailure(hr, "Failed to write description for Web"); - - ui = psw->iConnectionTimeout; - if (MSI_NULL_INTEGER != ui) - { - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_CONNECTION_TIMEOUT, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); - ExitOnFailure(hr, "Failed to write connection timeout for Web"); - } - - ui = psw->iState; - if (MSI_NULL_INTEGER != ui) - { - if (2 == ui) - { - ui = 1; - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_AUTOSTART, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); - ExitOnFailure(hr, "Failed to write auto start flag for Web"); - ui = 2; - } - - if (1 == ui || 2 == ui) - { - ui = 1; // start command - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_COMMAND, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); - ExitOnFailure(hr, "Failed to start Web"); - } - else if (0 == ui) - { - ui = 2; // stop command - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_COMMAND, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); - ExitOnFailure(hr, "Failed to stop Web"); - } - else - { - hr = E_UNEXPECTED; - ExitOnFailure(hr, "Unexpected value for Web State"); - } - } - - WCHAR wzRootOfWeb[METADATA_MAX_NAME_LEN]; - hr = ::StringCchPrintfW(wzRootOfWeb, countof(wzRootOfWeb), L"%s/Root", psw->wzWebBase); - ExitOnFailure(hr, "Failed to allocate WebBase/Root string for root of web"); - - // write the web dirproperties information - if (psw->fHasProperties) - { - hr = ScaWriteWebDirProperties(piMetabase, wzRootOfWeb, &psw->swp); - ExitOnFailure(hr, "Failed to write web security information to metabase"); - } - - // write the application information - if (psw->fHasApplication) - { - // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created - if (WcaIsReInstalling(psw->isInstalled, psw->isAction)) - { - hr = ScaDeleteApp(piMetabase, wzRootOfWeb); - ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); - } - - hr = ScaWriteWebApplication(piMetabase, wzRootOfWeb, &psw->swapp, psapList); - ExitOnFailure(hr, "Failed to write web application information to metabase"); - } - - // write the SSL certificate information - if (psw->pswscList) - { - hr = ScaSslCertificateWriteMetabase(piMetabase, psw->wzWebBase, psw->pswscList); - ExitOnFailure(hr, "Failed to write SSL certificates for Web site: %ls", psw->wzKey); - } - - hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SECURE_BINDINGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, MULTISZ_METADATA, wzSecureBindings); - ExitOnFailure(hr, "Failed to write secure bindings for Web"); - - // write the headers - if (psw->pshhList) - { - hr = ScaWriteHttpHeader(piMetabase, wzRootOfWeb, psw->pshhList); - ExitOnFailure(hr, "Failed to write custom HTTP headers for Web site: %ls", psw->wzKey); - } - - // write the errors - if (psw->psweList) - { - hr = ScaWriteWebError(piMetabase, weptWeb, psw->wzWebBase, psw->psweList); - ExitOnFailure(hr, "Failed to write custom web errors for Web site: %ls", psw->wzKey); - } - - // write the mimetypes - if (psw->psmm) - { - hr = ScaWriteMimeMap(piMetabase, wzRootOfWeb, psw->psmm); - ExitOnFailure(hr, "Failed to write mimemap for Web site: %ls", psw->wzKey); - } - - // write the log information to the metabase - if (psw->fHasLog) - { - hr = ScaWriteWebLog(piMetabase, psw->wzWebBase, &psw->swl); - ExitOnFailure(hr, "Failed to write web log information to metabase"); - } - -LExit: - return hr; -} - - -static HRESULT ScaWebRemove( - __in IMSAdminBase* piMetabase, - __in const SCA_WEB* psw - ) -{ - HRESULT hr = S_OK; - - // simply remove the root key and everything else is pulled at the same time - hr = ScaDeleteMetabaseKey(piMetabase, psw->wzWebBase, L""); - ExitOnFailure(hr, "Failed to remove web '%ls' from metabase", psw->wzKey); - -LExit: - return hr; -} - - -static DWORD SiteIdFromDescription( - __in_z LPCWSTR wzDescription - ) -{ - LPCWSTR pwz = wzDescription; - DWORD dwSiteId = 0; - while (pwz && *pwz) - { - WCHAR ch = *pwz & 0xdf; - dwSiteId = (dwSiteId * 101) + ch; - ++pwz; - } - - return (dwSiteId % INT_MAX) + 1; -} - - -// insertion sort -static void Sort( - __in_ecount(cArray) DWORD dwArray[], - __in int cArray - ) -{ - int i, j; - DWORD dwData; - - for (i = 1; i < cArray; ++i) - { - dwData = dwArray[i]; - - j = i - 1; - while (0 <= j && dwArray[j] > dwData) - { - dwArray[j + 1] = dwArray[j]; - j--; - } - - dwArray[j + 1] = dwData; - } -} diff --git a/src/ca/scaweb.h b/src/ca/scaweb.h deleted file mode 100644 index 294030b4..00000000 --- a/src/ca/scaweb.h +++ /dev/null @@ -1,123 +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 "scawebapp.h" -#include "scawebprop.h" -#include "scahttpheader.h" -#include "scaweberr.h" -#include "scassl.h" -#include "scaapppool.h" -#include "scaweblog.h" -#include "scamimemap.h" - -// globals -#define MAX_ADDRESSES_PER_WEB 10 - -enum eWebQuery { wqWeb = 1, wqComponent, wqId, wqDescription, wqConnectionTimeout, wqDirectory, - wqState, wqAttributes, wqProperties, wqApplication, wqAddress, wqIP, wqPort, wqHeader, wqSecure, wqLog, wqInstalled, wqAction, wqSourcePath, wqTargetPath}; - -enum eWebAddressQuery { waqAddress = 1, waqWeb, waqIP, waqPort, waqHeader, waqSecure }; - -enum SCA_WEB_ATTRIBUTES -{ - SWATTRIB_NOCONFIGUREIFEXISTS = 2 -}; - -// structs -struct SCA_WEB_ADDRESS -{ - WCHAR wzKey [MAX_DARWIN_KEY + 1]; - - WCHAR wzIP[MAX_DARWIN_COLUMN + 1]; - int iPort; - WCHAR wzHeader[MAX_DARWIN_COLUMN + 1]; - BOOL fSecure; -}; - -struct SCA_WEB -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - BOOL fHasComponent; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - // metabase information - WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; - BOOL fBaseExists; - - // iis configuation information - SCA_WEB_ADDRESS swaKey; - - SCA_WEB_ADDRESS swaExtraAddresses[MAX_ADDRESSES_PER_WEB + 1]; - DWORD cExtraAddresses; - - WCHAR wzDirectory[MAX_PATH]; - WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; - - int iState; - int iAttributes; - - BOOL fHasProperties; - SCA_WEB_PROPERTIES swp; - - BOOL fHasApplication; - SCA_WEB_APPLICATION swapp; - - BOOL fHasSecurity; - int dwAccessPermissions; - int iConnectionTimeout; - - SCA_MIMEMAP* psmm; // mime mappings - SCA_WEB_SSL_CERTIFICATE* pswscList; - SCA_HTTP_HEADER* pshhList; - SCA_WEB_ERROR* psweList; - - BOOL fHasLog; - SCA_WEB_LOG swl; - - SCA_WEB* pswNext; -}; - - -// prototypes -HRESULT ScaWebsRead( - __in IMSAdminBase* piMetabase, - __in SCA_MIMEMAP** ppsmmList, - __in SCA_WEB** ppswList, - __in SCA_HTTP_HEADER** pshhList, - __in SCA_WEB_ERROR** psweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hSslCertQuery, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ); - -HRESULT ScaWebsGetBase( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in LPCWSTR wzWeb, - __out_ecount(cchWebBase) LPWSTR wzWebBase, - __in DWORD cchWebBase, - __in WCA_WRAPQUERY_HANDLE hWrapQuery - ); - -HRESULT ScaWebsInstall( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in SCA_APPPOOL * psapList - ); - -HRESULT ScaWebsUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList - ); - -void ScaWebsFreeList( - __in SCA_WEB* pswHead - ); diff --git a/src/ca/scaweb7.cpp b/src/ca/scaweb7.cpp deleted file mode 100644 index 3ee781f2..00000000 --- a/src/ca/scaweb7.cpp +++ /dev/null @@ -1,953 +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" - -//Adding this because delivery doesn't have the updated specstrings.h that windows build does -#ifndef __in_xcount -#define __in_xcount(size) -#endif - -// prototypes for private helper functions -static SCA_WEB7* NewWeb7(); -static SCA_WEB7* AddWebToList7( - __in SCA_WEB7* pswList, - __in SCA_WEB7* psw - ); - -static HRESULT ScaWebFindBase7( - __in SCA_WEB7* pswList, - LPCWSTR wzDescription - ); - -static HRESULT ScaWebWrite7( - __in SCA_WEB7* psw, - __in SCA_APPPOOL * psapList - ); - -static HRESULT ScaWebRemove7(__in const SCA_WEB7* psw); - - -HRESULT ScaWebsRead7( - __in SCA_WEB7** ppswList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hSslCertQuery, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(ppswList); - WcaLog(LOGMSG_VERBOSE, "Entering ScaWebsRead7()"); - - HRESULT hr = S_OK; - - MSIHANDLE hRec; - MSIHANDLE hRecAddresses; - - WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL; - WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL; - - SCA_WEB7* psw = NULL; - LPWSTR pwzData = NULL; - - DWORD dwLen = 0; - errno_t error = EINVAL; - - // check to see what tables are available - hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); - - hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); - - - if (0 == WcaGetQueryRecords(hQueryWebSite) || 0 == WcaGetQueryRecords(hQueryWebAddress)) - { - WcaLog(LOGMSG_VERBOSE, "Required tables not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the webs - while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec))) - { - psw = NewWeb7(); - if (!psw) - { - hr = E_OUTOFMEMORY; - break; - } - - // get the darwin information - hr = WcaGetRecordString(hRec, wqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web"); - hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to web object"); - - // get component install state - hr = WcaGetRecordString(hRec, wqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get Component for Web"); - hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); - ExitOnFailure(hr, "Failed to copy component string to web object"); - if (*(psw->wzComponent)) - { - psw->fHasComponent = TRUE; - - hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled); - ExitOnFailure(hr, "Failed to get web Component's installed state"); - - WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction); - ExitOnFailure(hr, "Failed to get web Component's action state"); - } - - // Get the web's description. - hr = WcaGetRecordString(hRec, wqDescription, &pwzData); - ExitOnFailure(hr, "Failed to get Description for Web"); - hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); - ExitOnFailure(hr, "Failed to copy description string to web object"); - - //get web's site Id - hr = WcaGetRecordInteger(hRec, wqId, &psw->iSiteId); - ExitOnFailure(hr, "Failed to get SiteId for Web"); - - // get the web's key address (Bindings) - hr = WcaGetRecordString(hRec, wqAddress, &pwzData); - ExitOnFailure(hr, "Failed to get Address for Web"); - hr = ::StringCchCopyW(psw->swaBinding.wzKey, countof(psw->swaBinding.wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy web binding key"); - - hr = WcaGetRecordString(hRec, wqIP, &pwzData); - ExitOnFailure(hr, "Failed to get IP for Web"); - hr = ::StringCchCopyW(psw->swaBinding.wzIP, countof(psw->swaBinding.wzIP), pwzData); - ExitOnFailure(hr, "Failed to copy web IP"); - - hr = WcaGetRecordString(hRec, wqPort, &pwzData); - ExitOnFailure(hr, "Failed to get Web Address port"); - psw->swaBinding.iPort = wcstol(pwzData, NULL, 10); - - hr = WcaGetRecordString(hRec, wqHeader, &pwzData); - ExitOnFailure(hr, "Failed to get Header for Web"); - hr = ::StringCchCopyW(psw->swaBinding.wzHeader, countof(psw->swaBinding.wzHeader), pwzData); - ExitOnFailure(hr, "Failed to copy web header"); - - hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaBinding.fSecure); - ExitOnFailure(hr, "Failed to get if Web is secure"); - if (S_FALSE == hr) - { - psw->swaBinding.fSecure = FALSE; - } - - // look to see if site exists - dwLen = METADATA_MAX_NAME_LEN; - hr = ScaWebFindBase7(*ppswList, psw->wzDescription); - - // If we didn't find a web in memory, ignore it - during execute CA - // if the site truly does not exist then there will be an error. - if (S_OK == hr) - { - // site exists in config - psw->fBaseExists = TRUE; - } - else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) - { - hr = S_OK; - - // site does not exists in config - psw->fBaseExists = FALSE; - } - ExitOnFailure(hr, "Failed to find web site"); - - // get any extra web addresses - WcaFetchWrappedReset(hQueryWebAddress); - - while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses))) - { - if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) - { - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); - } - - hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); - ExitOnFailure(hr, "Failed to get extra web Address"); - - // if this isn't the key address add it - if (0 != lstrcmpW(pwzData, psw->swaBinding.wzKey)) - { - hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, - countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy web binding key"); - - hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData); - ExitOnFailure(hr, "Failed to get extra web IP"); - hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); - ExitOnFailure(hr, "Failed to copy web binding IP"); - - hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData); - ExitOnFailure(hr, "Failed to get port for extra web IP"); - psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); - - // errno is set to ERANGE if overflow or underflow occurs - _get_errno(&error); - - if (ERANGE == error) - { - hr = E_INVALIDARG; - ExitOnFailure(hr, "Failed to convert web Port address"); - } - - hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData); - ExitOnFailure(hr, "Failed to get header for extra web IP"); - hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); - ExitOnFailure(hr, "Failed to copy web binding header"); - - hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); - ExitOnFailure(hr, "Failed to get if secure extra web IP"); - if (S_FALSE == hr) - { - psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; - } - - ++psw->cExtraAddresses; - } - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure occured while getting extra web addresses"); - - // - // Connection time out - // - hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); - ExitOnFailure(hr, "Failed to get connection timeout for Web"); - - if (psw->fHasComponent) // If we're installing it, it needs a dir - { - // get the web's directory - if (INSTALLSTATE_SOURCE == psw->isAction) - { - hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData); - } - else - { - hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData); - } - ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); - - dwLen = lstrlenW(pwzData); - // remove trailing backslash - if (dwLen > 0 && pwzData[dwLen-1] == L'\\') - { - pwzData[dwLen-1] = 0; - } - hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData); - ExitOnFailure(hr, "Failed to copy web dir: '%ls'", pwzData); - - } - - hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); - ExitOnFailure(hr, "Failed to get state for Web"); - - hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); - ExitOnFailure(hr, "Failed to get attributes for Web"); - - // get the dir properties for this web - hr = WcaGetRecordString(hRec, wqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get directory properties for Web"); - if (*pwzData) - { - hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp); - ExitOnFailure(hr, "Failed to get directory properties for Web"); - - psw->fHasProperties = TRUE; - } - - // get the application information for this web - hr = WcaGetRecordString(hRec, wqApplication, &pwzData); - ExitOnFailure(hr, "Failed to get application identifier for Web"); - if (*pwzData) - { - hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp); - ExitOnFailure(hr, "Failed to get application for Web"); - - psw->fHasApplication = TRUE; - } - - // get the SSL certificates - hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList)); - ExitOnFailure(hr, "Failed to get SSL Certificates."); - - // get the custom headers - if (*ppshhList) - { - hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); - ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); - } - - // get the errors - if (*ppsweList) - { - hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); - ExitOnFailure(hr, "Failed to get Custom Errors"); - } - - // get the log information for this web - hr = WcaGetRecordString(hRec, wqLog, &pwzData); - ExitOnFailure(hr, "Failed to get log identifier for Web"); - if (*pwzData) - { - hr = ScaGetWebLog7(pwzData, hWebLogQuery, &psw->swl); - ExitOnFailure(hr, "Failed to get Log for Web."); - psw->fHasLog = TRUE; - } - - *ppswList = AddWebToList7(*ppswList, psw); - psw = NULL; // set the web NULL so it doesn't accidentally get freed below - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - -LExit: - // if anything was left over after an error clean it all up - WcaFinishUnwrapQuery(hQueryWebSite); - WcaFinishUnwrapQuery(hQueryWebAddress); - - ScaWebsFreeList7(psw); - - ReleaseStr(pwzData); - WcaLog(LOGMSG_VERBOSE, "Exiting ScaWebsRead7()"); - - return hr; -} - -BOOL CompareBinding( - __in IAppHostElement* pBinding, - __in LPVOID pContext - ) -{ - BOOL fFound = FALSE; - HRESULT hr = S_OK; - LPWSTR pwzBindingInfo = NULL; - SCA_WEB7* psw = (SCA_WEB7*)pContext; - - hr = Iis7GetPropertyString(pBinding, IIS_CONFIG_BINDINGINFO, &pwzBindingInfo); - ExitOnFailure(hr, "Failed to get bindinginfo for binding element"); - - LPWSTR pwzExists = pwzBindingInfo; - // Break down the address into its constituent parts (IP:Port:Header). - // Taken from IIS6 CA code for compatibility - while (S_OK == hr && *pwzExists) - { - LPCWSTR pwzIPExists = pwzExists; - pwzExists = const_cast(wcsstr(pwzIPExists, L":")); - if (NULL == pwzExists) - { - ExitFunction(); - } - *pwzExists = L'\0'; - - LPCWSTR pwzPortExists = pwzExists + 1; - pwzExists = const_cast(wcsstr(pwzPortExists, L":")); - if (NULL == pwzExists) - { - ExitFunction(); - } - *pwzExists = L'\0'; - int iPortExists = wcstol(pwzPortExists, NULL, 10); - - LPCWSTR pwzHeaderExists = pwzExists + 1; - - BOOL fIpMatches = (0 == lstrcmpW(psw->swaBinding.wzIP, pwzIPExists)); // Explicit IP match - fIpMatches |= (0 == lstrcmpW(psw->swaBinding.wzIP, L"*")); // Authored * matches any IP - fIpMatches |= ('\0' != psw->swaBinding.wzIP) && // Unauthored IP - (0 == lstrcmpW(pwzIPExists, L"*")); // matches the All Unassigned IP : '*' - - // compare the passed in address with the address listed for this web - if (fIpMatches && psw->swaBinding.iPort == iPortExists && - 0 == lstrcmpW(psw->swaBinding.wzHeader, pwzHeaderExists)) - { - fFound = TRUE; - break; - } - - // move to the next block of data, this may move beyond the available - // data and exit the while loop above. - pwzExists = const_cast(pwzHeaderExists + lstrlenW(pwzHeaderExists)); - } - -LExit: - WcaLog(LOGMSG_VERBOSE, "Site with binding %ls %s a match", pwzBindingInfo, fFound ? "is" : "is not"); - ReleaseNullStr(pwzBindingInfo); - return fFound; -} - -BOOL EnumSiteCompareBinding( - __in IAppHostElement* pSite, - __in LPVOID pContext - ) -{ - BOOL fFound = FALSE; - HRESULT hr = S_OK; - SCA_WEB7* psw = (SCA_WEB7*)pContext; - IAppHostChildElementCollection *pSiteChildren = NULL; - IAppHostElement *pBindings = NULL; - IAppHostElementCollection *pBindingsCollection = NULL; - IAppHostElement *pBinding = NULL; - VARIANT vtProp; - VariantInit(&vtProp); - - hr = pSite->get_ChildElements(&pSiteChildren); - ExitOnFailure(hr, "Failed get site child elements collection"); - - vtProp.vt = VT_BSTR; - vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_BINDINGS); - hr = pSiteChildren->get_Item(vtProp, &pBindings); - ExitOnFailure(hr, "Failed get bindings element"); - - hr = pBindings->get_Collection(&pBindingsCollection); - ExitOnFailure(hr, "Failed get bindings collection"); - - WcaLog(LOGMSG_VERBOSE, "Searching for site with binding %ls:%d:%ls", psw->swaBinding.wzIP, psw->swaBinding.iPort, psw->swaBinding.wzHeader); - - hr = Iis7EnumAppHostElements(pBindingsCollection, CompareBinding, psw, &pBinding, NULL); - ExitOnFailure(hr, "Failed search bindings collection"); - - fFound = NULL != pBinding; -LExit: - VariantClear(&vtProp); - ReleaseNullObject(pSiteChildren); - ReleaseNullObject(pBindings); - ReleaseNullObject(pBindingsCollection); - ReleaseNullObject(pBinding); - return fFound; -} - -HRESULT ScaWebSearch7( - __in SCA_WEB7* psw, - __deref_out_z_opt LPWSTR* pswWeb, - __out_opt BOOL* pfFound - ) -{ - HRESULT hr = S_OK; - BOOL fInitializedCom = FALSE; - BSTR bstrSites = NULL; - BSTR bstrAppHostRoot = NULL; - IAppHostAdminManager *pAdminMgr = NULL; - IAppHostElement *pSites = NULL; - IAppHostElementCollection *pCollection = NULL; - IAppHostElement *pSite = NULL; - - if (NULL != pswWeb) - { - ReleaseNullStr(*pswWeb); - } - - if (NULL != pfFound) - { - *pfFound = FALSE; - } - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "Failed to initialize COM"); - fInitializedCom = TRUE; - - hr = CoCreateInstance(__uuidof(AppHostAdminManager), NULL, CLSCTX_INPROC_SERVER, __uuidof(IAppHostAdminManager), reinterpret_cast (&pAdminMgr)); - if (REGDB_E_CLASSNOTREG == hr) - { - WcaLog(LOGMSG_VERBOSE, "AppHostAdminManager was not registered, cannot find site."); - hr = S_OK; - ExitFunction(); - } - ExitOnFailure(hr, "Failed to CoCreate IAppHostAdminManager"); - - bstrSites = ::SysAllocString(IIS_CONFIG_SITES_SECTION); - ExitOnNull(bstrSites, hr, E_OUTOFMEMORY, "Failed to allocate sites string."); - - bstrAppHostRoot = ::SysAllocString(IIS_CONFIG_APPHOST_ROOT); - ExitOnNull(bstrAppHostRoot, hr, E_OUTOFMEMORY, "Failed to allocate host root string."); - - hr = pAdminMgr->GetAdminSection(bstrSites, bstrAppHostRoot, &pSites); - ExitOnFailure(hr, "Failed get sites section"); - ExitOnNull(pSites, hr, ERROR_FILE_NOT_FOUND, "Failed get sites section object"); - - hr = pSites->get_Collection(&pCollection); - ExitOnFailure(hr, "Failed get sites collection"); - - // not explicitly doing a Description search - if (-1 != psw->iSiteId) - { - if (MSI_NULL_INTEGER == psw->iSiteId) - { - // Enumerate sites & determine if the binding matches - hr = Iis7EnumAppHostElements(pCollection, EnumSiteCompareBinding, psw, &pSite, NULL); - ExitOnFailure(hr, "Failed locate site by ID"); - } - else - { - // Find a site with ID matches - hr = Iis7FindAppHostElementInteger(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_ID, psw->iSiteId, &pSite, NULL); - ExitOnFailure(hr, "Failed locate site by ID"); - } - } - - if (NULL == pSite) - { - // Find a site with Name that matches - hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_NAME, psw->wzDescription, &pSite, NULL); - ExitOnFailure(hr, "Failed locate site by ID"); - } - - if (NULL != pSite) - { - if (NULL != pfFound) - { - *pfFound = TRUE; - } - - if (NULL != pswWeb) - { - // We found a site, return its description - hr = Iis7GetPropertyString(pSite, IIS_CONFIG_NAME, pswWeb); - ExitOnFailure(hr, "Failed get site name"); - } - } -LExit: - ReleaseNullObject(pAdminMgr); - ReleaseNullObject(pSites); - ReleaseNullObject(pCollection); - ReleaseNullObject(pSite); - ReleaseBSTR(bstrAppHostRoot); - ReleaseBSTR(bstrSites); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - return hr; -} - - -HRESULT ScaWebsGetBase7( - __in SCA_WEB7* pswList, - __in LPCWSTR pswWebKey, - __out_ecount(cchDest) LPWSTR pswWeb, - __in DWORD_PTR cchDest - ) -{ - HRESULT hr = S_OK; - BOOL fFound = FALSE; - SCA_WEB7* psw = pswList; - LPWSTR wzSiteName = NULL; - - *pswWeb = '/0'; - - //looking for psw->wzKey == pswWebKey - while(psw) - { - if (0 == wcscmp(pswWebKey, psw->wzKey)) - { - fFound = TRUE; - break; - } - psw = psw->pswNext; - } - - if (!fFound) - { - ExitFunction1(hr = S_FALSE); - } - - // Search if we're not installing the site - if (!psw->fHasComponent || (psw->iAttributes & SWATTRIB_NOCONFIGUREIFEXISTS)) - { - // We are not installing this website. Search for it in IIS config - hr = ScaWebSearch7(psw, &wzSiteName, NULL); - ExitOnFailure(hr, "Failed to search for Website"); - - if (NULL != wzSiteName) - { - hr = ::StringCchCopyW(pswWeb, cchDest, wzSiteName); - ExitOnFailure(hr, "Failed to set Website description for located Website"); - } - } - - if ('/0' == *pswWeb) - { - WcaLog(LOGMSG_VERBOSE, "Could not find Web: %ls, defaulting to %ls", psw->wzKey, psw->wzDescription); - // Default to the provided description, the Exec CA will locate by description - hr = ::StringCchCopyW(pswWeb, cchDest, psw->wzDescription); - ExitOnFailure(hr, "Failed to set Website description to default"); - } -LExit: - ReleaseNullStr(wzSiteName); - return hr; -} - -HRESULT ScaWebsInstall7( - __in SCA_WEB7* pswList, - __in SCA_APPPOOL * psapList - ) -{ - HRESULT hr = S_OK; - SCA_WEB7* psw = pswList; - - while (psw) - { - // if we are installing the web site - if (psw->fHasComponent && WcaIsInstalling(psw->isInstalled, psw->isAction)) - { - hr = ScaWebWrite7(psw, psapList); - ExitOnFailure(hr, "failed to write web '%ls' to metabase", psw->wzKey); - } - - psw = psw->pswNext; - } - -LExit: - return hr; -} - - -HRESULT ScaWebsUninstall7( - __in SCA_WEB7* pswList - ) -{ - HRESULT hr = S_OK; - SCA_WEB7* psw = pswList; - - while (psw) - { - if (psw->fHasComponent && WcaIsUninstalling(psw->isInstalled, psw->isAction)) - { - // If someone - hr = ScaWebRemove7(psw); - ExitOnFailure(hr, "Failed to remove web '%ls' ", psw->wzKey); - } - - psw = psw->pswNext; - } - -LExit: - return hr; -} - - -void ScaWebsFreeList7(__in SCA_WEB7* pswList) -{ - SCA_WEB7* pswDelete = pswList; - while (pswList) - { - pswDelete = pswList; - pswList = pswList->pswNext; - - // Free the SSL, headers and errors list first - ScaSslCertificateFreeList(pswDelete->pswscList); - ScaHttpHeaderFreeList(pswDelete->pshhList); - ScaWebErrorFreeList(pswDelete->psweList); - - MemFree(pswDelete); - } -} - - -// private helper functions - -static SCA_WEB7* NewWeb7() -{ - SCA_WEB7* psw = (SCA_WEB7*)MemAlloc(sizeof(SCA_WEB7), TRUE); - Assert(psw); - return psw; -} - - -static SCA_WEB7* AddWebToList7( - __in SCA_WEB7* pswList, - __in SCA_WEB7* psw - ) -{ - if (pswList) - { - SCA_WEB7* pswTemp = pswList; - while (pswTemp->pswNext) - { - pswTemp = pswTemp->pswNext; - } - - pswTemp->pswNext = psw; - } - else - { - pswList = psw; - } - - return pswList; -} - - -static HRESULT ScaWebFindBase7( - __in SCA_WEB7* pswList, - __in_z LPCWSTR wzDescription - ) -{ - HRESULT hr = S_OK; - BOOL fFound = FALSE; - - // try to find the web in memory first - for (SCA_WEB7* psw = pswList; psw; psw = psw->pswNext) - { - if (0 == wcscmp(wzDescription, psw->wzDescription)) - { - fFound = TRUE; - break; - } - } - - if (!fFound) - { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - } - - return hr; -} - - -static HRESULT ScaWebWrite7( - __in SCA_WEB7* psw, - __in SCA_APPPOOL * psapList - ) -{ - HRESULT hr = S_OK; - - BOOL fExists = FALSE; - UINT ui = 0; - WCHAR wzIP[64]; - WCHAR wzBinding[1024]; - WCHAR wzAppPoolName[MAX_PATH]; - - // - // determine if site must be new - // - if (psw->iAttributes & SWATTRIB_NOCONFIGUREIFEXISTS) - { - // Check if site already exists. - hr = ScaWebSearch7(psw, NULL, &fExists); - ExitOnFailure(hr, "Failed to search for web: %ls", psw->wzKey); - - if (fExists) - { - hr = S_FALSE; - WcaLog(LOGMSG_VERBOSE, "Skipping configuration of existing web: %ls", psw->wzKey); - ExitFunction(); - } - } - - //create a site - hr = ScaWriteConfigID(IIS_SITE); - ExitOnFailure(hr, "Failed write site ID"); - - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed write site ID create action"); - - //Site Name - hr = ScaWriteConfigString(psw->wzDescription); //Site Name - ExitOnFailure(hr, "Failed write site desc"); - - //Site Id -- value is MSI_NULL_INTEGER if not set in WIX - hr = ScaWriteConfigInteger(psw->iSiteId); //SiteID - ExitOnFailure(hr, "Failed write site id value"); - - //Site Auto Start -- value is MSI_NULL_INTEGER if not set in WIX - hr = ScaWriteConfigInteger(psw->iState); // serverAutoStart - ExitOnFailure(hr, "Failed write site autostart"); - - hr = ScaWriteConfigInteger(psw->iConnectionTimeout); //limits/connectionTimeout - ExitOnFailure(hr, "Failed write site timeout"); - - //create default application - hr = ScaWriteConfigID(IIS_APPLICATION); - ExitOnFailure(hr, "Failed write app ID"); - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed write app action ID"); - hr = ScaWriteConfigString(psw->wzDescription); //site name key - ExitOnFailure(hr, "Failed write app desc"); - hr = ScaWriteConfigString(L"/"); // App Path (default) - ExitOnFailure(hr, "Failed write app def path /"); - - if (psw->fHasApplication && *psw->swapp.wzAppPool) - { - hr = ScaFindAppPool7(psw->swapp.wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); - ExitOnFailure(hr, "Failed to read app pool from application"); - - hr = ScaWriteConfigString(wzAppPoolName); - ExitOnFailure(hr, "Failed write app appPool"); - } - else - { - hr = ScaWriteConfigString(L""); - ExitOnFailure(hr, "Failed write app appPool"); - } - - //create vdir for default application - hr = ScaWriteConfigID(IIS_VDIR); - ExitOnFailure(hr, "Failed write vdir ID"); - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed write vdir action"); - hr = ScaWriteConfigString(psw->wzDescription); //site name key - ExitOnFailure(hr, "Failed write vdir desc"); - hr = ScaWriteConfigString(L"/"); //vdir path (default) - ExitOnFailure(hr, "Failed write vdir app"); - hr = ScaWriteConfigString(psw->wzDirectory); //physical dir - ExitOnFailure(hr, "Failed write vdir dir"); - - //create bindings for site - hr = ScaWriteConfigID(IIS_BINDING); - ExitOnFailure(hr, "Failed write binding ID"); - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed write binding action ID"); - hr = ScaWriteConfigString(psw->wzDescription); //site name key - ExitOnFailure(hr, "Failed write binding site key"); - - if (psw->swaBinding.fSecure) - { - hr = ScaWriteConfigString(L"https"); // binding protocol - ExitOnFailure(hr, "Failed write binding https"); - } - else - { - hr = ScaWriteConfigString(L"http"); // binding protocol - ExitOnFailure(hr, "Failed write binding http"); - } - - // set the IP address appropriately - if (0 == wcscmp(psw->swaBinding.wzIP, L"")) - { - hr = ::StringCchCopyW(wzIP, countof(wzIP), L"*"); // if no IP specified = add * - } - else - { -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaBinding.wzIP); // else leave untouched - } - ExitOnFailure(hr, "Failed to copy IP string"); - - hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaBinding.iPort, psw->swaBinding.wzHeader); - ExitOnFailure(hr, "Failed to format IP:Port:Header binding string"); - - // write bindings CAData - hr = ScaWriteConfigString(wzBinding) ; //binding info - ExitOnFailure(hr, "Failed to create web bindings"); - - for (ui = 0; (ui < MAX_ADDRESSES_PER_WEB) && (ui < psw->cExtraAddresses); ++ui) - { - // set the IP address appropriately - if (0 == wcscmp(psw->swaExtraAddresses[ui].wzIP, L"")) - { - hr = ::StringCchCopyW(wzIP, countof(wzIP), L"*"); // if no IP specified = add * - } - else - { -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaExtraAddresses[ui].wzIP); //else leave untouched - } - ExitOnFailure(hr, "Failed to copy web IP string"); - - hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaExtraAddresses[ui].iPort, psw->swaExtraAddresses[ui].wzHeader); - ExitOnFailure(hr, "Failed to copy web IP"); - - //create bindings for site - hr = ScaWriteConfigID(IIS_BINDING); - ExitOnFailure(hr, "Failed write binding ID"); - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed write binding action"); - hr = ScaWriteConfigString(psw->wzDescription); //site name key - ExitOnFailure(hr, "Failed write binding web name"); - - if (psw->swaExtraAddresses[ui].fSecure) - { - hr = ScaWriteConfigString(L"https"); // binding protocol - } - else - { - hr = ScaWriteConfigString(L"http"); // binding protocol - } - ExitOnFailure(hr, "Failed write binding http(s)"); - - // write bindings CAData - hr = ScaWriteConfigString(wzBinding) ; //binding info - ExitOnFailure(hr, "Failed write binding info"); - } - - // write the web dirproperties information - if (psw->fHasProperties) - { - // dir properties are for the default application of the web - // with location '/' - hr = ScaWriteWebDirProperties7(psw->wzDescription, L"/", &psw->swp); - ExitOnFailure(hr, "Failed to write web security information to metabase"); - } - - //// write the application information - if (psw->fHasApplication) - { - hr = ScaWriteWebApplication7(psw->wzDescription, L"/", &psw->swapp, psapList); - ExitOnFailure(hr, "Failed to write web application information to metabase"); - } - - // write the SSL certificate information - if (psw->pswscList) - { - hr = ScaSslCertificateWrite7(psw->wzDescription, psw->pswscList); - ExitOnFailure(hr, "Failed to write SSL certificates for Web site: %ls", psw->wzKey); - } - - // write the headers - if (psw->pshhList) - { - hr = ScaWriteHttpHeader7(psw->wzDescription, L"/", psw->pshhList); - ExitOnFailure(hr, "Failed to write custom HTTP headers for Web site: %ls", psw->wzKey); - } - - // write the errors - if (psw->psweList) - { - hr = ScaWriteWebError7(psw->wzDescription, L"/", psw->psweList); - ExitOnFailure(hr, "Failed to write custom web errors for Web site: %ls", psw->wzKey); - } - - // write the log information to the metabase - if (psw->fHasLog) - { - hr = ScaWriteWebLog7(psw->wzDescription, &psw->swl); - ExitOnFailure(hr, "Failed to write web log information to metabase"); - } - -LExit: - return hr; -} - - -static HRESULT ScaWebRemove7( - __in const SCA_WEB7* psw - ) -{ - HRESULT hr = S_OK; - - hr = ScaWriteConfigID(IIS_SITE); - ExitOnFailure(hr, "Failed write site ID"); - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "Failed write site action"); - hr = ScaWriteConfigString(psw->wzDescription); //Site Name - ExitOnFailure(hr, "Failed write site name"); - -LExit: - return hr; -} diff --git a/src/ca/scaweb7.h b/src/ca/scaweb7.h deleted file mode 100644 index 78946756..00000000 --- a/src/ca/scaweb7.h +++ /dev/null @@ -1,97 +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 "scawebapp.h" -#include "scawebprop.h" -#include "scahttpheader.h" -#include "scaweberr.h" -#include "scassl.h" -#include "scaapppool.h" -#include "scaweblog.h" - -// globals -#define MAX_ADDRESSES_PER_WEB 10 - -// structs -struct SCA_WEB7 -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - BOOL fHasComponent; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - int iSiteId; - - // metabase information - WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; - BOOL fBaseExists; - - // iis configuation information - SCA_WEB_ADDRESS swaBinding; - - SCA_WEB_ADDRESS swaExtraAddresses[MAX_ADDRESSES_PER_WEB + 1]; - DWORD cExtraAddresses; - - WCHAR wzDirectory[MAX_PATH]; - WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; - - int iState; - int iAttributes; - - BOOL fHasProperties; - SCA_WEB_PROPERTIES swp; - - BOOL fHasApplication; - SCA_WEB_APPLICATION swapp; - - BOOL fHasSecurity; - int dwAccessPermissions; - int iConnectionTimeout; - - SCA_WEB_SSL_CERTIFICATE* pswscList; - SCA_HTTP_HEADER* pshhList; - SCA_WEB_ERROR* psweList; - - BOOL fHasLog; - SCA_WEB_LOG swl; - - SCA_WEB7* pswNext; -}; - - -// prototypes -HRESULT ScaWebsRead7( - __in SCA_WEB7** ppswList, - __in SCA_HTTP_HEADER** ppshhList, - __in SCA_WEB_ERROR** ppsweList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hSslCertQuery, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData - ); - -HRESULT ScaWebsGetBase7( - __in SCA_WEB7* pswList, - __in LPCWSTR pswWebKey, - __out_ecount(cchDest) LPWSTR pswWeb, - __in DWORD_PTR cchDest - ); - -HRESULT ScaWebsInstall7( - __in SCA_WEB7* pswList, - __in SCA_APPPOOL * psapList - ); - -HRESULT ScaWebsUninstall7( - __in SCA_WEB7* pswList - ); - -void ScaWebsFreeList7( - __in SCA_WEB7* pswHead - ); diff --git a/src/ca/scawebapp.cpp b/src/ca/scawebapp.cpp deleted file mode 100644 index a7e9cf82..00000000 --- a/src/ca/scawebapp.cpp +++ /dev/null @@ -1,194 +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 -enum eWebApplicationQuery { wappqName = 1, wappqIsolation, wappqAllowSession, - wappqSessionTimeout, wappqBuffer, wappqParentPaths, - wappqDefaultScript, wappqScriptTimeout, - wappqServerDebugging, wappqClientDebugging, wappqAppPool, wappqApplication}; - - -HRESULT ScaGetWebApplication(MSIHANDLE /*hViewApplications*/, - LPCWSTR pwzApplication, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - SCA_WEB_APPLICATION* pswapp) -{ - HRESULT hr = S_OK; - - MSIHANDLE hRec; - LPWSTR pwzData = NULL; - - // Reset back to the first record - WcaFetchWrappedReset(hWebAppQuery); - - // get the application information - hr = WcaFetchWrappedRecordWhereString(hWebAppQuery, wappqApplication, pwzApplication, &hRec); - if (S_OK == hr) - { - // application name - hr = WcaGetRecordString(hRec, wappqName, &pwzData); - ExitOnFailure(hr, "Failed to get Name of App"); - hr = ::StringCchCopyW(pswapp->wzName, countof(pswapp->wzName), pwzData); - if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) - { - // The application name is sometimes truncated to IIS's supported length, so ignore insufficient buffer errors here - WcaLog(LOGMSG_VERBOSE, "Application name \"%ls\" truncated to fit IIS's supported %d-character length", pwzData, MAX_APP_NAME); - hr = S_OK; - } - ExitOnFailure(hr, "Failed to copy name string to webapp object"); - - hr = WcaGetRecordInteger(hRec, wappqIsolation, &pswapp->iIsolation); - ExitOnFailure(hr, "Failed to get App isolation: '%ls'", pswapp->wzName); - - hr = WcaGetRecordInteger(hRec, wappqAllowSession, &pswapp->fAllowSessionState); - - hr = WcaGetRecordInteger(hRec, wappqSessionTimeout, &pswapp->iSessionTimeout); - - hr = WcaGetRecordInteger(hRec, wappqBuffer, &pswapp->fBuffer); - - hr = WcaGetRecordInteger(hRec, wappqParentPaths, &pswapp->fParentPaths); - - hr = WcaGetRecordString(hRec, wappqDefaultScript, &pwzData); - ExitOnFailure(hr, "Failed to get default scripting language for App: '%ls'", pswapp->wzName); - hr = ::StringCchCopyW(pswapp->wzDefaultScript, countof(pswapp->wzDefaultScript), pwzData); - ExitOnFailure(hr, "Failed to copy default script string to webapp object"); - - // asp script timeout - hr = WcaGetRecordInteger(hRec, wappqScriptTimeout, &pswapp->iScriptTimeout); - ExitOnFailure(hr, "Failed to get scripting timeout for App: '%ls'", pswapp->wzName); - - // asp server-side script debugging - hr = WcaGetRecordInteger(hRec, wappqServerDebugging, &pswapp->fServerDebugging); - - // asp client-side script debugging - hr = WcaGetRecordInteger(hRec, wappqClientDebugging, &pswapp->fClientDebugging); - - hr = WcaGetRecordString(hRec, wappqAppPool, &pwzData); - ExitOnFailure(hr, "Failed to get AppPool for App: '%ls'", pswapp->wzName); - hr = ::StringCchCopyW(pswapp->wzAppPool, countof(pswapp->wzAppPool), pwzData); - ExitOnFailure(hr, "failed to copy AppPool: '%ls' for App: '%ls'", pwzData, pswapp->wzName); - - // app extensions - hr = ScaWebAppExtensionsRead(pwzApplication, hWebAppExtQuery, &pswapp->pswappextList); - ExitOnFailure(hr, "Failed to read AppExtensions for App: '%ls'", pswapp->wzName); - - hr = S_OK; - } - else if (E_NOMOREITEMS == hr) - { - WcaLog(LOGMSG_STANDARD, "Error: Cannot locate IIsWebApplication.Application='%ls'", pwzApplication); - hr = E_FAIL; - } - else - ExitOnFailure(hr, "Error matching Application rows"); - - // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would - HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebAppQuery, wappqApplication, pwzApplication, &hRec); - if (SUCCEEDED(hrTemp)) - { - AssertSz(E_NOMOREITEMS == hrTemp, "ScaGetWebApplication found more than one record"); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaWriteWebApplication(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, - SCA_WEB_APPLICATION* pswapp, SCA_APPPOOL * psapList) -{ - HRESULT hr = S_OK; - WCHAR wzAppPoolName[MAX_PATH]; - - hr = ScaCreateApp(piMetabase, wzRootOfWeb, pswapp->iIsolation); - ExitOnFailure(hr, "Failed to create ASP App"); - - // Medium Isolation seems to have to be set through the metabase - if (2 == pswapp->iIsolation) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_ISOLATED, METADATA_INHERIT, IIS_MD_UT_WAM, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iIsolation)); - ExitOnFailure(hr, "Failed to write isolation value for App: '%ls'", pswapp->wzName); - } - - // application name - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_FRIENDLY_NAME, METADATA_INHERIT, IIS_MD_UT_WAM, STRING_METADATA, pswapp->wzName); - ExitOnFailure(hr, "Failed to write Name of App: '%ls'", pswapp->wzName); - - // allow session state - if (MSI_NULL_INTEGER != pswapp->fAllowSessionState) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ALLOWSESSIONSTATE, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fAllowSessionState)); - ExitOnFailure(hr, "Failed to write allow session information for App: '%ls'", pswapp->wzName); - } - - // session timeout - if (MSI_NULL_INTEGER != pswapp->iSessionTimeout) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SESSIONTIMEOUT, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iSessionTimeout)); - ExitOnFailure(hr, "Failed to write session timeout for App: '%ls'", pswapp->wzName); - } - - // asp buffering - if (MSI_NULL_INTEGER != pswapp->fBuffer) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_BUFFERINGON, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fBuffer)); - ExitOnFailure(hr, "Failed to write buffering flag for App: '%ls'", pswapp->wzName); - } - - // asp parent paths - if (MSI_NULL_INTEGER != pswapp->fParentPaths) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLEPARENTPATHS, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fParentPaths)); - ExitOnFailure(hr, "Failed to write parent paths flag for App: '%ls'", pswapp->wzName); - } - - // default scripting language - if (*pswapp->wzDefaultScript) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTLANGUAGE, METADATA_INHERIT, ASP_MD_UT_APP, STRING_METADATA, pswapp->wzDefaultScript); - ExitOnFailure(hr, "Failed to write default scripting language for App: '%ls'", pswapp->wzName); - } - - // asp script timeout - if (MSI_NULL_INTEGER != pswapp->iScriptTimeout) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTTIMEOUT, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iScriptTimeout)); - ExitOnFailure(hr, "Failed to write script timeout for App: '%ls'", pswapp->wzName); - } - - // asp server-side script debugging - if (MSI_NULL_INTEGER != pswapp->fServerDebugging) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLESERVERDEBUG, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fServerDebugging)); - ExitOnFailure(hr, "Failed to write ASP server-side script debugging flag for App: '%ls'", pswapp->wzName); - } - - // asp server-side script debugging - if (MSI_NULL_INTEGER != pswapp->fClientDebugging) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLECLIENTDEBUG, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fClientDebugging)); - ExitOnFailure(hr, "Failed to write ASP client-side script debugging flag for App: '%ls'", pswapp->wzName); - } - - // AppPool - if (*pswapp->wzAppPool && NULL != psapList) - { - hr = ScaFindAppPool(piMetabase, pswapp->wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); - ExitOnFailure(hr, "failed to find app pool: %ls", pswapp->wzAppPool); - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_APPPOOL_ID, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, wzAppPoolName); - ExitOnFailure(hr, "Failed to write default AppPool for App: '%ls'", pswapp->wzName); - } - - if (pswapp->pswappextList) - { - hr = ScaWebAppExtensionsWrite(piMetabase, wzRootOfWeb, pswapp->pswappextList); - ExitOnFailure(hr, "Failed to write AppExtensions for App: '%ls'", pswapp->wzName); - } - -LExit: - return hr; -} diff --git a/src/ca/scawebapp.h b/src/ca/scawebapp.h deleted file mode 100644 index a4152116..00000000 --- a/src/ca/scawebapp.h +++ /dev/null @@ -1,42 +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 "scaapppool.h" -#include "scawebappext.h" - -// global sql queries provided for optimization -extern LPCWSTR vcsWebApplicationQuery; -const int MAX_APP_NAME = 255; - -// structs -struct SCA_WEB_APPLICATION -{ - WCHAR wzName[MAX_APP_NAME + 1]; - - int iIsolation; - BOOL fAllowSessionState; - int iSessionTimeout; - BOOL fBuffer; - BOOL fParentPaths; - - WCHAR wzDefaultScript[MAX_DARWIN_COLUMN + 1]; - int iScriptTimeout; - BOOL fServerDebugging; - BOOL fClientDebugging; - WCHAR wzAppPool[MAX_DARWIN_COLUMN + 1]; - - SCA_WEB_APPLICATION_EXTENSION* pswappextList; -}; - - -// prototypes -HRESULT ScaGetWebApplication(MSIHANDLE hViewApplications, - LPCWSTR pwzApplication, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - SCA_WEB_APPLICATION* pswapp); - -HRESULT ScaWriteWebApplication(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, - SCA_WEB_APPLICATION* pswapp, SCA_APPPOOL * psapList); - diff --git a/src/ca/scawebapp7.cpp b/src/ca/scawebapp7.cpp deleted file mode 100644 index 94e6bb18..00000000 --- a/src/ca/scawebapp7.cpp +++ /dev/null @@ -1,120 +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" -HRESULT ScaWriteWebApplication7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - SCA_WEB_APPLICATION* pswapp, - SCA_APPPOOL * /*psapList*/ - ) -{ - HRESULT hr = S_OK; - - //all go to same web/root location tag - hr = ScaWriteConfigID(IIS_ASP_BEGIN); - ExitOnFailure(hr, "Failed to write WebApp ASP begin id"); - hr = ScaWriteConfigString(wzWebName); //site name key - ExitOnFailure(hr, "Failed to write app web key"); - hr = ScaWriteConfigString(wzRootOfWeb); //app path key - ExitOnFailure(hr, "Failed to write app web root"); - - // IIS7 Not Supported: Isolation - if (MSI_NULL_INTEGER != pswapp->iIsolation) - { - WcaLog(LOGMSG_TRACEONLY, "Not supported by IIS7: Isolation Mode, ignoring"); - } - - // allow session state - if (MSI_NULL_INTEGER != pswapp->fAllowSessionState) - { - //system.webServer/asp /session | allowSessionState - hr = ScaWriteConfigID(IIS_ASP_SESSIONSTATE); - ExitOnFailure(hr, "Failed to write WebApp ASP sessionstate id"); - hr = ScaWriteConfigInteger(pswapp->fAllowSessionState); - ExitOnFailure(hr, "Failed to write allow session information for App: '%ls'", pswapp->wzName); - } - - // session timeout - if (MSI_NULL_INTEGER != pswapp->iSessionTimeout) - { - //system.webServer/asp /session | timeout - hr = ScaWriteConfigID(IIS_ASP_SESSIONTIMEOUT); - ExitOnFailure(hr, "Failed to write WebApp ASP sessiontimepot id"); - hr = ScaWriteConfigInteger(pswapp->iSessionTimeout); - ExitOnFailure(hr, "Failed to write session timeout for App: '%ls'", pswapp->wzName); - } - - // asp buffering - if (MSI_NULL_INTEGER != pswapp->fBuffer) - { - //system.webServer/asp | bufferingOn - hr = ScaWriteConfigID(IIS_ASP_BUFFER); - ExitOnFailure(hr, "Failed to write WebApp ASP buffer id"); - hr = ScaWriteConfigInteger(pswapp->fBuffer); - ExitOnFailure(hr, "Failed to write buffering flag for App: '%ls'", pswapp->wzName); - } - - // asp parent paths - if (MSI_NULL_INTEGER != pswapp->fParentPaths) - { - //system.webServer/asp | enableParentPaths - hr = ScaWriteConfigID(IIS_ASP_PARENTPATHS); - ExitOnFailure(hr, "Failed to write WebApp ASP parentpaths id"); - hr = ScaWriteConfigInteger(pswapp->fParentPaths); - ExitOnFailure(hr, "Failed to write parent paths flag for App: '%ls'", pswapp->wzName); - } - - // default scripting language - if (*pswapp->wzDefaultScript) - { - //system.webServer/asp | scriptLanguage - hr = ScaWriteConfigID(IIS_ASP_SCRIPTLANG); - ExitOnFailure(hr, "Failed to write WebApp ASP script lang id"); - hr = ScaWriteConfigString(pswapp->wzDefaultScript); - ExitOnFailure(hr, "Failed to write default scripting language for App: '%ls'", pswapp->wzName); - } - - // asp script timeout - if (MSI_NULL_INTEGER != pswapp->iScriptTimeout) - { - //system.webServer/asp /limits | scriptTimeout - hr = ScaWriteConfigID(IIS_ASP_SCRIPTTIMEOUT); - ExitOnFailure(hr, "Failed to write WebApp ASP script timeout id"); - hr = ScaWriteConfigInteger(pswapp->iScriptTimeout); - ExitOnFailure(hr, "Failed to write script timeout for App: '%ls'", pswapp->wzName); - } - - // asp server-side script debugging - if (MSI_NULL_INTEGER != pswapp->fServerDebugging) - { - //system.webServer/asp | appAllowDebugging - hr = ScaWriteConfigID(IIS_ASP_SCRIPTSERVERDEBUG); - ExitOnFailure(hr, "Failed to write WebApp ASP script debug id"); - hr = ScaWriteConfigInteger(pswapp->fServerDebugging); - ExitOnFailure(hr, "Failed to write ASP server-side script debugging flag for App: '%ls'", pswapp->wzName); - } - - // asp client-side script debugging - if (MSI_NULL_INTEGER != pswapp->fClientDebugging) - { - //system.webServer/asp | appAllowClientDebug - hr = ScaWriteConfigID(IIS_ASP_SCRIPTCLIENTDEBUG); - ExitOnFailure(hr, "Failed to write WebApp ASP script debug id"); - hr = ScaWriteConfigInteger(pswapp->fClientDebugging); - ExitOnFailure(hr, "Failed to write ASP client-side script debugging flag for App: '%ls'", pswapp->wzName); - } - - //done with ASP application properties - hr = ScaWriteConfigID(IIS_ASP_END); - ExitOnFailure(hr, "Failed to write WebApp ASP begin id"); - - //write out app estensions - if (pswapp->pswappextList) - { - hr = ScaWebAppExtensionsWrite7(wzWebName, wzRootOfWeb, pswapp->pswappextList); - ExitOnFailure(hr, "Failed to write AppExtensions for App: '%ls'", pswapp->wzName); - } - -LExit: - return hr; -} diff --git a/src/ca/scawebapp7.h b/src/ca/scawebapp7.h deleted file mode 100644 index e1d87f53..00000000 --- a/src/ca/scawebapp7.h +++ /dev/null @@ -1,10 +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 ScaWriteWebApplication7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - SCA_WEB_APPLICATION* pswapp, - SCA_APPPOOL * psapList - ); diff --git a/src/ca/scawebappext.cpp b/src/ca/scawebappext.cpp deleted file mode 100644 index cf3b9dd3..00000000 --- a/src/ca/scawebappext.cpp +++ /dev/null @@ -1,207 +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" - -enum eWebAppExtensionQuery { wappextqExtension = 1, wappextqVerbs, wappextqExecutable, wappextqAttributes, wappextqApplication }; - -// prototypes for private helper functions -static HRESULT NewAppExt( - __out SCA_WEB_APPLICATION_EXTENSION** ppswappext - ); -static SCA_WEB_APPLICATION_EXTENSION* AddAppExtToList( - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList, - __in SCA_WEB_APPLICATION_EXTENSION* pswappext - ); - - - -HRESULT ScaWebAppExtensionsRead( - __in LPCWSTR wzApplication, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout SCA_WEB_APPLICATION_EXTENSION** ppswappextList - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - - SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; - LPWSTR pwzData = NULL; - - // Reset back to the first record - WcaFetchWrappedReset(hWebAppExtQuery); - - // get the application extension information - while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hWebAppExtQuery, wappextqApplication, wzApplication, &hRec))) - { - hr = NewAppExt(&pswappext); - ExitOnFailure(hr, "failed to create new web app extension"); - - // get the extension - hr = WcaGetRecordString(hRec, wappextqExtension, &pwzData); - ExitOnFailure(hr, "Failed to get Web Application Extension"); - hr = ::StringCchCopyW(pswappext->wzExtension, countof(pswappext->wzExtension), pwzData); - ExitOnFailure(hr, "Failed to copy extension string to webappext object"); - - // application extension verbs - hr = WcaGetRecordString(hRec, wappextqVerbs, &pwzData); - ExitOnFailure(hr, "Failed to get Verbs for Application: '%ls'", wzApplication); - hr = ::StringCchCopyW(pswappext->wzVerbs, countof(pswappext->wzVerbs), pwzData); - ExitOnFailure(hr, "Failed to copy verbs string to webappext object"); - - // extension executeable - hr = WcaGetRecordString(hRec, wappextqExecutable, &pwzData); - ExitOnFailure(hr, "Failed to get Executable for Application: '%ls'", wzApplication); - hr = ::StringCchCopyW(pswappext->wzExecutable, countof(pswappext->wzExecutable), pwzData); - ExitOnFailure(hr, "Failed to copy executable string to webappext object"); - - hr = WcaGetRecordInteger(hRec, wappextqAttributes, &pswappext->iAttributes); - if (S_FALSE == hr) - { - pswappext->iAttributes = 0; - hr = S_OK; - } - ExitOnFailure(hr, "Failed to get App isolation"); - - *ppswappextList = AddAppExtToList(*ppswappextList, pswappext); - pswappext = NULL; // set the appext NULL so it doesn't accidentally get freed below - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - -LExit: - // if anything was left over after an error clean it all up - if (pswappext) - { - ScaWebAppExtensionsFreeList(pswappext); - } - - ReleaseStr(pwzData); - - return hr; -} - - - -HRESULT ScaWebAppExtensionsWrite( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzRootOfWeb, - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList - ) -{ - HRESULT hr = S_OK; - - LPWSTR wzAppExt = NULL; - DWORD cchAppExt; - WCHAR wzAppExtension[1024]; - WCHAR wzAppExtensions[65536]; - SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; - - if (!pswappextList) - { - ExitFunction(); - } - - ::ZeroMemory(wzAppExtensions, sizeof(wzAppExtensions)); - wzAppExt = wzAppExtensions; - cchAppExt = countof(wzAppExtensions); - pswappext = pswappextList; - - while (pswappext) - { - // if all (represented by "*" or blank) - if (0 == lstrcmpW(pswappext->wzExtension, L"*") || 0 == lstrlenW(pswappext->wzExtension)) - { - hr = ::StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L"*,%s,%d", pswappext->wzExecutable, pswappext->iAttributes); - ExitOnFailure(hr, "Failed to format *,executable,attributes string"); - } - else - { - hr = ::StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L".%s,%s,%d", pswappext->wzExtension, pswappext->wzExecutable, pswappext->iAttributes); - ExitOnFailure(hr, "Failed to format extension,executable,attributes string"); - } - - // if verbs were specified and not the keyword "all" - if (pswappext->wzVerbs[0] && CSTR_EQUAL != CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pswappext->wzVerbs, -1, L"all", -1)) - { - hr = ::StringCchCatW(wzAppExtension, countof(wzAppExtension), L","); - ExitOnFailure(hr, "Failed to concatenate comma to app extension string"); - hr = ::StringCchCatW(wzAppExtension, countof(wzAppExtension), pswappext->wzVerbs); - ExitOnFailure(hr, "Failed to concatenate verb to app extension string"); - } - - hr = ::StringCchCopyW(wzAppExt, cchAppExt, wzAppExtension); - ExitOnFailure(hr, "Failed to copy app extension string"); - wzAppExt += lstrlenW(wzAppExtension) + 1; - cchAppExt -= lstrlenW(wzAppExtension) + 1; - pswappext = pswappext->pswappextNext; - } - - if (*wzAppExtensions) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SCRIPT_MAPS, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzAppExtensions); - ExitOnFailure(hr, "Failed to write AppExtension: '%ls'", wzAppExtension); - } - -LExit: - return hr; -} - - -void ScaWebAppExtensionsFreeList( - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList - ) -{ - SCA_WEB_APPLICATION_EXTENSION* pswappextDelete = pswappextList; - while (pswappextList) - { - pswappextDelete = pswappextList; - pswappextList = pswappextList->pswappextNext; - - MemFree(pswappextDelete); - } -} - - - -// private helper functions - -static HRESULT NewAppExt( - __out SCA_WEB_APPLICATION_EXTENSION** ppswappext - ) -{ - HRESULT hr = S_OK; - SCA_WEB_APPLICATION_EXTENSION* pswappext = static_cast(MemAlloc(sizeof(SCA_WEB_APPLICATION_EXTENSION), TRUE)); - ExitOnNull(pswappext, hr, E_OUTOFMEMORY, "failed to allocate memory for new web app ext element"); - - *ppswappext = pswappext; - -LExit: - return hr; -} - - -static SCA_WEB_APPLICATION_EXTENSION* AddAppExtToList( - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList, - __in SCA_WEB_APPLICATION_EXTENSION* pswappext - ) -{ - if (pswappextList) - { - SCA_WEB_APPLICATION_EXTENSION* pswappextT = pswappextList; - while (pswappextT->pswappextNext) - { - pswappextT = pswappextT->pswappextNext; - } - - pswappextT->pswappextNext = pswappext; - } - else - { - pswappextList = pswappext; - } - - return pswappextList; -} diff --git a/src/ca/scawebappext.h b/src/ca/scawebappext.h deleted file mode 100644 index 71adfd00..00000000 --- a/src/ca/scawebappext.h +++ /dev/null @@ -1,32 +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 SCA_WEB_APPLICATION_EXTENSION -{ - WCHAR wzExtension[MAX_DARWIN_COLUMN + 1]; - - WCHAR wzVerbs[MAX_DARWIN_COLUMN + 1]; - WCHAR wzExecutable[MAX_DARWIN_COLUMN + 1]; - int iAttributes; - - SCA_WEB_APPLICATION_EXTENSION* pswappextNext; -}; - - -// prototypes -HRESULT ScaWebAppExtensionsRead( - __in LPCWSTR wzApplication, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout SCA_WEB_APPLICATION_EXTENSION** ppswappextList - ); - -HRESULT ScaWebAppExtensionsWrite( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzRootOfWeb, - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList - ); - -void ScaWebAppExtensionsFreeList( - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList - ); diff --git a/src/ca/scawebappext7.cpp b/src/ca/scawebappext7.cpp deleted file mode 100644 index 50d3172f..00000000 --- a/src/ca/scawebappext7.cpp +++ /dev/null @@ -1,61 +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" - -HRESULT ScaWebAppExtensionsWrite7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList - ) -{ - HRESULT hr = S_OK; - SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; - - if (!pswappextList) - { - ExitFunction1(hr = S_OK); - } - - //create the Extension for this vdir application - //all go to same web/root location tag - hr = ScaWriteConfigID(IIS_APPEXT_BEGIN); - ExitOnFailure(hr, "Failed to write webappext begin id"); - hr = ScaWriteConfigString(wzWebName); //site name key - ExitOnFailure(hr, "Failed to write app web key"); - hr = ScaWriteConfigString(wzRootOfWeb); //app path key - ExitOnFailure(hr, "Failed to write app web key"); - - pswappext = pswappextList; - - while (pswappext) - { - //create the Extension for this vdir application - hr = ScaWriteConfigID(IIS_APPEXT); - ExitOnFailure(hr, "Failed to write webappext begin id"); - - if (*pswappext->wzExtension) - { - hr = ScaWriteConfigString(pswappext->wzExtension); - } - else // blank means "*" (all) - { - hr = ScaWriteConfigString(L"*"); - } - ExitOnFailure(hr, "Failed to write extension"); - - hr = ScaWriteConfigString(pswappext->wzExecutable); - ExitOnFailure(hr, "Failed to write extension executable"); - - hr = ScaWriteConfigString(pswappext->wzVerbs); - ExitOnFailure(hr, "Failed to write extension verbs"); - - pswappext = pswappext->pswappextNext; - } - - hr = ScaWriteConfigID(IIS_APPEXT_END); - ExitOnFailure(hr, "Failed to write webappext begin id"); - -LExit: - return hr; -} - diff --git a/src/ca/scawebappext7.h b/src/ca/scawebappext7.h deleted file mode 100644 index 55c8b5fc..00000000 --- a/src/ca/scawebappext7.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 ScaWebAppExtensionsWrite7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - __in SCA_WEB_APPLICATION_EXTENSION* pswappextList - ); diff --git a/src/ca/scawebdir.cpp b/src/ca/scawebdir.cpp deleted file mode 100644 index 26a7b32b..00000000 --- a/src/ca/scawebdir.cpp +++ /dev/null @@ -1,241 +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 -enum eWebDirQuery { wdqWeb = 1, wdqWebDir, wdqComponent , wdqPath, wdqProperties, wdqApplication, wdqInstalled, wdqAction }; - -// prototypes -static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd); - -static SCA_WEBDIR* NewWebDir(); -static void FreeWebDir(SCA_WEBDIR *pswd); - - -UINT __stdcall ScaWebDirsRead( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData, - __out SCA_WEBDIR** ppswdList - ) -{ - Assert(piMetabase && ppswdList); - - HRESULT hr = S_OK; - MSIHANDLE hRec; - - LPWSTR pwzData = NULL; - SCA_WEBDIR* pswd; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs() because IIsWebDir table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the web directories - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - pswd = NewWebDir(); - ExitOnNull(pswd, hr, E_OUTOFMEMORY, "Failed to allocate memory for web dir object in memory"); - - // get component install state - hr = WcaGetRecordString(hRec, wdqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get Component for WebDirs"); - hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData); - ExitOnFailure(hr, "Failed to copy component string to webdir object"); - - hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for webdir"); - - hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction); - ExitOnFailure(hr, "Failed to get Component action state for webdir"); - - // If this record has a component and no action is being taken for it, skip processing it entirely - if (0 < lstrlenW(pswd->wzComponent) && !WcaIsInstalling(pswd->isInstalled, pswd->isAction) - && !WcaIsUninstalling(pswd->isInstalled, pswd->isAction) && !WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) - { - FreeWebDir(pswd); - pswd = NULL; - continue; - } - - hr = WcaGetRecordString(hRec, wdqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web for WebDir"); - - hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pswd->wzWebBase, countof(pswd->wzWebBase), hWebBaseQuery); - if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) - { - // If we're uninstalling, ignore any failure to find the existing web - hr = S_OK; - } - - ExitOnFailure(hr, "Failed to get base of web for WebDir"); - - hr = WcaGetRecordString(hRec, wdqPath, &pwzData); - ExitOnFailure(hr, "Failed to get Path for WebDir"); - - hr = ::StringCchPrintfW(pswd->wzWebDirRoot, countof(pswd->wzWebDirRoot), L"%s/Root/%s", pswd->wzWebBase, pwzData); - ExitOnFailure(hr, "Failed to format webdir root string"); - - // get the directory properties for this web - hr = WcaGetRecordString(hRec, wdqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get security identifier for WebDir"); - if (*pwzData) - { - hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp); - ExitOnFailure(hr, "Failed to get properties for WebDir"); - - pswd->fHasProperties = TRUE; - } - - // get the application information for this web directory - hr = WcaGetRecordString(hRec, wdqApplication, &pwzData); - ExitOnFailure(hr, "Failed to get application identifier for WebDir"); - if (*pwzData) - { - hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp); - ExitOnFailure(hr, "Failed to get application for WebDir"); - - pswd->fHasApplication = TRUE; - } - - AddWebDirToList(ppswdList, pswd); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing WebDirs"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaWebDirsInstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList, SCA_APPPOOL * psapList) -{ - HRESULT hr = S_OK; - SCA_WEBDIR* pswd = pswdList; - int i; - - while (pswd) - { - // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created - if (WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) - { - if (pswd->fHasApplication) - { - hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); - ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); - } - } - - // if we are installing the web site - if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) - { - hr = ScaCreateMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); - ExitOnFailure(hr, "Failed to create key for WebDir"); - hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebDirectory"); - ExitOnFailure(hr, "Failed to write key type for for WebDir"); - i = 0x4000003e; // 1073741886: default directory browsing rights - hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); - ExitOnFailure(hr, "Failed to set directory browsing for WebDir"); - - // get the security information for this web - if (pswd->fHasProperties) - { - ScaWriteWebDirProperties(piMetabase, pswd->wzWebDirRoot, &pswd->swp); - ExitOnFailure(hr, "Failed to write properties for WebDir"); - } - - // get the application information for this web directory - if (pswd->fHasApplication) - { - hr = ScaWriteWebApplication(piMetabase, pswd->wzWebDirRoot, &pswd->swapp, psapList); - ExitOnFailure(hr, "Failed to write application for WebDir"); - } - } - - pswd = pswd->pswdNext; - } - -LExit: - return hr; -} - - -HRESULT ScaWebDirsUninstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - SCA_WEBDIR* pswd = pswdList; - - while (pswd) - { - if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) - { - // remove the application from this web directory - if (pswd->fHasApplication) - { - hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); - ExitOnFailure(hr, "Failed to remove application for WebDir"); - } - - hr = ScaDeleteMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); - ExitOnFailure(hr, "Failed to remove WebDir '%ls' from metabase", pswd->wzKey); - } - - pswd = pswd->pswdNext; - } - -LExit: - return hr; -} - - -static SCA_WEBDIR* NewWebDir() -{ - SCA_WEBDIR* pswd = static_cast(MemAlloc(sizeof(SCA_WEBDIR), TRUE)); - Assert(pswd); - return pswd; -} - -static void FreeWebDir(SCA_WEBDIR *pswd) -{ - MemFree(pswd); -} - -void ScaWebDirsFreeList(SCA_WEBDIR* pswdList) -{ - SCA_WEBDIR* pswdDelete = pswdList; - while (pswdList) - { - pswdDelete = pswdList; - pswdList = pswdList->pswdNext; - - FreeWebDir(pswdDelete); - } -} - - -static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd) -{ - pswd->pswdNext = *ppswdList; - *ppswdList = pswd; -} diff --git a/src/ca/scawebdir.h b/src/ca/scawebdir.h deleted file mode 100644 index 0b594532..00000000 --- a/src/ca/scawebdir.h +++ /dev/null @@ -1,57 +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 SCA_WEBDIR -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - // metabase information - WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; - WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; - WCHAR wzWebDirRoot[METADATA_MAX_NAME_LEN + 1]; - - // iis configuation information - WCHAR wzDirectory[MAX_PATH]; - - BOOL fHasProperties; - SCA_WEB_PROPERTIES swp; - - BOOL fHasApplication; - SCA_WEB_APPLICATION swapp; - - SCA_WEBDIR* pswdNext; -}; - - -// prototypes -UINT __stdcall ScaWebDirsRead( - __in IMSAdminBase* piMetabase, - __in SCA_WEB* pswList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData, - __out SCA_WEBDIR** ppswdList - ); - -HRESULT ScaWebDirsInstall( - __in IMSAdminBase* piMetabase, - __in SCA_WEBDIR* pswdList, - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaWebDirsUninstall( - __in IMSAdminBase* piMetabase, - __in SCA_WEBDIR* pswdList - ); - -void ScaWebDirsFreeList( - __in SCA_WEBDIR* pswdList - ); diff --git a/src/ca/scawebdir7.cpp b/src/ca/scawebdir7.cpp deleted file mode 100644 index 5ead0470..00000000 --- a/src/ca/scawebdir7.cpp +++ /dev/null @@ -1,219 +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 -static LPCWSTR vcsWebDirQuery7 = L"SELECT `Web_`, `WebDir`, `Component_`, `Path`, `DirProperties_`, `Application_`" - L"FROM `IIsWebDir`"; - -enum eWebDirQuery { wdqWeb = 1, wdqWebDir, wdqComponent , wdqPath, wdqProperties, wdqApplication, wdqInstalled, wdqAction }; - -// prototypes -static HRESULT AddWebDirToList(SCA_WEBDIR7** ppswdList); - - -UINT __stdcall ScaWebDirsRead7( - __in SCA_WEB7* pswList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData, - __out SCA_WEBDIR7** ppswdList - ) -{ - HRESULT hr = S_OK; - MSIHANDLE hRec; - - LPWSTR pwzData = NULL; - SCA_WEBDIR7* pswd; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead7"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs7() because IIsWebDir table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the web directories - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - hr = AddWebDirToList(ppswdList); - ExitOnFailure(hr, "failed to add web dir to list"); - - pswd = *ppswdList; - ExitOnNull(pswd, hr, E_INVALIDARG, "No web dir provided"); - - // get component install state - hr = WcaGetRecordString(hRec, wdqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get Component for WebDirs"); - hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData); - ExitOnFailure(hr, "Failed to copy component string to webdir object"); - - hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for webdir"); - - hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction); - ExitOnFailure(hr, "Failed to get Component action state for webdir"); - - hr = WcaGetRecordString(hRec, wdqWeb, &pwzData); - ExitOnFailure(hr, "Failed to get Web for WebDir"); - - // get the web key - hr = ScaWebsGetBase7(pswList, pwzData, pswd->wzWebSite, countof(pswd->wzWebSite)); - if (S_FALSE == hr) - { - hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); - ExitOnFailure(hr, "Failed to get base of web for WebDir"); - } - ExitOnFailure(hr, "Failed to format webdir root string"); - - hr = WcaGetRecordString(hRec, wdqPath, &pwzData); - ExitOnFailure(hr, "Failed to get Path for WebDir"); - - hr = ::StringCchCopyW(pswd->wzPath, countof(pswd->wzPath), pwzData); - ExitOnFailure(hr, "Failed to copy path for WebDir"); - - // get the directory properties for this web - hr = WcaGetRecordString(hRec, wdqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get security identifier for WebDir"); - if (*pwzData) - { - hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp); - ExitOnFailure(hr, "Failed to get properties for WebDir"); - - pswd->fHasProperties = TRUE; - } - - // get the application information for this web directory - hr = WcaGetRecordString(hRec, wdqApplication, &pwzData); - ExitOnFailure(hr, "Failed to get application identifier for WebDir"); - if (*pwzData) - { - hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp); - ExitOnFailure(hr, "Failed to get application for WebDir"); - - pswd->fHasApplication = TRUE; - } - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing WebDirs"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaWebDirsInstall7(SCA_WEBDIR7* pswdList, SCA_APPPOOL * psapList) -{ - HRESULT hr = S_OK; - SCA_WEBDIR7* pswd = pswdList; - - while (pswd) - { - // if we are installing the web site - if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) - { - hr = ScaWriteConfigID(IIS_WEBDIR); - ExitOnFailure(hr, "Failed to write WebDir ID"); - - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "Failed to write WebDir action ID"); - - hr = ScaWriteConfigString(pswd->wzWebSite); - ExitOnFailure(hr, "Failed to write WebDir site"); - - hr = ScaWriteConfigString(pswd->wzPath); - ExitOnFailure(hr, "Failed to write WebDir path"); - - // get the security information for this web - if (pswd->fHasProperties) - { - ScaWriteWebDirProperties7(pswd->wzWebSite, pswd->wzPath, &pswd->swp); - ExitOnFailure(hr, "Failed to write properties for WebDir"); - } - - // get the application information for this web directory - if (pswd->fHasApplication) - { - hr = ScaWriteWebApplication7(pswd->wzWebSite, pswd->wzPath, &pswd->swapp, psapList); - ExitOnFailure(hr, "Failed to write application for WebDir"); - } - } - - pswd = pswd->pswdNext; - } - -LExit: - return hr; -} - - -HRESULT ScaWebDirsUninstall7(SCA_WEBDIR7* pswdList) -{ - HRESULT hr = S_OK; - SCA_WEBDIR7* pswd = pswdList; - - while (pswd) - { - if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) - { - hr = ScaWriteConfigID(IIS_WEBDIR); - ExitOnFailure(hr, "Failed to write WebDir ID"); - - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "Failed to write WebDir action ID"); - - hr = ScaWriteConfigString(pswd->wzWebSite); - ExitOnFailure(hr, "Failed to write WebDir site"); - - hr = ScaWriteConfigString(pswd->wzPath); - ExitOnFailure(hr, "Failed to write WebDir path"); - } - - pswd = pswd->pswdNext; - } - -LExit: - return hr; -} - - -void ScaWebDirsFreeList7(SCA_WEBDIR7* pswdList) -{ - SCA_WEBDIR7* pswdDelete = pswdList; - while (pswdList) - { - pswdDelete = pswdList; - pswdList = pswdList->pswdNext; - - MemFree(pswdDelete); - } -} - - -static HRESULT AddWebDirToList(SCA_WEBDIR7** ppswdList) -{ - HRESULT hr = S_OK; - - SCA_WEBDIR7* pswd = static_cast(MemAlloc(sizeof(SCA_WEBDIR7), TRUE)); - ExitOnNull(pswd, hr, E_OUTOFMEMORY, "failed to allocate element for web dir list"); - - pswd->pswdNext = *ppswdList; - *ppswdList = pswd; - -LExit: - return hr; -} diff --git a/src/ca/scawebdir7.h b/src/ca/scawebdir7.h deleted file mode 100644 index c5c87e17..00000000 --- a/src/ca/scawebdir7.h +++ /dev/null @@ -1,51 +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 SCA_WEBDIR7 -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - - // iis configuation information - WCHAR wzPath[MAX_PATH]; - WCHAR wzWebSite[MAX_PATH]; - - BOOL fHasProperties; - SCA_WEB_PROPERTIES swp; - - BOOL fHasApplication; - SCA_WEB_APPLICATION swapp; - - SCA_WEBDIR7* pswdNext; -}; - - -// prototypes -UINT __stdcall ScaWebDirsRead7( - __in SCA_WEB7* pswList, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppQuery, - __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, - __inout LPWSTR *ppwzCustomActionData, - __out SCA_WEBDIR7** ppswdList - ); - -HRESULT ScaWebDirsInstall7( - __in SCA_WEBDIR7* pswdList, - __in SCA_APPPOOL* psapList - ); - -HRESULT ScaWebDirsUninstall7( - __in SCA_WEBDIR7* pswdList - ); - -void ScaWebDirsFreeList7( - __in SCA_WEBDIR7* pswdList - ); diff --git a/src/ca/scaweberr.cpp b/src/ca/scaweberr.cpp deleted file mode 100644 index 2441f006..00000000 --- a/src/ca/scaweberr.cpp +++ /dev/null @@ -1,371 +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" - -enum eWebErrorQuery { weqErrorCode = 1, weqSubCode, weqParentType, weqParentValue, weqFile, weqURL }; - -static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList); - -void ScaWebErrorFreeList(SCA_WEB_ERROR *psweList) -{ - SCA_WEB_ERROR *psweDelete = psweList; - while (psweList) - { - psweDelete = psweList; - psweList = psweList->psweNext; - - MemFree(psweDelete); - } -} - -HRESULT ScaWebErrorRead( - SCA_WEB_ERROR **ppsweList, - __inout LPWSTR *ppwzCustomActionData - ) -{ -// AssertSz(0, "Debug ScaWebErrorRead here"); - HRESULT hr = S_OK; - MSIHANDLE hRec; - LPWSTR pwzData = NULL; - SCA_WEB_ERROR* pswe; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - ExitOnNull(ppsweList, hr, E_INVALIDARG, "Failed to read web error, because no web error was provided to read"); - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebErrorRead() - required tables not present."); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the web errors - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - hr = AddWebErrorToList(ppsweList); - ExitOnFailure(hr, "failed to add web error to list"); - - pswe = *ppsweList; - - hr = WcaGetRecordInteger(hRec, weqErrorCode, &(pswe->iErrorCode)); - ExitOnFailure(hr, "failed to get IIsWebError.ErrorCode"); - - hr = WcaGetRecordInteger(hRec, weqSubCode, &(pswe->iSubCode)); - ExitOnFailure(hr, "failed to get IIsWebError.SubCode"); - - hr = WcaGetRecordInteger(hRec, weqParentType, &(pswe->iParentType)); - ExitOnFailure(hr, "failed to get IIsWebError.ParentType"); - - hr = WcaGetRecordString(hRec, weqParentValue, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebError.ParentValue"); - hr = ::StringCchCopyW(pswe->wzParentValue, countof(pswe->wzParentValue), pwzData); - ExitOnFailure(hr, "Failed to copy IIsWebError.ParentValue"); - - hr = WcaGetRecordString(hRec, weqFile, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebError.File"); - hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), pwzData); - ExitOnFailure(hr, "Failed to copy IIsWebError.File"); - - hr = WcaGetRecordString(hRec, weqURL, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebError.URL"); - hr = ::StringCchCopyW(pswe->wzURL, countof(pswe->wzURL), pwzData); - ExitOnFailure(hr, "Failed to copy IIsWebError.URL"); - - // If they've specified both a file and a URL, that's invalid - if (*(pswe->wzFile) && *(pswe->wzURL)) - ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Both File and URL specified for web error. File: %ls, URL: %ls", pswe->wzFile, pswe->wzURL); - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure while processing web errors"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - -HRESULT ScaGetWebError(int iParentType, LPCWSTR wzParentValue, SCA_WEB_ERROR **ppsweList, SCA_WEB_ERROR **ppsweOut) -{ - HRESULT hr = S_OK; - SCA_WEB_ERROR* psweAdd = NULL; - SCA_WEB_ERROR* psweLast = NULL; - - *ppsweOut = NULL; - - if (!*ppsweList) - return hr; - - SCA_WEB_ERROR* pswe = *ppsweList; - while (pswe) - { - if (iParentType == pswe->iParentType && 0 == lstrcmpW(wzParentValue, pswe->wzParentValue)) - { - // Found a match, take this one out of the list and add it to the matched out list - psweAdd = pswe; - - if (psweLast) - { - // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) - psweLast->psweNext = psweAdd->psweNext; - } - else - { - // If we are at the beginning (no psweLast) update the beginning (since we're taking it) - *ppsweList = pswe->psweNext; - } - pswe = pswe->psweNext; // move on - - // Add the one we've removed to the beginning of the out list - psweAdd->psweNext = *ppsweOut; - *ppsweOut = psweAdd; - } - else - { - psweLast = pswe; // remember the last we that didn't match - pswe = pswe->psweNext; // move on - } - } - - return hr; -} - -HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList) -{ -// AssertSz(0, "Debug ScaWriteWebError here"); - Assert(*wzRoot && psweList); - - HRESULT hr = S_OK; - - DWORD cchData = 0; - LPWSTR pwzSearchKey = NULL; - LPWSTR pwz = NULL; - LPWSTR pwzErrors = NULL; - - LPWSTR pwzCodeSubCode = NULL; - LPWSTR pwzAcceptableCodeSubCode = NULL; - LPCWSTR wzFoundCodeSubCode = NULL; - DWORD_PTR dwFoundCodeSubCodeIndex = 0xFFFFFFFF; - BOOL fOldValueFound = FALSE; - LPWSTR pwzAcceptableErrors = NULL; - - LPWSTR pwzNewError = NULL; - - METADATA_RECORD mr; - ::ZeroMemory(&mr, sizeof(mr)); - - ExitOnNull(piMetabase, hr, E_INVALIDARG, "Failed to write web error, because no metabase was provided"); - ExitOnNull(wzRoot, hr, E_INVALIDARG, "Failed to write web error, because no root was provided"); - - // get the set of all valid custom errors from the metabase - mr.dwMDIdentifier = MD_CUSTOM_ERROR_DESC; - mr.dwMDAttributes = METADATA_INHERIT; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = ALL_METADATA; - mr.dwMDDataLen = cchData = 0; - mr.pbMDData = NULL; - - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/Info", &mr); - ExitOnFailure(hr, "Unable to get set of acceptable error codes for this server."); - - pwzAcceptableErrors = reinterpret_cast(mr.pbMDData); - - // Check if web errors already exist here - mr.dwMDIdentifier = MD_CUSTOM_ERROR; - mr.dwMDAttributes = METADATA_INHERIT; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = ALL_METADATA; - mr.dwMDDataLen = cchData = 0; - mr.pbMDData = NULL; - - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzRoot, &mr); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) - { - // - // If we don't have one already, find an appropriate one to start with - // - - // we can walk up key by key and look for custom errors to inherit - - hr = StrAllocConcat(&pwzSearchKey, wzRoot, 0); - ExitOnFailure(hr, "Failed to copy root string: %ls", wzRoot); - - pwz = pwzSearchKey + lstrlenW(pwzSearchKey); - - while (NULL == pwzErrors) - { - // find the last slash - while (*pwz != '/' && pwz != pwzSearchKey) - pwz --; - - if (pwz == pwzSearchKey) - break; - - *pwz = L'\0'; - - // Try here. If it's not found, keep walking up the path - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, pwzSearchKey, &mr); - if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) - hr = S_FALSE; - ExitOnFailure(hr, "failed to discover default error values to start with for web root: %ls while walking up the tree", wzRoot); - - if (S_OK == hr) - { - pwzErrors = reinterpret_cast(mr.pbMDData); - break; - } - - // Don't keep going if we're at the root - if (0 == lstrcmpW(pwz + 1, L"W3SVC")) - break; - } - } - else - { - pwzErrors = reinterpret_cast(mr.pbMDData); - } - ExitOnFailure(hr, "failed to discover default error values to start with for web root: %ls", wzRoot); - - // The above code should have come up with some value to start pwzErrors off with. Make sure it did. - if (NULL == pwzErrors) - { - ExitOnFailure(hr = E_UNEXPECTED, "failed to discover default error values to start with for web root: %ls", wzRoot); - } - - // Loop through the web errors - for (SCA_WEB_ERROR* pswe = psweList; pswe; pswe = pswe->psweNext) - { - // Assume that we will have to replace - fOldValueFound = TRUE; - - // If the subcode is 0, that means "*" in MD_CUSTOM_ERROR (thus the special formatting logic) - if (0 == pswe->iSubCode) - { - hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,*", pswe->iErrorCode); - ExitOnFailure(hr, "failed to create error code string while installing web error"); - } - else - { - hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode); - ExitOnFailure(hr, "failed to create error code,subcode string while installing web error"); - } - - hr = MultiSzFindSubstring(pwzErrors, pwzCodeSubCode, &dwFoundCodeSubCodeIndex, &wzFoundCodeSubCode); - ExitOnFailure(hr, "failed to find existing error code,subcode: %ls", pwzCodeSubCode); - - // If we didn't find this error code/sub code pair in the list already, make sure it's acceptable to add - if (S_FALSE == hr) - { - // - // Make sure this error code/sub code pair is in the "acceptable" list - // - - // If the subcode is 0, that means "0" in MD_CUSTOM_ERROR_DESC (no special formatting logic needed) - hr = StrAllocFormatted(&pwzAcceptableCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode); - ExitOnFailure(hr, "failed to create error code,subcode string while installing web error"); - - // We don't care where it is, just whether it's there or not - hr = MultiSzFindSubstring(pwzAcceptableErrors, pwzAcceptableCodeSubCode, NULL, NULL); - ExitOnFailure(hr, "failed to find whether or not error code, subcode: %ls is supported", pwzCodeSubCode); - - if (S_FALSE == hr) - { - WcaLog(LOGMSG_VERBOSE, "Skipping error code, subcode: %ls because it is not supported by the server.", pwzCodeSubCode); - continue; - } - - // If we didn't find it (and its an acceptable error) then we have nothing to replace - fOldValueFound = FALSE; - } - - // Set up the new error string if needed - if (*(pswe->wzFile)) - { - hr = StrAllocFormatted(&pwzNewError, L"%s,FILE,%s", pwzCodeSubCode, pswe->wzFile); - ExitOnFailure(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile); - } - else if (*(pswe->wzURL)) - { - hr = StrAllocFormatted(&pwzNewError, L"%s,URL,%s", pwzCodeSubCode, pswe->wzURL); - ExitOnFailure(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile); - } - else if (fOldValueFound) - { - // If no File or URL was specified, they want a default error so remove the old value from the MULTISZ and move on - hr = MultiSzRemoveString(&pwzErrors, dwFoundCodeSubCodeIndex); - ExitOnFailure(hr, "failed to remove string for error code sub code: %ls in order to make it 'default'", pwzCodeSubCode); - continue; - } - - // If we have something to replace, replace it, otherwise, put it at the beginning (order shouldn't matter) - if (fOldValueFound) - { - hr = MultiSzReplaceString(&pwzErrors, dwFoundCodeSubCodeIndex, pwzNewError); - ExitOnFailure(hr, "failed to replace old error string with new error string for error code,subcode: %ls", pwzCodeSubCode); - } - else - { - hr = MultiSzPrepend(&pwzErrors, NULL, pwzNewError); - ExitOnFailure(hr, "failed to prepend new error string for error code,subcode: %ls", pwzCodeSubCode); - } - } - - // now write the CustomErrors to the metabase - if (weptWeb == iParentType) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRoot, L"/Root", MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors); - ExitOnFailure(hr, "Failed to write Web Error to /Root"); - } - else - { - hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors); - ExitOnFailure(hr, "Failed to write Web Error"); - } - -LExit: - ReleaseStr(pwzErrors); - ReleaseStr(pwzSearchKey); - ReleaseStr(pwzCodeSubCode); - ReleaseStr(pwzAcceptableCodeSubCode); - ReleaseStr(pwzAcceptableErrors); - - return hr; -} - -static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList) -{ - HRESULT hr = S_OK; - - SCA_WEB_ERROR* pswe = static_cast(MemAlloc(sizeof(SCA_WEB_ERROR), TRUE)); - ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); - - pswe->psweNext = *ppsweList; - *ppsweList = pswe; - -LExit: - return hr; -} - -HRESULT ScaWebErrorCheckList(SCA_WEB_ERROR* psweList) -{ - if (!psweList) - { - return S_OK; - } - - while (psweList) - { - WcaLog(LOGMSG_STANDARD, "WebError code: %d subcode: %d for parent: %ls not used!", psweList->iErrorCode, psweList->iSubCode, psweList->wzParentValue); - psweList = psweList->psweNext; - } - - return E_FAIL; -} - diff --git a/src/ca/scaweberr.h b/src/ca/scaweberr.h deleted file mode 100644 index ad8ff4f5..00000000 --- a/src/ca/scaweberr.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. - - -enum eWebErrorParentType { weptVDir = 1, weptWeb }; - -struct SCA_WEB_ERROR -{ - int iErrorCode; - int iSubCode; - - int iParentType; - WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; - - WCHAR wzFile[MAX_PATH]; - WCHAR wzURL[MAX_PATH]; // TODO: this needs to be bigger than MAX_PATH - - SCA_WEB_ERROR *psweNext; -}; - -// prototypes -HRESULT ScaWebErrorRead( - SCA_WEB_ERROR **ppsweList, - __inout LPWSTR *ppwzCustomActionData - ); -void ScaWebErrorFreeList(SCA_WEB_ERROR *psweList); -HRESULT ScaWebErrorCheckList(SCA_WEB_ERROR* psweList); -HRESULT ScaGetWebError(int iParentType, LPCWSTR wzParentValue, SCA_WEB_ERROR **ppsweList, SCA_WEB_ERROR **ppsweOut); -HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList); - diff --git a/src/ca/scaweberr7.cpp b/src/ca/scaweberr7.cpp deleted file mode 100644 index 33c2f1bd..00000000 --- a/src/ca/scaweberr7.cpp +++ /dev/null @@ -1,88 +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" - -HRESULT ScaWriteWebError7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRoot, - SCA_WEB_ERROR* psweList - ) -{ - HRESULT hr = S_OK; - - hr = ScaWriteConfigID(IIS_WEBERROR_BEGIN); - ExitOnFailure(hr, "Fail to write webError begin ID"); - - hr = ScaWriteConfigString(wzWebName); - ExitOnFailure(hr, "Fail to write webError Web Key"); - - hr = ScaWriteConfigString(wzRoot); - ExitOnFailure(hr, "Fail to write webError Vdir key"); - - // Loop through the HTTP headers - for (SCA_WEB_ERROR* pswe = psweList; pswe; pswe = pswe->psweNext) - { - hr = ScaWriteConfigID(IIS_WEBERROR); - ExitOnFailure(hr, "Fail to write webError ID"); - - hr = ScaWriteConfigInteger(pswe->iErrorCode); - ExitOnFailure(hr, "Fail to write webError code"); - - hr = ScaWriteConfigInteger(pswe->iSubCode); - ExitOnFailure(hr, "Fail to write webError subcode"); - - //just write one - if (*(pswe->wzFile)) - { - hr = ScaWriteConfigString(pswe->wzFile); - ExitOnFailure(hr, "Fail to write webError file"); - hr = ScaWriteConfigInteger(0); - ExitOnFailure(hr, "Fail to write webError file code"); - } - else if (*(pswe->wzURL)) - { - hr = ScaWriteConfigString(pswe->wzURL); - ExitOnFailure(hr, "Fail to write webError URL"); - hr = ScaWriteConfigInteger(1); - ExitOnFailure(hr, "Fail to write webError URL code"); - } - } - - hr = ScaWriteConfigID(IIS_WEBERROR_END); - ExitOnFailure(hr, "Fail to write httpHeader end ID"); - -LExit: - return hr; - -} - -//static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList) -//{ -// HRESULT hr = S_OK; -// -// SCA_WEB_ERROR* pswe = static_cast(MemAlloc(sizeof(SCA_WEB_ERROR), TRUE)); -// ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); -// -// pswe->psweNext = *ppsweList; -// *ppsweList = pswe; -// -//LExit: -// return hr; -//} - -HRESULT ScaWebErrorCheckList7(SCA_WEB_ERROR* psweList) -{ - if (!psweList) - { - return S_OK; - } - - while (psweList) - { - WcaLog(LOGMSG_STANDARD, "WebError code: %d subcode: %d for parent: %ls not used!", psweList->iErrorCode, psweList->iSubCode, psweList->wzParentValue); - psweList = psweList->psweNext; - } - - return E_FAIL; -} - diff --git a/src/ca/scaweberr7.h b/src/ca/scaweberr7.h deleted file mode 100644 index 62448211..00000000 --- a/src/ca/scaweberr7.h +++ /dev/null @@ -1,10 +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 ScaWriteWebError7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRoot, - SCA_WEB_ERROR* psweList - ); - diff --git a/src/ca/scaweblog.cpp b/src/ca/scaweblog.cpp deleted file mode 100644 index 01147848..00000000 --- a/src/ca/scaweblog.cpp +++ /dev/null @@ -1,177 +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" - -enum eWebLogQuery { wlqLog = 1, wlqFormat }; - -/* **************************************************************** - * LookupLogFormatGUID -Looks up a given IIS Log format type in - * the metabase and returns the GUID for it. - * ****************************************************************/ -static HRESULT LookupLogFormatGUID( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzLogFormat, - __out_ecount(cchGUID) LPWSTR wzGUID, - __in int cchGUID - ) -{ - WCHAR wzKey[METADATA_MAX_NAME_LEN]; - HRESULT hr = S_OK; - - METADATA_RECORD mrKeyType; - ::ZeroMemory(&mrKeyType, sizeof(mrKeyType)); - - mrKeyType.dwMDIdentifier = MD_KEY_TYPE; - mrKeyType.dwMDAttributes = METADATA_NO_ATTRIBUTES; - mrKeyType.dwMDUserType = IIS_MD_UT_SERVER; - mrKeyType.dwMDDataType = ALL_METADATA; - mrKeyType.dwMDDataLen = 0; - mrKeyType.pbMDData = NULL; - - METADATA_RECORD mrPluginId; - ::ZeroMemory(&mrPluginId, sizeof(mrPluginId)); - - mrPluginId.dwMDIdentifier = MD_LOG_PLUGIN_MOD_ID; - mrPluginId.dwMDAttributes = METADATA_INHERIT; - mrPluginId.dwMDUserType = IIS_MD_UT_SERVER; - mrPluginId.dwMDDataType = ALL_METADATA; - mrPluginId.dwMDDataLen = 0; - mrPluginId.pbMDData = NULL; - - hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/Logging/%s", wzLogFormat); - ExitOnFailure(hr, "failed to format logging metabase key name"); - - // verify that we have this log format available in IIS - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrKeyType); - ExitOnFailure(hr, "Failed to find specified Log format key in IIS for log format: %ls", wzLogFormat); - ExitOnNull(mrKeyType.pbMDData, hr, E_POINTER, "Request for Log format key in IIS for log format returned success, but value was NULL"); - - if (0 != lstrcmpW(L"IIsLogModule", (LPCWSTR)mrKeyType.pbMDData)) - { - ExitOnFailure(hr = E_UNEXPECTED, "Found invalid log format in IIS: %ls", (LPCWSTR)mrKeyType.pbMDData); - } - - // find the GUID for that log format - hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrPluginId); - ExitOnFailure(hr, "Failed to retrieve IISLog format GUID. Key: %ls", wzKey); - ExitOnNull(mrPluginId.pbMDData, hr, E_POINTER, "Retrieval of IISLog format GUID returned success, but value was NULL"); - - hr = ::StringCchCopyW(wzGUID, cchGUID, (LPCWSTR)mrPluginId.pbMDData); - ExitOnFailure(hr, "failed to copy metabase value: %ls", (LPCWSTR)mrPluginId.pbMDData); - -LExit: - - if (mrKeyType.pbMDData) - { - MetaFreeValue(&mrKeyType); - } - - if (mrPluginId.pbMDData) - { - MetaFreeValue(&mrPluginId); - } - - return hr; -} - - -/* **************************************************************** - * ScaGetWebLog -Retrieves Log table data for the specified Log key - * - * ****************************************************************/ -HRESULT ScaGetWebLog( - IMSAdminBase* piMetabase, - LPCWSTR wzLog, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - SCA_WEB_LOG* pswl - ) -{ - HRESULT hr = S_OK; - LPWSTR pwzData = NULL; - MSIHANDLE hRec; - - if (0 == WcaGetQueryRecords(hWebLogQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaGetWebLog() - no records to process"); - ExitFunction1(hr = S_FALSE); - } - - WcaFetchWrappedReset(hWebLogQuery); - - hr = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); - if (E_NOMOREITEMS == hr) - { - ExitOnFailure(hr, "cannot locate IIsWebLog.Log='%ls'", wzLog); - } - HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); - - if (SUCCEEDED(hrTemp)) - { - ExitOnFailure(hr, "error - found multiple matching IIsWebLog rows"); - } - - ::ZeroMemory(pswl, sizeof(SCA_WEB_LOG)); - - // check that log key matches - hr = WcaGetRecordString(hRec, wlqLog, &pwzData); - ExitOnFailure(hr, "failed to get IIsWebLog.Log for Log: %ls", wzLog); - hr = ::StringCchCopyW(pswl->wzLog, countof(pswl->wzLog), pwzData); - ExitOnFailure(hr, "failed to copy log name: %ls", pwzData); - - hr = WcaGetRecordString(hRec, wlqFormat, &pwzData); - ExitOnFailure(hr, "failed to get IIsWebLog.Format for Log:", wzLog); - hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), pwzData); - ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); - - // if they specified a log format, look up its GUID in the metabase - if (*pswl->wzFormat && 0 != lstrcmpW(pswl->wzFormat, L"none")) - { - hr = LookupLogFormatGUID(piMetabase, pswl->wzFormat, pswl->wzFormatGUID, countof(pswl->wzFormatGUID)); - ExitOnFailure(hr, "Failed to get Log Format GUID for Log: %ls", wzLog); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} - - -/* **************************************************************** - * ScaWriteWebLog -Writes the IIS log values to the metabase. - * - * ****************************************************************/ -HRESULT ScaWriteWebLog( - IMSAdminBase* piMetabase, - LPCWSTR wzWebBase, - SCA_WEB_LOG *pswl - ) -{ - HRESULT hr = S_OK; - - if (*pswl->wzFormat) - { - if (0 == lstrcmpW(pswl->wzFormat, L"none")) - { - // user wishes for Logging to be turned 'off' - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_TYPE, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)0)); - ExitOnFailure(hr, "Failed to write Log Type for Web: %ls", wzWebBase); - } - else - { - Assert(*pswl->wzFormatGUID); - - // write the GUID for the log format for the web to the metabase - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_PLUGIN_ORDER, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, pswl->wzFormatGUID); - ExitOnFailure(hr, "Failed to write Log GUID for Web: %ls", wzWebBase); - - hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_TYPE, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)1)); - ExitOnFailure(hr, "Failed to write Log Type for Web: %ls", wzWebBase); - } - } - -LExit: - return hr; -} - - diff --git a/src/ca/scaweblog.h b/src/ca/scaweblog.h deleted file mode 100644 index 1a690cce..00000000 --- a/src/ca/scaweblog.h +++ /dev/null @@ -1,27 +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 SCA_WEB_LOG -{ - // iis configuation information - WCHAR wzLog[MAX_DARWIN_KEY + 1]; - - // for specifying the log format - WCHAR wzFormat[MAX_DARWIN_KEY + 1]; - WCHAR wzFormatGUID[MAX_DARWIN_KEY + 1]; -}; - - -// prototypes -HRESULT ScaGetWebLog( - IMSAdminBase* piMetabase, - LPCWSTR wzLog, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - SCA_WEB_LOG* pswl - ); -HRESULT ScaWriteWebLog( - IMSAdminBase* piMetabase, - LPCWSTR wzRootOfWeb, - SCA_WEB_LOG *pswl - ); diff --git a/src/ca/scaweblog7.cpp b/src/ca/scaweblog7.cpp deleted file mode 100644 index c857c46f..00000000 --- a/src/ca/scaweblog7.cpp +++ /dev/null @@ -1,120 +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 vcsWebLogQuery7 = L"SELECT `Log`, `Format` " - L"FROM `IIsWebLog` WHERE `Log`=?"; - -enum eWebLogQuery { wlqLog = 1, wlqFormat }; - -/* **************************************************************** - * ScaGetWebLog7 -Retrieves Log table data for the specified Log key - * - * ****************************************************************/ -HRESULT ScaGetWebLog7( - __in_z LPCWSTR wzLog, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - __out SCA_WEB_LOG* pswl - ) -{ - HRESULT hr = S_OK; - LPWSTR pwzData = NULL; - MSIHANDLE hRec; - - if (0 == WcaGetQueryRecords(hWebLogQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaGetWebLog() - no records to process"); - ExitFunction1(hr = S_FALSE); - } - - WcaFetchWrappedReset(hWebLogQuery); - - hr = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); - if (E_NOMOREITEMS == hr) - { - ExitOnFailure(hr, "cannot locate IIsWebLog.Log='%ls'", wzLog); - } - HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); - - if (SUCCEEDED(hrTemp)) - { - ExitOnFailure(hr, "error - found multiple matching IIsWebLog rows"); - } - - ::ZeroMemory(pswl, sizeof(SCA_WEB_LOG)); - - // check that log key matches - hr = WcaGetRecordString(hRec, wlqLog, &pwzData); - ExitOnFailure(hr, "failed to get IIsWebLog.Log for Log: %ls", wzLog); - hr = ::StringCchCopyW(pswl->wzLog, countof(pswl->wzLog), pwzData); - ExitOnFailure(hr, "failed to copy log name: %ls", pwzData); - - hr = WcaGetRecordString(hRec, wlqFormat, &pwzData); - ExitOnFailure(hr, "failed to get IIsWebLog.Format for Log:", wzLog); - - //translate WIX log format name strings to IIS7 - if (0 == lstrcmpW(pwzData, L"Microsoft IIS Log File Format")) - { - hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"IIS"); - ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); - } - else if (0 == lstrcmpW(pwzData, L"NCSA Common Log File Format")) - { - hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"NCSA"); - ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); - } - else if (0 == lstrcmpW(pwzData, L"none")) - { - hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"none"); - ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); - } - else if (0 == lstrcmpW(pwzData, L"ODBC Logging")) - { - hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"W3C"); - ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); - } - else if (0 == lstrcmpW(pwzData, L"W3C Extended Log File Format")) - { - hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"W3C"); - ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); - } - else - { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_INDEX); - ExitOnFailure(hr, "Invalid log file format: %ls", pwzData); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} - - -/* **************************************************************** - * ScaWriteWebLog -Writes the IIS log values to the metabase. - * - * ****************************************************************/ -HRESULT ScaWriteWebLog7( - LPCWSTR wzWebBase, - const SCA_WEB_LOG *pswl - ) -{ - HRESULT hr = S_OK; - - if (*pswl->wzFormat) - { - //write pswl->wzFormat - hr = ScaWriteConfigID(IIS_WEBLOG); - ExitOnFailure(hr, "Failed to write log format id"); - hr = ScaWriteConfigString(wzWebBase); - ExitOnFailure(hr, "Failed to write log web key"); - hr = ScaWriteConfigString(pswl->wzFormat); - ExitOnFailure(hr, "Failed to write log format string"); - } - -LExit: - return hr; -} - - diff --git a/src/ca/scaweblog7.h b/src/ca/scaweblog7.h deleted file mode 100644 index f2bb60d7..00000000 --- a/src/ca/scaweblog7.h +++ /dev/null @@ -1,14 +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 ScaGetWebLog7( - __in_z LPCWSTR wzLog, - __in WCA_WRAPQUERY_HANDLE hWebLogQuery, - __out SCA_WEB_LOG* pswl - ); - -HRESULT ScaWriteWebLog7( - __in_z LPCWSTR wzRootOfWeb, - const SCA_WEB_LOG *pswl - ); diff --git a/src/ca/scawebprop.cpp b/src/ca/scawebprop.cpp deleted file mode 100644 index b5e38467..00000000 --- a/src/ca/scawebprop.cpp +++ /dev/null @@ -1,301 +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 -enum eWebDirPropertiesQuery { wpqProperties = 1, wpqAccess, wpqAuthorization, wpqUser, wpqControlledPassword, wpqLogVisits, wpqIndex, wpqDefaultDoc, wpqAspDetailedError, wpqHttpExp, wpqCCMaxAge, wpqCCCustom, wpqNoCustomError, wpqAccessSSLFlags, wpqAuthenticationProviders }; - -HRESULT ScaGetWebDirProperties( - __in LPCWSTR wzProperties, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __inout SCA_WEB_PROPERTIES* pswp - ) -{ - Assert(*wzProperties && pswp); - - HRESULT hr = S_OK; - MSIHANDLE hRec; - LPWSTR pwzData = NULL; - - ExitOnNull(wzProperties, hr, E_INVALIDARG, "Failed to get web directory properties because no properties were provided to get"); - - WcaFetchWrappedReset(hWebDirPropQuery); - - hr = WcaFetchWrappedRecordWhereString(hWebDirPropQuery, 1, wzProperties, &hRec); - if (S_OK == hr) - { - hr = WcaGetRecordString(hRec, wpqProperties, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.DirProperties"); - hr = ::StringCchCopyW(pswp->wzKey, countof(pswp->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to webdirproperties object"); - - Assert(0 == lstrcmpW(pswp->wzKey, wzProperties)); - - hr = WcaGetRecordInteger(hRec, wpqAccess, &pswp->iAccess); - ExitOnFailure(hr, "Failed to get access value"); - - hr = WcaGetRecordInteger(hRec, wpqAuthorization, &pswp->iAuthorization); - ExitOnFailure(hr, "Failed to get authorization value"); - - // if allow anonymous users - if (S_OK == hr && pswp->iAuthorization & 1) - { - // if there is an anonymous user specified - hr = WcaGetRecordString(hRec, wpqUser, &pwzData); - ExitOnFailure(hr, "Failed to get AnonymousUser_"); - if (pwzData && *pwzData) - { - hr = WcaGetRecordInteger(hRec, wpqControlledPassword, &pswp->fIIsControlledPassword); - ExitOnFailure(hr, "Failed to get IIsControlledPassword"); - if (S_FALSE == hr) - { - pswp->fIIsControlledPassword = FALSE; - hr = S_OK; - } - - hr = ScaGetUserDeferred(pwzData, hUserQuery, &pswp->scau); - ExitOnFailure(hr, "Failed to get User information for Web"); - - pswp->fHasUser = TRUE; - } - else - pswp->fHasUser = FALSE; - } - - hr = WcaGetRecordInteger(hRec, wpqLogVisits, &pswp->fLogVisits); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.LogVisits"); - - hr = WcaGetRecordInteger(hRec, wpqIndex, &pswp->fIndex); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.Index"); - - hr = WcaGetRecordString(hRec, wpqDefaultDoc, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.DefaultDoc"); - if (pwzData && *pwzData) - { - pswp->fHasDefaultDoc = TRUE; - if (0 == lstrcmpW(L"-", pwzData)) // remove any existing default documents by setting them blank - { - pswp->wzDefaultDoc[0] = L'\0'; - } - else // set the default documents - { - hr = ::StringCchCopyW(pswp->wzDefaultDoc, countof(pswp->wzDefaultDoc), pwzData); - ExitOnFailure(hr, "Failed to copy default document string to webdirproperties object"); - } - } - else - { - pswp->fHasDefaultDoc = FALSE; - } - - hr = WcaGetRecordInteger(hRec, wpqAspDetailedError, &pswp->fAspDetailedError); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.AspDetailedError"); - - hr = WcaGetRecordString(hRec, wpqHttpExp, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.HttpExp"); - if (pwzData && *pwzData) - { - pswp->fHasHttpExp = TRUE; - if (0 == lstrcmpW(L"-", pwzData)) // remove any existing default expiration settings by setting them blank - { - pswp->wzHttpExp[0] = L'\0'; - } - else // set the expiration setting - { - hr = ::StringCchCopyW(pswp->wzHttpExp, countof(pswp->wzHttpExp), pwzData); - ExitOnFailure(hr, "Failed to copy http expiration string to webdirproperties object"); - } - } - else - { - pswp->fHasHttpExp = FALSE; - } - - hr = WcaGetRecordInteger(hRec, wpqCCMaxAge, &pswp->iCacheControlMaxAge); - ExitOnFailure(hr, "failed to get IIsWebDirProperties.CacheControlMaxAge"); - - hr = WcaGetRecordString(hRec, wpqCCCustom, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.CacheControlCustom"); - if (pwzData && *pwzData) - { - pswp->fHasCacheControlCustom = TRUE; - if (0 == lstrcmpW(L"-", pwzData)) // remove any existing default cache control custom settings by setting them blank - { - pswp->wzCacheControlCustom[0] = L'\0'; - } - else // set the custom cache control setting - { - hr = ::StringCchCopyW(pswp->wzCacheControlCustom, countof(pswp->wzCacheControlCustom), pwzData); - ExitOnFailure(hr, "Failed to copy cache control custom settings to webdirproperites object"); - } - } - else - { - pswp->fHasCacheControlCustom = FALSE; - } - - hr = WcaGetRecordInteger(hRec, wpqNoCustomError, &pswp->fNoCustomError); - ExitOnFailure(hr, "failed to get IIsWebDirProperties.NoCustomError"); - if (MSI_NULL_INTEGER == pswp->fNoCustomError) - pswp->fNoCustomError = FALSE; - - hr = WcaGetRecordInteger(hRec, wpqAccessSSLFlags, &pswp->iAccessSSLFlags); - ExitOnFailure(hr, "failed to get IIsWebDirProperties.AccessSSLFlags"); - - hr = WcaGetRecordString(hRec, wpqAuthenticationProviders, &pwzData); - ExitOnFailure(hr, "Failed to get IIsWebDirProperties.AuthenticationProviders"); - if (pwzData && *pwzData) - { - hr = ::StringCchCopyW(pswp->wzAuthenticationProviders, countof(pswp->wzAuthenticationProviders), pwzData); - ExitOnFailure(hr, "Failed to copy authentication providers string to webdirproperties object"); - } - else - { - pswp->wzAuthenticationProviders[0] = L'\0'; - } - } - else if (E_NOMOREITEMS == hr) - { - WcaLog(LOGMSG_STANDARD, "Error: Cannot locate IIsWebDirProperties.DirProperties='%ls'", wzProperties); - hr = E_FAIL; - } - else - { - ExitOnFailure(hr, "Error getting appropriate webdirproperty"); - } - - // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would - HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebDirPropQuery, 1, wzProperties, &hRec); - if (SUCCEEDED(hrTemp)) - { - AssertSz(E_NOMOREITEMS == hrTemp, "ScaGetWebDirProperties found more than one record"); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} - - -HRESULT ScaWriteWebDirProperties( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzRootOfWeb, - __inout SCA_WEB_PROPERTIES* pswp - ) -{ - HRESULT hr = S_OK; - DWORD dw = 0; - WCHAR wz[METADATA_MAX_NAME_LEN + 1]; - - // write the access permissions to the metabase - if (MSI_NULL_INTEGER != pswp->iAccess) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ACCESS_PERM, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAccess)); - ExitOnFailure(hr, "Failed to write access permissions for Web"); - } - - if (MSI_NULL_INTEGER != pswp->iAuthorization) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_AUTHORIZATION, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAuthorization)); - ExitOnFailure(hr, "Failed to write authorization for Web"); - } - - if (pswp->fHasUser) - { - Assert(pswp->scau.wzName); - // write the user name - if (*pswp->scau.wzDomain) - { - hr = ::StringCchPrintfW(wz, countof(wz), L"%s\\%s", pswp->scau.wzDomain, pswp->scau.wzName); - ExitOnFailure(hr, "Failed to format domain\\username string"); - } - else - { - hr = ::StringCchCopyW(wz, countof(wz), pswp->scau.wzName); - ExitOnFailure(hr, "Failed to copy user name"); - } - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_USER_NAME, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)wz); - ExitOnFailure(hr, "Failed to write anonymous user name for Web"); - - // write the password - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_PWD, METADATA_INHERIT | METADATA_SECURE, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->scau.wzPassword); - ExitOnFailure(hr, "Failed to write anonymous user password for Web"); - - // store whether IIs controls password - dw = (pswp->fIIsControlledPassword) ? TRUE : FALSE; - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_USE_SUBAUTH, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); - ExitOnFailure(hr, "Failed to write if IIs controls user password for Web"); - } - - if (MSI_NULL_INTEGER != pswp->fLogVisits) - { - // The sense of this boolean value is reversed - it is "don't log", not "log visits." - dw = (pswp->fLogVisits) ? FALSE : TRUE; - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_DONT_LOG, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); - ExitOnFailure(hr, "Failed to write authorization for Web"); - } - - if (MSI_NULL_INTEGER != pswp->fIndex) - { - dw = (pswp->fIndex) ? TRUE : FALSE; - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_IS_CONTENT_INDEXED, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); - ExitOnFailure(hr, "Failed to write authorization for Web"); - } - - if (pswp->fHasDefaultDoc) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_DEFAULT_LOAD_FILE, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzDefaultDoc); - ExitOnFailure(hr, "Failed to write default documents for Web"); - } - - if (MSI_NULL_INTEGER != pswp->fAspDetailedError) - { - dw = (pswp->fAspDetailedError) ? TRUE : FALSE; - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTERRORSSENTTOBROWSER, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); - ExitOnFailure(hr, "Failed to write ASP script error for Web"); - } - - if (pswp->fHasHttpExp) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_HTTP_EXPIRES, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzHttpExp); - ExitOnFailure(hr, "Failed to write HTTP Expiration for Web"); - } - - if (MSI_NULL_INTEGER != pswp->iCacheControlMaxAge) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CC_MAX_AGE, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iCacheControlMaxAge)); - ExitOnFailure(hr, "Failed to write Cache Control Max Age for Web"); - } - - if (pswp->fHasCacheControlCustom) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CC_OTHER, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzCacheControlCustom); - ExitOnFailure(hr, "Failed to write Cache Control Custom for Web"); - } - - if (pswp->fNoCustomError) - { - memset(wz, 0, sizeof(wz)); - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wz); - ExitOnFailure(hr, "Failed to write Custom Error for Web"); - } - - if (MSI_NULL_INTEGER != pswp->iAccessSSLFlags) - { - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SSL_ACCESS_PERM, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAccessSSLFlags)); - ExitOnFailure(hr, "Failed to write AccessSSLFlags for Web"); - } - - if (*pswp->wzAuthenticationProviders) - { - hr = ::StringCchCopyW(wz, countof(wz), pswp->wzAuthenticationProviders); - ExitOnFailure(hr, "Failed to copy authentication providers string"); - hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_NTAUTHENTICATION_PROVIDERS, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)wz); - ExitOnFailure(hr, "Failed to write AuthenticationProviders for Web"); - } - -LExit: - return hr; -} diff --git a/src/ca/scawebprop.h b/src/ca/scawebprop.h deleted file mode 100644 index 7a3ae5c9..00000000 --- a/src/ca/scawebprop.h +++ /dev/null @@ -1,60 +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 "scauser.h" - -// global sql queries provided for optimization -extern LPCWSTR vcsWebDirPropertiesQuery; - - -// structs -struct SCA_WEB_PROPERTIES -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - - int iAccess; - - int iAuthorization; - BOOL fHasUser; - SCA_USER scau; - BOOL fIIsControlledPassword; - - BOOL fLogVisits; - BOOL fIndex; - - BOOL fHasDefaultDoc; - WCHAR wzDefaultDoc[MAX_DARWIN_COLUMN + 1]; - - BOOL fHasHttpExp; - WCHAR wzHttpExp[MAX_DARWIN_COLUMN + 1]; - - BOOL fAspDetailedError; - - int iCacheControlMaxAge; - - BOOL fHasCacheControlCustom; - WCHAR wzCacheControlCustom[MAX_DARWIN_COLUMN + 1]; - - BOOL fNoCustomError; - - int iAccessSSLFlags; - - WCHAR wzAuthenticationProviders[MAX_DARWIN_COLUMN + 1]; -}; - - -// prototypes -HRESULT ScaGetWebDirProperties( - __in LPCWSTR pwzProperties, - __in WCA_WRAPQUERY_HANDLE hUserQuery, - __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, - __inout SCA_WEB_PROPERTIES* pswp - ); - -HRESULT ScaWriteWebDirProperties( - __in IMSAdminBase* piMetabase, - __in LPCWSTR wzRootOfWeb, - __inout SCA_WEB_PROPERTIES* pswp - ); - diff --git a/src/ca/scawebprop7.cpp b/src/ca/scawebprop7.cpp deleted file mode 100644 index b8d99b0a..00000000 --- a/src/ca/scawebprop7.cpp +++ /dev/null @@ -1,155 +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" - -HRESULT ScaWriteWebDirProperties7( - __in_z LPCWSTR wzWebName, - __in_z LPCWSTR wzRootOfWeb, - __in const SCA_WEB_PROPERTIES* pswp - ) -{ - HRESULT hr = S_OK; - WCHAR wz[METADATA_MAX_NAME_LEN + 1]; - - //all go to same web/root location tag - hr = ScaWriteConfigID(IIS_DIRPROP_BEGIN); - ExitOnFailure(hr, "Failed to write DirProp begin id"); - hr = ScaWriteConfigString(wzWebName); //site name key - ExitOnFailure(hr, "Failed to write DirProp web key"); - hr = ScaWriteConfigString(wzRootOfWeb); //app path key - ExitOnFailure(hr, "Failed to write DirProp app key"); - - // write the access permissions to the metabase - if (MSI_NULL_INTEGER != pswp->iAccess) - { - hr = ScaWriteConfigID(IIS_DIRPROP_ACCESS); - ExitOnFailure(hr, "Failed to write DirProp access id"); - hr = ScaWriteConfigInteger(pswp->iAccess); - ExitOnFailure(hr, "Failed to write access permissions for Web"); - } - - if (MSI_NULL_INTEGER != pswp->iAuthorization) - { - hr = ScaWriteConfigID(IIS_DIRPROP_AUTH); - ExitOnFailure(hr, "Failed to write DirProp auth id"); - hr = ScaWriteConfigInteger(pswp->iAuthorization); - ExitOnFailure(hr, "Failed to write authorization for Web"); - } - - if (pswp->fHasUser) - { - Assert(pswp->scau.wzName); - // write the user name - if (*pswp->scau.wzDomain) - { - hr = ::StringCchPrintfW(wz, countof(wz), L"%s\\%s", pswp->scau.wzDomain, pswp->scau.wzName); - ExitOnFailure(hr, "Failed to format domain\\username string"); - } - else - { -#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") - hr = ::StringCchCopyW(wz, countof(wz), pswp->scau.wzName); - ExitOnFailure(hr, "Failed to copy user name"); - } - hr = ScaWriteConfigID(IIS_DIRPROP_USER); - ExitOnFailure(hr, "Failed to write DirProp user id"); - hr = ScaWriteConfigString(wz); - ExitOnFailure(hr, "Failed to write anonymous user name for Web"); - - // write the password - hr = ScaWriteConfigID(IIS_DIRPROP_PWD); - ExitOnFailure(hr, "Failed to write DirProp pwd id"); - hr = ScaWriteConfigString(pswp->scau.wzPassword); - ExitOnFailure(hr, "Failed to write anonymous user password for Web"); - - if (pswp->fIIsControlledPassword) - { - //Not Supported by IIS7 : pswp->fIIsControlledPassword - WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: WebDirProperties.IIsControlledPassword, ignoring"); - } - } - - if (MSI_NULL_INTEGER != pswp->fLogVisits) - { - hr = ScaWriteConfigID(IIS_DIRPROP_LOGVISITS); - ExitOnFailure(hr, "Failed to write DirProp logVisits id"); - hr = ScaWriteConfigInteger(pswp->fLogVisits ? FALSE : TRUE); // we capture "should log" but IIS7 wants "should not log" - ExitOnFailure(hr, "Failed to write DirProp logVisits"); - } - - if (MSI_NULL_INTEGER != pswp->fIndex) - { - //Not Supported by IIS7 : pswp->fIndex - WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: WebDirProperties.Index, ignoring"); - } - - if (pswp->fHasDefaultDoc) - { - hr = ScaWriteConfigID(IIS_DIRPROP_DEFDOCS); - ExitOnFailure(hr, "Failed to write DirProp defdocs id"); - hr = ScaWriteConfigString(pswp->wzDefaultDoc); - ExitOnFailure(hr, "Failed to write default documents for Web"); - } - - if (MSI_NULL_INTEGER != pswp->fAspDetailedError) - { - hr = ScaWriteConfigID(IIS_DIRPROP_ASPERROR); - ExitOnFailure(hr, "Failed to write ASP script error id"); - hr = ScaWriteConfigInteger(pswp->fAspDetailedError); - ExitOnFailure(hr, "Failed to write ASP script error for Web"); - } - - if (pswp->fHasHttpExp) - { - hr = ScaWriteConfigID(IIS_DIRPROP_HTTPEXPIRES); - ExitOnFailure(hr, "Failed to write DirProp HttpExpires id"); - hr = ScaWriteConfigString(pswp->wzHttpExp); - ExitOnFailure(hr, "Failed to write DirProp HttpExpires value"); - } - - if (MSI_NULL_INTEGER != pswp->iCacheControlMaxAge) - { - hr = ScaWriteConfigID(IIS_DIRPROP_MAXAGE); - ExitOnFailure(hr, "Failed to write DirProp MaxAge id"); - hr = ScaWriteConfigInteger(pswp->iCacheControlMaxAge); - ExitOnFailure(hr, "Failed to write DirProp MaxAge value"); - } - - if (pswp->fHasCacheControlCustom) - { - hr = ScaWriteConfigID(IIS_DIRPROP_CACHECUST); - ExitOnFailure(hr, "Failed to write DirProp Cache Control Custom id"); - hr = ScaWriteConfigString(pswp->wzCacheControlCustom); - ExitOnFailure(hr, "Failed to write Cache Control Custom for Web"); - } - - if (pswp->fNoCustomError) - { - hr = ScaWriteConfigID(IIS_DIRPROP_NOCUSTERROR); - ExitOnFailure(hr, "Failed to write DirProp clear Cust Errors id"); - } - - if (MSI_NULL_INTEGER != pswp->iAccessSSLFlags) - { - hr = ScaWriteConfigID(IIS_DIRPROP_SSLFLAGS); - ExitOnFailure(hr, "Failed to write DirProp sslFlags id"); - hr = ScaWriteConfigInteger(pswp->iAccessSSLFlags); - ExitOnFailure(hr, "Failed to write AccessSSLFlags for Web"); - } - - if (*pswp->wzAuthenticationProviders) - { - hr = ::StringCchCopyW(wz, countof(wz), pswp->wzAuthenticationProviders); - ExitOnFailure(hr, "Failed to copy authentication providers string"); - hr = ScaWriteConfigID(IIS_DIRPROP_AUTHPROVID); - ExitOnFailure(hr, "Failed to write DirProp AuthProvid id"); - hr = ScaWriteConfigString(wz); - ExitOnFailure(hr, "Failed to write AuthenticationProviders for Web"); - } - //End of Dir Properties - hr = ScaWriteConfigID(IIS_DIRPROP_END); - ExitOnFailure(hr, "Failed to write DirProp end id"); - -LExit: - return hr; -} diff --git a/src/ca/scawebprop7.h b/src/ca/scawebprop7.h deleted file mode 100644 index a97e8679..00000000 --- a/src/ca/scawebprop7.h +++ /dev/null @@ -1,12 +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 "scauser.h" - -HRESULT ScaWriteWebDirProperties7( - __in_z LPCWSTR wzwWebName, - __in_z LPCWSTR wzRootOfWeb, - const SCA_WEB_PROPERTIES* pswp - ); - diff --git a/src/ca/scawebsvcext.cpp b/src/ca/scawebsvcext.cpp deleted file mode 100644 index 369e951b..00000000 --- a/src/ca/scawebsvcext.cpp +++ /dev/null @@ -1,343 +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 -enum eWebSvcExtQuery { ldqComponent=1 , ldqFile, ldqDescription, ldqGroup, ldqAttributes, ldqInstalled, ldqAction }; - - -LPCWSTR vcsWebSvcExtRoot = L"/LM/W3SVC"; - -// prototypes for private helper functions -static HRESULT AddWebSvcExtToList( - __in SCA_WEBSVCEXT** ppsWseList - ); - -//static HRESULT ScaCheckWebSvcExtValue( -// __in IMSAdminBase* piMetabase, -// __in DWORD dwMDIdentifier -// ); - -static HRESULT ScaWebSvcExtInstall( - __in LPWSTR *pwzWebSvcExtList, - __in DWORD_PTR *pcchWebSvcExtList, - __in SCA_WEBSVCEXT* psWseList - ); - -static HRESULT ScaWebSvcExtUninstall( - __in LPWSTR *pwzWebSvcExtList, - __in const DWORD *pcchWebSvcExtList, - __in SCA_WEBSVCEXT* psWseList - ); - -// functions - -HRESULT __stdcall ScaWebSvcExtRead( - __in SCA_WEBSVCEXT** ppsWseList, - __inout LPWSTR *ppwzCustomActionData - ) -{ - Assert(ppsWseList); - - HRESULT hr = S_OK; - MSIHANDLE hRec; - LPWSTR pwzData = NULL; - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - SCA_WEBSVCEXT* psWebSvcExt = NULL; - WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; - - hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); - ExitOnFailure(hr, "Failed to unwrap query for ScaWebSvcExtRead"); - - if (0 == WcaGetQueryRecords(hWrapQuery)) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtRead() because IIsWebServiceExtension data not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the web service extensions - while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) - { - // Get the Component first. If the Component is not being modified during - // this transaction, skip processing this whole record. - hr = WcaGetRecordString(hRec, ldqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get Component for WebSvcExt"); - - hr = WcaGetRecordInteger(hRec, ldqInstalled, (int *)&isInstalled); - ExitOnFailure(hr, "Failed to get Component installed state for WebSvcExt"); - - hr = WcaGetRecordInteger(hRec, ldqAction, (int *)&isAction); - ExitOnFailure(hr, "Failed to get Component action state for WebSvcExt"); - - if (!WcaIsInstalling(isInstalled, isAction) && - !WcaIsReInstalling(isInstalled, isAction) && - !WcaIsUninstalling(isInstalled, isAction)) - { - continue; // skip this record. - } - - hr = AddWebSvcExtToList(ppsWseList); - ExitOnFailure(hr, "failed to add element to web svc ext list"); - - psWebSvcExt = *ppsWseList; - Assert(psWebSvcExt); - - psWebSvcExt->isInstalled = isInstalled; - psWebSvcExt->isAction = isAction; - - hr = WcaGetRecordString(hRec, ldqFile, &pwzData); - ExitOnFailure(hr, "Failed to get File for WebSvcExt"); - hr = ::StringCchCopyW(psWebSvcExt->wzFile, countof(psWebSvcExt->wzFile), pwzData); - ExitOnFailure(hr, "Failed to copy File for WebSvcExt"); - - hr = WcaGetRecordString(hRec, ldqDescription, &pwzData); - ExitOnFailure(hr, "Failed to get Description for WebSvcExt"); - hr = ::StringCchCopyW(psWebSvcExt->wzDescription, countof(psWebSvcExt->wzDescription), pwzData); - ExitOnFailure(hr, "Failed to copy Description for WebSvcExt"); - - hr = WcaGetRecordString(hRec, ldqGroup, &pwzData); - ExitOnFailure(hr, "Failed to get Group for WebSvcExt"); - hr = ::StringCchCopyW(psWebSvcExt->wzGroup, countof(psWebSvcExt->wzGroup), pwzData); - ExitOnFailure(hr, "Failed to copy Group for WebSvcExt"); - - hr = WcaGetRecordInteger(hRec, ldqAttributes, &psWebSvcExt->iAttributes); - ExitOnFailure(hr, "Failed to get Attributes for WebSvcExt"); - } - - if (E_NOMOREITEMS == hr) - hr = S_OK; - ExitOnFailure(hr, "Failure while processing WebSvcExt"); - -LExit: - WcaFinishUnwrapQuery(hWrapQuery); - - ReleaseStr(pwzData); - - return hr; -} - - -// Commit does both install and uninstall -HRESULT __stdcall ScaWebSvcExtCommit( - __in IMSAdminBase* piMetabase, - __in SCA_WEBSVCEXT* psWseList - ) -{ - Assert(piMetabase); - - HRESULT hr = S_OK; - METADATA_RECORD mr; - - LPWSTR wzWebSvcExtList = NULL; - DWORD cbWebSvcExtList = 0; - DWORD_PTR cchWebSvcExtList = 0; - - if (!psWseList) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because there are no web service extensions in the list"); - ExitFunction(); - } - - // Get current set of web service extensions. - ::ZeroMemory(&mr, sizeof(mr)); - mr.dwMDIdentifier = MD_WEB_SVC_EXT_RESTRICTION_LIST; - mr.dwMDAttributes = 0; - mr.dwMDUserType = IIS_MD_UT_SERVER; - mr.dwMDDataType = ALL_METADATA; - mr.pbMDData = NULL; - mr.dwMDDataLen = 0; - - hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, vcsWebSvcExtRoot, &mr, &cbWebSvcExtList); - if (MD_ERROR_DATA_NOT_FOUND == hr) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because WebSvcExtRestrictionList value is not present"); - ExitFunction1(hr = S_FALSE); - } - else if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) - { - // cchWebSvcExtList is returned in bytes. Convert to WCHAR size to call StrAlloc - cchWebSvcExtList = cbWebSvcExtList / sizeof(WCHAR); - hr = StrAlloc(&wzWebSvcExtList, cchWebSvcExtList); - ExitOnFailure(hr, "Failed allocating space for web service extensions"); - } - else - { - ExitOnFailure(hr, "Failed retrieving web service extensions"); - } - - mr.pbMDData = (unsigned char*)wzWebSvcExtList; - mr.dwMDDataLen = cbWebSvcExtList; - - hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, vcsWebSvcExtRoot, &mr, &cbWebSvcExtList); - ExitOnFailure(hr, "Failed retrieving web service extensions"); - - // Make changes to local copy of metabase - while (psWseList) - { - if (WcaIsInstalling(psWseList->isInstalled, psWseList->isAction)) - { - hr = ScaWebSvcExtInstall(&wzWebSvcExtList, &cchWebSvcExtList, psWseList); - ExitOnFailure(hr, "Failed to install Web Service extension"); - } - else if (WcaIsUninstalling(psWseList->isInstalled, psWseList->isAction)) - { - hr = ScaWebSvcExtUninstall(&wzWebSvcExtList, (DWORD *)&cchWebSvcExtList, psWseList); - ExitOnFailure(hr, "Failed to uninstall Web Service extension"); - } - - psWseList = psWseList->psWseNext; - } - - // Write Metabase - hr = ScaWriteMetabaseValue(piMetabase, vcsWebSvcExtRoot, NULL, MD_WEB_SVC_EXT_RESTRICTION_LIST, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzWebSvcExtList); - ExitOnFailure(hr, "Failed to write WebServiceExtensions: '%ls'", wzWebSvcExtList); - -LExit: - ReleaseStr(wzWebSvcExtList); - - return hr; -} - - -static HRESULT ScaWebSvcExtInstall( - __in LPWSTR *ppwzWebSvcExtList, - __in DWORD_PTR *pcchWebSvcExtList, - __in SCA_WEBSVCEXT* psWseList - ) -{ - Assert( ppwzWebSvcExtList && pcchWebSvcExtList && psWseList); - Assert(*ppwzWebSvcExtList); - - HRESULT hr = S_OK; - - LPWSTR pwzWebSvcExt = NULL; - int iAllow; - int iUiDeletable; - - BOOL fAlreadyExists = FALSE; - DWORD_PTR dwIndex = 0xFFFFFFFF; - LPCWSTR wzFoundString = NULL; - - // Check if it's already in there - hr = MultiSzFindSubstring(*ppwzWebSvcExtList, psWseList->wzFile, &dwIndex, &wzFoundString); - ExitOnFailure(hr, "failed to search for string:%ls in web service extension MULTISZ", psWseList->wzFile); - - if (S_FALSE != hr && NULL != wcsstr(wzFoundString, psWseList->wzGroup) && NULL != wcsstr(wzFoundString, psWseList->wzDescription)) - { - fAlreadyExists = TRUE; - } - - // Construct the single string in the format required for the WebSvc Ext list in metabase - iAllow = (psWseList->iAttributes & 1); - iUiDeletable = ((psWseList->iAttributes >> 1) & 1); - hr = StrAllocFormatted(&pwzWebSvcExt, L"%d,%s,%d,%s,%s", iAllow, psWseList->wzFile, iUiDeletable, psWseList->wzGroup, psWseList->wzDescription); - ExitOnFailure(hr, "Failure allocating space for web service extensions"); - - if (fAlreadyExists) - { - hr = MultiSzReplaceString(ppwzWebSvcExtList, dwIndex, pwzWebSvcExt); - ExitOnFailure(hr, "failed to update web service extension string: %ls", pwzWebSvcExt); - } - else - { - hr = MultiSzPrepend(ppwzWebSvcExtList, pcchWebSvcExtList, pwzWebSvcExt); - ExitOnFailure(hr, "failed to prepend web service extension string: %ls", pwzWebSvcExt); - } - -LExit: - ReleaseStr(pwzWebSvcExt); - - return hr; -} - - -static HRESULT ScaWebSvcExtUninstall( - __in LPWSTR *ppwzWebSvcExtList, - __in const DWORD* /*pcchWebSvcExtList*/, - __in SCA_WEBSVCEXT* psWseList - ) -{ - Assert(ppwzWebSvcExtList && *ppwzWebSvcExtList && psWseList); - Assert(*ppwzWebSvcExtList); - - HRESULT hr = S_OK; - DWORD_PTR dwIndex = 0xFFFFFFFF; - LPCWSTR wzFoundString = NULL; - - // Find the string to remove - hr = MultiSzFindSubstring(*ppwzWebSvcExtList, psWseList->wzFile, &dwIndex, &wzFoundString); - ExitOnFailure(hr, "failed to search for string:%ls in web service extension MULTISZ", psWseList->wzFile); - - // If we found a match (ignoring the Allow and Deletable flags) - if (S_FALSE != hr && NULL != wcsstr(wzFoundString, psWseList->wzGroup) && NULL != wcsstr(wzFoundString, psWseList->wzDescription)) - { - hr = MultiSzRemoveString(ppwzWebSvcExtList, dwIndex); - ExitOnFailure(hr, "failed to remove string: %d from web service extension MULTISZ", dwIndex); - } - -LExit: - return hr; -} - - -//static HRESULT ScaCheckWebSvcExtValue( -// __in IMSAdminBase* piMetabase, -// __in DWORD dwMDIdentifier -// ) -//{ -// if (!piMetabase) -// { -// return E_INVALIDARG; -// } -// -// HRESULT hr = S_OK; -// METADATA_RECORD mr = { 0 }; -// DWORD cch = 0; -// -// mr.dwMDIdentifier = dwMDIdentifier; -// mr.dwMDUserType = IIS_MD_UT_SERVER; -// -// hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, vcsWebSvcExtRoot, &mr, &cch); -// if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) -// { -// hr = S_OK; -// } -// else if (MD_ERROR_DATA_NOT_FOUND == hr) -// { -// hr = S_FALSE; -// } -// -// return hr; -//} - - -void ScaWebSvcExtFreeList( - __in SCA_WEBSVCEXT* psWseList - ) -{ - SCA_WEBSVCEXT* psWseDelete = psWseList; - while (psWseList) - { - psWseDelete = psWseList; - psWseList = psWseList->psWseNext; - MemFree(psWseDelete); - } -} - - -static HRESULT AddWebSvcExtToList( - __in SCA_WEBSVCEXT** ppsWseList - ) -{ - HRESULT hr = S_OK; - - SCA_WEBSVCEXT* psWse = static_cast(MemAlloc(sizeof(SCA_WEBSVCEXT), TRUE)); - ExitOnNull(psWse, hr, E_OUTOFMEMORY, "failed to allocate element for web svc ext list"); - - psWse->psWseNext = *ppsWseList; - *ppsWseList = psWse; - -LExit: - return hr; -} diff --git a/src/ca/scawebsvcext.h b/src/ca/scawebsvcext.h deleted file mode 100644 index 4d225b09..00000000 --- a/src/ca/scawebsvcext.h +++ /dev/null @@ -1,35 +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. - - -enum SCA_WEBSVCEXT_ATTRIBUTES { SWSEATTRIB_ALLOW = 1, SWSEATTRIB_UIDELETABLE = 2 }; - -struct SCA_WEBSVCEXT -{ - // darwin information - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - // iis configuation information - WCHAR wzFile[MAX_PATH + 1]; - WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; - WCHAR wzGroup[MAX_DARWIN_COLUMN + 1]; - - int iAttributes; - - SCA_WEBSVCEXT* psWseNext; -}; - -HRESULT __stdcall ScaWebSvcExtRead( - __in SCA_WEBSVCEXT** ppsWseList, - __inout LPWSTR *ppwzCustomActionData - ); - -HRESULT ScaWebSvcExtCommit( - __in IMSAdminBase* piMetabase, - __in SCA_WEBSVCEXT* psWseList - ); - -void ScaWebSvcExtFreeList( - __in SCA_WEBSVCEXT* psWseList - ); diff --git a/src/ca/scawebsvcext7.cpp b/src/ca/scawebsvcext7.cpp deleted file mode 100644 index dcf2f7f8..00000000 --- a/src/ca/scawebsvcext7.cpp +++ /dev/null @@ -1,106 +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" - -static HRESULT ScaWebSvcExtInstall( - const SCA_WEBSVCEXT* psWseList - ); - -static HRESULT ScaWebSvcExtUninstall( - const SCA_WEBSVCEXT* psWseList - ); - -// functions -// Commit does both install and uninstall -HRESULT __stdcall ScaWebSvcExtCommit7( - __in SCA_WEBSVCEXT* psWseList - ) -{ - HRESULT hr = S_OK; - - if (!psWseList) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because there are no web service extensions in the list"); - ExitFunction(); - } - - // Make changes to local copy of metabase - while (psWseList) - { - if (WcaIsInstalling(psWseList->isInstalled, psWseList->isAction)) - { - hr = ScaWebSvcExtInstall(psWseList); - ExitOnFailure(hr, "Failed to install Web Service extension"); - } - else if (WcaIsUninstalling(psWseList->isInstalled, psWseList->isAction)) - { - hr = ScaWebSvcExtUninstall(psWseList); - ExitOnFailure(hr, "Failed to uninstall Web Service extension"); - } - - psWseList = psWseList->psWseNext; - } - - -LExit: - - return hr; -} - - -static HRESULT ScaWebSvcExtInstall( - const SCA_WEBSVCEXT* psWseList - ) -{ - HRESULT hr = S_OK; - int iAllow; - - //Write CAData actions - hr = ScaWriteConfigID(IIS_WEB_SVC_EXT); - ExitOnFailure(hr, "failed add web svc ext ID"); - hr = ScaWriteConfigID(IIS_CREATE); - ExitOnFailure(hr, "failed add web svc ext action"); - - // write File path - hr = ScaWriteConfigString(psWseList->wzFile); - ExitOnFailure(hr, "failed add web svc ext file path"); - - // write allowed - // unDeleatable n/a in IIS7 - iAllow = (psWseList->iAttributes & 1); - hr = ScaWriteConfigInteger(iAllow); - ExitOnFailure(hr, "failed add web svc ext Allowed"); - - //write group - hr = ScaWriteConfigString(psWseList->wzGroup); - ExitOnFailure(hr, "failed add web svc ext group"); - - //write description - hr = ScaWriteConfigString(psWseList->wzDescription); - ExitOnFailure(hr, "failed add web svc ext description"); - -LExit: - - return hr; -} - - -static HRESULT ScaWebSvcExtUninstall( - const SCA_WEBSVCEXT* psWseList - ) -{ - HRESULT hr = S_OK; - - //Write CAData actions - hr = ScaWriteConfigID(IIS_WEB_SVC_EXT); - ExitOnFailure(hr, "failed add web svc ext ID"); - hr = ScaWriteConfigID(IIS_DELETE); - ExitOnFailure(hr, "failed add web svc ext action"); - - // write File path (Key) - hr = ScaWriteConfigString(psWseList->wzFile); - ExitOnFailure(hr, "failed add web svc ext file path"); - -LExit: - return hr; -} diff --git a/src/ca/scawebsvcext7.h b/src/ca/scawebsvcext7.h deleted file mode 100644 index 1a686aed..00000000 --- a/src/ca/scawebsvcext7.h +++ /dev/null @@ -1,8 +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 ScaWebSvcExtCommit7( - __in SCA_WEBSVCEXT* psWseList - ); - diff --git a/src/ext/Iis/CSharp.Build.props b/src/ext/Iis/CSharp.Build.props new file mode 100644 index 00000000..b12f4c6e --- /dev/null +++ b/src/ext/Iis/CSharp.Build.props @@ -0,0 +1,11 @@ + + + + + true + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk)) + + diff --git a/src/ext/Iis/Cpp.Build.props b/src/ext/Iis/Cpp.Build.props new file mode 100644 index 00000000..9b7a1bb5 --- /dev/null +++ b/src/ext/Iis/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/Iis/Directory.Build.props b/src/ext/Iis/Directory.Build.props new file mode 100644 index 00000000..f83cc154 --- /dev/null +++ b/src/ext/Iis/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/Iis/Directory.Build.targets b/src/ext/Iis/Directory.Build.targets new file mode 100644 index 00000000..dac7452a --- /dev/null +++ b/src/ext/Iis/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/Iis/Iis.wixext.sln b/src/ext/Iis/Iis.wixext.sln new file mode 100644 index 00000000..85323fde --- /dev/null +++ b/src/ext/Iis/Iis.wixext.sln @@ -0,0 +1,58 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iisca", "src\ca\iisca.vcxproj", "{CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}" +EndProject +Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "iis", "src\wixlib\iis.wixproj", "{92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Iis.wixext", "src\wixext\WixToolset.Iis.wixext.csproj", "{612029FB-B5D4-4D7E-B794-A0E202BFE493}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Iis", "src\test\WixToolsetTest.Iis\WixToolsetTest.Iis.csproj", "{E62712D7-31A1-49E4-B1F4-0084FAD14193}" +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 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|Any CPU.Build.0 = Debug|Win32 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|x86.ActiveCfg = Debug|Win32 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Debug|x86.Build.0 = Debug|Win32 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Release|Any CPU.ActiveCfg = Release|Win32 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Release|x86.ActiveCfg = Release|Win32 + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3}.Release|x86.Build.0 = Release|Win32 + {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Debug|Any CPU.ActiveCfg = Debug|x86 + {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Debug|x86.ActiveCfg = Debug|x86 + {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Debug|x86.Build.0 = Debug|x86 + {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Release|Any CPU.ActiveCfg = Release|x86 + {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Release|x86.ActiveCfg = Release|x86 + {92FE99D2-355D-4F52-A7C1-10EECB4A5BB1}.Release|x86.Build.0 = Release|x86 + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|Any CPU.Build.0 = Debug|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|x86.ActiveCfg = Debug|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Debug|x86.Build.0 = Debug|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|Any CPU.ActiveCfg = Release|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|Any CPU.Build.0 = Release|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|x86.ActiveCfg = Release|Any CPU + {612029FB-B5D4-4D7E-B794-A0E202BFE493}.Release|x86.Build.0 = Release|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|x86.ActiveCfg = Debug|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Debug|x86.Build.0 = Debug|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|Any CPU.Build.0 = Release|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|x86.ActiveCfg = Release|Any CPU + {E62712D7-31A1-49E4-B1F4-0084FAD14193}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {89256463-14A3-4968-8688-F75EC230B021} + EndGlobalSection +EndGlobal diff --git a/src/ext/Iis/README.md b/src/ext/Iis/README.md new file mode 100644 index 00000000..ddb21a82 --- /dev/null +++ b/src/ext/Iis/README.md @@ -0,0 +1,2 @@ +# Iis.wixext +WixToolset.Iis.wixext - Iis WiX Toolset Extension diff --git a/src/ext/Iis/appveyor.cmd b/src/ext/Iis/appveyor.cmd new file mode 100644 index 00000000..af993a8f --- /dev/null +++ b/src/ext/Iis/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.Iis\WixToolsetTest.Iis.csproj || exit /b +dotnet test -c Release --no-build src\test\WixToolsetTest.Iis || exit /b + +msbuild -p:Configuration=Release -t:Pack src\wixext\WixToolset.Iis.wixext.csproj || exit /b + +@popd +@endlocal \ No newline at end of file diff --git a/src/ext/Iis/appveyor.yml b/src/ext/Iis/appveyor.yml new file mode 100644 index 00000000..7c686b04 --- /dev/null +++ b/src/ext/Iis/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/Iis/ca/CustomMsiErrors.h b/src/ext/Iis/ca/CustomMsiErrors.h new file mode 100644 index 00000000..1fd8d050 --- /dev/null +++ b/src/ext/Iis/ca/CustomMsiErrors.h @@ -0,0 +1,48 @@ +#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 msierrIISCannotConnect 26001 +#define msierrIISFailedReadWebSite 26002 +#define msierrIISFailedReadWebDirs 26003 +#define msierrIISFailedReadVDirs 26004 +#define msierrIISFailedReadFilters 26005 +#define msierrIISFailedReadAppPool 26006 +#define msierrIISFailedReadMimeMap 26007 +#define msierrIISFailedReadProp 26008 +#define msierrIISFailedReadWebSvcExt 26009 +#define msierrIISFailedReadWebError 26010 +#define msierrIISFailedReadHttpHeader 26011 + +#define msierrIISFailedSchedTransaction 26031 +#define msierrIISFailedSchedInstallWebs 26032 +#define msierrIISFailedSchedInstallWebDirs 26033 +#define msierrIISFailedSchedInstallVDirs 26034 +#define msierrIISFailedSchedInstallFilters 26035 +#define msierrIISFailedSchedInstallAppPool 26036 +#define msierrIISFailedSchedInstallProp 26037 +#define msierrIISFailedSchedInstallWebSvcExt 26038 + +#define msierrIISFailedSchedUninstallWebs 26051 +#define msierrIISFailedSchedUninstallWebDirs 26052 +#define msierrIISFailedSchedUninstallVDirs 26053 +#define msierrIISFailedSchedUninstallFilters 26054 +#define msierrIISFailedSchedUninstallAppPool 26055 +#define msierrIISFailedSchedUninstallProp 26056 +#define msierrIISFailedSchedUninstallWebSvcExt 26057 + +#define msierrIISFailedStartTransaction 26101 +#define msierrIISFailedOpenKey 26102 +#define msierrIISFailedCreateKey 26103 +#define msierrIISFailedWriteData 26104 +#define msierrIISFailedCreateApp 26105 +#define msierrIISFailedDeleteKey 26106 +#define msierrIISFailedDeleteApp 26107 +#define msierrIISFailedDeleteValue 26108 +#define msierrIISFailedCommitInUse 26109 + +// Last available value 26200 + +#define msierrCERTFailedOpen 26351 +#define msierrCERTFailedAdd 26352 + +// Last available value 26450 diff --git a/src/ext/Iis/ca/caDecor.h b/src/ext/Iis/ca/caDecor.h new file mode 100644 index 00000000..da274650 --- /dev/null +++ b/src/ext/Iis/ca/caDecor.h @@ -0,0 +1,13 @@ +#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. + + +#if defined(_M_ARM64) +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_A64" +#elif defined(_M_AMD64) +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X64" +#elif defined(_M_ARM) +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_ARM" +#else +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X86" +#endif diff --git a/src/ext/Iis/ca/dllmain.cpp b/src/ext/Iis/ca/dllmain.cpp new file mode 100644 index 00000000..35ae6d1c --- /dev/null +++ b/src/ext/Iis/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/Iis/ca/iisca.cpp b/src/ext/Iis/ca/iisca.cpp new file mode 100644 index 00000000..37664a1c --- /dev/null +++ b/src/ext/Iis/ca/iisca.cpp @@ -0,0 +1,3 @@ +// 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" diff --git a/src/ext/Iis/ca/iisca.def b/src/ext/Iis/ca/iisca.def new file mode 100644 index 00000000..b9127da6 --- /dev/null +++ b/src/ext/Iis/ca/iisca.def @@ -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. + + +LIBRARY "iisca" + +EXPORTS +;scacert.cpp + InstallCertificates + UninstallCertificates +;scacertexec.cpp + AddUserCertificate + AddMachineCertificate + DeleteUserCertificate + DeleteMachineCertificate +;scaexec.cpp + StartMetabaseTransaction + RollbackMetabaseTransaction + CommitMetabaseTransaction + + WriteMetabaseChanges + + StartIIS7ConfigTransaction + RollbackIIS7ConfigTransaction + CommitIIS7ConfigTransaction + + WriteIIS7ConfigChanges +;scasched.cpp + ConfigureIIs + ConfigureIIsExec + ConfigureIIs7Exec diff --git a/src/ext/Iis/ca/iisca.vcxproj b/src/ext/Iis/ca/iisca.vcxproj new file mode 100644 index 00000000..eb1174be --- /dev/null +++ b/src/ext/Iis/ca/iisca.vcxproj @@ -0,0 +1,147 @@ + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + + {CB3FB8C4-14BF-4EA6-9F01-7FB258E5AEF3} + DynamicLibrary + iisca + v142 + Unicode + iisca.def + WiX Toolset Iis CustomAction + + + + + + + crypt32.lib;msi.lib;Ws2_32.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}. + + + + + \ No newline at end of file diff --git a/src/ext/Iis/ca/packages.config b/src/ext/Iis/ca/packages.config new file mode 100644 index 00000000..e3dc0e43 --- /dev/null +++ b/src/ext/Iis/ca/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/ext/Iis/ca/precomp.h b/src/ext/Iis/ca/precomp.h new file mode 100644 index 00000000..85ee0890 --- /dev/null +++ b/src/ext/Iis/ca/precomp.h @@ -0,0 +1,66 @@ +#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. + + +#if _WIN32_MSI < 150 +#define _WIN32_MSI 150 +#endif + +#include +#include +#include +#include + +#include // NetApi32.lib + +#include +#include +#include // IIS 7 config + +#define MAXUINT USHRT_MAX + +#include "wcautil.h" +#include "wcawow64.h" +#include "wcawrapquery.h" + +#include "certutil.h" +#include "cryputil.h" +#include "fileutil.h" +#include "iis7util.h" +#include "memutil.h" +#include "metautil.h" +#include "strutil.h" +#include "userutil.h" +#include "wiutil.h" + +#include "CustomMsiErrors.h" +#include "sca.h" +#include "scacost.h" +#include "scacert.h" +#include "scafilter.h" + +#include "scaiis.h" +#include "scaiis7.h" +#include "scaproperty.h" +#include "scaweb.h" +#include "scawebdir.h" +#include "scawebsvcext.h" +#include "scavdir.h" +#include "scaweb7.h" +#include "scaapppool7.h" +#include "scavdir7.h" +#include "scawebapp7.h" +#include "scawebappext7.h" +#include "scamimemap7.h" +#include "scawebprop7.h" +#include "scaweblog7.h" +#include "scafilter7.h" +#include "scahttpheader7.h" +#include "scaweberr7.h" +#include "scawebsvcext7.h" +#include "scaproperty7.h" +#include "scawebdir7.h" +#include "scassl7.h" +#include "scaexecIIS7.h" + +#include "caDecor.h" diff --git a/src/ext/Iis/ca/sca.h b/src/ext/Iis/ca/sca.h new file mode 100644 index 00000000..64567dcb --- /dev/null +++ b/src/ext/Iis/ca/sca.h @@ -0,0 +1,124 @@ +#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 MAGIC_MULTISZ_CHAR 127 + +// Generic action enum. +enum SCA_ACTION +{ + SCA_ACTION_NONE, + SCA_ACTION_INSTALL, + SCA_ACTION_UNINSTALL +}; + + +// IIS Metabase actions +enum METABASE_ACTION +{ + MBA_UNKNOWNACTION = 0, + MBA_CREATEKEY, + MBA_DELETEKEY, + MBA_WRITEVALUE, + MBA_DELETEVALUE, + MBA_CREATEAPP, + MBA_DELETEAPP, +}; + +// IIS 7 Config actions +enum IIS_CONFIG_ACTION +{ + IIS_CREATE, + IIS_DELETE, + IIS_SITE, + IIS_APPLICATION, + IIS_APPPOOL, + IIS_APPPOOL_RECYCLE_MIN, + IIS_APPPOOL_RECYCLE_REQ, + IIS_APPPOOL_RECYCLE_TIMES, + IIS_APPPOOL_RECYCLE_VIRMEM, + IIS_APPPOOL_RECYCLE_PRIVMEM, + IIS_APPPOOL_RECYCLE_IDLTIMEOUT, + IIS_APPPOOL_RECYCLE_QUEUELIMIT, + IIS_APPPOOL_RECYCLE_CPU_PCT, + IIS_APPPOOL_RECYCLE_CPU_REFRESH, + IIS_APPPOOL_RECYCLE_CPU_ACTION, + IIS_APPPOOL_MAXPROCESS, + IIS_APPPOOL_IDENTITY, + IIS_APPPOOL_USER, + IIS_APPPOOL_PWD, + IIS_APPPOOL_32BIT, + IIS_APPPOOL_MANAGED_PIPELINE_MODE, + IIS_APPPOOL_MANAGED_RUNTIME_VERSION, + IIS_APPPOOL_END, + IIS_APPEXT_BEGIN, + IIS_APPEXT, + IIS_APPEXT_END, + IIS_VDIR, + IIS_BINDING, + IIS_MIMEMAP_BEGIN, + IIS_MIMEMAP, + IIS_MIMEMAP_END, + IIS_DIRPROP_BEGIN, + IIS_DIRPROP_ACCESS, + IIS_DIRPROP_AUTH, + IIS_DIRPROP_USER, + IIS_DIRPROP_PWD, + IIS_DIRPROP_PWDCTRL, + IIS_DIRPROP_LOG, + IIS_DIRPROP_DEFDOCS, + IIS_DIRPROP_SSLFLAGS, + IIS_DIRPROP_AUTHPROVID, + IIS_DIRPROP_ASPERROR, + IIS_DIRPROP_HTTPEXPIRES, + IIS_DIRPROP_MAXAGE, + IIS_DIRPROP_CACHECUST, + IIS_DIRPROP_NOCUSTERROR, + IIS_DIRPROP_LOGVISITS, + IIS_DIRPROP_END, + IIS_WEBLOG, + IIS_FILTER_BEGIN, + IIS_FILTER_GLOBAL_BEGIN, + IIS_FILTER, + IIS_FILTER_END, + IIS_HTTP_HEADER_BEGIN, + IIS_HTTP_HEADER, + IIS_HTTP_HEADER_END, + IIS_WEBERROR_BEGIN, + IIS_WEBERROR, + IIS_WEBERROR_END, + IIS_WEB_SVC_EXT, + IIS_PROPERTY, + IIS_PROPERTY_MAXBAND, + IIS_PROPERTY_LOGUTF8, + IIS_WEBDIR, + IIS_ASP_BEGIN, + IIS_ASP_SESSIONSTATE, + IIS_ASP_SESSIONTIMEOUT, + IIS_ASP_BUFFER, + IIS_ASP_PARENTPATHS, + IIS_ASP_SCRIPTLANG, + IIS_ASP_SCRIPTTIMEOUT, + IIS_ASP_SCRIPTSERVERDEBUG, + IIS_ASP_SCRIPTCLIENTDEBUG, + IIS_ASP_END, + IIS_SSL_BINDING +}; + + +// user creation attributes definitions +enum SCAU_ATTRIBUTES +{ + SCAU_DONT_EXPIRE_PASSWRD = 0x00000001, + SCAU_PASSWD_CANT_CHANGE = 0x00000002, + SCAU_PASSWD_CHANGE_REQD_ON_LOGIN = 0x00000004, + SCAU_DISABLE_ACCOUNT = 0x00000008, + SCAU_FAIL_IF_EXISTS = 0x00000010, + SCAU_UPDATE_IF_EXISTS = 0x00000020, + SCAU_ALLOW_LOGON_AS_SERVICE = 0x00000040, + SCAU_ALLOW_LOGON_AS_BATCH = 0x00000080, + + SCAU_DONT_REMOVE_ON_UNINSTALL = 0x00000100, + SCAU_DONT_CREATE_USER = 0x00000200, + SCAU_NON_VITAL = 0x00000400, +}; diff --git a/src/ext/Iis/ca/scaapppool.cpp b/src/ext/Iis/ca/scaapppool.cpp new file mode 100644 index 00000000..781c55ca --- /dev/null +++ b/src/ext/Iis/ca/scaapppool.cpp @@ -0,0 +1,594 @@ +// 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" + +/*------------------------------------------------------------------ +AppPool table: + +Column Type Nullable Example Value +AppPool s72 No TestPool +Name s72 No "TestPool" +Component_ s72 No ComponentName +Attributes i2 No 8 (APATTR_OTHERUSER) +User_ s72 Yes UserKey +RecycleMinutes i2 Yes 500 +RecycleRequests i2 Yes 5000 +RecycleTimes s72 Yes "1:45,13:30,22:00" +IdleTimeout i2 Yes 15 +QueueLimit i2 Yes 500 +CPUMon s72 Yes "65,500,1" (65% CPU usage, 500 minutes, Shutdown Action) +MaxProc i2 Yes 5 +ManagedRuntimeVersion s72 Yes "v2.0" +ManagedPipelineMode s72 Yes "Integrated" + +Notes: +RecycleTimes is a comma delimeted list of times. CPUMon is a +comma delimeted list of the following format: +,,. The values for +Action are 1 (Shutdown) and 0 (No Action). + +------------------------------------------------------------------*/ + +enum eAppPoolQuery { apqAppPool = 1, apqName, apqComponent, apqAttributes, apqUser, apqRecycleMinutes, apqRecycleRequests, apqRecycleTimes, apqVirtualMemory, apqPrivateMemory, apqIdleTimeout, apqQueueLimit, apqCpuMon, apqMaxProc, apqManagedRuntimeVersion, apqManagedPipelineMode, apqInstalled, apqAction }; + +enum eComponentAttrQuery { caqComponent = 1, caqAttributes }; + +// prototypes +static HRESULT AppPoolExists( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzAppPool + ); + +// functions + +void ScaAppPoolFreeList( + __in SCA_APPPOOL* psapList + ) +{ + SCA_APPPOOL* psapDelete = psapList; + while (psapList) + { + psapDelete = psapList; + psapList = psapList->psapNext; + + MemFree(psapDelete); + } +} + + +HRESULT ScaAppPoolRead( + __inout SCA_APPPOOL** ppsapList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(ppsapList); + + HRESULT hr = S_OK; + + MSIHANDLE hRec, hRecComp; + LPWSTR pwzData = NULL; + SCA_APPPOOL* psap = NULL; + WCA_WRAPQUERY_HANDLE hAppPoolQuery = NULL; + WCA_WRAPQUERY_HANDLE hComponentQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hAppPoolQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hAppPoolQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaAppPoolRead() - required table not present"); + ExitFunction1(hr = S_FALSE); + } + + hr = WcaBeginUnwrapQuery(&hComponentQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + // loop through all the AppPools + while (S_OK == (hr = WcaFetchWrappedRecord(hAppPoolQuery, &hRec))) + { + // Add this record's information into the list of things to process. + hr = AddAppPoolToList(ppsapList); + ExitOnFailure(hr, "failed to add app pool to app pool list"); + + psap = *ppsapList; + + hr = WcaGetRecordString(hRec, apqComponent, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.Component"); + + if (pwzData && *pwzData) + { + psap->fHasComponent = TRUE; + + hr = ::StringCchCopyW(psap->wzComponent, countof(psap->wzComponent), pwzData); + ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, apqInstalled, (int *)&psap->isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for app pool"); + + hr = WcaGetRecordInteger(hRec, apqAction, (int *)&psap->isAction); + ExitOnFailure(hr, "Failed to get Component action state for app pool"); + + WcaFetchWrappedReset(hComponentQuery); + hr = WcaFetchWrappedRecordWhereString(hComponentQuery, caqComponent, psap->wzComponent, &hRecComp); + ExitOnFailure(hr, "Failed to fetch Component.Attributes for Component '%ls'", psap->wzComponent); + + hr = WcaGetRecordInteger(hRecComp, caqAttributes, &psap->iCompAttributes); + ExitOnFailure(hr, "failed to get Component.Attributes"); + } + + hr = WcaGetRecordString(hRec, apqAppPool, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.AppPool"); + hr = ::StringCchCopyW(psap->wzAppPool, countof(psap->wzAppPool), pwzData); + ExitOnFailure(hr, "failed to copy AppPool name: %ls", pwzData); + + hr = WcaGetRecordString(hRec, apqName, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.Name"); + hr = ::StringCchCopyW(psap->wzName, countof(psap->wzName), pwzData); + ExitOnFailure(hr, "failed to copy app pool name: %ls", pwzData); + hr = ::StringCchPrintfW(psap->wzKey, countof(psap->wzKey), L"/LM/W3SVC/AppPools/%s", pwzData); + ExitOnFailure(hr, "failed to format app pool key name"); + + hr = WcaGetRecordInteger(hRec, apqAttributes, &psap->iAttributes); + ExitOnFailure(hr, "failed to get AppPool.Attributes"); + + hr = WcaGetRecordString(hRec, apqUser, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.User"); + hr = ScaGetUserDeferred(pwzData, hUserQuery, &psap->suUser); + ExitOnFailure(hr, "failed to get user: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, apqRecycleRequests, &psap->iRecycleRequests); + ExitOnFailure(hr, "failed to get AppPool.RecycleRequests"); + + hr = WcaGetRecordInteger(hRec, apqRecycleMinutes, &psap->iRecycleMinutes); + ExitOnFailure(hr, "failed to get AppPool.Minutes"); + + hr = WcaGetRecordString(hRec, apqRecycleTimes, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.RecycleTimes"); + hr = ::StringCchCopyW(psap->wzRecycleTimes, countof(psap->wzRecycleTimes), pwzData); + ExitOnFailure(hr, "failed to copy recycle value: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, apqVirtualMemory, &psap->iVirtualMemory); + ExitOnFailure(hr, "failed to get AppPool.VirtualMemory"); + + hr = WcaGetRecordInteger(hRec, apqPrivateMemory, &psap->iPrivateMemory); + ExitOnFailure(hr, "failed to get AppPool.PrivateMemory"); + + hr = WcaGetRecordInteger(hRec, apqIdleTimeout, &psap->iIdleTimeout); + ExitOnFailure(hr, "failed to get AppPool.IdleTimeout"); + + hr = WcaGetRecordInteger(hRec, apqQueueLimit, &psap->iQueueLimit); + ExitOnFailure(hr, "failed to get AppPool.QueueLimit"); + + hr = WcaGetRecordString(hRec, apqCpuMon, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.CPUMon"); + hr = ::StringCchCopyW(psap->wzCpuMon, countof(psap->wzCpuMon), pwzData); + ExitOnFailure(hr, "failed to copy cpu monitor value: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, apqMaxProc, &psap->iMaxProcesses); + ExitOnFailure(hr, "failed to get AppPool.MaxProc"); + + hr = WcaGetRecordString(hRec, apqManagedRuntimeVersion, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.ManagedRuntimeVersion"); + hr = ::StringCchCopyW(psap->wzManagedRuntimeVersion, countof(psap->wzManagedRuntimeVersion), pwzData); + ExitOnFailure(hr, "failed to copy ManagedRuntimeVersion value: %ls", pwzData); + + hr = WcaGetRecordString(hRec, apqManagedPipelineMode, &pwzData); + ExitOnFailure(hr, "failed to get AppPool.ManagedPipelineMode"); + hr = ::StringCchCopyW(psap->wzManagedPipelineMode, countof(psap->wzManagedPipelineMode), pwzData); + ExitOnFailure(hr, "failed to copy ManagedPipelineMode value: %ls", pwzData); + + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "failure while processing AppPools"); + +LExit: + WcaFinishUnwrapQuery(hAppPoolQuery); + WcaFinishUnwrapQuery(hComponentQuery); + + ReleaseStr(pwzData); + return hr; +} + + +HRESULT ScaFindAppPool( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzAppPool, + __out_ecount(cchName) LPWSTR wzName, + __in DWORD cchName, + __in SCA_APPPOOL *psapList + ) +{ + Assert(piMetabase && wzAppPool && *wzAppPool && wzName && *wzName); + + HRESULT hr = S_OK; + + // check memory first + SCA_APPPOOL* psap = psapList; + for (; psap; psap = psap->psapNext) + { + if (0 == lstrcmpW(psap->wzAppPool, wzAppPool)) + { + break; + } + } + ExitOnNull(psap, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Could not find the app pool: %ls", wzAppPool); + + // copy the web app pool name + hr = ::StringCchCopyW(wzName, cchName, psap->wzName); + ExitOnFailure(hr, "failed to copy app pool name while finding app pool: %ls", psap->wzName); + + // if it's not being installed now, check if it exists already + if (!psap->fHasComponent) + { + hr = AppPoolExists(piMetabase, psap->wzName); + ExitOnFailure(hr, "failed to check for existence of app pool: %ls", psap->wzName); + } + +LExit: + return hr; +} + + +static HRESULT AppPoolExists( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzAppPool + ) +{ + Assert(piMetabase && wzAppPool && *wzAppPool); + + HRESULT hr = S_OK; + WCHAR wzSubKey[METADATA_MAX_NAME_LEN]; + + for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex) + { + hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/AppPools", wzSubKey, dwIndex); + if (SUCCEEDED(hr) && 0 == lstrcmpW(wzSubKey, wzAppPool)) + { + hr = S_OK; + break; + } + } + + if (E_NOMOREITEMS == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + hr = S_FALSE; + } + + return hr; +} + + +HRESULT ScaAppPoolInstall( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psapList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + + for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) + { + // if we are installing the app pool + if (psap->fHasComponent && WcaIsInstalling(psap->isInstalled, psap->isAction)) + { + hr = ScaWriteAppPool(piMetabase, psap); + ExitOnFailure(hr, "failed to write AppPool '%ls' to metabase", psap->wzAppPool); + } + } + +LExit: + return hr; +} + + +HRESULT ScaAppPoolUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psapList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + + for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) + { + // if we are uninstalling the app pool + if (psap->fHasComponent && WcaIsUninstalling(psap->isInstalled, psap->isAction)) + { + hr = ScaRemoveAppPool(piMetabase, psap); + ExitOnFailure(hr, "Failed to remove AppPool '%ls' from metabase", psap->wzAppPool); + } + } + +LExit: + return hr; +} + + +HRESULT ScaWriteAppPool( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psap + ) +{ + Assert(piMetabase && psap); + + HRESULT hr = S_OK; + DWORD dwIdentity = 0xFFFFFFFF; + BOOL fExists = FALSE; + LPWSTR pwzValue = NULL; + LPWSTR wz = NULL; + + hr = AppPoolExists(piMetabase, psap->wzName); + ExitOnFailure(hr, "failed to check if app pool already exists"); + if (S_FALSE == hr) + { + // didn't find the AppPool key, so we need to create it + hr = ScaCreateMetabaseKey(piMetabase, psap->wzKey, L""); + ExitOnFailure(hr, "failed to create AppPool key: %ls", psap->wzKey); + + // mark it as an AppPool + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsApplicationPool"); + ExitOnFailure(hr, "failed to mark key as AppPool key: %ls", psap->wzKey); + + // TODO: Make this an Attribute? + // set autostart value + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_AUTO_START, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)1); + ExitOnFailure(hr, "failed to mark key as AppPool key: %ls", psap->wzKey); + } + else + { + fExists = TRUE; + } + + // + // Set the AppPool Recycling Tab + // + if (MSI_NULL_INTEGER != psap->iRecycleMinutes) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_TIME, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iRecycleMinutes)); + ExitOnFailure(hr, "failed to set periodic restart time"); + } + + if (MSI_NULL_INTEGER != psap->iRecycleRequests) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_REQUEST_COUNT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iRecycleRequests)); + ExitOnFailure(hr, "failed to set periodic restart request count"); + } + + if (*psap->wzRecycleTimes) + { + // Add another NULL' onto pwz since it's a 'MULTISZ' + hr = StrAllocString(&pwzValue, psap->wzRecycleTimes, 0); + ExitOnFailure(hr, "failed to allocate string for MULTISZ"); + hr = StrAllocConcat(&pwzValue, L"\0", 1); + ExitOnFailure(hr, "failed to add second null to RecycleTime multisz"); + + // Replace the commas with NULLs + wz = pwzValue; + while (NULL != (wz = wcschr(wz, L','))) + { + *wz = L'\0'; + ++wz; + } + + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_SCHEDULE, METADATA_INHERIT, IIS_MD_UT_SERVER, MULTISZ_METADATA, (LPVOID)pwzValue); + ExitOnFailure(hr, "failed to set periodic restart schedule"); + } + + if (MSI_NULL_INTEGER != psap->iVirtualMemory) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_MEMORY, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iVirtualMemory)); + ExitOnFailure(hr, "failed to set periodic restart memory count"); + } + + if (MSI_NULL_INTEGER != psap->iPrivateMemory) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_PERIODIC_RESTART_PRIVATE_MEMORY, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iPrivateMemory)); + ExitOnFailure(hr, "failed to set periodic restart private memory count"); + } + + + // + // Set AppPool Performance Tab + // + if (MSI_NULL_INTEGER != psap->iIdleTimeout) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_IDLE_TIMEOUT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iIdleTimeout)); + ExitOnFailure(hr, "failed to set idle timeout value"); + } + + if (MSI_NULL_INTEGER != psap->iQueueLimit) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_UL_APPPOOL_QUEUE_LENGTH, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iQueueLimit)); + ExitOnFailure(hr, "failed to set request queue limit value"); + } + + if (*psap->wzCpuMon) + { + hr = StrAllocString(&pwzValue, psap->wzCpuMon, 0); + ExitOnFailure(hr, "failed to allocate CPUMonitor string"); + + DWORD dwPercent = 0; + DWORD dwRefreshMinutes = 0; + DWORD dwAction = 0; + + dwPercent = wcstoul(pwzValue, &wz, 10); + if (100 < dwPercent) + { + ExitOnFailure(hr = E_INVALIDARG, "invalid maximum cpu percentage value: %d", dwPercent); + } + if (wz && L',' == *wz) + { + ++wz; + dwRefreshMinutes = wcstoul(wz, &wz, 10); + if (wz && L',' == *wz) + { + ++wz; + dwAction = wcstoul(wz, &wz, 10); + } + } + + if (dwPercent) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_LIMIT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)(dwPercent * 1000))); + ExitOnFailure(hr, "failed to set CPU percentage max"); + } + if (dwRefreshMinutes) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_RESET_INTERVAL, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwRefreshMinutes)); + ExitOnFailure(hr, "failed to set refresh CPU minutes"); + } + if (dwAction) + { + // 0 = No Action + // 1 = Shutdown + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_CPU_ACTION, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwAction)); + ExitOnFailure(hr, "failed to set CPU action"); + } + } + + if (MSI_NULL_INTEGER != psap->iMaxProcesses) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_MAX_PROCESS_COUNT, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psap->iMaxProcesses)); + ExitOnFailure(hr, "failed to set web garden maximum worker processes"); + } + + // TODO: Health Tab if anyone wants it? + + // + // Set the AppPool Identity tab + // + if (psap->iAttributes & APATTR_NETSERVICE) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE; + } + else if (psap->iAttributes & APATTR_LOCSERVICE) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE; + } + else if (psap->iAttributes & APATTR_LOCSYSTEM) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM; + } + else if (psap->iAttributes & APATTR_OTHERUSER) + { + if (!*psap->suUser.wzDomain || CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzDomain, -1, L".", -1)) + { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"NetworkService", -1)) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"LocalService", -1)) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"LocalSystem", -1)) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM; + } + else + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER; + } + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzDomain, -1, L"NT AUTHORITY", -1)) + { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"NETWORK SERVICE", -1)) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_NETWORKSERVICE; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"SERVICE", -1)) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSERVICE; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, psap->suUser.wzName, -1, L"SYSTEM", -1)) + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM; + } + else + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER; + } + } + else + { + dwIdentity = MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER; + } + } + + if (-1 != dwIdentity) + { + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_APPPOOL_IDENTITY_TYPE, METADATA_INHERIT , IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwIdentity)); + ExitOnFailure(hr, "failed to set app pool identity"); + + if (MD_APPPOOL_IDENTITY_TYPE_SPECIFICUSER == dwIdentity) + { + if (*psap->suUser.wzDomain) + { + hr = StrAllocFormatted(&pwzValue, L"%s\\%s", psap->suUser.wzDomain, psap->suUser.wzName); + ExitOnFailure(hr, "failed to format user name: %ls domain: %ls", psap->suUser.wzName, psap->suUser.wzDomain); + } + else + { + hr = StrAllocFormatted(&pwzValue, L"%s", psap->suUser.wzName); + ExitOnFailure(hr, "failed to format user name: %ls", psap->suUser.wzName); + } + + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_WAM_USER_NAME, METADATA_INHERIT , IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pwzValue); + ExitOnFailure(hr, "failed to set app pool identity name"); + + hr = ScaWriteMetabaseValue(piMetabase, psap->wzKey, NULL, MD_WAM_PWD, METADATA_INHERIT | METADATA_SECURE, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psap->suUser.wzPassword); + ExitOnFailure(hr, "failed to set app pool identity password"); + } + } + +LExit: + ReleaseStr(pwzValue); + + return hr; +} + + +HRESULT ScaRemoveAppPool( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psap + ) +{ + Assert(piMetabase && psap); + + HRESULT hr = S_OK; + + // simply remove the root key and everything else is pulled at the same time + if (0 != lstrlenW(psap->wzKey)) + { + hr = ScaDeleteMetabaseKey(piMetabase, psap->wzKey, L""); + ExitOnFailure(hr, "failed to delete AppPool key: %ls", psap->wzKey); + } + + // TODO: Maybe check to make sure any web sites that are using this AppPool are put back in the 'DefaultAppPool' + +LExit: + return hr; +} + + +HRESULT AddAppPoolToList( + __in SCA_APPPOOL** ppsapList + ) +{ + HRESULT hr = S_OK; + SCA_APPPOOL* psap = static_cast(MemAlloc(sizeof(SCA_APPPOOL), TRUE)); + ExitOnNull(psap, hr, E_OUTOFMEMORY, "failed to allocate memory for new element in app pool list"); + + psap->psapNext = *ppsapList; + *ppsapList = psap; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scaapppool.h b/src/ext/Iis/ca/scaapppool.h new file mode 100644 index 00000000..68575fcb --- /dev/null +++ b/src/ext/Iis/ca/scaapppool.h @@ -0,0 +1,88 @@ +#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 "scauser.h" + +// Identity +#define APATTR_NETSERVICE 0x0001 // Network Service +#define APATTR_LOCSERVICE 0x0002 // Local Service +#define APATTR_LOCSYSTEM 0x0004 // Local System +#define APATTR_OTHERUSER 0x0008 // Other User + +struct SCA_APPPOOL +{ + // iis app pool configuation information + WCHAR wzAppPool[MAX_DARWIN_KEY + 1]; + WCHAR wzName[METADATA_MAX_NAME_LEN + 1]; + WCHAR wzKey[METADATA_MAX_NAME_LEN + 1]; + WCHAR wzComponent[METADATA_MAX_NAME_LEN + 1]; + BOOL fHasComponent; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + INT iAttributes; + + SCA_USER suUser; + + INT iRecycleRequests; + INT iRecycleMinutes; + WCHAR wzRecycleTimes[MAX_DARWIN_KEY + 1]; + INT iVirtualMemory; + INT iPrivateMemory; + + INT iIdleTimeout; + INT iQueueLimit; + WCHAR wzCpuMon[MAX_DARWIN_KEY + 1]; + INT iMaxProcesses; + WCHAR wzManagedPipelineMode[MAX_DARWIN_KEY + 1]; + WCHAR wzManagedRuntimeVersion[MAX_DARWIN_KEY + 1]; + + int iCompAttributes; + + SCA_APPPOOL *psapNext; +}; + + +// prototypes + +HRESULT ScaAppPoolRead( + __inout SCA_APPPOOL** ppsapList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __inout LPWSTR *ppwzCustomActionData + ); + +void ScaAppPoolFreeList( + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaFindAppPool( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzAppPool, + __out_ecount(cchName) LPWSTR wzName, + __in DWORD cchName, + __in SCA_APPPOOL *psapList + ); + +HRESULT ScaAppPoolInstall( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaAppPoolUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaWriteAppPool( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psap + ); + +HRESULT ScaRemoveAppPool( + __in IMSAdminBase* piMetabase, + __in SCA_APPPOOL* psap + ); + +HRESULT AddAppPoolToList( + __in SCA_APPPOOL** ppsapList + ); diff --git a/src/ext/Iis/ca/scaapppool7.cpp b/src/ext/Iis/ca/scaapppool7.cpp new file mode 100644 index 00000000..0fac4346 --- /dev/null +++ b/src/ext/Iis/ca/scaapppool7.cpp @@ -0,0 +1,401 @@ +// 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" + +// prototypes +static HRESULT AppPoolExists( + __in LPCWSTR wzAppPool + ); + +// functions +HRESULT ScaFindAppPool7( + __in LPCWSTR wzAppPool, + __out_ecount(cchName) LPWSTR wzName, + __in DWORD cchName, + __in SCA_APPPOOL *psapList + ) +{ + Assert(wzAppPool && *wzAppPool && wzName && *wzName); + + HRESULT hr = S_OK; + + // check memory first + SCA_APPPOOL* psap = psapList; + for (; psap; psap = psap->psapNext) + { + if (0 == wcscmp(psap->wzAppPool, wzAppPool)) + { + break; + } + } + ExitOnNull(psap, hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Could not find the app pool: %ls", wzAppPool); + + // copy the web app pool name +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ::StringCchCopyW(wzName, cchName, psap->wzName); + ExitOnFailure(hr, "failed to copy app pool name while finding app pool: %ls", psap->wzName); + + // if it's not being installed now, check if it exists already + if (!psap->fHasComponent) + { + hr = AppPoolExists(psap->wzName); + ExitOnFailure(hr, "failed to check for existence of app pool: %ls", psap->wzName); + } + +LExit: + return hr; +} + + +static HRESULT AppPoolExists( + __in LPCWSTR /*wzAppPool*/ + ) +{ + HRESULT hr = S_OK; + + //this function checks for existance of app pool in IIS7 config + //at schedule time, we will defer this to execute time. + + return hr; +} + + +HRESULT ScaAppPoolInstall7( + __in SCA_APPPOOL* psapList + ) +{ + HRESULT hr = S_OK; + + for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) + { + // if we are installing the app pool + if (psap->fHasComponent && WcaIsInstalling(psap->isInstalled, psap->isAction)) + { + hr = ScaWriteAppPool7(psap); + ExitOnFailure(hr, "failed to write AppPool '%ls' to metabase", psap->wzAppPool); + } + } + +LExit: + return hr; +} + + +HRESULT ScaAppPoolUninstall7( + __in SCA_APPPOOL* psapList + ) +{ + + HRESULT hr = S_OK; + + for (SCA_APPPOOL* psap = psapList; psap; psap = psap->psapNext) + { + // if we are uninstalling the app pool + if (psap->fHasComponent && WcaIsUninstalling(psap->isInstalled, psap->isAction)) + { + hr = ScaRemoveAppPool7(psap); + ExitOnFailure(hr, "Failed to remove AppPool '%ls' from metabase", psap->wzAppPool); + } + } + +LExit: + return hr; +} + + +HRESULT ScaWriteAppPool7( + __in const SCA_APPPOOL* psap + ) +{ + Assert(psap); + + HRESULT hr = S_OK; + DWORD dwIdentity = 0xFFFFFFFF; + LPWSTR pwzValue = NULL; + LPWSTR wz = NULL; + + //create the app pool + hr = ScaWriteConfigID(IIS_APPPOOL); + ExitOnFailure(hr, "failed to write AppPool key."); + + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "failed to write AppPool create action."); + + hr = ScaWriteConfigString(psap->wzName); + ExitOnFailure(hr, "failed to write AppPool name: %ls", psap->wzName); + + // Now do all the optional stuff + + // Set the AppPool Recycling Tab + if (MSI_NULL_INTEGER != psap->iRecycleMinutes) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_MIN); + ExitOnFailure(hr, "failed to set periodic restart time id"); + hr = ScaWriteConfigInteger(psap->iRecycleMinutes); + ExitOnFailure(hr, "failed to set periodic restart time"); + } + + if (MSI_NULL_INTEGER != psap->iRecycleRequests) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_REQ); + ExitOnFailure(hr, "failed to set periodic restart request count id"); + hr = ScaWriteConfigInteger(psap->iRecycleRequests); + ExitOnFailure(hr, "failed to set periodic restart request count"); + } + + if (*psap->wzRecycleTimes) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_TIMES); + ExitOnFailure(hr, "failed to set periodic restart schedule id"); + hr = ScaWriteConfigString(psap->wzRecycleTimes); + ExitOnFailure(hr, "failed to set periodic restart schedule"); + } + + if (MSI_NULL_INTEGER != psap->iVirtualMemory) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_VIRMEM); + ExitOnFailure(hr, "failed to set periodic restart memory count id"); + hr = ScaWriteConfigInteger(psap->iVirtualMemory); + ExitOnFailure(hr, "failed to set periodic restart memory count"); + } + + if (MSI_NULL_INTEGER != psap->iPrivateMemory) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_PRIVMEM); + ExitOnFailure(hr, "failed to set periodic restart private memory count id"); + hr = ScaWriteConfigInteger(psap->iPrivateMemory); + ExitOnFailure(hr, "failed to set periodic restart private memory count"); + } + + // Set AppPool Performance Tab + if (MSI_NULL_INTEGER != psap->iIdleTimeout) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_IDLTIMEOUT); + ExitOnFailure(hr, "failed to set idle timeout value id"); + hr = ScaWriteConfigInteger(psap->iIdleTimeout); + ExitOnFailure(hr, "failed to set idle timeout value"); + } + + if (MSI_NULL_INTEGER != psap->iQueueLimit) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_QUEUELIMIT); + ExitOnFailure(hr, "failed to set request queue limit value id"); + hr = ScaWriteConfigInteger(psap->iQueueLimit); + ExitOnFailure(hr, "failed to set request queue limit value"); + } + if (*psap->wzCpuMon) + { +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ::StrAllocString(&pwzValue, psap->wzCpuMon, 0); + ExitOnFailure(hr, "failed to allocate CPUMonitor string"); + + DWORD dwPercent = 0; + DWORD dwRefreshMinutes = 0; + DWORD dwAction = 0; + + dwPercent = wcstoul(pwzValue, &wz, 10); + if (100 < dwPercent) + { + ExitOnFailure(hr = E_INVALIDARG, "invalid maximum cpu percentage value: %d", dwPercent); + } + if (wz && L',' == *wz) + { + ++wz; + dwRefreshMinutes = wcstoul(wz, &wz, 10); + if (wz && L',' == *wz) + { + ++wz; + dwAction = wcstoul(wz, &wz, 10); + } + } + if (dwPercent) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_CPU_PCT); + ExitOnFailure(hr, "failed to set recycle pct id"); + hr = ScaWriteConfigInteger(dwPercent); + ExitOnFailure(hr, "failed to set CPU percentage max"); + } + if (dwRefreshMinutes) + { + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_CPU_REFRESH); + ExitOnFailure(hr, "failed to set recycle refresh id"); + hr = ScaWriteConfigInteger(dwRefreshMinutes); + ExitOnFailure(hr, "failed to set refresh CPU minutes"); + } + if (dwAction) + { + // 0 = No Action + // 1 = Shutdown + hr = ScaWriteConfigID(IIS_APPPOOL_RECYCLE_CPU_ACTION); + ExitOnFailure(hr, "failed to set recycle refresh id"); + hr = ScaWriteConfigInteger(dwAction); + ExitOnFailure(hr, "failed to set CPU action"); + } + } + + if (MSI_NULL_INTEGER != psap->iMaxProcesses) + { + hr = ScaWriteConfigID(IIS_APPPOOL_MAXPROCESS); + ExitOnFailure(hr, "Failed to write max processes config ID"); + + hr = ScaWriteConfigInteger(psap->iMaxProcesses); + ExitOnFailure(hr, "failed to set web garden maximum worker processes"); + } + + hr = ScaWriteConfigID(IIS_APPPOOL_32BIT); + ExitOnFailure(hr, "Failed to write 32 bit app pool config ID"); + hr = ScaWriteConfigInteger(psap->iCompAttributes & msidbComponentAttributes64bit ? 0 : 1); + ExitOnFailure(hr, "Failed to write 32 bit app pool config value"); + + // + // Set the AppPool Identity tab + // + if (psap->iAttributes & APATTR_APPPOOLIDENTITY) + { + dwIdentity = 4; + } + else if (psap->iAttributes & APATTR_NETSERVICE) + { + dwIdentity = 2; + } + else if (psap->iAttributes & APATTR_LOCSERVICE) + { + dwIdentity = 1; + } + else if (psap->iAttributes & APATTR_LOCSYSTEM) + { + dwIdentity = 0; + } + else if (psap->iAttributes & APATTR_OTHERUSER) + { + if (!*psap->suUser.wzDomain || 0 == _wcsicmp(psap->suUser.wzDomain, L".")) + { + if (0 == _wcsicmp(psap->suUser.wzName, L"NetworkService")) + { + dwIdentity = 2; + } + else if (0 == _wcsicmp(psap->suUser.wzName, L"LocalService")) + { + dwIdentity = 1; + } + else if (0 == _wcsicmp(psap->suUser.wzName, L"LocalSystem")) + { + dwIdentity = 0; + } + else + { + dwIdentity = 3; + } + } + else if (0 == _wcsicmp(psap->suUser.wzDomain, L"NT AUTHORITY")) + { + if (0 == _wcsicmp(psap->suUser.wzName, L"NETWORK SERVICE")) + { + dwIdentity = 2; + } + else if (0 == _wcsicmp(psap->suUser.wzName, L"SERVICE")) + { + dwIdentity = 1; + } + else if (0 == _wcsicmp(psap->suUser.wzName, L"SYSTEM")) + { + dwIdentity = 0; + } + else + { + dwIdentity = 3; + } + } + else + { + dwIdentity = 3; + } + } + + if (-1 != dwIdentity) + { + hr = ScaWriteConfigID(IIS_APPPOOL_IDENTITY); + ExitOnFailure(hr, "failed to set app pool identity id"); + hr = ScaWriteConfigInteger(dwIdentity); + ExitOnFailure(hr, "failed to set app pool identity"); + + if (3 == dwIdentity) + { + if (*psap->suUser.wzDomain) + { + hr = StrAllocFormatted(&pwzValue, L"%s\\%s", psap->suUser.wzDomain, psap->suUser.wzName); + ExitOnFailure(hr, "failed to format user name: %ls domain: %ls", psap->suUser.wzName, psap->suUser.wzDomain); + } + else + { + hr = StrAllocFormatted(&pwzValue, L"%s", psap->suUser.wzName); + ExitOnFailure(hr, "failed to format user name: %ls", psap->suUser.wzName); + } + + hr = ScaWriteConfigID(IIS_APPPOOL_USER); + ExitOnFailure(hr, "failed to set app pool identity name id"); + hr = ScaWriteConfigString(pwzValue); + ExitOnFailure(hr, "failed to set app pool identity name"); + + hr = ScaWriteConfigID(IIS_APPPOOL_PWD); + ExitOnFailure(hr, "failed to set app pool identity password id"); + hr = ScaWriteConfigString(psap->suUser.wzPassword); + ExitOnFailure(hr, "failed to set app pool identity password"); + } + } + + if (*psap->wzManagedPipelineMode) + { + hr = ScaWriteConfigID(IIS_APPPOOL_MANAGED_PIPELINE_MODE); + ExitOnFailure(hr, "failed to set app pool integrated mode"); + hr = ScaWriteConfigString(psap->wzManagedPipelineMode); + ExitOnFailure(hr, "failed to set app pool managed pipeline mode value"); + } + + if (*psap->wzManagedRuntimeVersion) + { + hr = ScaWriteConfigID(IIS_APPPOOL_MANAGED_RUNTIME_VERSION); + ExitOnFailure(hr, "failed to set app pool managed runtime version mode"); + hr = ScaWriteConfigString(psap->wzManagedRuntimeVersion); + ExitOnFailure(hr, "failed to set app pool managed runtime version value"); + } + + // + //The number of properties above is variable so we put an end tag in so the + //execute CA will know when to stop looking for AppPool properties + // + hr = ScaWriteConfigID(IIS_APPPOOL_END); + ExitOnFailure(hr, "failed to set app pool end of properties id"); + +LExit: + ReleaseStr(pwzValue); + + return hr; +} + + +HRESULT ScaRemoveAppPool7( + __in const SCA_APPPOOL* psap + ) +{ + Assert(psap); + + HRESULT hr = S_OK; + + //do not delete the default App Pool + if (0 != _wcsicmp(psap->wzAppPool, L"DefaultAppPool")) + { + //delete the app pool + hr = ScaWriteConfigID(IIS_APPPOOL); + ExitOnFailure(hr, "failed to write AppPool key."); + + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "failed to write AppPool delete action."); + + hr = ScaWriteConfigString(psap->wzName); + ExitOnFailure(hr, "failed to delete AppPool: %ls", psap->wzName); + } + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scaapppool7.h b/src/ext/Iis/ca/scaapppool7.h new file mode 100644 index 00000000..1f49d899 --- /dev/null +++ b/src/ext/Iis/ca/scaapppool7.h @@ -0,0 +1,36 @@ +#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 "scauser.h" + +// Identity +#define APATTR_NETSERVICE 0x0001 // Network Service +#define APATTR_LOCSERVICE 0x0002 // Local Service +#define APATTR_LOCSYSTEM 0x0004 // Local System +#define APATTR_OTHERUSER 0x0008 // Other User +#define APATTR_APPPOOLIDENTITY 0x0010 // ApplicationPoolIdentity + +// prototypes +HRESULT ScaFindAppPool7( + __in LPCWSTR wzAppPool, + __out_ecount(cchName) LPWSTR wzName, + __in DWORD cchName, + __in SCA_APPPOOL *psapList + ); + +HRESULT ScaAppPoolInstall7( + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaAppPoolUninstall7( + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaWriteAppPool7( + __in const SCA_APPPOOL* psap + ); + +HRESULT ScaRemoveAppPool7( + __in const SCA_APPPOOL* psap + ); diff --git a/src/ext/Iis/ca/scacert.cpp b/src/ext/Iis/ca/scacert.cpp new file mode 100644 index 00000000..5eae905a --- /dev/null +++ b/src/ext/Iis/ca/scacert.cpp @@ -0,0 +1,1482 @@ +// 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" + +// prototypes +static HRESULT ConfigureCertificates( + __in SCA_ACTION saAction + ); + +static LPCWSTR StoreMapping( + __in int iStore + ); + +static HRESULT FindExistingCertificate( + __in LPCWSTR wzName, + __in DWORD dwStoreLocation, + __in LPCWSTR wzStore, + __out BYTE** prgbCertificate, + __out DWORD* pcbCertificate + ); + +static HRESULT ResolveCertificate( + __in LPCWSTR wzId, + __in LPCWSTR wzName, + __in DWORD dwStoreLocation, + __in LPCWSTR wzStoreName, + __in DWORD dwAttributess, + __in LPCWSTR wzData, + __in LPCWSTR wzPFXPassword, + __out BYTE** ppbCertificate, + __out DWORD* pcbCertificate + ); + +static HRESULT ReadCertificateFile( + __in LPCWSTR wzPath, + __out BYTE** prgbData, + __out DWORD* pcbData + ); + +static HRESULT CertificateToHash( + __in BYTE* pbCertificate, + __in DWORD cbCertificate, + __in DWORD dwStoreLocation, + __in LPCWSTR wzPFXPassword, + __in BYTE rgbHash[], + __in DWORD cbHash + ); + +/* +HRESULT ScaGetCertificateByPath(LPCWSTR pwzName, BOOL fIsInstalling, + BOOL fIsUninstalling, INT iStore, + INT iStoreLocation, LPCWSTR wzSslCertificate, + LPCWSTR wzPFXPassword, BSTR* pbstrCertificate, + DWORD* pcbCertificate, BYTE* pbaHashBuffer); + +HRESULT ScaGetCertificateByRequest(LPCWSTR pwzName, BOOL fIsInstalling, + BOOL fIsUninstalling, INT iStore, + INT iStoreLocation, LPCWSTR wzDistinguishedName, + LPCWSTR wzCA, BSTR* pbstrCertificate, + DWORD* pcbCertificate, BYTE* pbaHashBuffer); + +HRESULT ScaSslNewCertificate(LPCWSTR pwzName, INT iStore, + INT iStoreLocation, LPCWSTR wzComputerName, + LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthorityOrig, + BSTR* pbstrCertificate, DWORD* pcbCertificate, + BYTE* pbaHashBuffer); + +HRESULT ScaSslExistingCertificateByName(LPCWSTR pwzName, INT iStore, + INT iStoreLocation, BSTR* pbstrCertificate, + DWORD* pcbCertificate, BYTE* pbaHashBuffer); + +HRESULT ScaSslExistingCertificateByBinaryData(INT iStore, INT iStoreLocation, + BYTE* pwzData, DWORD cchData); + +HRESULT CreateEnroll(ICEnroll2 **hEnroll, INT iStore, + INT iStoreLocation); + +HRESULT RequestCertificate(LPCWSTR pwzName, INT iStore, + INT iStoreLocation, LPCWSTR wzComputerName, + LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthority, + BSTR *pbstrCertificate); + +VOID ParseCertificateAuthority(__in LPCWSTR wzCertificateAuthorityOrig, __out LPWSTR *pwzBuffer, + __out LPWSTR **hwzCAArray, __out int *piCAArray); +*/ + + +LPCWSTR vcsCertQuery = L"SELECT `Certificate`, `Name`, `Component_`, `StoreLocation`, `StoreName`, `Attributes`, `Binary_`, `CertificatePath`, `PFXPassword` FROM `Certificate`"; +enum eCertQuery { cqCertificate = 1, cqName, cqComponent, cqStoreLocation, cqStoreName, cqAttributes, cqCertificateBinary, cqCertificatePath, cqPFXPassword }; + + +/******************************************************************** +InstallCertificates - CUSTOM ACTION ENTRY POINT for installing + certificates + +********************************************************************/ +extern "C" UINT __stdcall InstallCertificates( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + // initialize + hr = WcaInitialize(hInstall, "InstallCertificates"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = ConfigureCertificates(SCA_ACTION_INSTALL); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/******************************************************************** +UninstallCertificates - CUSTOM ACTION ENTRY POINT for uninstalling + certificates + +********************************************************************/ +extern "C" UINT __stdcall UninstallCertificates( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + // initialize + hr = WcaInitialize(hInstall, "UninstallCertificates"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = ConfigureCertificates(SCA_ACTION_UNINSTALL); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +static HRESULT ConfigureCertificates( + __in SCA_ACTION saAction + ) +{ + //AssertSz(FALSE, "debug ConfigureCertificates()."); + + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + + PMSIHANDLE hViewCertificate; + PMSIHANDLE hRecCertificate; + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + + WCHAR* pwzId = NULL; + WCHAR* pwzName = NULL; + WCHAR* pwzComponent = NULL; + int iData = 0; + DWORD dwStoreLocation = 0; + LPWSTR pwzStoreName = 0; + DWORD dwAttributes = 0; + WCHAR* pwzData = NULL; + WCHAR* pwzPFXPassword = NULL; + WCHAR* pwzCaData = NULL; + WCHAR* pwzRollbackCaData = NULL; + + BYTE* pbCertificate = NULL; + DWORD cbCertificate = 0; + DWORD_PTR cbPFXPassword = 0; + + // Bail quickly if the Certificate table isn't around. + if (S_OK != WcaTableExists(L"Certificate")) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ConfigureCertificates() - required table not present."); + ExitFunction1(hr = S_FALSE); + } + + // Process the Certificate table. + hr = WcaOpenExecuteView(vcsCertQuery, &hViewCertificate); + ExitOnFailure(hr, "failed to open view on Certificate table"); + + while (SUCCEEDED(hr = WcaFetchRecord(hViewCertificate, &hRecCertificate))) + { + hr = WcaGetRecordString(hRecCertificate, cqCertificate, &pwzId); // the id is just useful to have up front + ExitOnFailure(hr, "failed to get Certificate.Certificate"); + + hr = WcaGetRecordString(hRecCertificate, cqComponent, &pwzComponent); + ExitOnFailure(hr, "failed to get Certificate.Component_"); + + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to get state for component: %ls", pwzComponent); + + if (!(WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL == saAction) && + !(WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL == saAction) && + !(WcaIsReInstalling(isInstalled, isAction))) + { + WcaLog(LOGMSG_VERBOSE, "Skipping non-action certificate: %ls", pwzId); + continue; + } + + // extract the rest of the data from the Certificate table + hr = WcaGetRecordFormattedString(hRecCertificate, cqName, &pwzName); + ExitOnFailure(hr, "failed to get Certificate.Name"); + + hr = WcaGetRecordInteger(hRecCertificate, cqStoreLocation, &iData); + ExitOnFailure(hr, "failed to get Certificate.StoreLocation"); + + switch (iData) + { + case SCA_CERTSYSTEMSTORE_CURRENTUSER: + dwStoreLocation = CERT_SYSTEM_STORE_CURRENT_USER; + break; + case SCA_CERTSYSTEMSTORE_LOCALMACHINE: + dwStoreLocation = CERT_SYSTEM_STORE_LOCAL_MACHINE; + break; + default: + hr = E_INVALIDARG; + ExitOnFailure(hr, "Invalid store location value: %d", iData); + } + + hr = WcaGetRecordString(hRecCertificate, cqStoreName, &pwzStoreName); + ExitOnFailure(hr, "failed to get Certificate.StoreName"); + + hr = WcaGetRecordInteger(hRecCertificate, cqAttributes, reinterpret_cast(&dwAttributes)); + ExitOnFailure(hr, "failed to get Certificate.Attributes"); + + if (dwAttributes & SCA_CERT_ATTRIBUTE_BINARYDATA) + { + hr = WcaGetRecordString(hRecCertificate, cqCertificateBinary, &pwzData); + ExitOnFailure(hr, "failed to get Certificate.Binary_"); + } + else + { + hr = WcaGetRecordFormattedString(hRecCertificate, cqCertificatePath, &pwzData); + ExitOnFailure(hr, "failed to get Certificate.CertificatePath"); + } + + hr = WcaGetRecordFormattedString(hRecCertificate, cqPFXPassword, &pwzPFXPassword); + ExitOnFailure(hr, "failed to get Certificate.PFXPassword"); + + // Write the common data (for both install and uninstall) to the CustomActionData + // to pass data to the deferred CustomAction. + hr = StrAllocString(&pwzCaData, pwzName, 0); + ExitOnFailure(hr, "Failed to pass Certificate.Certificate to deferred CustomAction."); + hr = WcaWriteStringToCaData(pwzStoreName, &pwzCaData); + ExitOnFailure(hr, "Failed to pass Certificate.StoreName to deferred CustomAction."); + hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCaData); + ExitOnFailure(hr, "Failed to pass Certificate.Attributes to deferred CustomAction."); + + // Copy the rollback data from the deferred data because it's the same up to this point. + hr = StrAllocString(&pwzRollbackCaData, pwzCaData, 0); + ExitOnFailure(hr, "Failed to allocate string for rollback CustomAction."); + + // Finally, schedule the correct deferred CustomAction to actually do work. + LPCWSTR wzAction = NULL; + LPCWSTR wzRollbackAction = NULL; + DWORD dwCost = 0; + if (SCA_ACTION_UNINSTALL == saAction) + { + // Find an existing certificate one (if there is one) to so we have it for rollback. + hr = FindExistingCertificate(pwzName, dwStoreLocation, pwzStoreName, &pbCertificate, &cbCertificate); + ExitOnFailure(hr, "Failed to search for existing certificate with friendly name: %ls", pwzName); + + if (pbCertificate) + { + hr = WcaWriteStreamToCaData(pbCertificate, cbCertificate, &pwzRollbackCaData); + ExitOnFailure(hr, "Failed to pass Certificate.Data to rollback CustomAction."); + + hr = WcaWriteStringToCaData(pwzPFXPassword, &pwzRollbackCaData); + ExitOnFailure(hr, "Failed to pass Certificate.PFXPassword to rollback CustomAction."); + + hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCaData); + ExitOnFailure(hr, "Failed to pass Certificate.Attributes to deferred CustomAction."); + } + + // Pick the right action to run based on what store we're uninstalling from. + if (CERT_SYSTEM_STORE_LOCAL_MACHINE == dwStoreLocation) + { + wzAction = CUSTOM_ACTION_DECORATION(L"DeleteMachineCertificate"); + if (pbCertificate) + { + wzRollbackAction = L"RollbackDeleteMachineCertificate"; + } + } + else + { + wzAction = CUSTOM_ACTION_DECORATION(L"DeleteUserCertificate"); + if (pbCertificate) + { + wzRollbackAction = L"RollbackDeleteUserCertificate"; + } + } + dwCost = COST_CERT_DELETE; + } + else + { + // Actually get the certificate, resolve it to a blob, and get the blob's hash. + hr = ResolveCertificate(pwzId, pwzName, dwStoreLocation, pwzStoreName, dwAttributes, pwzData, pwzPFXPassword, &pbCertificate, &cbCertificate); + ExitOnFailure(hr, "Failed to resolve certificate: %ls", pwzId); + + hr = WcaWriteStreamToCaData(pbCertificate, cbCertificate, &pwzCaData); + ExitOnFailure(hr, "Failed to pass Certificate.Data to deferred CustomAction."); + + hr = WcaWriteStringToCaData(pwzPFXPassword, &pwzCaData); + ExitOnFailure(hr, "Failed to pass Certificate.PFXPassword to deferred CustomAction."); + + // Pick the right action to run based on what store we're installing into. + if (CERT_SYSTEM_STORE_LOCAL_MACHINE == dwStoreLocation) + { + wzAction = CUSTOM_ACTION_DECORATION(L"AddMachineCertificate"); + wzRollbackAction = CUSTOM_ACTION_DECORATION(L"RollbackAddMachineCertificate"); + } + else + { + wzAction = CUSTOM_ACTION_DECORATION(L"AddUserCertificate"); + wzRollbackAction = CUSTOM_ACTION_DECORATION(L"RollbackAddUserCertificate"); + } + dwCost = COST_CERT_ADD; + } + + if (wzRollbackAction) + { + hr = WcaDoDeferredAction(wzRollbackAction, pwzRollbackCaData, dwCost); + ExitOnFailure(hr, "Failed to schedule rollback certificate action '%ls' for: %ls", wzRollbackAction, pwzId); + } + + hr = WcaDoDeferredAction(wzAction, pwzCaData, dwCost); + ExitOnFailure(hr, "Failed to schedule certificate action '%ls' for: %ls", wzAction, pwzId); + + // Clean up for the next certificate. + ReleaseNullMem(pbCertificate); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + +LExit: + if (NULL != pwzPFXPassword && SUCCEEDED(StrSize(pwzPFXPassword, &cbPFXPassword))) + { + SecureZeroMemory(pwzPFXPassword, cbPFXPassword); + } + + ReleaseMem(pbCertificate); + ReleaseStr(pwzCaData); + ReleaseStr(pwzPFXPassword); + ReleaseStr(pwzData); + ReleaseStr(pwzName); + ReleaseStr(pwzStoreName); + ReleaseStr(pwzComponent); + ReleaseStr(pwzId); + + return hr; +} + + +static HRESULT ResolveCertificate( + __in LPCWSTR wzId, + __in LPCWSTR /*wzName*/, + __in DWORD dwStoreLocation, + __in LPCWSTR /*wzStoreName*/, + __in DWORD dwAttributes, + __in LPCWSTR wzData, + __in LPCWSTR wzPFXPassword, + __out BYTE** ppbCertificate, + __out DWORD* pcbCertificate + ) +{ + HRESULT hr = S_OK; + + LPWSTR pwzSql = NULL; + PMSIHANDLE hView; + PMSIHANDLE hRec; + MSIHANDLE hCertificateHashView = NULL; + MSIHANDLE hCertificateHashColumns = NULL; + + BYTE rgbCertificateHash[CB_CERTIFICATE_HASH] = { 0 }; + WCHAR wzEncodedCertificateHash[CB_CERTIFICATE_HASH * 2 + 1] = { 0 }; + + PMSIHANDLE hViewCertificateRequest, hRecCertificateRequest; + + WCHAR* pwzDistinguishedName = NULL; + WCHAR* pwzCA = NULL; + + BYTE* pbData = NULL; + DWORD cbData = 0; + + if (dwAttributes & SCA_CERT_ATTRIBUTE_REQUEST) + { + hr = E_NOTIMPL; + ExitOnFailure(hr, "Installing certificates by requesting them from a certificate authority is not currently supported"); + //if (dwAttributes & SCA_CERT_ATTRIBUTE_OVERWRITE) + //{ + // // try to overwrite with the patch to a cert file + // WcaLog(LOGMSG_VERBOSE, "ConfigureCertificates - Overwrite with SSLCERTIFICATE"); + // hr = ScaGetCertificateByPath(pwzName, fIsInstalling, fIsUninstalling, + // iStore, iStoreLocation, pwzData, wzPFXPassword, pbstrCertificate, pcbCertificate, pbaHashBuffer); + //} + //if (hr != S_OK) + //{ + // if (fIsUninstalling && !fIsInstalling) + // { + // // for uninstall, we just want to find the existing certificate + // hr = ScaSslExistingCertificateByName(pwzName, iStore, iStoreLocation, pbstrCertificate, pcbCertificate, pbaHashBuffer); + // ExitOnFailure(hr, "Failed Retrieving existing certificate during uninstall"); + // // ok if no existing cert + // if (S_OK != hr) + // hr = S_OK; + // } + // else + // { + // // still no certificate + // // user has request this certificate, try to locate DistinguishedName and CA + // hr = WcaTableExists(L"CertificateRequest"); + // ExitOnFailure(hr, "CertificateRequest is referenced but not found"); + // WcaLog(LOGMSG_VERBOSE, "ConfigureCertificates - CertificateRequest table present"); + // cchSQLView = 255 + lstrlenW(pwzName); + // pwzSQLView = new WCHAR[cchSQLView]; + // if (pwzSQLView) + // { + // hr = ::StringCchPrintfW(pwzSQLView, cchSQLView, L"SELECT `DistinguishedName`, `CA` FROM `CertificateRequest` WHERE `Certificate_`=\'%s\'", pwzName); + // ExitOnFailure(hr, "::StringCchPrintfW failed"); + // hr = WcaOpenExecuteView(pwzSQLView, &hViewCertificateRequest); + // ExitOnFailure(hr, "failed to open view on CertificateRequest table"); + // hr = WcaFetchSingleRecord(hViewCertificateRequest, &hRecCertificateRequest); + // ExitOnFailure(hr, "failed to retrieve request from CertificateRequest table"); + // hr = WcaGetRecordString(hRecCertificateRequest, 1, &pwzDistinguishedName); + // ExitOnFailure(hr, "failed to get DistinguishedName"); + // hr = WcaGetRecordString(hRecCertificateRequest, 2, &pwzCA); + // ExitOnFailure(hr, "failed to get CA"); + // if (pwzDistinguishedName && pwzCA && *pwzDistinguishedName && *pwzCA) + // { + // hr = ScaGetCertificateByRequest(pwzName, fIsInstalling, fIsUninstalling, iStore, iStoreLocation, pwzDistinguishedName, pwzCA, pbstrCertificate, pcbCertificate, pbaHashBuffer); + // } + // else + // { + // hr = E_FAIL; + // ExitOnFailure(hr, "CertificateRequest entry is empty"); + // } + // } + // else + // { + // hr = E_FAIL; + // ExitOnFailure(hr, "Out of memory"); + // } + // } + //} + } + else if (dwAttributes & SCA_CERT_ATTRIBUTE_BINARYDATA) + { + // get the binary stream in Binary + hr = WcaTableExists(L"Binary"); + if (S_OK != hr) + { + if (SUCCEEDED(hr)) + { + hr = E_UNEXPECTED; + } + ExitOnFailure(hr, "Binary was referenced but there is no Binary table."); + } + + hr = StrAllocFormatted(&pwzSql, L"SELECT `Data` FROM `Binary` WHERE `Name`=\'%s\'", wzData); + ExitOnFailure(hr, "Failed to allocate Binary table query."); + + hr = WcaOpenExecuteView(pwzSql, &hView); + ExitOnFailure(hr, "Failed to open view on Binary table"); + + hr = WcaFetchSingleRecord(hView, &hRec); + ExitOnFailure(hr, "Failed to retrieve request from Binary table"); + + hr = WcaGetRecordStream(hRec, 1, &pbData, &cbData); + ExitOnFailure(hr, "Failed to ready Binary.Data for certificate."); + } + else if (dwAttributes == SCA_CERT_ATTRIBUTE_DEFAULT) + { + hr = ReadCertificateFile(wzData, &pbData, &cbData); + ExitOnFailure(hr, "Failed to read certificate from file path."); + } + else + { + hr = E_INVALIDARG; + ExitOnFailure(hr, "Invalid Certificate.Attributes."); + } + + // If we have loaded a certificate, update the Certificate.Hash column. + if (pbData) + { + hr = CertificateToHash(pbData, cbData, dwStoreLocation, wzPFXPassword, rgbCertificateHash, countof(rgbCertificateHash)); + ExitOnFailure(hr, "Failed to get SHA1 hash of certificate."); + + hr = StrHexEncode(rgbCertificateHash, countof(rgbCertificateHash), wzEncodedCertificateHash, countof(wzEncodedCertificateHash)); + ExitOnFailure(hr, "Failed to hex encode SHA1 hash of certificate."); + + // Update the CertificateHash table. + hr = WcaAddTempRecord(&hCertificateHashView, &hCertificateHashColumns, L"CertificateHash", NULL, 0, 2, wzId, wzEncodedCertificateHash); + ExitOnFailure(hr, "Failed to add encoded has for certificate: %ls", wzId); + } + + *ppbCertificate = pbData; + *pcbCertificate = cbData; + pbData = NULL; + +LExit: + if (hCertificateHashColumns) + { + ::MsiCloseHandle(hCertificateHashColumns); + } + + if (hCertificateHashView) + { + ::MsiCloseHandle(hCertificateHashView); + } + + ReleaseStr(pwzDistinguishedName); + ReleaseStr(pwzCA); + ReleaseMem(pbData); + ReleaseStr(pwzSql); + + return hr; +} + + +static HRESULT ReadCertificateFile( + __in LPCWSTR wzPath, + __out BYTE** prgbData, + __out DWORD* pcbData + ) +{ + HRESULT hr = S_OK; + + PCCERT_CONTEXT pCertContext = NULL; + DWORD dwContentType; + BYTE* pbData = NULL; + DWORD cbData = 0; + + if (!::CryptQueryObject(CERT_QUERY_OBJECT_FILE, reinterpret_cast(wzPath), CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &dwContentType, NULL, NULL, NULL, (LPCVOID*)&pCertContext)) + { + ExitOnFailure(hr, "Failed to read certificate from file: %ls", wzPath); + } + + if (pCertContext) + { + cbData = pCertContext->cbCertEncoded; + pbData = static_cast(MemAlloc(cbData, FALSE)); + ExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to allocate memory to read certificate from file: %ls", wzPath); + + CopyMemory(pbData, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded); + } + else + { + // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. + if (dwContentType & CERT_QUERY_CONTENT_PFX) + { + hr = FileRead(&pbData, &cbData, wzPath); + ExitOnFailure(hr, "Failed to read PFX file: %ls", wzPath); + } + else + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Unexpected certificate type read from disk."); + } + } + + *pcbData = cbData; + *prgbData = pbData; + pbData = NULL; + +LExit: + ReleaseMem(pbData); + return hr; +} + + +static HRESULT CertificateToHash( + __in BYTE* pbCertificate, + __in DWORD cbCertificate, + __in DWORD dwStoreLocation, + __in LPCWSTR wzPFXPassword, + __in BYTE rgbHash[], + __in DWORD cbHash + ) +{ + HRESULT hr = S_OK; + + HCERTSTORE hPfxCertStore = NULL; + PCCERT_CONTEXT pCertContext = NULL; + PCCERT_CONTEXT pCertContextEnum = NULL; + CRYPT_DATA_BLOB blob = { 0 }; + CRYPT_KEY_PROV_INFO* pPfxInfo = NULL; + DWORD dwKeyset = (CERT_SYSTEM_STORE_CURRENT_USER == dwStoreLocation) ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; + DWORD dwEncodingType; + DWORD dwContentType; + DWORD dwFormatType; + + blob.pbData = pbCertificate; + blob.cbData = cbCertificate; + + if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) + { + ExitWithLastError(hr, "Failed to process certificate as a valid certificate."); + } + + if (!pCertContext) + { + // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. + if (dwContentType & CERT_QUERY_CONTENT_PFX) + { + // If we fail and our password is blank, also try passing in NULL for the password (according to the docs) + hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, dwKeyset); + if (NULL == hPfxCertStore && !*wzPFXPassword) + { + hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, NULL, dwKeyset); + } + ExitOnNullWithLastError(hPfxCertStore, hr, "Failed to open PFX file."); + + // Find the first cert with a private key, or just use the last one + for (pCertContextEnum = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContextEnum); + pCertContextEnum; + pCertContextEnum = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContextEnum)) + { + pCertContext = pCertContextEnum; + + if (pCertContext && CertHasPrivateKey(pCertContext, NULL)) + { + break; + } + } + + ExitOnNullWithLastError(pCertContext, hr, "Failed to read first certificate out of PFX file."); + + // Ignore failures, the worst that happens is some parts of the PFX get left behind. + CertReadProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, &pPfxInfo, NULL); + } + else + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Unexpected certificate type processed."); + } + } + + DWORD cb = cbHash; + if (!::CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, static_cast(rgbHash), &cb)) + { + ExitWithLastError(hr, "Failed to get certificate SHA1 hash property."); + } + AssertSz(cb == cbHash, "Did not correctly read certificate SHA1 hash."); + +LExit: + if (pCertContext) + { + ::CertFreeCertificateContext(pCertContext); + } + + if (hPfxCertStore) + { + ::CertCloseStore(hPfxCertStore, 0); + } + + if (pPfxInfo) + { + HCRYPTPROV hProvIgnored = NULL; // ignored on deletes. + ::CryptAcquireContextW(&hProvIgnored, pPfxInfo->pwszContainerName, pPfxInfo->pwszProvName, pPfxInfo->dwProvType, dwKeyset | CRYPT_DELETEKEYSET | CRYPT_SILENT); + + MemFree(pPfxInfo); + } + + return hr; +} + + +static HRESULT FindExistingCertificate( + __in LPCWSTR wzName, + __in DWORD dwStoreLocation, + __in LPCWSTR wzStore, + __out BYTE** prgbCertificate, + __out DWORD* pcbCertificate + ) +{ + HRESULT hr = S_OK; + HCERTSTORE hCertStore = NULL; + PCCERT_CONTEXT pCertContext = NULL; + BYTE* pbCertificate = NULL; + DWORD cbCertificate = 0; + + hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation | CERT_STORE_READONLY_FLAG, wzStore); + MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store."); + + // Loop through the certificate, looking for certificates that match our friendly name. + pCertContext = CertFindCertificateInStore(hCertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL); + while (pCertContext) + { + WCHAR wzFriendlyName[256] = { 0 }; + DWORD cbFriendlyName = sizeof(wzFriendlyName); + + if (::CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, reinterpret_cast(wzFriendlyName), &cbFriendlyName) && + CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, wzName, -1, wzFriendlyName, -1)) + { + // If the certificate with matching friendly name is valid, let's use that. + long lVerify = ::CertVerifyTimeValidity(NULL, pCertContext->pCertInfo); + if (0 == lVerify) + { + cbCertificate = pCertContext->cbCertEncoded; + pbCertificate = static_cast(MemAlloc(cbCertificate, FALSE)); + ExitOnNull(pbCertificate, hr, E_OUTOFMEMORY, "Failed to allocate memory to copy out exist certificate."); + + CopyMemory(pbCertificate, pCertContext->pbCertEncoded, cbCertificate); + break; // found a matching certificate, no more searching necessary + } + } + + // Next certificate in the store. + PCCERT_CONTEXT pNext = ::CertFindCertificateInStore(hCertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pCertContext); + // old pCertContext is freed by CertFindCertificateInStore + pCertContext = pNext; + } + + *prgbCertificate = pbCertificate; + *pcbCertificate = cbCertificate; + pbCertificate = NULL; + +LExit: + ReleaseMem(pbCertificate); + + if (pCertContext) + { + ::CertFreeCertificateContext(pCertContext); + } + + if (hCertStore) + { + ::CertCloseStore(hCertStore, 0); + } + + return hr; +} + +/* +HRESULT CreateEnroll(ICEnroll2 **hEnroll, INT iStore, INT iStoreLocation) +{ + ICEnroll2 *pEnroll = NULL; + HRESULT hr = S_OK; + LONG lFlags; + DWORD dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; + + // create IEntroll + hr = CoCreateInstance( CLSID_CEnroll, NULL, CLSCTX_INPROC_SERVER, IID_ICEnroll2, (void **)&pEnroll ); + if (FAILED(hr)) + return hr; + + switch (iStore) + { + case SCA_CERT_STORENAME_MY: + pEnroll->get_MyStoreFlags(&lFlags); + lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; + lFlags |= dwFlags; + // following call will change Request store flags also + pEnroll->put_MyStoreFlags(lFlags); + break; + case SCA_CERT_STORENAME_CA: + pEnroll->get_CAStoreFlags(&lFlags); + lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; + lFlags |= dwFlags; + // following call will change Request store flags also + pEnroll->put_CAStoreFlags(lFlags); + break; + case SCA_CERT_STORENAME_REQUEST: + pEnroll->get_RequestStoreFlags(&lFlags); + lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; + lFlags |= dwFlags; + // following call will change Request store flags also + pEnroll->put_RequestStoreFlags(lFlags); + break; + case SCA_CERT_STORENAME_ROOT: + pEnroll->get_RootStoreFlags(&lFlags); + lFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK; + lFlags |= dwFlags; + // following call will change Request store flags also + pEnroll->put_RootStoreFlags(lFlags); + break; + default: + hr = E_FAIL; + return hr; + } + + pEnroll->get_GenKeyFlags(&lFlags); + lFlags |= CRYPT_EXPORTABLE; + pEnroll->put_GenKeyFlags(lFlags); + + pEnroll->put_KeySpec(AT_KEYEXCHANGE); + pEnroll->put_ProviderType(PROV_RSA_SCHANNEL); + pEnroll->put_DeleteRequestCert(TRUE); + + *hEnroll = pEnroll; + return hr; +} + + +HRESULT RequestCertificate(LPCWSTR pwzName, INT iStore, INT iStoreLocation, + LPCWSTR wzComputerName, LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthority, + BSTR *pbstrCertificate) +{ + if (pbstrCertificate == NULL) + return E_INVALIDARG; + + HRESULT hr; + ICEnroll2 *pEnroll = NULL; + ICertRequest *pCertRequest = NULL; + BSTR bstrRequest = NULL; + LONG nDisposition; + + BSTR bstrCertificateUsage = NULL; + BSTR bstrCertificateAttributes = NULL; + BSTR bstrCertificateAuthority = NULL; + + // equivalent to: sprintf(bstrDistinguishedName, L"%s,CN=%s", wzDistinguishedName, wzComputerName); + DWORD cchComputerName = lstrlenW(wzComputerName); + DWORD cchDistinguishedName = lstrlenW(wzDistinguishedName); + CONST DWORD cchbstrDistinguishedName = 5 + cchComputerName + cchDistinguishedName; + BSTR bstrDistinguishedName = SysAllocStringLen(NULL, cchbstrDistinguishedName); + ExitOnNull(bstrDistinguishedName, hr, E_OUTOFMEMORY, "Failed to allocate space for distinguished name."); + ::StringCchCopyW((WCHAR*) bstrDistinguishedName, cchbstrDistinguishedName, wzDistinguishedName); + ::StringCchCatW((WCHAR*) bstrDistinguishedName, cchbstrDistinguishedName, L",CN="); + ::StringCchCatW((WCHAR*) bstrDistinguishedName, cchbstrDistinguishedName, wzComputerName); + + bstrCertificateUsage = SysAllocString(WIDE(szOID_PKIX_KP_SERVER_AUTH)); + ExitOnNull(bstrCertificateUsage, hr, E_OUTOFMEMORY, "Failed to allocate space for Certificate Usage."); + bstrCertificateAttributes = SysAllocString(L"CertificateTemplate:WebServer"); + bstrCertificateAuthority = SysAllocString(wzCertificateAuthority); + ExitOnNull(bstrCertificateAuthority, hr, E_OUTOFMEMORY, "Failed to allocate space for Certificate Authority."); + + hr = CreateEnroll(&pEnroll, iStore, iStoreLocation); + ExitOnFailure(hr, "failed CoCreateInstance IEnroll"); + + hr = pEnroll->createPKCS10(bstrDistinguishedName, bstrCertificateUsage, &bstrRequest); + ExitOnFailure(hr, "failed createPKCS10"); + + hr = CoCreateInstance(CLSID_CCertRequest, NULL, CLSCTX_INPROC_SERVER, IID_ICertRequest, (void **)&pCertRequest); + ExitOnFailure(hr, "failed CoCreateInstance ICertRequest"); + + hr = pCertRequest->Submit(CR_IN_BASE64 | CR_IN_PKCS10, bstrRequest, bstrCertificateAttributes, bstrCertificateAuthority, &nDisposition); + ExitOnFailure(hr, "failed ICertRequest.Submit"); + + hr = (nDisposition == CR_DISP_ISSUED) ? S_OK : E_FAIL; + ExitOnFailure(hr, "failed CR_DISP_ISSUED"); + + hr = pCertRequest->GetCertificate(CR_OUT_BASE64, pbstrCertificate); + ExitOnFailure(hr, "failed ICertRequest.GetCertificate"); + + // save the certificate in place, cannot be passed to a deferred custom action + hr = pEnroll->acceptPKCS7(*pbstrCertificate); + ExitOnFailure(hr, "failed accept certificate into MY store"); + +LExit: + ReleaseObject(pCertRequest); + ReleaseBSTR(bstrRequest); + ReleaseObject(pEnroll); + ReleaseBSTR(bstrCertificateAuthority); + ReleaseBSTR(bstrCertificateAttributes); + ReleaseBSTR(bstrDistinguishedName); + + return hr; +} + + +VOID ParseCertificateAuthority(__in LPCWSTR wzCertificateAuthorityOrig, __out LPWSTR *pwzBuffer, __out LPWSTR **hwzCAArray, __out int *piCAArray) +{ + // @asAuthorities = split /;/, $sAuthority; + CONST WCHAR wchDelimiter = L';'; + + // copy constant into a buffer + Assert(wzCertificateAuthorityOrig); + + INT cchCA = lstrlenW(wzCertificateAuthorityOrig) + 1; + WCHAR* wzBuffer = new WCHAR[cchCA]; + if (!wzBuffer) + return; + + ::StringCchCopyW(wzBuffer, cchCA, wzCertificateAuthorityOrig); + + // determine the number of strings in the field + int iCAArray = 1; + int i; + for (i = 0; i < cchCA; ++i) + { + if (wzBuffer[i] == wchDelimiter) + ++iCAArray; + } + LPWSTR *pwzCAArray = (LPWSTR*) new BYTE[iCAArray * sizeof(LPWSTR)]; + if (!pwzCAArray) + { + return; + } + + pwzCAArray[0] = wzBuffer; + iCAArray = 0; + for (i = 0; i < cchCA; ++i) + { + if (wzBuffer[i] != wchDelimiter) + continue; + wzBuffer[i] = 0; // convert buffer into MULTISZ + pwzCAArray[iCAArray] = &wzBuffer[i+1]; + ++iCAArray; + } + + *pwzBuffer = wzBuffer; + *hwzCAArray = pwzCAArray; + *piCAArray = iCAArray; +} + + +HRESULT ScaSslExistingCertificateByBinaryData(INT iStore, INT iStoreLocation, BYTE* pwzData, DWORD cchData) +{ + HRESULT hr = S_FALSE; + HCERTSTORE hCertStore = NULL; + PCCERT_CONTEXT pCertCtx = NULL, pCertCtxExisting = NULL; + DWORD dwFlags = 0; + LPCWSTR wzStore = StoreMapping(iStore); + CERT_BLOB blob; + + dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; + hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwFlags, wzStore); + MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "failed to open certificate store, OK on uninstall"); + + blob.pbData = pwzData; + blob.cbData = cchData; + + if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, + 0, NULL, NULL, NULL, NULL, NULL, (LPCVOID*)&pCertCtx)) + ExitOnLastError(hr, "failed to parse the certificate blob, OK on uninstall"); + + pCertCtxExisting = CertFindCertificateInStore( + hCertStore, + PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, + 0, + CERT_FIND_EXISTING, + pCertCtx, + NULL); + + if (pCertCtxExisting) + { + hr = S_OK; + } + +LExit: + if (pCertCtx) + { + CertFreeCertificateContext(pCertCtx); + pCertCtx = NULL; + } + if (pCertCtxExisting) + { + CertFreeCertificateContext(pCertCtxExisting); + pCertCtxExisting = NULL; + } + if (hCertStore) + { + CertCloseStore(hCertStore, 0); + hCertStore = NULL; + } + + return hr; +} + + +HRESULT ScaSslExistingCertificateByName(LPCWSTR pwzName, INT iStore, INT iStoreLocation, + BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) +{ + HRESULT hr = S_FALSE; + HCERTSTORE hSystemStore = NULL; + PCCERT_CONTEXT pTargetCert = NULL; + WCHAR wzFriendlyName[MAX_PATH] = {0}; + DWORD dwFriendlyNameLen = sizeof(wzFriendlyName); + + // Call CertOpenStore to open the CA store. + hSystemStore = CertOpenStore( + CERT_STORE_PROV_SYSTEM_REGISTRY, + 0, + NULL, + (iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT) | CERT_STORE_OPEN_EXISTING_FLAG, + StoreMapping(iStore)); + if (hSystemStore == NULL) + ExitFunction(); + + // Get a particular certificate using CertFindCertificateInStore. + pTargetCert = CertFindCertificateInStore( + hSystemStore, + PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, + 0, + CERT_FIND_ANY, + NULL, + NULL); + while (pTargetCert != NULL) + { + if ((CertGetCertificateContextProperty(pTargetCert, CERT_FRIENDLY_NAME_PROP_ID, + (BYTE*)wzFriendlyName, &dwFriendlyNameLen)) && + lstrcmpW(wzFriendlyName, pwzName) == 0) + { + // pTargetCert is a pointer to the desired certificate. + // Check the certificate's validity. + switch (CertVerifyTimeValidity( + NULL, + pTargetCert->pCertInfo)) + { + case 1: + // Certificate is expired + WcaLog(LOGMSG_STANDARD, "The SSL certificate has expired"); + // always remove it + { + PCCERT_CONTEXT pDupCertContext = CertDuplicateCertificateContext(pTargetCert); + if (pDupCertContext && CertDeleteCertificateFromStore(pDupCertContext)) + { + WcaLog(LOGMSG_STANDARD, "A SSL certificate has removed"); + } + } + break; + case 0: + // Certificate is valid + WcaLog(LOGMSG_STANDARD, "The SSL certificate is valid"); + hr = S_OK; + if (pbaHashBuffer) + { + // if the certificate already exists and is valid, use that one + DWORD dwHashSize = CB_CERTIFICATE_HASH; + hr = CertGetCertificateContextProperty(pTargetCert, CERT_SHA1_HASH_PROP_ID, (VOID*)pbaHashBuffer, &dwHashSize) + ? S_OK : E_FAIL; + ExitOnFailure(hr, "failed CertGetCertificateContextProperty CERT_SHA1_HASH_PROP_ID"); + Assert(pbstrCertificate); + Assert(pcbCertificate); + ReleaseBSTR(*pbstrCertificate); + + *pbstrCertificate = SysAllocStringByteLen((LPCSTR)(pTargetCert->pbCertEncoded), pTargetCert->cbCertEncoded); + *pcbCertificate = pTargetCert->cbCertEncoded; + } + ExitFunction(); + break; + default: + // Certificate not valid yet, ignore it + WcaLog(LOGMSG_STANDARD, "The SSL certificate is not valid"); + break; + } + } + pTargetCert = CertFindCertificateInStore( + hSystemStore, + PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, + 0, + CERT_FIND_ANY, + NULL, + pTargetCert); + wzFriendlyName[0] = 0; + dwFriendlyNameLen = sizeof(wzFriendlyName); + } + +LExit: + // Clean up memory and quit. + if (pTargetCert) + { + CertFreeCertificateContext(pTargetCert); + pTargetCert = NULL; + } + if (hSystemStore) + { + CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG); + hSystemStore = NULL; + } + + return hr; +} + + +HRESULT ScaSslNewCertificate(LPCWSTR pwzName, INT iStore, INT iStoreLocation, LPCWSTR wzComputerName, LPCWSTR wzDistinguishedName, LPCWSTR wzCertificateAuthorityOrig, + BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) +{ + + if (pbstrCertificate == NULL) + return E_INVALIDARG; + + HRESULT hr = S_OK; + LPWSTR wzCABuffer = NULL; + LPWSTR *wzCAArray = NULL; + int iCAArray = 0; + + // otherwise call the CA for one + ParseCertificateAuthority(wzCertificateAuthorityOrig, &wzCABuffer, &wzCAArray, &iCAArray); + + // try each authority three times + for (int i = 0; i < 3 * iCAArray; ++i) + { + LPCWSTR wzCA = wzCAArray[i % iCAArray]; + if (NULL == wzCA || NULL == wzCA[0]) continue; + WcaLog(LOGMSG_STANDARD, "Requesting SSL certificate from %ls", wzCA); + hr = RequestCertificate(pwzName, iStore, iStoreLocation, wzComputerName, wzDistinguishedName, wzCA, pbstrCertificate); + if (hr == S_OK && pbstrCertificate) + { + // set the friendly name + CRYPT_HASH_BLOB hblob; + CERT_BLOB blob; + HCERTSTORE hCertStore = NULL; + PCCERT_CONTEXT pCertCtxExisting = NULL; + + blob.pbData = (BYTE*)pwzName; + blob.cbData = (lstrlenW(pwzName) + 1) * sizeof(pwzName[0]); // including terminating null + + *pcbCertificate = SysStringByteLen(*pbstrCertificate); + hr = CertificateToHash(*pbstrCertificate, pbaHashBuffer); + ExitOnFailure(hr, "failed to CertificateToHash for an existing certificate"); + + hblob.pbData = pbaHashBuffer; + hblob.cbData = CB_CERTIFICATE_HASH; + + hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, (iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT), StoreMapping(iStore)); + MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "failed to open certificate store"); + + pCertCtxExisting = CertFindCertificateInStore( + hCertStore, + PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, + 0, + CERT_FIND_HASH, + &hblob, + NULL); + + if (pCertCtxExisting) + { + CertSetCertificateContextProperty( + pCertCtxExisting, + CERT_FRIENDLY_NAME_PROP_ID, + 0, + &blob); + } + + if (pCertCtxExisting) + { + CertFreeCertificateContext(pCertCtxExisting); + pCertCtxExisting = NULL; + } + if (hCertStore) + { + CertCloseStore(hCertStore, 0); + hCertStore = NULL; + } + ExitFunction(); + } + if (pbstrCertificate && *pbstrCertificate) + { + SysFreeString(*pbstrCertificate); + pbstrCertificate = NULL; + } + } + hr = E_FAIL; + ExitOnFailure(hr, "failed to RequestCertificate"); + +LExit: + if (wzCABuffer) + { + delete wzCABuffer; + } + if (wzCAArray) + { + delete wzCAArray; + } + + return hr; +} + + +HRESULT ScaGetCertificateByRequest(LPCWSTR pwzName, BOOL fIsInstalling, BOOL fIsUninstalling, + INT iStore, INT iStoreLocation, + LPCWSTR wzDistinguishedName, LPCWSTR wzCA, + BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) +{ + HRESULT hr = S_OK; + WCHAR wzComputerName[MAX_COMPUTER_NAME] = {0}; + WCHAR* pwzData = NULL; + DWORD cchData = 0; + + // override %COMPUTERNAME% with DOMAINNAME property + hr = WcaGetProperty( L"DOMAINNAME", &pwzData); + ExitOnFailure(hr, "Failed to get Property DOMAINNAME"); + if (*pwzData) + { + // if DOMAINNAME is set, use it + ::StringCchCopyW(wzComputerName, MAX_COMPUTER_NAME, pwzData); + } + else + { + // otherwise get the intranet name given by %COMPUTERNAME% + GetEnvironmentVariableW(L"COMPUTERNAME", wzComputerName, MAX_COMPUTER_NAME); + } + + hr = ScaSslExistingCertificateByName(pwzName, iStore, iStoreLocation, pbstrCertificate, pcbCertificate, pbaHashBuffer); + ExitOnFailure(hr, "Failed ScaSslExistingCertificateByName"); + if (S_OK != hr) + { + if (!fIsUninstalling && fIsInstalling) + { + // if no existing cert and not on uninstall, hit the authority + WcaLog(LOGMSG_STANDARD, "Adding certificate: requested, %ls", wzDistinguishedName); + hr = ScaSslNewCertificate(pwzName, iStore, iStoreLocation, wzComputerName, wzDistinguishedName, wzCA, + pbstrCertificate, pcbCertificate, pbaHashBuffer); + ExitOnFailure(hr, "Failed ScaSslNewCertificate"); + } + else + { + // if no existing cert and uninstall + hr = S_OK; + } + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaInstallCertificateByContext(LPCWSTR pwzName, INT iStore, INT iStoreLocation, + PCCERT_CONTEXT pCertContext) +{ + HRESULT hr = S_OK; + HCERTSTORE hCertStore = NULL; + DWORD dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; + CERT_BLOB blob; + + hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwFlags, StoreMapping(iStore)); + if (hCertStore == NULL) + MessageExitOnLastError(hr, msierrCERTFailedOpen, "failed to open certificate store"); + + blob.pbData = (BYTE*)pwzName; + blob.cbData = (lstrlenW(pwzName) + 1) * sizeof(pwzName[0]); // including terminating null + CertSetCertificateContextProperty( + pCertContext, + CERT_FRIENDLY_NAME_PROP_ID, + 0, + &blob); + + if (!CertAddCertificateContextToStore( + hCertStore, + pCertContext, + CERT_STORE_ADD_REPLACE_EXISTING, + NULL)) + { + hr = E_FAIL; + MessageExitOnLastError(hr, msierrCERTFailedAdd, "failed to add certificate to the store"); + } + +LExit: + if (hCertStore) + { + CertCloseStore(hCertStore, 0); + hCertStore = NULL; + } + + return hr; +} + + +HRESULT ScaGetCertificateByPath(LPCWSTR pwzName, BOOL fIsInstalling, BOOL fIsUninstalling, + INT iStore, INT iStoreLocation, LPCWSTR wzSslCertificate, LPCWSTR wzPFXPassword, + BSTR* pbstrCertificate, DWORD* pcbCertificate, BYTE* pbaHashBuffer) +{ + Assert(wzSslCertificate); + HRESULT hr = S_OK; + PCCERT_CONTEXT pCertContext = NULL; + DWORD dwEncodingType = 0; + DWORD dwContentType = 0; + DWORD dwFormatType = 0; + DWORD dwHashSize = CB_CERTIFICATE_HASH; + HANDLE hPfxFile = INVALID_HANDLE_VALUE; + CRYPT_DATA_BLOB blob; + + blob.pbData = NULL; + blob.cbData = 0; + + if (wzSslCertificate && wzSslCertificate[0] != 0) + { + if (!::CryptQueryObject(CERT_QUERY_OBJECT_FILE, (LPVOID)wzSslCertificate, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, + 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) + hr = fIsUninstalling ? S_FALSE : HRESULT_FROM_WIN32(::GetLastError()); // don't fail on uninstall + ExitOnFailure(hr, "failed CryptQueryObject"); + } + else + { + hr = S_FALSE; + ExitFunction(); + } + + if (!pCertContext) + { + // this is a pfx? + // make sure to exit this block of code properly for clean up blob.pbData + if (dwContentType & CERT_QUERY_CONTENT_PFX) + { + DWORD iSize = 0, iReadSize = 0; + HCERTSTORE hPfxCertStore = NULL; + + hPfxFile = ::CreateFileW(wzSslCertificate, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + hr = (hPfxFile != INVALID_HANDLE_VALUE) ? S_OK : E_FAIL; + ExitOnFailure(hr, "failed CryptQueryObject, file handle is null"); + iSize = ::GetFileSize(hPfxFile, NULL); + hr = (iSize > 0) ? S_OK : E_FAIL; + ExitOnFailure(hr, "failed CryptQueryObject, file size is 0"); + blob.pbData = new BYTE[iSize]; + blob.cbData = iSize; + hr = (blob.pbData) ? S_OK : E_FAIL; + ExitOnFailure(hr, "out of memory for blob"); + + if (::ReadFile(hPfxFile, (LPVOID)blob.pbData, iSize, &iReadSize, NULL)) + { + hPfxCertStore = PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, + (iStoreLocation == SCA_CERTSYSTEMSTORE_CURRENTUSER) ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET); + if (hPfxCertStore) + { + pCertContext = CertEnumCertificatesInStore(hPfxCertStore, NULL); + // work only with the first certificate in pfx + if (pCertContext) + { + hr = CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, (VOID*)pbaHashBuffer, &dwHashSize) + ? S_OK : E_FAIL; + ExitOnFailure(hr, "failed CertGetCertificateContextProperty CERT_SHA1_HASH_PROP_ID"); + ReleaseBSTR(*pbstrCertificate); + + *pbstrCertificate = SysAllocStringByteLen((LPCSTR)(pCertContext->pbCertEncoded), pCertContext->cbCertEncoded); + *pcbCertificate = pCertContext->cbCertEncoded; + if (fIsInstalling) + { + // install the certificate, cannot defer because the data required cannot be passed + hr = ScaInstallCertificateByContext(pwzName, iStore, iStoreLocation, pCertContext); + } + } + else + hr = E_FAIL; + } + else + hr = E_FAIL; + } + else + hr = E_FAIL; + } + else + { + ExitOnFailure(hr = E_FAIL, "failed CryptQueryObject, unknown data"); + } + } + else + { + // return cert and its hash + hr = CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, (VOID*)pbaHashBuffer, &dwHashSize) + ? S_OK : E_FAIL; + ExitOnFailure(hr, "failed CertGetCertificateContextProperty CERT_SHA1_HASH_PROP_ID"); + ReleaseBSTR(*pbstrCertificate); + + *pbstrCertificate = SysAllocStringByteLen((LPCSTR)(pCertContext->pbCertEncoded), pCertContext->cbCertEncoded); + *pcbCertificate = pCertContext->cbCertEncoded; + if (fIsInstalling) + { + // install the certificate, cannot defer because the data required cannot be passed + hr = ScaInstallCertificateByContext(pwzName, iStore, iStoreLocation, pCertContext); + } + } + +LExit: + if (pCertContext) + { + CertFreeCertificateContext(pCertContext); + pCertContext = NULL; + } + if (hPfxFile != INVALID_HANDLE_VALUE) + { + CloseHandle(hPfxFile); + hPfxFile = INVALID_HANDLE_VALUE; + } + if (blob.pbData) + { + delete [] blob.pbData; + blob.pbData = NULL; + blob.cbData = 0; + } + + return hr; +} + + +HRESULT ScaInstallCertificateByBinaryData(BOOL fAddCert, INT iStore, INT iStoreLocation, LPCWSTR wzName, BYTE* pwzData, DWORD cchData, + LPCWSTR wzPFXPassword) +{ + Assert(wzName); + Assert(pwzData); + Assert(cchData); + HRESULT hr = S_OK; + HCERTSTORE hCertStore = NULL, hPfxCertStore = NULL; + PCCERT_CONTEXT pCertCtx = NULL, pCertCtxExisting = NULL; + DWORD dwFlags, dwEncodingType, dwContentType, dwFormatType; + CERT_BLOB blob; + LPCWSTR wzStore = StoreMapping(iStore); + + dwFlags = iStoreLocation << CERT_SYSTEM_STORE_LOCATION_SHIFT; + hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwFlags, wzStore); + MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "failed to open certificate store"); + + blob.pbData = pwzData; + blob.cbData = cchData; + + if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, + 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertCtx)) + ExitOnLastError(hr, "failed to parse the certificate blob"); + ExitOnNull(pCertCtx, hr, E_UNEXPECTED, "failed to parse the certificate blob"); + + blob.pbData = (BYTE*)wzName; + blob.cbData = (lstrlenW(wzName) + 1) * sizeof(wzName[0]); // including terminating null + + CertSetCertificateContextProperty( + pCertCtx, + CERT_FRIENDLY_NAME_PROP_ID, + 0, + &blob); + + if (fAddCert) + { + // Add + WcaLog(LOGMSG_STANDARD, "Adding certificate: binary name, %ls", wzName); + if (!CertAddCertificateContextToStore( + hCertStore, + pCertCtx, + CERT_STORE_ADD_REPLACE_EXISTING, + NULL)) + { + hr = E_FAIL; + MessageExitOnLastError(hr, msierrCERTFailedAdd, "failed to add certificate to the store"); + } + } + else + { + // Delete + WcaLog(LOGMSG_STANDARD, "Deleting certificate provided: binary name, %ls", wzName); + pCertCtxExisting = CertFindCertificateInStore( + hCertStore, + PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, + 0, + CERT_FIND_EXISTING, + pCertCtx, + NULL); + + if (pCertCtxExisting) + { + if (!CertDeleteCertificateFromStore(pCertCtxExisting)) + { + ExitOnLastError(hr, "failed to delete certificate"); + } + else + { + pCertCtxExisting = NULL; + } + } + } + +LExit: + if (pCertCtx) + { + CertFreeCertificateContext(pCertCtx); + pCertCtx = NULL; + } + if (pCertCtxExisting) + { + CertFreeCertificateContext(pCertCtxExisting); + pCertCtxExisting = NULL; + } + // order is important for store + if (hCertStore) + { + CertCloseStore(hCertStore, 0); + hCertStore = NULL; + } + if (hPfxCertStore) + { + CertCloseStore(hPfxCertStore, 0); + hPfxCertStore = NULL; + } + + return hr; +} +*/ diff --git a/src/ext/Iis/ca/scacert.h b/src/ext/Iis/ca/scacert.h new file mode 100644 index 00000000..39b00d3d --- /dev/null +++ b/src/ext/Iis/ca/scacert.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. + + +#define CB_CERTIFICATE_HASH 20 + +// Certificate.Attribute +enum SCA_CERT_ATTRIBUTES +{ + SCA_CERT_ATTRIBUTE_DEFAULT = 0, + SCA_CERT_ATTRIBUTE_REQUEST = 1, + SCA_CERT_ATTRIBUTE_BINARYDATA = 2, + SCA_CERT_ATTRIBUTE_OVERWRITE = 4, + SCA_CERT_ATTRIBUTE_VITAL = 8, +}; + + +// Certificate.StoreLocation +enum SCA_CERTSYSTEMSTORE +{ + SCA_CERTSYSTEMSTORE_CURRENTUSER = 1, + SCA_CERTSYSTEMSTORE_LOCALMACHINE = 2, +}; diff --git a/src/ext/Iis/ca/scacertexec.cpp b/src/ext/Iis/ca/scacertexec.cpp new file mode 100644 index 00000000..95870c79 --- /dev/null +++ b/src/ext/Iis/ca/scacertexec.cpp @@ -0,0 +1,431 @@ +// 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" + +#define SIXTY_FOUR_MEG 64 * 1024 * 1024 + +// prototypes +static HRESULT ExecuteCertificateOperation( + __in MSIHANDLE hInstall, + __in SCA_ACTION saAction, + __in DWORD dwStoreRoot + ); + +static HRESULT ReadCertificateFile( + __in LPCWSTR wzPath, + __out BYTE** prgbData, + __out DWORD* pcbData + ); + +static HRESULT InstallCertificatePackage( + __in HCERTSTORE hStore, + __in BOOL fUserCertificateStore, + __in LPCWSTR wzName, + __in_opt BYTE* rgbData, + __in DWORD cbData, + __in BOOL fVital, + __in_opt LPCWSTR wzPFXPassword + ); + +static HRESULT UninstallCertificatePackage( + __in HCERTSTORE hStore, + __in BOOL fUserCertificateStore, + __in LPCWSTR wzName + ); + +static HRESULT AddCertificate( + __in HCERTSTORE hStore, + __in PCCERT_CONTEXT pCertContext, + __in LPCWSTR wzCertificateUniqueName, + __in BOOL fVital +); + +/* **************************************************************** + AddUserCertificate - CUSTOM ACTION ENTRY POINT for adding per-user + certificates + + * ***************************************************************/ +extern "C" UINT __stdcall AddUserCertificate( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, "AddUserCertificate"); + ExitOnFailure(hr, "Failed to initialize AddUserCertificate."); + + hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_INSTALL, CERT_SYSTEM_STORE_CURRENT_USER); + ExitOnFailure(hr, "Failed to install per-user certificate."); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/* **************************************************************** + AddMachineCertificate - CUSTOM ACTION ENTRY POINT for adding + per-machine certificates + + * ***************************************************************/ +extern "C" UINT __stdcall AddMachineCertificate( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, "AddMachineCertificate"); + ExitOnFailure(hr, "Failed to initialize AddMachineCertificate."); + + hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_INSTALL, CERT_SYSTEM_STORE_LOCAL_MACHINE); + ExitOnFailure(hr, "Failed to install per-machine certificate."); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/* **************************************************************** + DeleteUserCertificate - CUSTOM ACTION ENTRY POINT for deleting + per-user certificates + + * ***************************************************************/ +extern "C" UINT __stdcall DeleteUserCertificate( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, "DeleteUserCertificate"); + ExitOnFailure(hr, "Failed to initialize DeleteUserCertificate."); + + hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_UNINSTALL, CERT_SYSTEM_STORE_CURRENT_USER); + ExitOnFailure(hr, "Failed to uninstall per-user certificate."); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/* **************************************************************** + DeleteMachineCertificate - CUSTOM ACTION ENTRY POINT for deleting + per-machine certificates + + * ***************************************************************/ +extern "C" UINT __stdcall DeleteMachineCertificate( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, "DeleteMachineCertificate"); + ExitOnFailure(hr, "Failed to initialize DeleteMachineCertificate."); + + hr = ExecuteCertificateOperation(hInstall, SCA_ACTION_UNINSTALL, CERT_SYSTEM_STORE_LOCAL_MACHINE); + ExitOnFailure(hr, "Failed to uninstall per-machine certificate."); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +static HRESULT ExecuteCertificateOperation( + __in MSIHANDLE /*hInstall*/, + __in SCA_ACTION saAction, + __in DWORD dwStoreLocation + ) +{ + //AssertSz(FALSE, "Debug ExecuteCertificateOperation() here."); + Assert(saAction & SCA_ACTION_INSTALL || saAction & SCA_ACTION_UNINSTALL); + + HRESULT hr = S_OK; + LPWSTR pwzCaData = NULL; + LPWSTR pwz; + LPWSTR pwzName = NULL; + LPWSTR pwzStore = NULL; + int iAttributes = 0; + LPWSTR pwzPFXPassword = NULL; + LPWSTR pwzFilePath = NULL; + BYTE* pbData = NULL; + DWORD cbData = 0; + DWORD_PTR cbPFXPassword = 0; + + BOOL fUserStoreLocation = (CERT_SYSTEM_STORE_CURRENT_USER == dwStoreLocation); + HCERTSTORE hCertStore = NULL; + + hr = WcaGetProperty(L"CustomActionData", &pwzCaData); + ExitOnFailure(hr, "Failed to get CustomActionData"); + + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCaData); + + pwz = pwzCaData; + hr = WcaReadStringFromCaData(&pwz, &pwzName); + ExitOnFailure(hr, "Failed to parse certificate name."); + hr = WcaReadStringFromCaData(&pwz, &pwzStore); + ExitOnFailure(hr, "Failed to parse CustomActionData, StoreName"); + hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); + ExitOnFailure(hr, "Failed to parse certificate attribute"); + if (SCA_ACTION_INSTALL == saAction) // install operations need more data + { + hr = WcaReadStreamFromCaData(&pwz, &pbData, (DWORD_PTR*)&cbData); + ExitOnFailure(hr, "Failed to parse certificate stream."); + + hr = WcaReadStringFromCaData(&pwz, &pwzPFXPassword); + ExitOnFailure(hr, "Failed to parse certificate password."); + } + + // Open the right store. + hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation | CERT_STORE_MAXIMUM_ALLOWED_FLAG, pwzStore); + MessageExitOnNullWithLastError(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store: %ls", pwzStore); + + if (SCA_ACTION_INSTALL == saAction) // install operations need more data + { + // Uninstall existing versions of this package. Ignore any failures + // This is needed to clean up the private key of a cert when we replace an existing cert + // CertAddCertificateContextToStore(CERT_STORE_ADD_REPLACE_EXISTING) does not remove the private key if the cert is replaced + UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName); + + hr = InstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName, pbData, cbData, iAttributes & SCA_CERT_ATTRIBUTE_VITAL, pwzPFXPassword); + ExitOnFailure(hr, "Failed to install certificate."); + } + else + { + Assert(SCA_ACTION_UNINSTALL == saAction); + + hr = UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName); + ExitOnFailure(hr, "Failed to uninstall certificate."); + } + +LExit: + if (NULL != pwzPFXPassword && SUCCEEDED(StrSize(pwzPFXPassword, &cbPFXPassword))) + { + SecureZeroMemory(pwzPFXPassword, cbPFXPassword); + } + + if (hCertStore) + { + if (!::CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG)) + { + WcaLog(LOGMSG_VERBOSE, "Cert store was closed but not all resources were freed. Error 0x%x", GetLastError()); + } + } + + ReleaseMem(pbData); + ReleaseStr(pwzFilePath); + ReleaseStr(pwzPFXPassword); + ReleaseStr(pwzStore); + ReleaseStr(pwzName); + ReleaseStr(pwzCaData); + return hr; +} + + +static HRESULT InstallCertificatePackage( + __in HCERTSTORE hStore, + __in BOOL fUserCertificateStore, + __in LPCWSTR wzName, + __in_opt BYTE* rgbData, + __in DWORD cbData, + __in BOOL fVital, + __in_opt LPCWSTR wzPFXPassword + ) +{ + HRESULT hr = S_OK; + + HCERTSTORE hPfxCertStore = NULL; + PCCERT_CONTEXT pCertContext = NULL; + CERT_BLOB blob = { 0 }; + DWORD dwKeyset = fUserCertificateStore ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; + DWORD dwEncodingType; + DWORD dwContentType; + DWORD dwFormatType; + LPWSTR pwzUniqueName = NULL; + int iUniqueId = 0; + + // Figure out what type of blob (certificate or PFX) we're dealing with here. + blob.pbData = rgbData; + blob.cbData = cbData; + + if (!::CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, &dwEncodingType, &dwContentType, &dwFormatType, NULL, NULL, (LPCVOID*)&pCertContext)) + { + ExitWithLastError(hr, "Failed to parse the certificate blob: %ls", wzName); + } + + hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId); + ExitOnFailure(hr, "Failed to format unique name"); + + if (!pCertContext) + { + // If we have a PFX blob, get the first certificate out of the PFX and use that instead of the PFX. + if (dwContentType & CERT_QUERY_CONTENT_PFX) + { + ExitOnNull(wzPFXPassword, hr, E_INVALIDARG, "Failed to import PFX blob because no password was provided"); + + // If we fail and our password is blank, also try passing in NULL for the password (according to the docs) + hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, wzPFXPassword, dwKeyset); + if (NULL == hPfxCertStore && !*wzPFXPassword) + { + hPfxCertStore = ::PFXImportCertStore((CRYPT_DATA_BLOB*)&blob, NULL, dwKeyset); + } + ExitOnNullWithLastError(hPfxCertStore, hr, "Failed to open PFX file."); + + // Install all certificates in the PFX + for (pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext); + pCertContext; + pCertContext = ::CertEnumCertificatesInStore(hPfxCertStore, pCertContext)) + { + hr = AddCertificate(hStore, pCertContext, pwzUniqueName, fVital); + MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store."); + + hr = StrAllocFormatted(&pwzUniqueName, L"%s_wixCert_%d", wzName, ++iUniqueId); + ExitOnFailure(hr, "Failed to format unique name"); + } + } + else + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Unexpected certificate type processed."); + } + } + else + { + hr = AddCertificate(hStore, pCertContext, pwzUniqueName, fVital); + MessageExitOnFailure(hr, msierrCERTFailedAdd, "Failed to add certificate to the store."); + } + + hr = WcaProgressMessage(COST_CERT_ADD, FALSE); + ExitOnFailure(hr, "Failed to send install progress message."); + +LExit: + ReleaseStr(pwzUniqueName); + + if (pCertContext) + { + ::CertFreeCertificateContext(pCertContext); + } + + // Close the stores after the context's are released. + if (hPfxCertStore) + { + if (!::CertCloseStore(hPfxCertStore, CERT_CLOSE_STORE_CHECK_FLAG)) + { + WcaLog(LOGMSG_VERBOSE, "PFX cert store was closed but not all resources were freed. Error 0x%x", GetLastError()); + } + } + + return hr; +} + + +static HRESULT UninstallCertificatePackage( + __in HCERTSTORE hStore, + __in BOOL fUserCertificateStore, + __in LPCWSTR wzName + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + PCCERT_CONTEXT pCertContext = NULL; + CRYPT_KEY_PROV_INFO* pPrivateKeyInfo = NULL; + LPWSTR pwzUniquePrefix = NULL; + int ccUniquePrefix = 0; + + hr = StrAllocFormatted(&pwzUniquePrefix, L"%s_wixCert_", wzName); + ExitOnFailure(hr, "Failed to format unique name"); + ccUniquePrefix = ::lstrlenW(pwzUniquePrefix); + + WcaLog(LOGMSG_STANDARD, "Deleting certificate that begin with friendly name: %ls", pwzUniquePrefix); + + // Loop through all certificates in the store, deleting the ones that begin with our prefix. + while (NULL != (pCertContext = ::CertFindCertificateInStore(hStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pCertContext))) + { + WCHAR wzFriendlyName[256] = { 0 }; + DWORD cbFriendlyName = sizeof(wzFriendlyName); + + if (::CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, reinterpret_cast(wzFriendlyName), &cbFriendlyName) && + lstrlenW(wzFriendlyName) >= ccUniquePrefix && + CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, pwzUniquePrefix, ccUniquePrefix, wzFriendlyName, ccUniquePrefix)) + { + PCCERT_CONTEXT pCertContextDelete = ::CertDuplicateCertificateContext(pCertContext); // duplicate the context so we can delete it with out disrupting the looping + if(pCertContextDelete) + { + // Delete the certificate and if successful delete the matching private key as well. + if (::CertDeleteCertificateFromStore(pCertContextDelete)) + { + // If we found private key info, delete it. + hr = CertReadProperty(pCertContextDelete, CERT_KEY_PROV_INFO_PROP_ID, &pPrivateKeyInfo, NULL); + if (SUCCEEDED(hr)) + { + HCRYPTPROV hProvIgnored = NULL; // ignored on deletes. + DWORD dwKeyset = fUserCertificateStore ? CRYPT_USER_KEYSET : CRYPT_MACHINE_KEYSET; + + if (!::CryptAcquireContextW(&hProvIgnored, pPrivateKeyInfo->pwszContainerName, pPrivateKeyInfo->pwszProvName, pPrivateKeyInfo->dwProvType, dwKeyset | CRYPT_DELETEKEYSET | CRYPT_SILENT)) + { + er = ::GetLastError(); + hr = HRESULT_FROM_WIN32(er); + } + + ReleaseNullMem(pPrivateKeyInfo); + } + else // don't worry about failures to delete private keys. + { + hr = S_OK; + } + } + else + { + er = ::GetLastError(); + hr = HRESULT_FROM_WIN32(er); + } + + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "Failed to delete certificate with friendly name: %ls, continuing anyway. Error: 0x%x", wzFriendlyName, hr); + } + + pCertContextDelete = NULL; + } + } + } + + hr = WcaProgressMessage(COST_CERT_DELETE, FALSE); + ExitOnFailure(hr, "Failed to send uninstall progress message."); + +LExit: + ReleaseStr(pwzUniquePrefix); + ReleaseMem(pPrivateKeyInfo); + if(pCertContext) + { + ::CertFreeCertificateContext(pCertContext); + } + + return hr; +} + +static HRESULT AddCertificate( + __in HCERTSTORE hStore, + __in PCCERT_CONTEXT pCertContext, + __in LPCWSTR wzCertificateUniqueName, + __in BOOL fVital +) +{ + HRESULT hr = S_OK; + + WcaLog(LOGMSG_STANDARD, "Adding certificate: %ls", wzCertificateUniqueName); + + hr = CertInstallSingleCertificate(hStore, pCertContext, wzCertificateUniqueName); + if (FAILED(hr) && !fVital) + { + WcaLog(LOGMSG_STANDARD, "Could not add non-vital certificate: %ls due to error: 0x%x, continuing...", wzCertificateUniqueName, hr); + hr = S_FALSE; + } + + return hr; +} diff --git a/src/ext/Iis/ca/scacost.h b/src/ext/Iis/ca/scacost.h new file mode 100644 index 00000000..be92cf26 --- /dev/null +++ b/src/ext/Iis/ca/scacost.h @@ -0,0 +1,15 @@ +#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. + + +const UINT COST_IIS_TRANSACTIONS = 10000; + +const UINT COST_IIS_CREATEKEY = 5000; +const UINT COST_IIS_DELETEKEY = 5000; +const UINT COST_IIS_WRITEVALUE = 5000; +const UINT COST_IIS_DELETEVALUE = 5000; +const UINT COST_IIS_CREATEAPP = 5000; +const UINT COST_IIS_DELETEAPP = 5000; + +const UINT COST_CERT_ADD = 5000; +const UINT COST_CERT_DELETE = 5000; diff --git a/src/ext/Iis/ca/scaexec.cpp b/src/ext/Iis/ca/scaexec.cpp new file mode 100644 index 00000000..df25e8db --- /dev/null +++ b/src/ext/Iis/ca/scaexec.cpp @@ -0,0 +1,1184 @@ +// 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" + + +/******************************************************************** + StartMetabaseTransaction - CUSTOM ACTION ENTRY POINT for backing up metabase + + Input: deferred CustomActionData - BackupName +********************************************************************/ +extern "C" UINT __stdcall StartMetabaseTransaction(MSIHANDLE hInstall) +{ +//AssertSz(FALSE, "debug StartMetabaseTransaction here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + IMSAdminBase* piMetabase = NULL; + LPWSTR pwzData = NULL; + BOOL fInitializedCom = FALSE; + + // initialize + hr = WcaInitialize(hInstall, "StartMetabaseTransaction"); + ExitOnFailure(hr, "failed to initialize StartMetabaseTransaction"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to initialize COM"); + fInitializedCom = TRUE; + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + if (hr == REGDB_E_CLASSNOTREG) + { + WcaLog(LOGMSG_STANDARD, "Failed to get IIMSAdminBase to backup - continuing"); + hr = S_OK; + } + else + { + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); + + hr = WcaGetProperty(L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + // back up the metabase + Assert(lstrlenW(pwzData) < MD_BACKUP_MAX_LEN); + + // MD_BACKUP_OVERWRITE = Overwrite if a backup of the same name and version exists in the backup location + hr = piMetabase->Backup(pwzData, MD_BACKUP_NEXT_VERSION, MD_BACKUP_OVERWRITE | MD_BACKUP_FORCE_BACKUP | MD_BACKUP_SAVE_FIRST); + if (MD_WARNING_SAVE_FAILED == hr) + { + WcaLog(LOGMSG_STANDARD, "Failed to save metabase before backing up - continuing"); + hr = S_OK; + } + MessageExitOnFailure(hr, msierrIISFailedStartTransaction, "failed to begin metabase transaction: '%ls'", pwzData); + } + hr = WcaProgressMessage(COST_IIS_TRANSACTIONS, FALSE); +LExit: + ReleaseStr(pwzData); + ReleaseObject(piMetabase); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + er = ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/******************************************************************** + RollbackMetabaseTransaction - CUSTOM ACTION ENTRY POINT for unbacking up metabase + + Input: deferred CustomActionData - BackupName +********************************************************************/ +extern "C" UINT __stdcall RollbackMetabaseTransaction(MSIHANDLE hInstall) +{ +//AssertSz(FALSE, "debug RollbackMetabaseTransaction here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + IMSAdminBase* piMetabase = NULL; + LPWSTR pwzData = NULL; + BOOL fInitializedCom = FALSE; + + hr = WcaInitialize(hInstall, "RollbackMetabaseTransaction"); + ExitOnFailure(hr, "failed to initialize"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to initialize COM"); + fInitializedCom = TRUE; + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + if (hr == REGDB_E_CLASSNOTREG) + { + WcaLog(LOGMSG_STANDARD, "Failed to get IIMSAdminBase to rollback - continuing"); + hr = S_OK; + ExitFunction(); + } + ExitOnFailure(hr, "failed to get IID_IIMSAdminBase object"); + + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + hr = piMetabase->Restore(pwzData, MD_BACKUP_HIGHEST_VERSION, 0); + ExitOnFailure(hr, "failed to rollback metabase transaction: '%ls'", pwzData); + + hr = piMetabase->DeleteBackup(pwzData, MD_BACKUP_HIGHEST_VERSION); + ExitOnFailure(hr, "failed to cleanup metabase transaction '%ls', continuing", pwzData); + +LExit: + ReleaseStr(pwzData); + ReleaseObject(piMetabase); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} + + +/******************************************************************** + CommitMetabaseTransaction - CUSTOM ACTION ENTRY POINT for unbacking up metabase + + Input: deferred CustomActionData - BackupName + * *****************************************************************/ +extern "C" UINT __stdcall CommitMetabaseTransaction(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + IMSAdminBase* piMetabase = NULL; + LPWSTR pwzData = NULL; + BOOL fInitializedCom = FALSE; + + hr = WcaInitialize(hInstall, "CommitMetabaseTransaction"); + ExitOnFailure(hr, "failed to initialize"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to initialize COM"); + fInitializedCom = TRUE; + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + if (hr == REGDB_E_CLASSNOTREG) + { + WcaLog(LOGMSG_STANDARD, "Failed to get IIMSAdminBase to commit - continuing"); + hr = S_OK; + ExitFunction(); + } + ExitOnFailure(hr, "failed to get IID_IIMSAdminBase object"); + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + hr = piMetabase->DeleteBackup(pwzData, MD_BACKUP_HIGHEST_VERSION); + ExitOnFailure(hr, "failed to cleanup metabase transaction: '%ls'", pwzData); + +LExit: + ReleaseStr(pwzData); + ReleaseObject(piMetabase); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} + + +/******************************************************************** + CreateMetabaseKey - Installs metabase keys + + Input: deferred CustomActionData - Key + * *****************************************************************/ +static HRESULT CreateMetabaseKey(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase) +{ +//AssertSz(FALSE, "debug CreateMetabaseKey here"); + HRESULT hr = S_OK; + METADATA_HANDLE mhRoot = 0; + LPWSTR pwzData = NULL; + LPCWSTR pwzKey; + + int i; + + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "failed to read key from custom action data"); + + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); + for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) + { + ::Sleep(1000); + WcaLog(LOGMSG_STANDARD, "failed to open root key, retrying %d time(s)...", i); + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); + } + MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", L"/LM"); + + pwzKey = pwzData + 3; + + WcaLog(LOGMSG_VERBOSE, "Creating Metabase Key: %ls", pwzKey); + + hr = piMetabase->AddKey(mhRoot, pwzKey); + if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr) + { + WcaLog(LOGMSG_VERBOSE, "Key `%ls` already existed, continuing.", pwzData); + hr = S_OK; + } + MessageExitOnFailure(hr, msierrIISFailedCreateKey, "failed to create metabase key: %ls", pwzKey); + + hr = WcaProgressMessage(COST_IIS_CREATEKEY, FALSE); + +LExit: + if (mhRoot) + { + piMetabase->CloseKey(mhRoot); + } + + return hr; +} + + +/******************************************************************** + WriteMetabaseValue -Installs metabase values + + Input: deferred CustomActionData - Key\tIdentifier\tAttributes\tUserType\tDataType\tData + * *****************************************************************/ +static HRESULT WriteMetabaseValue(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase) +{ + //AssertSz(FALSE, "debug WriteMetabaseValue here"); + HRESULT hr = S_OK; + + METADATA_HANDLE mhKey = 0; + + LPWSTR pwzKey = NULL; + LPWSTR pwzTemp = NULL; + DWORD dwData = 0; + DWORD dwTemp = 0; + BOOL fFreeData = FALSE; + METADATA_RECORD mr; + ::ZeroMemory((LPVOID)&mr, sizeof(mr)); + METADATA_RECORD mrGet; + ::ZeroMemory((LPVOID)&mrGet, sizeof(mrGet)); + + int i; + + // get the key first + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzKey); + ExitOnFailure(hr, "failed to read key"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDIdentifier)); + ExitOnFailure(hr, "failed to read identifier"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDAttributes)); + ExitOnFailure(hr, "failed to read attributes"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDUserType)); + ExitOnFailure(hr, "failed to read user type"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&mr.dwMDDataType)); + ExitOnFailure(hr, "failed to read data type"); + + switch (mr.dwMDDataType) // data + { + case DWORD_METADATA: + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&dwData)); + mr.dwMDDataLen = sizeof(dwData); + mr.pbMDData = reinterpret_cast(&dwData); + break; + case STRING_METADATA: + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzTemp); + mr.dwMDDataLen = (lstrlenW(pwzTemp) + 1) * sizeof(WCHAR); + mr.pbMDData = reinterpret_cast(pwzTemp); + break; + case MULTISZ_METADATA: + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzTemp); + mr.dwMDDataLen = (lstrlenW(pwzTemp) + 1) * sizeof(WCHAR); + for (LPWSTR pwzT = pwzTemp; *pwzT; ++pwzT) + { + if (MAGIC_MULTISZ_CHAR == *pwzT) + { + *pwzT = L'\0'; + } + } + mr.pbMDData = reinterpret_cast(pwzTemp); + } + break; + case BINARY_METADATA: + hr = WcaReadStreamFromCaData(ppwzCustomActionData, &mr.pbMDData, reinterpret_cast(&mr.dwMDDataLen)); + fFreeData = TRUE; + break; + default: + hr = E_UNEXPECTED; + break; + } + ExitOnFailure(hr, "failed to parse CustomActionData into metabase record"); + + WcaLog(LOGMSG_VERBOSE, "Writing Metabase Value Under Key: %ls ID: %d", pwzKey, mr.dwMDIdentifier); + + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); + for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) + { + ::Sleep(1000); + WcaLog(LOGMSG_STANDARD, "failed to open '%ls' key, retrying %d time(s)...", pwzKey, i); + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); + } + MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", pwzKey); + + if (lstrlenW(pwzKey) < 3) + { + ExitOnFailure(hr = E_INVALIDARG, "Key didn't begin with \"/LM\" as expected - key value: %ls", pwzKey); + } + + hr = piMetabase->SetData(mhKey, pwzKey + 3, &mr); // pwzKey + 3 to skip "/LM" that was used to open the key. + + // This means we're trying to write to a secure key without the secure flag set - let's try again with the secure flag set + if (MD_ERROR_CANNOT_REMOVE_SECURE_ATTRIBUTE == hr) + { + mr.dwMDAttributes |= METADATA_SECURE; + hr = piMetabase->SetData(mhKey, pwzKey + 3, &mr); + } + + // If IIS6 returned failure, let's check if the correct value exists in the metabase before actually failing the CA + if (FAILED(hr)) + { + // Backup the original failure error, so we can log it below if necessary + HRESULT hrOldValue = hr; + + mrGet.dwMDIdentifier = mr.dwMDIdentifier; + mrGet.dwMDAttributes = METADATA_NO_ATTRIBUTES; + mrGet.dwMDUserType = mr.dwMDUserType; + mrGet.dwMDDataType = mr.dwMDDataType; + mrGet.dwMDDataLen = mr.dwMDDataLen; + mrGet.pbMDData = static_cast(MemAlloc(mr.dwMDDataLen, TRUE)); + + hr = piMetabase->GetData(mhKey, pwzKey + 3, &mrGet, &dwTemp); + if (SUCCEEDED(hr)) + { + if (mrGet.dwMDDataType == mr.dwMDDataType && mrGet.dwMDDataLen == mr.dwMDDataLen && 0 == memcmp(mrGet.pbMDData, mr.pbMDData, mr.dwMDDataLen)) + { + WcaLog(LOGMSG_VERBOSE, "Received error while writing metabase value under key: %ls ID: %d with error 0x%x, but the correct value is in the metabase - continuing", pwzKey, mr.dwMDIdentifier, hrOldValue); + hr = S_OK; + } + else + { + WcaLog(LOGMSG_VERBOSE, "Succeeded in checking metabase value after write value, but the values didn't match"); + hr = hrOldValue; + } + } + else + { + WcaLog(LOGMSG_VERBOSE, "Failed to check value after metabase write failure (error code 0x%x)", hr); + hr = hrOldValue; + } + } + MessageExitOnFailure(hr, msierrIISFailedWriteData, "failed to write data to metabase key: %ls", pwzKey); + + hr = WcaProgressMessage(COST_IIS_WRITEVALUE, FALSE); + +LExit: + ReleaseStr(pwzTemp); + ReleaseStr(pwzKey); + + if (mhKey) + { + piMetabase->CloseKey(mhKey); + } + + if (fFreeData && mr.pbMDData) + { + MemFree(mr.pbMDData); + } + + return hr; +} + + +/******************************************************************** + DeleteMetabaseValue -Installs metabase values + + Input: deferred CustomActionData - Key\tIdentifier\tAttributes\tUserType\tDataType\tData + * *****************************************************************/ +static HRESULT DeleteMetabaseValue(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase) +{ + //AssertSz(FALSE, "debug DeleteMetabaseValue here"); + HRESULT hr = S_OK; + + METADATA_HANDLE mhKey = 0; + + LPWSTR pwzKey = NULL; + DWORD dwIdentifier = 0; + DWORD dwDataType = 0; + + int i; + + // get the key first + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzKey); + ExitOnFailure(hr, "failed to read key"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&dwIdentifier)); + ExitOnFailure(hr, "failed to read identifier"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&dwDataType)); + ExitOnFailure(hr, "failed to read data type"); + + WcaLog(LOGMSG_VERBOSE, "Deleting Metabase Value Under Key: %ls ID: %d", pwzKey, dwIdentifier); + + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); + for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) + { + ::Sleep(1000); + WcaLog(LOGMSG_STANDARD, "failed to open '%ls' key, retrying %d time(s)...", pwzKey, i); + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhKey); + } + MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", pwzKey); + + if (lstrlenW(pwzKey) < 3) + { + ExitOnFailure(hr = E_INVALIDARG, "Key didn't begin with \"/LM\" as expected - key value: %ls", pwzKey); + } + + hr = piMetabase->DeleteData(mhKey, pwzKey + 3, dwIdentifier, dwDataType); // pwzKey + 3 to skip "/LM" that was used to open the key. + if (MD_ERROR_DATA_NOT_FOUND == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) + { + hr = S_OK; + } + MessageExitOnFailure(hr, msierrIISFailedDeleteValue, "failed to delete value %d from metabase key: %ls", dwIdentifier, pwzKey); + + hr = WcaProgressMessage(COST_IIS_DELETEVALUE, FALSE); +LExit: + ReleaseStr(pwzKey); + + if (mhKey) + piMetabase->CloseKey(mhKey); + + return hr; +} + + +/******************************************************************** + DeleteAspApp - Deletes applications in IIS + + Input: deferred CustomActionData - MetabaseRoot\tRecursive + * *****************************************************************/ +static HRESULT DeleteAspApp(__in LPWSTR* ppwzCustomActionData, __in IMSAdminBase* piMetabase, __in ICatalogCollection* pApplicationCollection, __in IWamAdmin* piWam) +{ + const int BUFFER_BYTES = 512; + const BSTR bstrPropName = SysAllocString(L"Deleteable"); + + HRESULT hr = S_OK; + ICatalogObject* pApplication = NULL; + + LPWSTR pwzRoot = NULL; + DWORD dwActualBufferSize = 0; + long lSize = 0; + long lIndex = 0; + long lChanges = 0; + + VARIANT keyValue; + ::VariantInit(&keyValue); + VARIANT propValue; + propValue.vt = VT_BOOL; + propValue.boolVal = TRUE; + + METADATA_RECORD mr; + // Get current set of web service extensions. + ::ZeroMemory(&mr, sizeof(mr)); + mr.dwMDIdentifier = MD_APP_PACKAGE_ID; + mr.dwMDAttributes = 0; + mr.dwMDUserType = ASP_MD_UT_APP; + mr.dwMDDataType = STRING_METADATA; + mr.pbMDData = new unsigned char[BUFFER_BYTES]; + mr.dwMDDataLen = BUFFER_BYTES; + + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzRoot); // MetabaseRoot + ExitOnFailure(hr, "failed to get metabase root"); + + hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, pwzRoot, &mr, &dwActualBufferSize); + if (HRESULT_FROM_WIN32(MD_ERROR_DATA_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + // This one doesn't have an independent app GUID associated with it - it may have been already partially deleted, or a low isolation app + WcaLog(LOGMSG_VERBOSE, "No independent COM+ application found associated with %ls. It either doesn't exist, or was already removed - continuing", pwzRoot); + ExitFunction1(hr = S_OK); + } + MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get GUID for application at path: %ls", pwzRoot); + + WcaLog(LOGMSG_VERBOSE, "Deleting ASP App (used query: %ls) with GUID: %ls", pwzRoot, (LPWSTR)(mr.pbMDData)); + + // Delete the application association from IIS's point of view before it's obliterated from the application collection + hr = piWam->AppDelete(pwzRoot, FALSE); + if (FAILED(hr)) + { + // This isn't necessarily an error if we fail here, but let's log a failure if it happens + WcaLog(LOGMSG_VERBOSE, "error 0x%x: failed to call IWamAdmin::AppDelete() while removing web application - continuing"); + hr = S_OK; + } + + if (!pApplicationCollection) + { + WcaLog(LOGMSG_STANDARD, "Could not remove application with GUID %ls because the application collection could not be found", (LPWSTR)(mr.pbMDData)); + ExitFunction1(hr = S_OK); + } + + hr = pApplicationCollection->Populate(); + MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to populate Application collection"); + + hr = pApplicationCollection->get_Count(&lSize); + MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get size of Application collection"); + WcaLog(LOGMSG_TRACEONLY, "Found %u items in application collection", lSize); + + // No need to check this too early, as we may not even need this to have successfully allocated + ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "failed to allocate memory for \"Deleteable\" string"); + + for (lIndex = 0; lIndex < lSize; ++lIndex) + { + hr = pApplicationCollection->get_Item(lIndex, reinterpret_cast(&pApplication)); + MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get COM+ application while enumerating through COM+ applications"); + + hr = pApplication->get_Key(&keyValue); + MessageExitOnFailure(hr, msierrIISFailedDeleteApp, "failed to get key of COM+ application while enumerating through COM+ applications"); + + WcaLog(LOGMSG_TRACEONLY, "While enumerating through COM+ applications, found an application with GUID: %ls", (LPWSTR)keyValue.bstrVal); + + if (VT_BSTR == keyValue.vt && 0 == lstrcmpW((LPWSTR)keyValue.bstrVal, (LPWSTR)(mr.pbMDData))) + { + hr = pApplication->put_Value(bstrPropName, propValue); + if (FAILED(hr)) + { + // This isn't necessarily a critical error unless we fail to actually delete it in the next step + WcaLog(LOGMSG_VERBOSE, "error 0x%x: failed to ensure COM+ application with guid %ls is deletable - continuing", hr, (LPWSTR)(mr.pbMDData)); + } + + hr = pApplicationCollection->SaveChanges(&lChanges); + if (FAILED(hr)) + { + // This isn't necessarily a critical error unless we fail to actually delete it in the next step + WcaLog(LOGMSG_VERBOSE, "error 0x%x: failed to save changes while ensuring COM+ application with guid %ls is deletable - continuing", hr, (LPWSTR)(mr.pbMDData)); + } + + hr = pApplicationCollection->Remove(lIndex); + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "error 0x%x: failed to remove COM+ application with guid %ls. The COM application will not be removed", hr, (LPWSTR)(mr.pbMDData)); + } + else + { + hr = pApplicationCollection->SaveChanges(&lChanges); + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "error 0x%x: failed to save changes when removing COM+ application with guid %ls. The COM application will not be removed - continuing", hr, (LPWSTR)(mr.pbMDData)); + } + else + { + WcaLog(LOGMSG_VERBOSE, "Found and removed application with GUID %ls", (LPWSTR)(mr.pbMDData)); + } + } + + // We've found the right key and successfully deleted the app - let's exit the loop now + lIndex = lSize; + } + } + // If we didn't find it, it isn't an error, because the application we want to delete doesn't seem to exist! + + hr = WcaProgressMessage(COST_IIS_DELETEAPP, FALSE); +LExit: + ReleaseBSTR(bstrPropName); + + ReleaseStr(pwzRoot); + // Don't release pApplication, because it points to an object within the collection + + delete [] mr.pbMDData; + + return hr; +} + + +/******************************************************************** + CreateAspApp - Creates applications in IIS + + Input: deferred CustomActionData - MetabaseRoot\tInProc + * ****************************************************************/ +static HRESULT CreateAspApp(__in LPWSTR* ppwzCustomActionData, __in IWamAdmin* piWam) +{ + HRESULT hr = S_OK; + + LPWSTR pwzRoot = NULL; + BOOL fInProc; + + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzRoot); // MetabaseRoot + ExitOnFailure(hr, "failed to get metabase root"); + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, reinterpret_cast(&fInProc)); // InProc + ExitOnFailure(hr, "failed to get in proc flag"); + + WcaLog(LOGMSG_VERBOSE, "Creating ASP App: %ls", pwzRoot); + + hr = piWam->AppCreate(pwzRoot, fInProc); + MessageExitOnFailure(hr, msierrIISFailedCreateApp, "failed to create web application: %ls", pwzRoot); + + hr = WcaProgressMessage(COST_IIS_CREATEAPP, FALSE); +LExit: + return hr; +} + + +/******************************************************************** + DeleteMetabaseKey - Deletes metabase keys + + Input: deferred CustomActionData - Key + ******************************************************************/ +static HRESULT DeleteMetabaseKey(__in LPWSTR *ppwzCustomActionData, __in IMSAdminBase* piMetabase) +{ + HRESULT hr = S_OK; + + METADATA_HANDLE mhRoot = 0; + + LPWSTR pwzData = NULL; + + LPCWSTR pwzKey; + int i; + + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "failed to read key to be deleted"); + + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); + for (i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) + { + ::Sleep(1000); + WcaLog(LOGMSG_STANDARD, "failed to open root key, retrying %d time(s)...", i); + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", METADATA_PERMISSION_WRITE, 10, &mhRoot); + } + MessageExitOnFailure(hr, msierrIISFailedOpenKey, "failed to open metabase key: %ls", L"/LM"); + + pwzKey = pwzData + 3; + + WcaLog(LOGMSG_VERBOSE, "Deleting Metabase Key: %ls", pwzKey); + + hr = piMetabase->DeleteKey(mhRoot, pwzKey); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) + { + WcaLog(LOGMSG_STANDARD, "Key `%ls` did not exist, continuing.", pwzData); + hr = S_OK; + } + MessageExitOnFailure(hr, msierrIISFailedDeleteKey, "failed to delete metabase key: %ls", pwzData); + + hr = WcaProgressMessage(COST_IIS_DELETEKEY, FALSE); +LExit: + if (mhRoot) + { + piMetabase->CloseKey(mhRoot); + } + + return hr; +} + + +/******************************************************************** + WriteMetabaseChanges - CUSTOM ACTION ENTRY POINT for IIS Metabase changes + + *******************************************************************/ +extern "C" UINT __stdcall WriteMetabaseChanges(MSIHANDLE hInstall) +{ +//AssertSz(FALSE, "debug WriteMetabaseChanges here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + IMSAdminBase* piMetabase = NULL; + IWamAdmin* piWam = NULL; + ICOMAdminCatalog* pCatalog = NULL; + ICatalogCollection* pApplicationCollection = NULL; + WCA_CASCRIPT_HANDLE hWriteMetabaseScript = NULL; + BSTR bstrApplications = SysAllocString(L"Applications"); + BOOL fInitializedCom = FALSE; + + LPWSTR pwzData = NULL; + LPWSTR pwz = NULL; + LPWSTR pwzScriptKey = NULL; + METABASE_ACTION maAction = MBA_UNKNOWNACTION; + + hr = WcaInitialize(hInstall, "WriteMetabaseChanges"); + ExitOnFailure(hr, "failed to initialize"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to initialize COM"); + fInitializedCom = TRUE; + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); + + // Get the CaScript key + hr = WcaReadStringFromCaData(&pwzData, &pwzScriptKey); + ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); + + hr = WcaCaScriptOpen(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzScriptKey, &hWriteMetabaseScript); + ExitOnFailure(hr, "Failed to open CaScript file"); + + // The rest of our existing custom action data string should be empty - go ahead and overwrite it + ReleaseNullStr(pwzData); + hr = WcaCaScriptReadAsCustomActionData(hWriteMetabaseScript, &pwzData); + ExitOnFailure(hr, "Failed to read script into CustomAction data."); + + pwz = pwzData; + + while (S_OK == (hr = WcaReadIntegerFromCaData(&pwz, (int *)&maAction))) + { + switch (maAction) + { + case MBA_CREATEAPP: + if (NULL == piWam) + { + hr = ::CoCreateInstance(CLSID_WamAdmin, NULL, CLSCTX_ALL, IID_IWamAdmin, reinterpret_cast(&piWam)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IWamAdmin object"); + } + + hr = CreateAspApp(&pwz, piWam); + ExitOnFailure(hr, "failed to create ASP App"); + break; + case MBA_DELETEAPP: + if (NULL == piMetabase) + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); + } + + if (NULL == pCatalog) + { + hr = CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pCatalog); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_ICOMAdmin object"); + + hr = pCatalog->GetCollection(bstrApplications, reinterpret_cast(&pApplicationCollection)); + if (FAILED(hr)) + { + hr = S_OK; + WcaLog(LOGMSG_STANDARD, "error 0x%x: failed to get ApplicationCollection object for list of COM+ applications - COM+ applications will not be able to be uninstalled - continuing", hr); + } + } + + if (NULL == piWam) + { + hr = ::CoCreateInstance(CLSID_WamAdmin, NULL, CLSCTX_ALL, IID_IWamAdmin, reinterpret_cast(&piWam)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IWamAdmin object"); + } + + hr = DeleteAspApp(&pwz, piMetabase, pApplicationCollection, piWam); + ExitOnFailure(hr, "failed to delete ASP App"); + break; + case MBA_CREATEKEY: + if (NULL == piMetabase) + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); + } + + hr = CreateMetabaseKey(&pwz, piMetabase); + ExitOnFailure(hr, "failed to create metabase key"); + break; + case MBA_DELETEKEY: + if (NULL == piMetabase) + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); + } + + hr = DeleteMetabaseKey(&pwz, piMetabase); + ExitOnFailure(hr, "failed to delete metabase key"); + break; + case MBA_WRITEVALUE: + if (NULL == piMetabase) + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); + } + + hr = WriteMetabaseValue(&pwz, piMetabase); + ExitOnFailure(hr, "failed to write metabase value"); + break; + case MBA_DELETEVALUE: + if (NULL == piMetabase) + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, reinterpret_cast(&piMetabase)); + MessageExitOnFailure(hr, msierrIISCannotConnect, "failed to get IID_IIMSAdminBase object"); + } + + hr = DeleteMetabaseValue(&pwz, piMetabase); + ExitOnFailure(hr, "failed to delete metabase value"); + break; + default: + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected metabase action specified: %d", maAction); + break; + } + } + if (E_NOMOREITEMS == hr) // If there are no more items, all is well + { + if (NULL != piMetabase) + { + hr = piMetabase->SaveData(); + for (int i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) + { + ::Sleep(1000); + WcaLog(LOGMSG_VERBOSE, "Failed to force save of metabase data, retrying %d time(s)...", i); + hr = piMetabase->SaveData(); + } + if (FAILED(hr)) + { + WcaLog(LOGMSG_VERBOSE, "Failed to force save of metabase data: 0x%x - continuing", hr); + } + hr = S_OK; + } + else + { + hr = S_OK; + } + } + +LExit: + WcaCaScriptClose(hWriteMetabaseScript, WCA_CASCRIPT_CLOSE_DELETE); + + ReleaseBSTR(bstrApplications); + ReleaseStr(pwzScriptKey); + ReleaseStr(pwzData); + ReleaseObject(piMetabase); + ReleaseObject(piWam); + ReleaseObject(pCatalog); + ReleaseObject(pApplicationCollection); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} +/******************************************************************** + WriteIIS7ConfigChanges - CUSTOM ACTION ENTRY POINT for IIS7 config changes + + *******************************************************************/ +extern "C" UINT __stdcall WriteIIS7ConfigChanges(MSIHANDLE hInstall) +{ + //AssertSz(FALSE, "debug WriteIIS7ConfigChanges here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + LPWSTR pwzData = NULL; + LPWSTR pwzScriptKey = NULL; + LPWSTR pwzHashString = NULL; + BYTE rgbActualHash[SHA1_HASH_LEN] = { }; + DWORD dwHashedBytes = SHA1_HASH_LEN; + + WCA_CASCRIPT_HANDLE hWriteIis7Script = NULL; + + hr = WcaInitialize(hInstall, "WriteIIS7ConfigChanges"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = WcaGetProperty( L"CustomActionData", &pwzScriptKey); + ExitOnFailure(hr, "Failed to get CustomActionData"); + WcaLog(LOGMSG_TRACEONLY, "Script WriteIIS7ConfigChanges: %ls", pwzScriptKey); + + hr = WcaCaScriptOpen(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzScriptKey, &hWriteIis7Script); + ExitOnFailure(hr, "Failed to open CaScript file"); + + hr = WcaCaScriptReadAsCustomActionData(hWriteIis7Script, &pwzData); + ExitOnFailure(hr, "Failed to read script into CustomAction data."); + + hr = CrypHashBuffer((BYTE*)pwzData, sizeof(pwzData) * sizeof(WCHAR), PROV_RSA_AES, CALG_SHA1, rgbActualHash, dwHashedBytes); + ExitOnFailure(hr, "Failed to calculate hash of CustomAction data."); + + hr = StrAlloc(&pwzHashString, ((dwHashedBytes * 2) + 1)); + ExitOnFailure(hr, "Failed to allocate string for script hash"); + + hr = StrHexEncode(rgbActualHash, dwHashedBytes, pwzHashString, ((dwHashedBytes * 2) + 1)); + ExitOnFailure(hr, "Failed to convert hash bytes to string."); + + WcaLog(LOGMSG_TRACEONLY, "CustomActionData WriteIIS7ConfigChanges: %ls", pwzData); + WcaLog(LOGMSG_VERBOSE, "Custom action data hash: %ls", pwzHashString); + WcaLog(LOGMSG_VERBOSE, "CustomActionData WriteIIS7ConfigChanges length: %d", wcslen(pwzData)); + + hr = IIS7ConfigChanges(hInstall, pwzData); + ExitOnFailure(hr, "WriteIIS7ConfigChanges Failed."); + +LExit: + WcaCaScriptClose(hWriteIis7Script, WCA_CASCRIPT_CLOSE_DELETE); + ReleaseStr(pwzScriptKey); + ReleaseStr(pwzData); + ReleaseStr(pwzHashString); + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + + return WcaFinalize(er); +} + + +/******************************************************************** + CommitIIS7ConfigTransaction - CUSTOM ACTION ENTRY POINT for unbacking up config + + Input: deferred CustomActionData - BackupName + * *****************************************************************/ +extern "C" UINT __stdcall CommitIIS7ConfigTransaction(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + LPWSTR pwzData = NULL; + WCHAR wzConfigCopy[MAX_PATH]; + DWORD dwSize = 0; + + BOOL fIsWow64Process = FALSE; + BOOL fIsFSRedirectDisabled = FALSE; + + hr = WcaInitialize(hInstall, "CommitIIS7ConfigTransaction"); + ExitOnFailure(hr, "failed to initialize IIS7 commit transaction"); + + WcaInitializeWow64(); + fIsWow64Process = WcaIsWow64Process(); + if (fIsWow64Process) + { + hr = WcaDisableWow64FSRedirection(); + if(FAILED(hr)) + { + //eat this error + hr = S_OK; + } + else + { + fIsFSRedirectDisabled = TRUE; + } + } + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + // Config AdminMgr changes already committed, just + // delete backup config file. + + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", + wzConfigCopy, + MAX_PATH + ); + if ( dwSize == 0 ) + { + ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + } + + hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, L"."); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of ."); + + hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, pwzData); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of extension"); + + if (!::DeleteFileW(wzConfigCopy)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || + HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + WcaLog(LOGMSG_STANDARD, "Failed to delete backup applicationHost, not found - continuing"); + hr = S_OK; + } + else + { + ExitOnFailure(hr, "failed to delete config backup"); + } + } + +LExit: + ReleaseStr(pwzData); + + // Make sure we revert FS Redirection if necessary before exiting + if (fIsFSRedirectDisabled) + { + fIsFSRedirectDisabled = FALSE; + WcaRevertWow64FSRedirection(); + } + WcaFinalizeWow64(); + + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} +/******************************************************************** + StartIIS7Config Transaction - CUSTOM ACTION ENTRY POINT for backing up config + + Input: deferred CustomActionData - BackupName +********************************************************************/ +extern "C" UINT __stdcall StartIIS7ConfigTransaction(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + LPWSTR pwzData = NULL; + WCHAR wzConfigSource[MAX_PATH]; + WCHAR wzConfigCopy[MAX_PATH]; + DWORD dwSize = 0; + + + BOOL fIsWow64Process = FALSE; + BOOL fIsFSRedirectDisabled = FALSE; + + // initialize + hr = WcaInitialize(hInstall, "StartIIS7ConfigTransaction"); + ExitOnFailure(hr, "failed to initialize StartIIS7ConfigTransaction"); + + WcaInitializeWow64(); + fIsWow64Process = WcaIsWow64Process(); + if (fIsWow64Process) + { + hr = WcaDisableWow64FSRedirection(); + if(FAILED(hr)) + { + //eat this error + hr = S_OK; + } + else + { + fIsFSRedirectDisabled = TRUE; + } + } + + hr = WcaGetProperty(L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", + wzConfigSource, + MAX_PATH + ); + if ( dwSize == 0 ) + { + ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + } + hr = ::StringCchCopyW(wzConfigCopy, MAX_PATH, wzConfigSource); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCopyW"); + + //add ca action as extension + + hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, L"."); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of ."); + + hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, pwzData); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of extension"); + + if ( !::CopyFileW(wzConfigSource, wzConfigCopy, FALSE) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || + HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + // IIS may not be installed on the machine, we'll fail later if we try to install anything + WcaLog(LOGMSG_STANDARD, "Failed to back up applicationHost, not found - continuing"); + hr = S_OK; + } + else + { + ExitOnFailure(hr, "Failed to copy config backup %ls -> %ls", wzConfigSource, wzConfigCopy); + } + } + + + hr = WcaProgressMessage(COST_IIS_TRANSACTIONS, FALSE); + + +LExit: + + ReleaseStr(pwzData); + + // Make sure we revert FS Redirection if necessary before exiting + if (fIsFSRedirectDisabled) + { + fIsFSRedirectDisabled = FALSE; + WcaRevertWow64FSRedirection(); + } + WcaFinalizeWow64(); + + if (FAILED(hr)) + er = ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/******************************************************************** + RollbackIIS7ConfigTransaction - CUSTOM ACTION ENTRY POINT for unbacking up config + + Input: deferred CustomActionData - BackupName +********************************************************************/ +extern "C" UINT __stdcall RollbackIIS7ConfigTransaction(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + LPWSTR pwzData = NULL; + WCHAR wzConfigSource[MAX_PATH]; + WCHAR wzConfigCopy[MAX_PATH]; + DWORD dwSize = 0; + + BOOL fIsWow64Process = FALSE; + BOOL fIsFSRedirectDisabled = FALSE; + + hr = WcaInitialize(hInstall, "RollbackIIS7ConfigTransaction"); + ExitOnFailure(hr, "failed to initialize"); + + WcaInitializeWow64(); + fIsWow64Process = WcaIsWow64Process(); + if (fIsWow64Process) + { + hr = WcaDisableWow64FSRedirection(); + if(FAILED(hr)) + { + //eat this error + hr = S_OK; + } + else + { + fIsFSRedirectDisabled = TRUE; + } + } + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", + wzConfigSource, + MAX_PATH + ); + if ( dwSize == 0 ) + { + ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + } + hr = ::StringCchCopyW(wzConfigCopy, MAX_PATH, wzConfigSource); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCopyW"); + + //add ca action as extension + + hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, L"."); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of ."); + + hr = ::StringCchCatW(wzConfigCopy, MAX_PATH, pwzData); + ExitOnFailure(hr, "Commit IIS7 failed StringCchCatW of extension"); + + //copy is reverse of start transaction + if (!::CopyFileW(wzConfigCopy, wzConfigSource, FALSE)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || + HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + WcaLog(LOGMSG_STANDARD, "Failed to restore applicationHost, not found - continuing"); + hr = S_OK; + } + else + { + ExitOnFailure(hr, "failed to restore config backup"); + } + } + + if (!::DeleteFileW(wzConfigCopy)) + { + ExitWithLastError(hr, "failed to delete config backup"); + } + + hr = WcaProgressMessage(COST_IIS_TRANSACTIONS, FALSE); + +LExit: + ReleaseStr(pwzData); + + // Make sure we revert FS Redirection if necessary before exiting + if (fIsFSRedirectDisabled) + { + fIsFSRedirectDisabled = FALSE; + WcaRevertWow64FSRedirection(); + } + WcaFinalizeWow64(); + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} diff --git a/src/ext/Iis/ca/scaexecIIS7.cpp b/src/ext/Iis/ca/scaexecIIS7.cpp new file mode 100644 index 00000000..108007a1 --- /dev/null +++ b/src/ext/Iis/ca/scaexecIIS7.cpp @@ -0,0 +1,4205 @@ +#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 "precomp.h" + +//local CAData action functions +HRESULT IIS7Site( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); + +HRESULT IIS7Application( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7VDir( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7Binding( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7AppPool( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7AppExtension( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7MimeMap( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7DirProperties( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7WebLog( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7FilterGlobal( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7FilterSite( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7HttpHeader( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7WebError( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7WebSvcExt( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7WebProperty( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7WebDir( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7AspProperty( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +HRESULT IIS7SslBinding( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ); +//local helper functions + +static HRESULT GetNextAvailableSiteId( + IAppHostWritableAdminManager *pAdminMgr, + DWORD *plSiteId + ); +static HRESULT GetSiteElement( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swSiteName, + IAppHostElement **pSiteElement, + BOOL* fFound + ); +static HRESULT GetApplicationElement( + IAppHostElement *pSiteElement, + LPCWSTR swAppPath, + IAppHostElement **pAppElement, + BOOL* fFound + ); +static HRESULT GetApplicationElementForVDir( + IAppHostElement *pSiteElement, + LPCWSTR swVDirPath, + IAppHostElement **ppAppElement, + LPCWSTR *ppwzVDirSubPath, + BOOL* fFound + ); + +static HRESULT CreateApplication( + IAppHostElement *pSiteElement, + LPCWSTR swAppPath, + IAppHostElement **pAppElement + ); +static HRESULT DeleteApplication( + IAppHostElement *pSiteElement, + LPCWSTR swAppPath + ); + +static HRESULT SetAppPool( + IAppHostElement *pAppElementpAppElement, + LPCWSTR pwzAppPool + ); +static HRESULT CreateVdir( + IAppHostElement *pAppElement, + LPCWSTR pwzVDirPath, + LPCWSTR pwzVDirPhyDir + ); +static HRESULT DeleteVdir( + IAppHostElement *pAppElement, + LPCWSTR pwzVDirPath + ); + +static HRESULT CreateBinding( + IAppHostElement *pSiteElem, + LPCWSTR pwzProtocol, + LPCWSTR pwzInfo + ); +static HRESULT DeleteBinding( + IAppHostElement *pSiteElem, + LPCWSTR pwzProtocol, + LPCWSTR pwzInfo + ); + +static HRESULT CreateSslBinding( + IAppHostElement *pSiteElem, + LPCWSTR pwzStoreName, + LPCWSTR pwzEncodedCertificateHash + ); +static HRESULT DeleteSslBinding( + IAppHostElement *pSiteElem, + LPCWSTR pwzStoreName, + LPCWSTR pwzEncodedCertificateHash + ); + +static HRESULT CreateSite( + IAppHostElementCollection *pAdminMgr, + LPCWSTR swSiteName, + IAppHostElement **pSiteElement + ); + +static HRESULT DeleteAppPool( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swAppPoolName + ); +static HRESULT CreateAppPool( + __inout LPWSTR *ppwzCustomActionData, + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swAppPoolName + ); + +static HRESULT SetDirPropAuthentications( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR wcConfigPath, + DWORD dwData + ); +static HRESULT SetDirPropAuthProvider( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR wszConfigPath, + __in LPWSTR wszData + ); +static HRESULT SetDirPropDefDoc( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR wszConfigPath, + __in LPWSTR wszData + ); + +static HRESULT ClearLocationTag( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swLocationPath + ); + +static HRESULT CreateWebLog( + IAppHostElement *pSiteElem, + LPCWSTR pwzFormat + ); + +static HRESULT CreateGlobalFilter( + __inout LPWSTR *ppwzCustomActionData, + IAppHostElement *pSection + ); +static HRESULT DeleteGlobalFilter( + __inout LPWSTR *ppwzCustomActionData, + IAppHostElement *pSection + ); + +static HRESULT CreateSiteFilter( + __inout LPWSTR *ppwzCustomActionData, + IAppHostWritableAdminManager *pAdminMgr + ); +static HRESULT DeleteSiteFilter( + __inout LPWSTR *ppwzCustomActionData, + IAppHostWritableAdminManager *pAdminMgr + ); + +static HRESULT DeleteCollectionElement( + __in IAppHostElementCollection *pCollection, + __in LPCWSTR pwzElementName, + __in LPCWSTR pwzAttributeName, + __in LPCWSTR pwzAttributeValue + ); + +struct SCA_WEB_ERROR_SERVER +{ + int iErrorCode; + int iSubCode; + WCHAR wzFile[MAX_PATH]; + WCHAR wzLangPath[MAX_PATH]; + int iResponseMode; + SCA_WEB_ERROR_SERVER *psweNext; +}; +static HRESULT AddWebErrorToList( + SCA_WEB_ERROR_SERVER** ppsweList + ); +static void ScaWebErrorFreeList7( + SCA_WEB_ERROR_SERVER *psweList + ); +static HRESULT PopulateHttpErrors( + IAppHostElement *pSection, + SCA_WEB_ERROR_SERVER **psweList + ); +static HRESULT GetErrorFromList( + const SCA_WEB_ERROR_SERVER & we, + SCA_WEB_ERROR_SERVER **ppsweList, + SCA_WEB_ERROR_SERVER **pswe, + BOOL *fFound + ); + +static void ConvSecToHMS( + int Sec, + __out_ecount(cchDest) LPWSTR wcTime, + size_t cchDest + ); +static void ConvSecToDHMS( + unsigned int Sec, + __out_ecount(cchDest) LPWSTR wcTime, + size_t cchDest + ); + +//////////////////////////////////////////////////////////////////// +// ScopeBSTR: Local helper class to construct & free BSTR from LPWSTR +// +///////////////////////////////////////////////////////////////////// +class ScopeBSTR +{ +public: + BSTR m_str; + + ScopeBSTR() + { + m_str = NULL; + } + + ScopeBSTR( __in LPCWSTR pSrc) + { + if (pSrc == NULL) + { + m_str = NULL; + } + else + { + m_str = ::SysAllocString(pSrc); + + } + } + + ~ScopeBSTR() + { + ::SysFreeString(m_str); + } + + operator BSTR() + { + return m_str; + } +}; + + +/******************************************************************** + IIS7ConfigChanges - Start of IIS7 config changes + + *******************************************************************/ +HRESULT IIS7ConfigChanges(MSIHANDLE /*hInstall*/, __inout LPWSTR pwzData) +{ + HRESULT hr = S_OK; + BOOL fInitializedCom = FALSE; + + IAppHostWritableAdminManager *pAdminMgr = NULL; + + LPWSTR pwz = NULL; + LPWSTR pwzLast = NULL; + LPWSTR pwzBackup = NULL; + DWORD cchData = lstrlenW(pwzData); + int iAction = -1; + + int iRetryCount = 0; + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "Failed to initialize COM"); + fInitializedCom = TRUE; + + pwz = pwzLast = pwzData; + + hr = StrAllocString(&pwzBackup, pwz, 0); + ExitOnFailure(hr, "Failed to backup custom action data"); + + while (S_OK == (hr = WcaReadIntegerFromCaData(&pwz, &iAction))) + { + if (NULL == pAdminMgr) + { + hr = ::CoCreateInstance( __uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + reinterpret_cast (&pAdminMgr)); + ExitOnFailure(hr , "Failed to open AppHostWritableAdminManager to configure IIS7"); + } + + switch (iAction) + { + case IIS_SITE: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7Site(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS site."); + break; + } + case IIS_APPLICATION: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7Application(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS application."); + break; + } + case IIS_VDIR: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7VDir(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS VDir."); + break; + } + case IIS_BINDING: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7Binding(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS site binding."); + break; + } + case IIS_APPPOOL: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7AppPool(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS appPool."); + break; + } + case IIS_APPEXT_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7AppExtension(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS AppExtension."); + break; + } + case IIS_MIMEMAP_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7MimeMap(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS MimeMap."); + break; + } + case IIS_DIRPROP_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7DirProperties(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS DirProperties."); + break; + } + case IIS_WEBLOG: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7WebLog(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS WebLog."); + break; + } + case IIS_FILTER_GLOBAL_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7FilterGlobal(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS filter global."); + break; + } + case IIS_FILTER_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7FilterSite(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS Filter."); + break; + } + case IIS_HTTP_HEADER_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7HttpHeader(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS http Header."); + break; + } + case IIS_WEBERROR_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7WebError(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS http Errors."); + break; + } + case IIS_WEB_SVC_EXT: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7WebSvcExt(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS web svc ext."); + break; + } + case IIS_PROPERTY: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7WebProperty(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS web property."); + break; + } + case IIS_WEBDIR: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7WebDir(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS web directory."); + break; + } + case IIS_ASP_BEGIN: + { +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7AspProperty(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS Asp property."); + break; + } + case IIS_SSL_BINDING: +#pragma prefast(suppress:26010, "This is a prefast issue - pAdminMgr is correctly allocated") + hr = IIS7SslBinding(&pwz, pAdminMgr); + ExitOnFailure(hr, "Failed to configure IIS SSL binding."); + break; + + default: + ExitOnFailure(hr = E_UNEXPECTED, "IIS7ConfigChanges: Unexpected IIS Config action specified: %d", iAction); + break; + } + if (S_OK == hr) + { + // commit config changes now to close out IIS Admin changes, + // the Rollback or Commit defered CAs will determine final commit status. + hr = pAdminMgr->CommitChanges(); + + // Our transaction may have been interrupted. + if (hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) || hr == HRESULT_FROM_WIN32(ERROR_TRANSACTIONAL_CONFLICT)) + { + WcaLog(LOGMSG_VERBOSE, "Sharing violation or transactional conflict during attempt to save changes to applicationHost.config"); + if (++iRetryCount > 30) + { + if (IDRETRY == WcaErrorMessage(msierrIISFailedCommitInUse, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0)) + { + iRetryCount = 0; + } + else + { + ExitOnFailure(hr, "Failed to Commit IIS Config Changes, in silent mode or user has chosen to cancel"); + } + } + + // Throw away the changes since IIS has no way to remove uncommited changes from an AdminManager. + ReleaseNullObject(pAdminMgr); + + // Restore our CA data backup + pwz = pwzLast; + hr = ::StringCchCopyW(pwz, cchData - (pwz - pwzData) + 1, pwzBackup); + ExitOnFailure(hr , "Failed to restore custom action data backup"); + + } + else if (FAILED(hr)) + { + ExitOnFailure(hr , "Failed to Commit IIS Config Changes"); + } + else + { + // store a backup of CA data @ the last place that we successfully commited changes unless we are done. + if(NULL != pwz) + { + pwzLast = pwz; + hr = StrAllocString(&pwzBackup, pwz, 0); + ExitOnFailure(hr, "Failed to backup custom action data"); + } + } + } + } + if (E_NOMOREITEMS == hr) // If there are no more items, all is well + { + hr = S_OK; + } +LExit: + ReleaseObject(pAdminMgr); + ReleaseStr(pwzBackup); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + return hr; +} +//------------------------------------------------------------------------------------------------- +// IIS7AspProperty +// Called by WriteIIS7ConfigChanges +// Processes asp properties for WebApplication +// +//------------------------------------------------------------------------------------------------- + +HRESULT IIS7AspProperty( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + + int iAction = -1; + int iData = 0; + + LPWSTR pwzData = NULL; + LPWSTR pwzSiteName = NULL; + LPWSTR pwzPathName = NULL; + LPWSTR pwzLocationPath = NULL; + WCHAR wcTime[60]; + + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + + //read web site key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed read webDir webkey"); + + //read path key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzPathName); + ExitOnFailure(hr, "Failed read webDir path"); + + //Construct Location path + hr = StrAllocFormatted(&pwzLocationPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); + ExitOnFailure(hr, "failed to format webDir location"); + // + //Do not append trailing '/' for default vDir + // + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzPathName, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzLocationPath, L"/", 0); + ExitOnFailure(hr, "failed to copy location WebDir '/'"); + hr = StrAllocConcat(&pwzLocationPath, pwzPathName, 0); + ExitOnFailure(hr, "failed to copy location WebDir path"); + } + + //get asp section at config path location tag + hr = pAdminMgr->GetAdminSection( ScopeBSTR(IIS_CONFIG_ASP_SECTION), pwzLocationPath, &pSection); + ExitOnFailure(hr, "Failed get httpErrors section"); + + // Get action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read property action"); + + while (IIS_ASP_END != iAction) + { + switch (iAction) + { + case IIS_ASP_SESSIONSTATE: + { + //system.webServer/asp /session | allowSessionState + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp session state"); + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_SESSION), &pElement); + ExitOnFailure(hr, "Failed to get asp session element"); + hr = Iis7PutPropertyBool( pElement, IIS_CONFIG_ALLOWSTATE, iData); + ExitOnFailure(hr, "Failed to put asp session value"); + ReleaseNullObject(pElement); + break; + } + case IIS_ASP_SESSIONTIMEOUT: + { + //system.webServer/asp /session | timeout + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp session timeout"); + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_SESSION), &pElement); + ExitOnFailure(hr, "Failed to get asp session timeout"); + *wcTime = '\0'; + ConvSecToHMS(iData * 60, wcTime, countof( wcTime)); + hr = Iis7PutPropertyString( pElement, IIS_CONFIG_TIMEOUT, wcTime); + ExitOnFailure(hr, "Failed to put asp timeout value"); + ReleaseNullObject(pElement); + break; + } + case IIS_ASP_BUFFER: + { + //system.webServer/asp | bufferingOn + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp bufferingOn"); + hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_BUFFERING, iData); + ExitOnFailure(hr, "Failed to put asp bufferingOn value"); + break; + } + case IIS_ASP_PARENTPATHS: + { + //system.webServer/asp | enableParentPaths + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp ParentPaths"); + hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_PARENTPATHS, iData); + ExitOnFailure(hr, "Failed to put asp ParentPaths value"); + break; + } + case IIS_ASP_SCRIPTLANG: + { + //system.webServer/asp | scriptLanguage + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read asp scriptLanguage"); + hr = Iis7PutPropertyString( pSection, IIS_CONFIG_SCRIPTLANG, pwzData); + ExitOnFailure(hr, "Failed to put asp scriptLanguage value"); + break; + } + case IIS_ASP_SCRIPTTIMEOUT: + { + //system.webServer/asp /limits | scriptTimeout + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp scriptTimeout"); + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_LIMITS), &pElement); + ExitOnFailure(hr, "Failed to get asp session element"); + *wcTime = '\0'; + ConvSecToHMS(iData, wcTime, countof( wcTime)); + hr = Iis7PutPropertyString( pElement, IIS_CONFIG_SCRIPTTIMEOUT, wcTime); + ExitOnFailure(hr, "Failed to put asp scriptTimeout value"); + ReleaseNullObject(pElement); + break; + + } + case IIS_ASP_SCRIPTSERVERDEBUG: + { + //system.webServer/asp | appAllowDebugging + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp appAllowDebugging"); + hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_ALLOWDEBUG, iData); + ExitOnFailure(hr, "Failed to put asp appAllowDebugging value"); + break; + } + case IIS_ASP_SCRIPTCLIENTDEBUG: + { + //system.webServer/asp | appAllowClientDebug + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read asp appAllowClientDebug"); + hr = Iis7PutPropertyBool( pSection, IIS_CONFIG_ALLOWCLIENTDEBUG, iData); + ExitOnFailure(hr, "Failed to put asp appAllowClientDebug value"); + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for asp properties"); + break; + } + } + // Get next action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read asp prop action"); + } + +LExit: + ReleaseStr(pwzData); + ReleaseStr(pwzSiteName); + ReleaseStr(pwzPathName); + ReleaseStr(pwzLocationPath); + ReleaseObject(pSection); + ReleaseObject(pElement); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7WebDir +// Called by WriteIIS7ConfigChanges +// Processes WebDir +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7WebDir( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + + int iAction = -1; + + LPWSTR pwzSiteName = NULL; + LPWSTR pwzPathName = NULL; + LPWSTR pwzLocationPath = NULL; + + // Get action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read property action"); + + //read web site key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed read webDir webkey"); + + //read path key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzPathName); + ExitOnFailure(hr, "Failed read webDir path"); + + switch (iAction) + { + case IIS_CREATE: + { + //no action needed for create since WebDir has a + //WebDirProperties element that will create and populate + //location tag + break; + } + case IIS_DELETE: + { + //Construct Location path + hr = StrAllocString(&pwzLocationPath, pwzSiteName, 0); + ExitOnFailure(hr, "failed to copy location WebDir web name"); + // + //Do not append trailing '/' for default vDir + // + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzPathName, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzLocationPath, L"/", 0); + ExitOnFailure(hr, "failed to copy location WebDir '/'"); + hr = StrAllocConcat(&pwzLocationPath, pwzPathName, 0); + ExitOnFailure(hr, "failed to copy location WebDir path"); + } + // and delete location tag for this application + hr = ClearLocationTag(pAdminMgr, pwzLocationPath); + ExitOnFailure(hr, "failed to clear location tag for %ls", pwzLocationPath) + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for WebDir"); + break; + } + } +LExit: + ReleaseStr(pwzSiteName); + ReleaseStr(pwzPathName); + ReleaseStr(pwzLocationPath); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7WebProperty +// Called by WriteIIS7ConfigChanges +// Processes isapiCgiRestriction +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7WebProperty( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + + int iAction = -1; + int iData = 0; + + IAppHostElement *pSection = NULL; + + // Get action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read property action"); + + switch (iAction) + { + case IIS_PROPERTY_MAXBAND: + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read property max band"); + //set value at system.applicationHost/webLimits | maxGlobalBandwidth + //Get IIS config section + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_WEBLIMITS_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); + ExitOnFailure(hr, "Failed get isapiCgiRestriction section"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get isapiCgiRestriction section object"); + } + hr = Iis7PutPropertyInteger(pSection, IIS_CONFIG_WEBLIMITS_MAXBAND, iData); + + break; + } + case IIS_PROPERTY_LOGUTF8: + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read property log"); + //set value at system.applicationHost/log | logInUTF8 + //Get IIS config section + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_LOG_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); + ExitOnFailure(hr, "Failed get isapiCgiRestriction section"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get isapiCgiRestriction section object"); + } + hr = Iis7PutPropertyBool(pSection, IIS_CONFIG_LOG_UTF8, iData); + + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for Web Property"); + break; + } + } + +LExit: + ReleaseObject(pSection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7WebSvcExt +// Called by WriteIIS7ConfigChanges +// Processes isapiCgiRestriction +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7WebSvcExt( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + + int iAction = -1; + int iData = 0; + BOOL fFound = FALSE; + LPWSTR pwzData = NULL; + LPWSTR pwzPath = NULL; + + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + // Get action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read WebSvcExt action"); + + //get path + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzPath); + ExitOnFailure(hr, "Failed to read WebSvcExt key"); + + //Get IIS config section + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_RESTRICTION_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); + ExitOnFailure(hr, "Failed get isapiCgiRestriction section"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get isapiCgiRestriction section object"); + } + //get collection + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get isapiCgiRestriction collection"); + + //find element + hr = Iis7FindAppHostElementPath(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_PATH, pwzPath, &pElement, NULL); + ExitOnFailure(hr, "Failed get isapiCgiRestriction element"); + fFound = (NULL != pElement); + + switch (iAction) + { + case IIS_CREATE: + { + if (!fFound) + { + //create a restriction element + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement); + ExitOnFailure(hr, "Failed create isapiCgiRestriction element"); + //put path + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzPath); + ExitOnFailure(hr, "Failed set isapiCgiRestriction path property"); + } + //update common properties + + //update allowed + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read WebSvcExt allowed"); + hr = Iis7PutPropertyBool(pElement, IIS_CONFIG_ALLOWED, iData); + ExitOnFailure(hr, "Failed set isapiCgiRestriction allowed property"); + + //update groupId + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read WebSvcExt group ID"); + if (*pwzData) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_GROUPID, pwzData); + ExitOnFailure(hr, "Failed set isapiCgiRestriction groupId property"); + } + //update description + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read WebSvcExt description"); + if (*pwzData) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_DESC, pwzData); + ExitOnFailure(hr, "Failed set isapiCgiRestriction description property"); + } + // add element if new + if (!fFound) + { + hr = pCollection->AddElement(pElement); + ExitOnFailure(hr, "Failed add isapiCgiRestriction element"); + } + + break; + } + case IIS_DELETE: + { + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_PATH, pwzPath); + ExitOnFailure(hr, "Failed delete isapiCgiRestriction element"); + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for WebSvcExt"); + break; + } + } + +LExit: + ReleaseStr(pwzPath); + ReleaseStr(pwzData); + ReleaseObject(pSection); + ReleaseObject(pElement); + ReleaseObject(pCollection); + + return hr; + +} + +//------------------------------------------------------------------------------------------------- +// IIS7WebError +// Called by WriteIIS7ConfigChanges +// Processes http header CA Data +// +//------------------------------------------------------------------------------------------------- + +HRESULT IIS7WebError( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzConfigPath = NULL; + LPWSTR pwzSiteName = NULL; + LPWSTR pwzAppName = NULL; + + IAppHostElement *pElement = NULL; + IAppHostElement *pSection = NULL; + IAppHostElementCollection *pCollection = NULL; + + SCA_WEB_ERROR_SERVER *psweList = NULL; + SCA_WEB_ERROR_SERVER* pswe = NULL; + SCA_WEB_ERROR_SERVER we; + BOOL fFound = FALSE; + + int iAction = -1; + LPWSTR pwzData = NULL; + + //read web site key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed read web error site name"); + + //read app key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppName); + ExitOnFailure(hr, "Failed read web error app name"); + + //Construct config root path + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); + ExitOnFailure(hr, "failed to format web error config path"); + + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzAppName, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzConfigPath, L"/", 0); + ExitOnFailure(hr, "failed to copy web error config path delim"); + hr = StrAllocConcat(&pwzConfigPath, pwzAppName, 0); + ExitOnFailure(hr, "failed to app name to web error config path"); + } + + //get httpErrors section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPERRORS_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get httpErrors section"); + + //get existing httpErrors list & clear collection + hr = PopulateHttpErrors(pSection, &psweList); + ExitOnFailure(hr, "Failed to read httpErrors list"); + + //get collection + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get httpErrors collection"); + + DWORD cErrors = 0; + hr = pCollection->get_Count(&cErrors); + + // Get web error action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + while (IIS_WEBERROR_END != iAction) + { + //Process property action + if (IIS_WEBERROR == iAction) + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &(we.iErrorCode)); + ExitOnFailure(hr, "failed to get httpErrors ErrorCode"); + + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &(we.iSubCode)); + ExitOnFailure(hr, "failed to get httpErrors SubCode"); + //0 is the sub error code wild card for IIS6, change to -1 for IIS7 + if (we.iSubCode == 0) + { + we.iSubCode = -1; + } + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to get httpErrors File"); + hr = ::StringCchCopyW(we.wzFile, countof(we.wzFile), pwzData); + ExitOnFailure(hr, "Failed to copy httpErrors File"); + + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &(we.iResponseMode)); + ExitOnFailure(hr, "Failed to get httpErrors File code"); + + fFound = FALSE; + hr = GetErrorFromList( we, &psweList, &pswe, &fFound); + if (!fFound) + { + hr = AddWebErrorToList(&psweList); + ExitOnFailure(hr, "failed to add web error to list"); + pswe = psweList; + } + else + { + //if overwriting existing http errors element then clear lang path + hr = ::StringCchCopyW(pswe->wzLangPath, countof(pswe->wzLangPath), L""); + ExitOnFailure(hr, "Failed to copy httpErrors lang path value"); + } + pswe->iErrorCode = we.iErrorCode; + pswe->iSubCode = we.iSubCode; + hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), we.wzFile); + ExitOnFailure(hr, "Failed to copy httpErrors File value"); + pswe->iResponseMode = we.iResponseMode; + + } + else + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for http header"); + } + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + } + + //No inheritance - put a clear in at this loc tag + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pElement); + ExitOnFailure(hr, "Failed create httpErrors clear"); + hr = pCollection->AddElement(pElement); + ExitOnFailure(hr, "Failed add httpErrors clear"); + + //now we have merged new, from MSI, http errors with global list + //write this back out at location tag. + // Loop through the HTTP headers + for ( pswe = psweList; pswe; pswe = pswe->psweNext) + { + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ERROR), &pElement); + ExitOnFailure(hr, "Failed create httpErrors element"); + + // status code + hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_STATUSCODE, pswe->iErrorCode); + ExitOnFailure(hr, "Failed set httpErrors code value"); + + //sub status + hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_SUBSTATUS, pswe->iSubCode); + ExitOnFailure(hr, "Failed set httpErrors sub code value"); + + //lang path + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_LANGPATH, pswe->wzLangPath); + ExitOnFailure(hr, "Failed set httpErrors lang path value"); + + //path + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pswe->wzFile); + ExitOnFailure(hr, "Failed set httpErrors path value"); + + //response mode + hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_RESPMODE, pswe->iResponseMode); + ExitOnFailure(hr, "Failed set httpErrors resp mode value"); + + //add the element + hr = pCollection->AddElement(pElement); + ExitOnFailure(hr, "Failed add httpErrors element"); + ReleaseNullObject(pElement); + } + +LExit: + ScaWebErrorFreeList7(psweList); + + ReleaseStr(pwzConfigPath); + ReleaseStr(pwzSiteName); + ReleaseStr(pwzAppName); + ReleaseStr(pwzData); + ReleaseObject(pElement); + ReleaseObject(pSection); + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT PopulateHttpErrors(IAppHostElement *pSection, SCA_WEB_ERROR_SERVER **ppsweList) +{ + HRESULT hr = S_OK; + + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + IAppHostProperty *pProperty = NULL; + + DWORD cErrors = 0; + SCA_WEB_ERROR_SERVER *pswe = NULL; + + VARIANT vPropValue; + VARIANT vtIndex; + + VariantInit(&vPropValue); + VariantInit(&vtIndex); + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get httpErrors collection"); + + hr = pCollection->get_Count(&cErrors); + ExitOnFailure(hr, "Failed get sites collection count"); + + vtIndex.vt = VT_UI4; + for (DWORD i = 0; i < cErrors; ++i) + { + vtIndex.ulVal = i; + hr = pCollection->get_Item(vtIndex , &pElement); + ExitOnFailure(hr, "Failed get httpErrors collection item"); + + hr = AddWebErrorToList(ppsweList); + ExitOnFailure(hr, "Failed add web error list item"); + pswe = *ppsweList; + + //get all properties + // + // statusCode UINT + // subStatusCode INT + // prefixLanguageFilePath type="string" + // path type="string" + // responseMode type="enum" defaultValue="File"> + // + // + // + + // status code + hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_STATUSCODE), &pProperty); + ExitOnFailure(hr, "Failed get httpErrors code property"); + hr = pProperty->get_Value(&vPropValue); + ExitOnFailure(hr, "Failed get httpErrors code value"); + pswe->iErrorCode = vPropValue.uintVal; + ReleaseVariant(vPropValue); + + //sub status + hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_SUBSTATUS), &pProperty); + ExitOnFailure(hr, "Failed get httpErrors sub code property"); + hr = pProperty->get_Value(&vPropValue); + ExitOnFailure(hr, "Failed get httpErrors sub code value"); + pswe->iSubCode = vPropValue.intVal; + ReleaseVariant(vPropValue); + + //lang path + hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_LANGPATH), &pProperty); + ExitOnFailure(hr, "Failed get httpErrors lang path property"); + hr = pProperty->get_Value(&vPropValue); + ExitOnFailure(hr, "Failed get httpErrors lang path value"); + hr = ::StringCchCopyW(pswe->wzLangPath, countof(pswe->wzLangPath), vPropValue.bstrVal); + ExitOnFailure(hr, "Failed to copy httpErrors lang path"); + ReleaseVariant(vPropValue); + + //path + hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_PATH), &pProperty); + ExitOnFailure(hr, "Failed get httpErrors path property"); + hr = pProperty->get_Value(&vPropValue); + ExitOnFailure(hr, "Failed get httpErrors path value"); + hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), vPropValue.bstrVal); + ExitOnFailure(hr, "Failed to copy httpErrors File"); + ReleaseVariant(vPropValue); + + //response mode + hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_RESPMODE), &pProperty); + ExitOnFailure(hr, "Failed get httpErrors resp mode property"); + hr = pProperty->get_Value(&vPropValue); + ExitOnFailure(hr, "Failed get httpErrors resp mode value"); + pswe->iResponseMode = vPropValue.intVal; + ReleaseVariant(vPropValue); + + ReleaseNullObject(pElement); + ReleaseNullObject(pProperty); + } + + //remove the elements from connection so we can add back later + hr = pCollection->Clear(); + ExitOnFailure(hr, "Failed clear httpErrors collection"); + +LExit: + ReleaseVariant(vPropValue); + ReleaseObject(pProperty); + ReleaseObject(pElement); + ReleaseObject(pCollection); + + return hr; +} + +static void ScaWebErrorFreeList7(SCA_WEB_ERROR_SERVER *psweList) +{ + SCA_WEB_ERROR_SERVER *psweDelete = psweList; + while (psweList) + { + psweDelete = psweList; + psweList = psweList->psweNext; + + MemFree(psweDelete); + } +} +static HRESULT AddWebErrorToList(SCA_WEB_ERROR_SERVER **ppsweList) +{ + HRESULT hr = S_OK; + + SCA_WEB_ERROR_SERVER* pswe = static_cast(MemAlloc(sizeof(SCA_WEB_ERROR_SERVER), TRUE)); + + ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); + + pswe->psweNext = *ppsweList; + *ppsweList = pswe; + +LExit: + return hr; +} +static HRESULT GetErrorFromList( const SCA_WEB_ERROR_SERVER& we, + SCA_WEB_ERROR_SERVER **ppsweList, + SCA_WEB_ERROR_SERVER **ppswe, + BOOL *fFound) +{ + HRESULT hr = S_OK; + + *fFound = FALSE; + + SCA_WEB_ERROR_SERVER *pswe; + + for ( pswe = *ppsweList; pswe; pswe = pswe->psweNext) + { + if ((pswe->iErrorCode == we.iErrorCode) && (pswe->iSubCode == we.iSubCode)) + { + *fFound = TRUE; + *ppswe = pswe; + break; + } + } + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7HttpHeader +// Called by WriteIIS7ConfigChanges +// Processes http header CA Data +// +//------------------------------------------------------------------------------------------------- + +HRESULT IIS7HttpHeader( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzConfigPath = NULL; + LPWSTR pwzSiteName = NULL; + LPWSTR pwzAppName = NULL; + + LPWSTR pwzHeaderName = NULL; + LPWSTR pwzHeaderValue = NULL; + + IAppHostElement *pElement = NULL; + IAppHostElement *pSection = NULL; + IAppHostElementCollection *pCollection = NULL; + IAppHostElement *pElementHeaders = NULL; + + int iAction = -1; + BOOL fFound = FALSE; + + //read web site key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed read header web site name"); + + //read app key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppName); + ExitOnFailure(hr, "Failed read header appkey"); + + //Construct config root path + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); + ExitOnFailure(hr, "failed to format web error config path"); + + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzAppName, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzConfigPath, L"/", 0); + ExitOnFailure(hr, "failed to copy web error config path delim"); + hr = StrAllocConcat(&pwzConfigPath, pwzAppName, 0); + ExitOnFailure(hr, "failed to app name to web error config path"); + } + + //get admin handlers section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPPROTO_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get http protocol section"); + + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_HEADERS), &pElementHeaders); + ExitOnFailure(hr, "Failed get http customHeaders section"); + + hr = pElementHeaders->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get http customHeaders collection"); + + // Get filter action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + while (IIS_HTTP_HEADER_END != iAction) + { + //Process property action + if (IIS_HTTP_HEADER == iAction) + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzHeaderName); + ExitOnFailure(hr, "Fail to read httpHeader name"); + + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzHeaderValue); + ExitOnFailure(hr, "Fail to read httpHeader value"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, pwzHeaderName, &pElement, NULL); + ExitOnFailure(hr, "Failed get isapiCgiRestriction element"); + fFound = (NULL != pElement); + + if (!fFound) + { + //make a new element + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement); + ExitOnFailure(hr, "Failed to create filter config element"); + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_NAME, pwzHeaderName); + ExitOnFailure(hr, "Failed to set header name"); + } + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_VALUE, pwzHeaderValue); + ExitOnFailure(hr, "Failed to set header Value"); + + if (!fFound) + { + hr = pCollection->AddElement(pElement); + ExitOnFailure(hr, "Failed add http header"); + } + + } + else + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for http header"); + } + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + } + +LExit: + ReleaseStr(pwzConfigPath); + ReleaseStr(pwzSiteName); + ReleaseStr(pwzAppName); + ReleaseStr(pwzHeaderName); + ReleaseStr(pwzHeaderValue); + ReleaseObject(pElementHeaders); + ReleaseObject(pElement); + ReleaseObject(pSection); + ReleaseObject(pCollection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7FilterGlobal +// Called by WriteIIS7ConfigChanges +// Processes Filter CA Data +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7FilterGlobal( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + int iAction = 0; + + IAppHostElement *pSection = NULL; + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ISAPI_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSection); + ExitOnFailure(hr, "Failed get sites section"); + + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get isapiFilters section object"); + } + + // Get filter action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + + while (IIS_FILTER_END != iAction) + { + //Process property action + switch (iAction) + { + case IIS_FILTER : + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + + if (iAction == IIS_CREATE) + { + hr = CreateGlobalFilter(ppwzCustomActionData, pSection); + } + else + { + hr = DeleteGlobalFilter(ppwzCustomActionData, pSection); + } + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for global filter"); + break; + } + } + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + + } + +LExit: + ReleaseObject(pSection); + + return hr; +} + +static HRESULT CreateGlobalFilter( __inout LPWSTR *ppwzCustomActionData, IAppHostElement *pSection) +{ + HRESULT hr = S_OK; + + LPWSTR pwzFilterName = NULL; + LPWSTR pwzSiteName = NULL; + LPWSTR pwzFilterPath = NULL; + int iLoadOrder = 0; + DWORD cFilters = 0; + + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get filter collection"); + + hr = pCollection->get_Count(&cFilters); + ExitOnFailure(hr, "Failed get filter collection count"); + + // Attempt to delete, we will we recreate with desired property values and order + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); + ExitOnFailure(hr, "Failed to delete filter"); + + //make a new element + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_FILTER), &pElement); + ExitOnFailure(hr, "Failed to create filter config element"); + + //filter Name key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); + ExitOnFailure(hr, "Failed to read filter name"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_NAME, pwzFilterName); + ExitOnFailure(hr, "Failed to set filter name"); + + //web site name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read filter site name"); + + // filter path + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterPath); + ExitOnFailure(hr, "Failed to read filter path"); + hr = Iis7PutPropertyString(pElement,IIS_CONFIG_PATH, pwzFilterPath); + ExitOnFailure(hr, "Failed to set filter path"); + + //filter load order + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iLoadOrder); + ExitOnFailure(hr, "Failed to read filter load order"); + + // put element in order in list + int iPosition = -1; + int icFilters = cFilters; + switch (iLoadOrder) + { + case 0 : + { + iPosition = -1; + break; + } + case -1 : + { + iPosition = icFilters; + break; + } + case MSI_NULL_INTEGER : + { + iPosition = icFilters; + break; + } + default: + { + if (iLoadOrder > icFilters) + { + iPosition = icFilters; + } + else + { + iPosition = iLoadOrder; + } + break; + } + } + hr = pCollection->AddElement(pElement, iPosition); + ExitOnFailure(hr, "Failed to add filter element"); + +LExit: + ReleaseStr(pwzFilterName); + ReleaseStr(pwzSiteName); + ReleaseStr(pwzFilterPath); + ReleaseObject(pCollection); + ReleaseObject(pElement); + + return hr; +} + +static HRESULT DeleteGlobalFilter( __inout LPWSTR *ppwzCustomActionData, IAppHostElement *pSection) +{ + HRESULT hr = S_OK; + + LPWSTR pwzFilterName = NULL; + LPWSTR pwzSiteName = NULL; + + IAppHostElementCollection *pCollection = NULL; + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get filter collection"); + + //filter Name key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); + ExitOnFailure(hr, "Failed to read filter name"); + + //web site name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); // TODO: unused? + ExitOnFailure(hr, "Failed to read filter site name"); + + DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); + ExitOnFailure(hr, "Failed to delete filter %ls", pwzFilterName); + +LExit: + ReleaseStr(pwzFilterName); + ReleaseStr(pwzSiteName); + ReleaseObject(pCollection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7FilterSite +// Called by WriteIIS7ConfigChanges +// Processes Filter CA Data +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7FilterSite( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + int iAction = 0; + + // Get filter action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + + while (IIS_FILTER_END != iAction) + { + //Process property action + switch (iAction) + { + case IIS_FILTER : + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + + if (iAction == IIS_CREATE) + { + hr = CreateSiteFilter(ppwzCustomActionData, pAdminMgr); + } + else + { + hr = DeleteSiteFilter(ppwzCustomActionData, pAdminMgr); + } + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for global filter"); + break; + } + } + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read filter action"); + } + +LExit: + return hr; + +} + +static HRESULT CreateSiteFilter(__inout LPWSTR *ppwzCustomActionData, IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + LPWSTR pwzFilterName = NULL; + LPWSTR pwzSiteName = NULL; + LPWSTR pwzFilterPath = NULL; + LPWSTR pwzConfigPath = NULL; + int iLoadOrder = 0; + DWORD cFilters; + + IAppHostElement *pElement = NULL; + IAppHostElement *pSection = NULL; + IAppHostElementCollection *pCollection = NULL; + + //filter Name key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); + ExitOnFailure(hr, "Failed to read filter name"); + + //web site name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read filter site name"); + + //Construct config root + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); + ExitOnFailure(hr, "failed to format filter config path"); + + //get admin isapiFilters section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ISAPI_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get isapiFilters section"); + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get filter collection"); + + hr = pCollection->get_Count(&cFilters); + ExitOnFailure(hr, "Failed get filter collection count"); + + // Attempt to delete, we will we recreate with desired property values and order + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); + ExitOnFailure(hr, "Failed to delete filter"); + + //make a new element + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_FILTER), &pElement); + ExitOnFailure(hr, "Failed to create filter config element"); + + hr = Iis7PutPropertyString(pElement,IIS_CONFIG_NAME, pwzFilterName); + ExitOnFailure(hr, "Failed to set filter name"); + + // filter path + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterPath); + ExitOnFailure(hr, "Failed to read filter path"); + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzFilterPath); + ExitOnFailure(hr, "Failed to set filter path"); + + //filter load order + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iLoadOrder); + ExitOnFailure(hr, "Failed to read filter load order"); + + // put element in order in list + int iPosition = -1; + int icFilters = cFilters; + switch (iLoadOrder) + { + case 0 : + { + iPosition = -1; + break; + } + case -1 : + { + iPosition = icFilters; + break; + } + case MSI_NULL_INTEGER : + { + iPosition = icFilters; + break; + } + default: + { + if (iLoadOrder > icFilters) + { + iPosition = icFilters; + } + else + { + iPosition = iLoadOrder; + } + break; + } + } + + hr = pCollection->AddElement(pElement, iPosition); + ExitOnFailure(hr, "Failed to add filter element"); + +LExit: + ReleaseStr(pwzFilterName); + ReleaseStr(pwzSiteName); + ReleaseStr(pwzFilterPath); + ReleaseStr(pwzConfigPath); + ReleaseObject(pElement); + ReleaseObject(pSection); + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT DeleteSiteFilter(__inout LPWSTR *ppwzCustomActionData, IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + LPWSTR pwzFilterName = NULL; + LPWSTR pwzSiteName = NULL; + LPWSTR pwzConfigPath = NULL; + + IAppHostElement *pSection = NULL; + IAppHostElementCollection *pCollection = NULL; + + //filter Name key + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzFilterName); + ExitOnFailure(hr, "Failed to read filter name"); + + //web site name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read filter site name"); + + //Construct config root + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzSiteName); + ExitOnFailure(hr, "failed to format filter config path"); + + //get admin isapiFilters section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ISAPI_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get isapiFilters section"); + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get filter collection"); + + DeleteCollectionElement(pCollection, IIS_CONFIG_FILTER, IIS_CONFIG_NAME, pwzFilterName); + ExitOnFailure(hr, "Failed to delete filter %ls", pwzFilterName); + +LExit: + ReleaseStr(pwzFilterName); + ReleaseStr(pwzSiteName); + ReleaseStr(pwzConfigPath); + ReleaseObject(pSection); + ReleaseObject(pCollection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7Site +// Called by WriteIIS7ConfigChanges +// Processes WebSite CA Data +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7Site( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + int iAction = -1; + int iData = 0; + BOOL fFound = FALSE; + + LPWSTR pwzSiteName = NULL; + IAppHostElement *pSites = NULL; + IAppHostElementCollection *pCollection = NULL; + IAppHostElement *pSiteElem = NULL; + IAppHostElement *pElement = NULL; + + // Get site action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read site action"); + + //get site name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read site key"); + + //Get site if it exists + hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fFound); + ExitOnFailure(hr, "Failed to read sites from config"); + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_SITES_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSites); + ExitOnFailure(hr, "Failed get sites section"); + ExitOnNull(pSites, hr, ERROR_FILE_NOT_FOUND, "Failed get sites section object"); + + hr = pSites->get_Collection( &pCollection); + ExitOnFailure(hr, "Failed get site collection"); + switch (iAction) + { + case IIS_DELETE : + { + if (fFound) + { + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_NAME, pwzSiteName); + ExitOnFailure(hr, "Failed to delete website"); + } + ExitFunction(); + break; + } + case IIS_CREATE : + { + if (!fFound) + { + //Create the site + hr = CreateSite(pCollection, pwzSiteName, &pSiteElem); + ExitOnFailure(hr, "Failed to create site"); + + } + } + } + // + //Set other Site properties + // + //set site Id + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read site Id"); + if (iData != MSI_NULL_INTEGER && -1 != iData) + { + hr = Iis7PutPropertyInteger(pSiteElem, IIS_CONFIG_SITE_ID, iData); + ExitOnFailure(hr, "Failed set site Id data"); + } + //Set Site AutoStart + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read site autostart"); + if (MSI_NULL_INTEGER != iData) + { + hr = Iis7PutPropertyBool(pSiteElem, IIS_CONFIG_AUTOSTART, iData); + ExitOnFailure(hr, "Failed set site config data"); + } + + //Set Site Connection timeout + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read site connection tomeout data"); + if (MSI_NULL_INTEGER != iData) + { + // get limits element, get connectionTimeout property + hr = pSiteElem->GetElementByName(ScopeBSTR(IIS_CONFIG_LIMITS), &pElement); + ExitOnFailure(hr, "Failed to read limits from config"); + //convert iData in seconds to timeSpan hh:mm:ss + WCHAR wcTime[60]; + *wcTime = '\0'; + ConvSecToHMS( iData, wcTime, countof( wcTime)); + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CONNECTTIMEOUT, wcTime); + ExitOnFailure(hr, "IIS: failed set connection timeout config data"); + } + +LExit: + ReleaseStr(pwzSiteName); + ReleaseObject(pSites); + ReleaseObject(pCollection); + ReleaseObject(pSiteElem); + ReleaseObject(pElement); + + return hr; +} +//------------------------------------------------------------------------------------------------- +// IIS7Application +// Processes Application CA Data +// +// +//------------------------------------------------------------------------------------------------- + +HRESULT IIS7Application( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + + int iAction = -1; + BOOL fSiteFound = FALSE; + BOOL fAppFound = FALSE; + + LPWSTR pwzSiteName = NULL; + LPWSTR pwzAppPath = NULL; + LPWSTR pwzAppPool = NULL; + LPWSTR pwzLocationPath = NULL; + IAppHostElement *pSiteElem = NULL; + IAppHostElement *pAppElement = NULL; + // Get Application action + hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read application action") + //get site key name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read app site key"); + //get application path + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppPath); + ExitOnFailure(hr, "Failed to read app path key"); + //get application Pool + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppPool); + ExitOnFailure(hr, "Failed to read app pool key"); + + //Get site if it exists + hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); + ExitOnFailure(hr, "Failed to read sites from config"); + + switch (iAction) + { + case IIS_CREATE : + { + if (fSiteFound) + { + //have site get application collection + hr = GetApplicationElement(pSiteElem, + pwzAppPath, + &pAppElement, + &fAppFound); + ExitOnFailure(hr, "Error reading application from config"); + + if (!fAppFound) + { + //Create Application + hr = CreateApplication(pSiteElem, pwzAppPath, &pAppElement); + ExitOnFailure(hr, "Error creating application in config"); + } + //Update application properties: + // + //Set appPool + hr = SetAppPool(pAppElement, pwzAppPool); + ExitOnFailure(hr, "Unable to set appPool for application"); + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Site not found for create application"); + } + break; + } + case IIS_DELETE : + { + if (fSiteFound) + { + //have site get application collection + hr = GetApplicationElement( pSiteElem, + pwzAppPath, + &pAppElement, + &fAppFound); + ExitOnFailure(hr, "Error reading application from config") + if (fAppFound) + { + //delete Application + hr = DeleteApplication(pSiteElem, pwzAppPath); + ExitOnFailure(hr, "Error deleating application from config") + //Construct Location path + // TODO: it seems odd that these are just + // jammed together, need to determine if this requires a '\' + hr = StrAllocString(&pwzLocationPath, pwzSiteName, 0); + ExitOnFailure(hr, "failed to copy location config path web name"); + hr = StrAllocConcat(&pwzLocationPath, pwzAppPath, 0); + ExitOnFailure(hr, "failed to copy location config path appPath "); + + // and delete location tag for this application + hr = ClearLocationTag(pAdminMgr, pwzLocationPath); + ExitOnFailure(hr, "failed to clear location tag for %ls", pwzLocationPath); + } + } + break; + } + default: + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for Application"); + break; + } + +LExit: + ReleaseStr(pwzSiteName); + ReleaseStr(pwzAppPath); + ReleaseStr(pwzAppPool); + ReleaseStr(pwzLocationPath); + ReleaseObject(pSiteElem); + ReleaseObject(pAppElement); + + return hr; +} +//------------------------------------------------------------------------------------------------- +// IIS7VDir +// Processes VDir CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7VDir( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + + int iAction = -1; + BOOL fSiteFound = FALSE; + BOOL fAppFound = FALSE; + + LPWSTR pwzSiteName = NULL; + LPWSTR pwzVDirPath = NULL; + LPWSTR pwzVDirPhyDir = NULL; + LPCWSTR pwzVDirSubPath = NULL; + + IAppHostElement *pSiteElem = NULL; + IAppHostElement *pAppElement = NULL; + IAppHostElementCollection *pElement = NULL; + + // Get Application action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read VDir action"); + + //get site key name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read site key"); + //get VDir path + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzVDirPath); + ExitOnFailure(hr, "Failed to read VDir key"); + //get physical dir path + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzVDirPhyDir); + ExitOnFailure(hr, "Failed to read VDirPath key"); + + //Get site if it exists + hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); + ExitOnFailure(hr, "Failed to read sites from config"); + + if (IIS_CREATE == iAction) + { + if (fSiteFound) + { + //have site get application + hr = GetApplicationElementForVDir( pSiteElem, + pwzVDirPath, + &pAppElement, + &pwzVDirSubPath, + &fAppFound); + ExitOnFailure(hr, "Error reading application element from config"); + + if (!fAppFound) + { + // need application to add vDir + hr = E_FILENOTFOUND; + ExitOnFailure(hr, "Error application not found for create VDir"); + } + // + // create the virDir + // + hr = CreateVdir(pAppElement, pwzVDirSubPath, pwzVDirPhyDir); + ExitOnFailure(hr, "Failed to create vdir for application"); + } + else + { + hr = E_FILENOTFOUND; + ExitOnFailure(hr, "IIS: site not found for create VDir"); + } + } + else if (IIS_DELETE == iAction) + { + if (fSiteFound) + { + //have site get application + hr = GetApplicationElementForVDir( pSiteElem, + pwzVDirPath, + &pAppElement, + &pwzVDirSubPath, + &fAppFound); + ExitOnFailure(hr, "Error reading application from config") + if (fAppFound) + { + //delete vdir + hr = DeleteVdir(pAppElement, pwzVDirSubPath); + ExitOnFailure(hr, "Unable to delete vdir for application"); + } + } + } + + LExit: + ReleaseStr(pwzSiteName); + ReleaseStr(pwzVDirPath); + ReleaseStr(pwzVDirPhyDir); + ReleaseObject(pSiteElem); + ReleaseObject(pAppElement); + ReleaseObject(pElement); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7Binding +// Processes Bindings CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7Binding( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + + int iAction = -1; + BOOL fSiteFound = FALSE; + + LPWSTR pwzSiteName = NULL; + LPWSTR pwzProtocol = NULL; + LPWSTR pwzInfo = NULL; + + IAppHostElement *pSiteElem = NULL; + + // Get Application action + hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read binding action"); + + //get site key name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read binding site name key"); + + //get binding protocol + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzProtocol); + ExitOnFailure(hr, "Failed to read binding protocol"); + + //get binding info + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzInfo); + ExitOnFailure(hr, "Failed to read binding info"); + + //Get site if it exists + hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); + ExitOnFailure(hr, "Failed to read sites from config"); + + if (IIS_CREATE == iAction) + { + if (fSiteFound) + { + //add binding + hr = CreateBinding(pSiteElem, pwzProtocol, pwzInfo); + ExitOnFailure(hr, "Failed to create site binding"); + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Site not found for create binding"); + } + } + else if (IIS_DELETE == iAction) + { + if (fSiteFound) + { + //delete binding + hr = DeleteBinding(pSiteElem, pwzProtocol, pwzInfo); + ExitOnFailure(hr, "Failed to delete binding"); + } + } + + LExit: + ReleaseStr(pwzSiteName); + ReleaseStr(pwzProtocol); + ReleaseStr(pwzInfo); + ReleaseObject(pSiteElem); + + return hr; +} +//------------------------------------------------------------------------------------------------- +// IIS7Binding +// Processes WebLog CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7WebLog( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + + BOOL fSiteFound = FALSE; + + LPWSTR pwzSiteName = NULL; + LPWSTR pwzLogFormat = NULL; + + IAppHostElement *pSiteElem = NULL; + + //get site key name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read web log site name key"); + + //get log format + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzLogFormat); + ExitOnFailure(hr, "Failed to read web log protocol"); + + //Get site if it exists + hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); + ExitOnFailure(hr, "Failed to read web log sites from config"); + + if (fSiteFound) + { + //add log format + hr = CreateWebLog(pSiteElem, pwzLogFormat); + ExitOnFailure(hr, "Failed to create weblog file format"); + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Site not found for create weblog file format"); + } + + LExit: + ReleaseStr(pwzSiteName); + ReleaseStr(pwzLogFormat); + ReleaseObject(pSiteElem); + + return hr; +} +//------------------------------------------------------------------------------------------------- +// IIS7AppPool +// Processes AppPool CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7AppPool( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + + int iAction = -1; + + LPWSTR pwzAppPoolName = NULL; + + // Get AppPool action + hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read AppPool action"); + + //get appPool name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzAppPoolName); + ExitOnFailure(hr, "Failed to read AppPool name key"); + + switch (iAction) + { + case IIS_CREATE : + { + hr = CreateAppPool(ppwzCustomActionData, pAdminMgr, pwzAppPoolName); + break; + } + case IIS_DELETE: + { + hr = DeleteAppPool(pAdminMgr, pwzAppPoolName); + break; + } + default: + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for appPool"); + break; + } + +LExit: + ReleaseStr(pwzAppPoolName); + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7AppExtension +// Processes AppExtension (config handlers) CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7AppExtension( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr) +{ + HRESULT hr = S_OK; + + LPWSTR pwzWebName = NULL; + LPWSTR pwzWebRoot = NULL; + LPWSTR pwzData = NULL; + LPWSTR pwzConfigPath = NULL; + LPWSTR pwzHandlerName = NULL; + LPWSTR pwzPath = NULL; + int iAction = -1; + + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + BOOL fFound = FALSE; + DWORD cHandlers = 1000; + + //get web name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebName); + ExitOnFailure(hr, "Failed to read appExt Web name key"); + + //get root name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebRoot); + ExitOnFailure(hr, "Failed to read appExt Web name key"); + + //Construct config root + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzWebName); + ExitOnFailure(hr, "failed to format appext config path"); + // + //Do not append trailing '/' for default vDir + // + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzWebRoot, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzConfigPath, L"/", 0); + ExitOnFailure(hr, "failed to copy appext config path delim"); + hr = StrAllocConcat(&pwzConfigPath, pwzWebRoot, 0); + ExitOnFailure(hr, "failed to copy appext config path root name"); + } + //get admin handlers section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HANDLERS_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get appext section"); + + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get appext section object"); + } + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read appExt action"); + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get handlers collection for appext"); + + while (IIS_APPEXT_END != iAction) + { + fFound = FALSE; + + //Process property action + switch (iAction) + { + case IIS_APPEXT : + { + // These IDs aren't really stable but this is stable enough to support repair since the MSI won't change + hr = StrAllocFormatted(&pwzHandlerName, L"MsiCustom-%u", ++cHandlers); + ExitOnFailure(hr, "Failed increment handler name"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, pwzHandlerName, &pElement, NULL); + ExitOnFailure(hr, "Failed to find mimemap extension"); + + fFound = (NULL != pElement); + if (!fFound) + { + //create new handler element + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement); + ExitOnFailure(hr, "Failed get create handler element for appext"); + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_NAME, pwzHandlerName); + ExitOnFailure(hr, "Failed set appext name property"); + } + + //BUGBUG: For compat we are assuming these are all ISAPI MODULES so we are + //setting the modules property to IsapiModule. + //Currently can't deal with handlers of different module types. + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_MODULES, L"IsapiModule"); + ExitOnFailure(hr, "Failed set site appExt path property"); + + //get extension (path) + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read appExt extension"); + hr = StrAllocFormatted(&pwzPath, L"*.%s", pwzData); + ExitOnFailure(hr, "Failed decorate appExt path"); + //put property + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzPath); + ExitOnFailure(hr, "Failed set site appExt path property"); + + //get executable + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read appExt executable"); + //put property + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_EXECUTABLE, pwzData); + ExitOnFailure(hr, "Failed set site appExt executable property"); + + //get verbs + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read appExt verbs"); + //put property + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_VERBS, pwzData); + ExitOnFailure(hr, "Failed set site appExt verbs property"); + + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for AppExt"); + break; + } + } + + if (!fFound) + { + // put handler element at beginning of list + hr = pCollection->AddElement(pElement, 0); + ExitOnFailure(hr, "Failed add handler element for appext"); + } + + ReleaseNullObject(pElement); + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read AppPool Property action"); + } + +LExit: + ReleaseStr(pwzWebName); + ReleaseStr(pwzWebRoot); + ReleaseStr(pwzData); + ReleaseStr(pwzConfigPath); + ReleaseStr(pwzHandlerName); + ReleaseStr(pwzPath); + ReleaseObject(pSection); + ReleaseObject(pElement); + ReleaseObject(pCollection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7MimeMap +// Processes Mime Map (config handlers) CA Data +// +// +//------------------------------------------------------------------------------------------------- + HRESULT IIS7MimeMap( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzConfigPath = NULL; + LPWSTR pwzWebName = NULL; + LPWSTR pwzWebRoot = NULL; + LPWSTR pwzData = NULL; + int iAction = -1; + + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + BOOL fFound = FALSE; + + //get web name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebName); + ExitOnFailure(hr, "Failed to read mime map Web name key"); + + //get vdir root name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebRoot); + ExitOnFailure(hr, "Failed to read vdir root name key"); + + //Construct config root + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzWebName); + ExitOnFailure(hr, "failed to format mime map config path web name"); + // + //Do not append trailing '/' for default vDir + // + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzWebRoot, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzConfigPath, L"/", 0); + ExitOnFailure(hr, "failed to copy appext config path delim"); + hr = StrAllocConcat(&pwzConfigPath, pwzWebRoot, 0); + ExitOnFailure(hr, "failed to copy appext config path root name"); + } + + //get admin section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get staticContent section for mimemap"); + + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get staticContent section object"); + } + + // Get mimemap action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read mimemap action"); + + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get staticContent collection for mimemap"); + + while (IIS_MIMEMAP_END != iAction) + { + //Process property action + switch (iAction) + { + case IIS_MIMEMAP : + { + //get extension + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read mimemap extension"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_MIMEMAP, IIS_CONFIG_FILEEXT, pwzData, &pElement, NULL); + ExitOnFailure(hr, "Failed to find mimemap extension"); + fFound = (NULL != pElement); + + if (!fFound) + { + //create new mimeMap element + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_MIMEMAP), &pElement); + ExitOnFailure(hr, "Failed get create MimeMap element"); + } + + //put property + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_FILEEXT, pwzData); + ExitOnFailure(hr, "Failed set mimemap extension property"); + + //get type + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read mimemap type"); + //put property + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_MIMETYPE, pwzData); + ExitOnFailure(hr, "Failed set mimemap type property"); + + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for mimeMap"); + break; + } + } + + if (!fFound) + { + // put mimeMap element at beginning of list + hr = pCollection->AddElement(pElement, -1); + ExitOnFailure(hr, "Failed add mimemap"); + } + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read mimemap action"); + + ReleaseNullObject(pElement); + } + +LExit: + ReleaseStr(pwzConfigPath); + ReleaseStr(pwzWebName); + ReleaseStr(pwzWebRoot); + ReleaseStr(pwzData); + ReleaseObject(pSection); + ReleaseObject(pElement); + ReleaseObject(pCollection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7DirProperties +// ProcessesVdir Properties CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7DirProperties( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + WCHAR wcTime[60]; + LPWSTR pwzConfigPath = NULL; + LPWSTR pwzWebName = NULL; + LPWSTR pwzWebRoot = NULL; + LPWSTR pwzData = NULL; + int iAction = -1; + int iData = 0; + DWORD dwData = 0; + + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + //get web name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebName); + ExitOnFailure(hr, "Failed to read DirProp Web name key"); + + //get vdir root name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzWebRoot); + ExitOnFailure(hr, "Failed to read DirProp Web name key"); + + //Construct config root + hr = StrAllocFormatted(&pwzConfigPath, L"%s/%s", IIS_CONFIG_APPHOST_ROOT, pwzWebName); + ExitOnFailure(hr, "failed to format mime map config path web name"); + // + //Do not append trailing '/' for default vDir + // + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzWebRoot, -1, L"/", -1)) + { + hr = StrAllocConcat(&pwzConfigPath, L"/", 0); + ExitOnFailure(hr, "failed to copy appext config path delim"); + hr = StrAllocConcat(&pwzConfigPath, pwzWebRoot, 0); + ExitOnFailure(hr, "failed to copy appext config path root name"); + } + + // Get DirProps action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read DirProps action"); + + while (IIS_DIRPROP_END != iAction) + { + //Process property action + switch (iAction) + { + case IIS_DIRPROP_ACCESS : + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read DirProps access"); + //iData contains bit flags for + //no translation required + //get admin section at config path location tag + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HANDLERS_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get handlers section for DirProp"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get handlers section object for DirProps"); + } + dwData = iData; + hr = Iis7PutPropertyInteger( pSection, L"accessPolicy", dwData); + ExitOnFailure(hr, "Failed set accessPolicy for DirProps"); + ReleaseNullObject(pSection); + break; + } + case IIS_DIRPROP_USER : + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read DirProps user"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/anonymousAuthentication"), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get AnonymousAuthentication section for DirProp"); + hr = Iis7PutPropertyString( pSection, IIS_CONFIG_USERNAME, pwzData); + ExitOnFailure(hr, "Failed set accessPolicy for DirProps"); + ReleaseNullObject(pSection); + break; + } + case IIS_DIRPROP_PWD : + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read DirProps pwd"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/anonymousAuthentication"), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get AnonymousAuthentication section for DirProp"); + hr = Iis7PutPropertyString( pSection, IIS_CONFIG_PASSWORD, pwzData); + ExitOnFailure(hr, "Failed set accessPolicy for DirProps"); + ReleaseNullObject(pSection); + break; + } + case IIS_DIRPROP_DEFDOCS : + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read DirProps def doc"); + hr = SetDirPropDefDoc(pAdminMgr, pwzConfigPath, pwzData); + ExitOnFailure(hr, "Failed to set DirProps Default Documents"); + break; + } + case IIS_DIRPROP_AUTH : + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read DirProps auth"); + //iData contains bit flags for /security/authentication/<...> + // Anonymous = 1 + // Basic = 2 + // Windows = 4 + // Digest =16 + // Passport =64 *not supported + //translation required from bit map to section + // E.G security/authentication/windowsAuthentication [property enabled true|false] + dwData= iData; + hr = SetDirPropAuthentications(pAdminMgr, pwzConfigPath, dwData); + ExitOnFailure(hr, "Failed set Authentication for DirProps"); + break; + } + case IIS_DIRPROP_SSLFLAGS : + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read DirProps sslFlags"); + //iData contains bit flags for /security/access sslFlags + //no translation required + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/access"), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get security/access section for DirProp"); + dwData = iData; + hr = Iis7PutPropertyInteger( pSection, L"sslFlags", dwData); + ExitOnFailure(hr, "Failed set security/access for DirProps"); + ReleaseNullObject(pSection); + break; + } + case IIS_DIRPROP_AUTHPROVID : + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read DirProps auth provider"); + hr = SetDirPropAuthProvider(pAdminMgr, pwzConfigPath, pwzData); + ExitOnFailure(hr, "Failed to set DirProps auth provider"); + break; + } + case IIS_DIRPROP_ASPERROR: + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read DirProps aspDetailedError"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_ASP_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get asp section for DirProp"); + hr = Iis7PutPropertyBool(pSection, IIS_CONFIG_SCRIPTERROR, iData); + ExitOnFailure(hr, "Failed to set DirProps aspDetailedError"); + ReleaseNullObject(pSection); + break; + } + case IIS_DIRPROP_HTTPEXPIRES: + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read DirProps httpExpires provider"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get staticContent section for DirProp"); + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_CLIENTCACHE), &pElement); + ExitOnFailure(hr, "Failed to get clientCache element"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_HTTPEXPIRES, pwzData); + ExitOnFailure(hr, "Failed to set clientCache httpExpires value"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CACHECONTROLMODE, IIS_CONFIG_USEEXPIRES); + ExitOnFailure(hr, "Failed to set clientCache cacheControlMode value"); + ReleaseNullObject(pSection); + ReleaseNullObject(pElement); + break; + } + case IIS_DIRPROP_MAXAGE: + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read DirProps httpExpires provider"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get staticContent section for DirProp"); + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_CLIENTCACHE), &pElement); + ExitOnFailure(hr, "Failed to get clientCache element"); + *wcTime = '\0'; + ConvSecToDHMS(iData, wcTime, countof(wcTime)); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_MAXAGE, wcTime); + ExitOnFailure(hr, "Failed to set clientCache maxAge value"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CACHECONTROLMODE, IIS_CONFIG_USEMAXAGE); + ExitOnFailure(hr, "Failed to set clientCache cacheControlMode value"); + ReleaseNullObject(pSection); + ReleaseNullObject(pElement); + break; + } + case IIS_DIRPROP_CACHECUST: + { + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read DirProps cacheControlCustom"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_STATICCONTENT_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get staticContent section for DirProp"); + hr = pSection->GetElementByName(ScopeBSTR(IIS_CONFIG_CLIENTCACHE), &pElement); + ExitOnFailure(hr, "Failed to get clientCache element"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CACHECUST, pwzData); + ExitOnFailure(hr, "Failed to set clientCache cacheControlCustom value"); + ReleaseNullObject(pSection); + ReleaseNullObject(pElement); + break; + } + case IIS_DIRPROP_NOCUSTERROR: + { + //no value, if have ID tag write clear to system.webServer/httpErrors + //error collection + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPERRORS_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get httperrors section for DirProp"); + hr = pSection->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get error collection for DirProp"); + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pElement); + ExitOnFailure(hr, "Failed to create clear element for error collection for DirProp"); + hr = pCollection->AddElement(pElement); + ExitOnFailure(hr, "Failed to add lear element for error collection for DirProp"); + ReleaseNullObject(pSection); + ReleaseNullObject(pElement); + break; + } + case IIS_DIRPROP_LOGVISITS: + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read DirProps logVisits"); + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_HTTPLOGGING_SECTION), pwzConfigPath, &pSection); + ExitOnFailure(hr, "Failed get httpLogging section for DirProp"); + hr = Iis7PutPropertyBool(pSection, IIS_CONFIG_DONTLOG, iData); + ExitOnFailure(hr, "Failed to set DirProps aspDetailedError"); + ReleaseNullObject(pSection); + break; + } + default: + { + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for WebDirProperties"); + break; + } + } + + // Get AppExt action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read DirProps Property action"); + } +LExit: + ReleaseStr(pwzConfigPath); + ReleaseStr(pwzWebName); + ReleaseStr(pwzWebRoot); + ReleaseStr(pwzData); + ReleaseObject(pSection); + ReleaseObject(pElement); + ReleaseObject(pCollection); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// IIS7SslBinding +// ProcessesVdir Properties CA Data +// +// +//------------------------------------------------------------------------------------------------- +HRESULT IIS7SslBinding( + __inout LPWSTR *ppwzCustomActionData, + __in IAppHostWritableAdminManager *pAdminMgr + ) +{ + HRESULT hr = S_OK; + int iAction = -1; + BOOL fSiteFound = FALSE; + + LPWSTR pwzSiteName = NULL; + LPWSTR pwzStoreName = NULL; + LPWSTR pwzEncodedCertificateHash = NULL; + + IAppHostElement *pSiteElem = NULL; + + // Get Application action + hr = WcaReadIntegerFromCaData( ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read binding action"); + + //get site key name + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzSiteName); + ExitOnFailure(hr, "Failed to read binding site name key"); + + //get binding protocol + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzStoreName); + ExitOnFailure(hr, "Failed to read binding protocol"); + + //get binding info + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzEncodedCertificateHash); + ExitOnFailure(hr, "Failed to read binding info"); + + //Get site if it exists + hr = GetSiteElement(pAdminMgr, pwzSiteName, &pSiteElem, &fSiteFound); + ExitOnFailure(hr, "Failed to read sites from config"); + + if (IIS_CREATE == iAction) + { + if (fSiteFound) + { + //add SSL cert to binding + hr = CreateSslBinding(pSiteElem, pwzStoreName, pwzEncodedCertificateHash); + ExitOnFailure(hr, "Failed to create site binding"); + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Site not found for create binding"); + } + } + else if (IIS_DELETE == iAction) + { + if (fSiteFound) + { + //delete binding + hr = DeleteSslBinding(pSiteElem, pwzStoreName, pwzEncodedCertificateHash); + ExitOnFailure(hr, "Failed to delete binding"); + } + } + + LExit: + ReleaseStr(pwzSiteName); + ReleaseStr(pwzStoreName); + ReleaseStr(pwzEncodedCertificateHash); + ReleaseObject(pSiteElem); + + return hr; +} + +//------------------------------------------------------------------------------------------------- +// Helper Functions +// +// +// +//------------------------------------------------------------------------------------------------- + +static HRESULT GetNextAvailableSiteId( + IAppHostElementCollection *pCollection, + DWORD *plSiteId + ) +{ + HRESULT hr = S_OK; + IAppHostElement *pElement = NULL; + IAppHostProperty *pProperty = NULL; + + DWORD cSites; + DWORD plNextAvailSite = 0; + VARIANT vPropValue; + VARIANT vtIndex; + + VariantInit(&vPropValue); + VariantInit(&vtIndex); + + *plSiteId = 0; + + hr = pCollection->get_Count(&cSites); + ExitOnFailure(hr, "Failed get sites collection count"); + + vtIndex.vt = VT_UI4; + for (DWORD i = 0; i < cSites; ++i) + { + vtIndex.ulVal = i; + hr = pCollection->get_Item(vtIndex , &pElement); + ExitOnFailure(hr, "Failed get sites collection item"); + + hr = pElement->GetPropertyByName(ScopeBSTR(IIS_CONFIG_ID), &pProperty); + ExitOnFailure(hr, "Failed get site property"); + + hr = pProperty->get_Value(&vPropValue); + ExitOnFailure(hr, "Failed get site property value"); + + *plSiteId = vPropValue.lVal; + if (*plSiteId > plNextAvailSite) + { + plNextAvailSite = *plSiteId; + } + ReleaseNullObject(pElement); + ReleaseNullObject(pProperty); + } + *plSiteId = ++plNextAvailSite; + +LExit: + ReleaseVariant(vPropValue); + ReleaseVariant(vtIndex); + + ReleaseObject(pElement); + ReleaseObject(pProperty); + + return hr; +} + +static HRESULT GetSiteElement( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swSiteName, + IAppHostElement **ppSiteElement, + BOOL* fFound + ) +{ + HRESULT hr = S_OK; + IAppHostElement *pSites = NULL; + IAppHostElementCollection *pCollection = NULL; + + *fFound = FALSE; + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_SITES_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pSites); + ExitOnFailure(hr, "Failed get sites section"); + ExitOnNull(pSites, hr, ERROR_FILE_NOT_FOUND, "Failed get sites section object"); + + hr = pSites->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get sites collection"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_NAME, swSiteName, ppSiteElement, NULL); + ExitOnFailure(hr, "Failed to find site %ls", swSiteName); + + *fFound = ppSiteElement != NULL && *ppSiteElement != NULL; + +LExit: + ReleaseObject(pSites); + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT GetApplicationElement( IAppHostElement *pSiteElement, + LPCWSTR swAppPath, + IAppHostElement **ppAppElement, + BOOL* fFound) +{ + HRESULT hr = S_OK; + IAppHostElementCollection *pCollection = NULL; + + *fFound = FALSE; + + hr = pSiteElement->get_Collection( &pCollection); + ExitOnFailure(hr, "Failed get site app collection"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_APPLICATION, IIS_CONFIG_PATH, swAppPath, ppAppElement, NULL); + ExitOnFailure(hr, "Failed to find app %ls", swAppPath); + + *fFound = ppAppElement != NULL && *ppAppElement != NULL; + +LExit: + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT GetApplicationElementForVDir( IAppHostElement *pSiteElement, + LPCWSTR pwzVDirPath, + IAppHostElement **ppAppElement, + LPCWSTR *ppwzVDirSubPath, + BOOL* fFound) +{ + HRESULT hr = S_OK; + IAppHostElementCollection *pCollection = NULL; + LPWSTR pwzAppPath = NULL; + *fFound = FALSE; + *ppwzVDirSubPath = NULL; + + hr = pSiteElement->get_Collection( &pCollection); + ExitOnFailure(hr, "Failed get site app collection"); + + // Start with full path + int iLastPathIndex = lstrlenW(pwzVDirPath) - 1; + hr = StrAllocString(&pwzAppPath, pwzVDirPath, 0); + ExitOnFailure(hr, "Failed allocate application path"); + + for (int iSubPathIndex = iLastPathIndex; (iSubPathIndex >= 0) && (!*fFound); --iSubPathIndex) + { + // We are looking at the full path, or at a directory boundary, or at the root + if (iSubPathIndex == iLastPathIndex || + '/' == pwzAppPath[iSubPathIndex] || + 0 == iSubPathIndex) + { + // break the path if needed + if ('/' == pwzAppPath[iSubPathIndex]) + { + pwzAppPath[iSubPathIndex] = '\0'; + } + + // Special case for root path, need an empty app path + LPCWSTR pwzAppSearchPath = 0 == iSubPathIndex ? L"/" : pwzAppPath; + + // Try to find an app with the specified path + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_APPLICATION, IIS_CONFIG_PATH, pwzAppSearchPath, ppAppElement, NULL); + ExitOnFailure(hr, "Failed to search for app %ls", pwzAppSearchPath); + *fFound = ppAppElement != NULL && *ppAppElement != NULL; + + if (*fFound) + { + // set return value for sub path + // special case for app path == vdir path, need an empty subpath. + *ppwzVDirSubPath = (iSubPathIndex == iLastPathIndex) ? L"/" : pwzVDirPath + iSubPathIndex; + } + } + } + +LExit: + ReleaseObject(pCollection); + ReleaseStr(pwzAppPath); + + return hr; +} + +static HRESULT CreateSite( + __in IAppHostElementCollection *pCollection, + __in LPCWSTR swSiteName, + __out IAppHostElement **pSiteElement + ) +{ + HRESULT hr = S_OK; + IAppHostElement *pNewElement = NULL; + + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_SITE), &pNewElement); + ExitOnFailure(hr, "Failed create site element"); + + hr = Iis7PutPropertyString(pNewElement, IIS_CONFIG_NAME, swSiteName); + ExitOnFailure(hr, "Failed set site name property"); + + DWORD lSiteId = 0; + hr = GetNextAvailableSiteId(pCollection, &lSiteId); + ExitOnFailure(hr, "Failed get next site id"); + + Iis7PutPropertyInteger(pNewElement, IIS_CONFIG_ID, lSiteId); + ExitOnFailure(hr, "Failed set site id property"); + + hr = pCollection->AddElement(pNewElement); + ExitOnFailure(hr, "Failed add site element"); + + *pSiteElement = pNewElement; + pNewElement = NULL; + +LExit: + ReleaseObject(pNewElement); + + return hr; +} + +static HRESULT CreateApplication( + IAppHostElement *pSiteElement, + LPCWSTR swAppPath, + IAppHostElement **pAppElement + ) +{ + HRESULT hr = S_OK; + IAppHostElement *pNewElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + hr = pSiteElement->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get application collection"); + + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_APPLICATION), &pNewElement); + ExitOnFailure(hr, "Failed get application element"); + + hr = Iis7PutPropertyString(pNewElement, IIS_CONFIG_PATH, swAppPath); + ExitOnFailure(hr, "Failed set application path property"); + + hr = pCollection->AddElement(pNewElement); + ExitOnFailure(hr, "Failed add application to collection"); + + *pAppElement = pNewElement; + pNewElement = NULL; + +LExit: + ReleaseObject(pCollection); + ReleaseObject(pNewElement); + + return hr; +} + +static HRESULT DeleteApplication( + IAppHostElement *pSiteElement, + LPCWSTR swAppPath + ) +{ + HRESULT hr = S_OK; + IAppHostElementCollection *pCollection = NULL; + + hr = pSiteElement->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get application collection"); + + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_APPLICATION, IIS_CONFIG_PATH, swAppPath); + ExitOnFailure(hr, "Failed to delete website"); + +LExit: + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT SetAppPool( + IAppHostElement *pAppElement, + LPCWSTR pwzAppPool + ) +{ + HRESULT hr = S_OK; + + if (*pwzAppPool != 0) + { + hr = Iis7PutPropertyString(pAppElement, IIS_CONFIG_APPPOOL, pwzAppPool); + ExitOnFailure(hr, "Failed set application appPool property"); + } +LExit: + return hr; +} + +static HRESULT CreateVdir( + IAppHostElement *pAppElement, + LPCWSTR pwzVDirPath, + LPCWSTR pwzVDirPhyDir + ) +{ + HRESULT hr = S_OK; + IAppHostElement *pElement = NULL; + IAppHostElementCollection *pCollection = NULL; + BOOL fFound; + + hr = pAppElement->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get application VDir collection"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_VDIR, IIS_CONFIG_PATH, pwzVDirPath, &pElement, NULL); + ExitOnFailure(hr, "Failed while finding virtualDir"); + fFound = (NULL != pElement); + + if (!fFound) + { + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_VDIR), &pElement); + ExitOnFailure(hr, "Failed create application VDir collection"); + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PATH, pwzVDirPath); + ExitOnFailure(hr, "Failed set VDir path property"); + } + + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PHYSPATH, pwzVDirPhyDir); + ExitOnFailure(hr, "Failed set VDir phys path property"); + + if (!fFound) + { + hr = pCollection->AddElement(pElement); + ExitOnFailure(hr, "Failed add application VDir element"); + } + +LExit: + ReleaseObject(pCollection); + ReleaseObject(pElement); + + return hr; +} + +static HRESULT DeleteVdir( + IAppHostElement *pAppElement, + LPCWSTR pwzVDirPath + ) +{ + HRESULT hr = S_OK; + IAppHostElementCollection *pCollection = NULL; + + hr = pAppElement->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get application VDir collection"); + + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_VDIR, IIS_CONFIG_PATH, pwzVDirPath); + ExitOnFailure(hr, "Failed to delete vdir"); + +LExit: + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT CreateBinding( + IAppHostElement *pSiteElem, + LPCWSTR pwzProtocol, + LPCWSTR pwzInfo + ) +{ + HRESULT hr = S_OK; + IAppHostChildElementCollection *pChildElems = NULL; + IAppHostElement *pBindings = NULL; + IAppHostElement *pBindingElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + VARIANT vtProp; + + VariantInit(&vtProp); + + hr = pSiteElem->get_ChildElements(&pChildElems); + ExitOnFailure(hr, "Failed get site child elements collection"); + + vtProp.vt = VT_BSTR; + vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_BINDINGS); + hr = pChildElems->get_Item(vtProp, &pBindings); + ExitOnFailure(hr, "Failed get bindings element"); + ReleaseVariant(vtProp); + + hr = pBindings->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get bindings collection"); + + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_BINDING), &pBindingElement); + ExitOnFailure(hr, "Failed get binding element"); + + hr = Iis7PutPropertyString(pBindingElement, IIS_CONFIG_PROTOCOL, pwzProtocol); + ExitOnFailure(hr, "Failed set binding protocol property"); + + hr = Iis7PutPropertyString(pBindingElement, IIS_CONFIG_BINDINGINFO, pwzInfo); + ExitOnFailure(hr, "Failed set binding information property"); + + hr = pCollection->AddElement(pBindingElement); + if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) + { + //Eat this error. Binding is there and nothing to repair since + //identity == protocol + info so all is OK + hr = S_OK; + } + else + { + ExitOnFailure(hr, "Failed add binding to site"); + } + +LExit: + ReleaseVariant(vtProp); + + ReleaseObject(pCollection); + ReleaseObject(pChildElems); + ReleaseObject(pBindingElement); + ReleaseObject(pBindings); + + return hr; +} +static HRESULT CreateWebLog( + IAppHostElement *pSiteElem, + LPCWSTR pwzFormat + ) +{ + HRESULT hr = S_OK; + IAppHostChildElementCollection *pChildElems = NULL; + IAppHostElement *pLogFile = NULL; + + VARIANT vtProp; + + VariantInit(&vtProp); + + hr = pSiteElem->get_ChildElements(&pChildElems); + ExitOnFailure(hr, "Failed get site child elements collection"); + + vtProp.vt = VT_BSTR; + vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_WEBLOG); + hr = pChildElems->get_Item(vtProp, &pLogFile); + ExitOnFailure(hr, "Failed get logfile element"); + ReleaseVariant(vtProp); + + if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pwzFormat, -1, L"none", -1)) + { + hr = Iis7PutPropertyString(pLogFile, IIS_CONFIG_LOGFORMAT, pwzFormat); + ExitOnFailure(hr, "Failed set logfile format property"); + hr = Iis7PutPropertyString(pLogFile, IIS_CONFIG_ENABLED, IIS_CONFIG_TRUE); + ExitOnFailure(hr, "Failed set logfile enabled property"); + } + else + { + hr = Iis7PutPropertyString(pLogFile, IIS_CONFIG_ENABLED, IIS_CONFIG_FALSE); + ExitOnFailure(hr, "Failed set logfile enabled property"); + } + +LExit: + ReleaseVariant(vtProp); + + ReleaseObject(pLogFile); + ReleaseObject(pChildElems); + + return hr; +} + +static HRESULT DeleteBinding( + IAppHostElement* /*pSiteElem*/, + LPCWSTR /*pwzProtocol*/, + LPCWSTR /*pwzInfo*/ + ) +{ + HRESULT hr = S_OK; + // + //this isn't supported right now, we should support this for the SiteSearch scenario + return hr; +} + +struct SCA_SSLBINDINGINFO +{ + IIS7_APPHOSTELEMENTCOMPARISON comparison; + LPCWSTR pwzStoreName; + LPCWSTR pwzEncodedCertificateHash; + HRESULT hr; +}; + +static BOOL AddSslCertificateToBindingCallback(IAppHostElement *pBindingElement, LPVOID pContext) +{ + HRESULT hr = S_OK; + VARIANT vtProp; + VariantInit(&vtProp); + SCA_SSLBINDINGINFO* pBindingInfo = (SCA_SSLBINDINGINFO*)pContext; + IAppHostMethodCollection *pAppHostMethodCollection = NULL; + IAppHostMethod *pAddSslMethod = NULL; + IAppHostMethodInstance *pAddSslMethodInstance = NULL; + IAppHostElement *pAddSslInput = NULL; + int iWsaError = 0; + WSADATA wsaData = {}; + BOOL fWsaInitialized = FALSE; + + // IIS's AddSslCertificate doesn't initialize WinSock on 2008 before using it to parse the IP + // Initialize before calling to workaround the failure. + iWsaError = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (0 != iWsaError) + { + ExitOnWin32Error(iWsaError, hr, "Failed to initialize WinSock"); + } + + fWsaInitialized = TRUE; + + if (Iis7IsMatchingAppHostElement(pBindingElement, &pBindingInfo->comparison)) + { + hr = pBindingElement->get_Methods(&pAppHostMethodCollection); + ExitOnFailure(hr, "failed to get binding method collection"); + + hr = Iis7FindAppHostMethod(pAppHostMethodCollection, L"AddSslCertificate", &pAddSslMethod, NULL); + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "The AddSslCertificate method is not supported by the binding element, SSL certificate will not be associated with the website"); + ExitFunction(); + } + + pAddSslMethod->CreateInstance(&pAddSslMethodInstance); + ExitOnFailure(hr, "failed to create an instance of AddSslCertificate method"); + + pAddSslMethodInstance->get_Input(&pAddSslInput); + ExitOnFailure(hr, "failed to get input element of AddSslCertificate method"); + + Iis7PutPropertyString(pAddSslInput, IIS_CONFIG_CERTIFICATESTORENAME, pBindingInfo->pwzStoreName); + ExitOnFailure(hr, "failed to set certificateStoreName input parameter of AddSslCertificate method"); + + Iis7PutPropertyString(pAddSslInput, IIS_CONFIG_CERTIFICATEHASH, pBindingInfo->pwzEncodedCertificateHash); + ExitOnFailure(hr, "failed to set certificateHash input parameter of AddSslCertificate method"); + + hr = pAddSslMethodInstance->Execute(); + ExitOnFailure(hr, "failed to execute AddSslCertificate method"); + } +LExit: + pBindingInfo->hr = hr; + ReleaseObject(pAppHostMethodCollection); + ReleaseObject(pAddSslMethod); + ReleaseObject(pAddSslMethodInstance); + ReleaseObject(pAddSslInput); + if (fWsaInitialized) + { + WSACleanup(); + } + + return FAILED(hr); +} + +static HRESULT CreateSslBinding( IAppHostElement *pSiteElem, LPCWSTR pwzStoreName, LPCWSTR pwzEncodedCertificateHash) +{ + HRESULT hr = S_OK; + IAppHostChildElementCollection *pChildElems = NULL; + IAppHostElement *pBindingsElement = NULL; + IAppHostElementCollection *pBindingsCollection = NULL; + SCA_SSLBINDINGINFO bindingInfo = {}; + VARIANT vtProp; + VariantInit(&vtProp); + + hr = pSiteElem->get_ChildElements(&pChildElems); + ExitOnFailure(hr, "Failed get site child elements collection"); + + vtProp.vt = VT_BSTR; + vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_BINDINGS); + hr = pChildElems->get_Item(vtProp, &pBindingsElement); + ExitOnFailure(hr, "Failed get bindings element"); + ReleaseVariant(vtProp); + + hr = pBindingsElement->get_Collection(&pBindingsCollection); + ExitOnFailure(hr, "Failed get bindings collection"); + + bindingInfo.comparison.sczElementName = IIS_CONFIG_BINDING; + bindingInfo.comparison.sczAttributeName = IIS_CONFIG_PROTOCOL; + vtProp.vt = VT_BSTR; + vtProp.bstrVal = ::SysAllocString(L"https"); + bindingInfo.comparison.pvAttributeValue = &vtProp; + bindingInfo.pwzStoreName = pwzStoreName; + bindingInfo.pwzEncodedCertificateHash = pwzEncodedCertificateHash; + + // Our current IISWebSiteCertificates schema does not allow specification of the website binding + // to associate the certificate with. For now just associate it with all secure bindings. + + hr = Iis7EnumAppHostElements(pBindingsCollection, AddSslCertificateToBindingCallback, &bindingInfo, NULL, NULL); + ExitOnFailure(hr, "Failed to enumerate bindings collection"); + hr = bindingInfo.hr; + ExitOnFailure(hr, "Failed to add ssl binding"); + +LExit: + ReleaseVariant(vtProp); + + ReleaseObject(pChildElems); + ReleaseObject(pBindingsElement); + ReleaseObject(pBindingsCollection); + + return hr; +} + +static HRESULT DeleteSslBinding( + IAppHostElement * /*pSiteElem*/, + LPCWSTR /*pwzStoreName*/, + LPCWSTR /*pwzEncodedCertificateHash*/ + ) +{ + HRESULT hr = S_OK; + // + //this isn't supported right now, we should support this for the SiteSearch scenario + return hr; +} + +static HRESULT DeleteAppPool( IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swAppPoolName) +{ + HRESULT hr = S_OK; + IAppHostElement *pAppPools = NULL; + IAppHostElementCollection *pCollection = NULL; + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_APPPOOL_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pAppPools); + ExitOnFailure(hr, "Failed get AppPools section"); + ExitOnNull(pAppPools, hr, E_UNEXPECTED, "Failed get appPools section object"); + + hr = pAppPools->get_Collection( &pCollection); + ExitOnFailure(hr, "Failed get AppPools collection"); + + hr = DeleteCollectionElement(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, swAppPoolName); + ExitOnFailure(hr, "Failed to delete app pool %ls", swAppPoolName); + +LExit: + ReleaseObject(pAppPools); + ReleaseObject(pCollection); + + return hr; +} + +static HRESULT CreateAppPool( + __inout LPWSTR *ppwzCustomActionData, + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swAppPoolName + ) +{ + HRESULT hr = S_OK; + IAppHostElement *pAppPools = NULL; + IAppHostElement *pAppPoolElement = NULL; + IAppHostElement *pElement = NULL; + IAppHostElement *pElement2 = NULL; + IAppHostElement *pElement3 = NULL; + IAppHostElementCollection *pCollection = NULL; + IAppHostElementCollection *pCollection2 = NULL; + int iAction = -1; + int iData = 0; + LPWSTR pwzData = NULL; + WCHAR wcData[512]; + WCHAR wcTime[60]; + BOOL fFound = FALSE; + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_APPPOOL_SECTION), ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pAppPools); + ExitOnFailure(hr, "Failed get AppPools section"); + ExitOnNull(pAppPools, hr, ERROR_FILE_NOT_FOUND, "Failed get AppPools section object"); + + hr = pAppPools->get_Collection( &pCollection); + ExitOnFailure(hr, "Failed get AppPools collection"); + + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_ADD, IIS_CONFIG_NAME, swAppPoolName, &pAppPoolElement, NULL); + ExitOnFailure(hr, "Failed find AppPool element"); + fFound = (NULL != pAppPoolElement); + + if (!fFound) + { + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pAppPoolElement); + ExitOnFailure(hr, "Failed create AppPool element"); + } + + hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_NAME, swAppPoolName); + ExitOnFailure(hr, "Failed set AppPool name property"); + + //For WiX II6 /ABO compat we will default managedPipelineMode="Classic" + hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_PIPELINEMODE, L"Classic"); + ExitOnFailure(hr, "Failed set AppPool managedPipelineMode property"); + //For WiX II6 /ABO compat we will be hardcoding autostart="true" + hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_APPPOOL_AUTO, L"true"); + ExitOnFailure(hr, "Failed set AppPool autoStart property"); + + if (!fFound) + { + hr = pCollection->AddElement(pAppPoolElement); + ExitOnFailure(hr, "Failed to add appPool element"); + } + + // Get AppPool Property action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read AppPool Property action"); + while (IIS_APPPOOL_END != iAction) + { + //Process property action + switch (iAction) + { + case IIS_APPPOOL_RECYCLE_MIN : + { + // /recycling / periodicRestart | time + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool recycle min"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); + ExitOnFailure(hr, "Failed to get AppPool recycling element"); + hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); + ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); + *wcTime = '\0'; + ConvSecToHMS(iData * 60, wcTime, countof(wcTime)); + hr = Iis7PutPropertyString(pElement2, IIS_CONFIG_TIME, wcTime); + ExitOnFailure(hr, "Failed to set AppPool periodicRestart time value"); + ReleaseNullObject(pElement); + ReleaseNullObject(pElement2); + break; + } + case IIS_APPPOOL_RECYCLE_REQ : + { + // /recycling / periodicRestart | requests + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool recycle req"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); + ExitOnFailure(hr, "Failed to get AppPool recycling element"); + hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); + ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); + hr = Iis7PutPropertyInteger(pElement2, IIS_CONFIG_REQUESTS, iData); + ExitOnFailure(hr, "Failed to set AppPool periodicRestart time value"); + ReleaseNullObject(pElement); + ReleaseNullObject(pElement2); + break; + } + case IIS_APPPOOL_RECYCLE_TIMES : + { + // /recycling / periodicRestart | schedule + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read AppPool recycle times"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); + ExitOnFailure(hr, "Failed to get AppPool recycling element"); + hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); + ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); + hr = pElement2->GetElementByName(ScopeBSTR(IIS_CONFIG_SCHEDULE), &pElement3); + ExitOnFailure(hr, "Failed to get AppPool schedule element"); + hr = pElement3->get_Collection(&pCollection2); + ExitOnFailure(hr, "Failed to get AppPool schedule collection"); + + WCHAR wcDelim[] = L","; + const WCHAR *wszToken = NULL; + WCHAR *wszNextToken = NULL; + wszToken = wcstok_s( pwzData, wcDelim, &wszNextToken); + + while (wszToken) + { + *wcData = '\0'; + hr = ::StringCchCopyW(wcData, countof(wcData), wszToken); + ExitOnFailure(hr, "failed to copy AppPool schedule"); + hr = ::StringCchCatW(wcData, countof(wcData), L":00"); + ExitOnFailure(hr, "failed to append AppPool schedule"); + + hr = pCollection2->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pElement3); + ExitOnFailure(hr, "Failed to create AppPool schedule element"); + + hr = Iis7PutPropertyString(pElement3, IIS_CONFIG_VALUE, wcData); + ExitOnFailure(hr, "Failed to set AppPool schedule value"); + + hr = pCollection2->AddElement(pElement3); + if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) + { + //Eat this error, recycle time already exists NBD + hr = S_OK; + } + ExitOnFailure(hr, "Failed to add win auth providers element"); + ReleaseNullObject(pElement3); + wszToken = wcstok_s( NULL, wcDelim, &wszNextToken); + } + ReleaseNullObject(pElement); + ReleaseNullObject(pElement2); + ReleaseNullObject(pElement3); + ReleaseNullObject(pCollection2); + break; + } + case IIS_APPPOOL_RECYCLE_VIRMEM : + { + // /recycling / periodicRestart | memory + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool recycle vir memory"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); + ExitOnFailure(hr, "Failed to get AppPool recycling element"); + hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); + ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); + hr = Iis7PutPropertyInteger(pElement2, IIS_CONFIG_MEMORY, iData); + ExitOnFailure(hr, "Failed to set AppPool periodicRestart memory"); + ReleaseNullObject(pElement); + ReleaseNullObject(pElement2); + break; + } + case IIS_APPPOOL_RECYCLE_PRIVMEM : + { + // /recycling / periodicRestart | privateMemory + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool recycle priv mem"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_RECYCLING), &pElement); + ExitOnFailure(hr, "Failed to get AppPool recycling element"); + hr = pElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PEROIDRESTART), &pElement2); + ExitOnFailure(hr, "Failed to get AppPool periodicRestart element"); + hr = Iis7PutPropertyInteger(pElement2, IIS_CONFIG_PRIVMEMORY, iData); + ExitOnFailure(hr, "Failed to set AppPool periodicRestart private memory"); + ReleaseNullObject(pElement); + ReleaseNullObject(pElement2); + break; + } + case IIS_APPPOOL_RECYCLE_IDLTIMEOUT : + { + // /processModel | idleTimeout + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool idle timeout"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); + ExitOnFailure(hr, "Failed to get AppPool processModel element"); + *wcTime = '\0'; + ConvSecToHMS(iData * 60, wcTime, countof(wcTime)); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDLETIMEOUT, wcTime); + ExitOnFailure(hr, "Failed to set AppPool processModel idle timeout value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_RECYCLE_QUEUELIMIT : + { + // /applicationPools | queueLength + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool recycle queue limit"); + hr = Iis7PutPropertyInteger(pAppPoolElement, IIS_CONFIG_QUEUELENGTH, iData); + ExitOnFailure(hr, "Failed to set AppPool recycle queue limit value"); + break; + } + case IIS_APPPOOL_MAXPROCESS : + { + // /processModel | maxProcesses + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool max processes"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); + ExitOnFailure(hr, "Failed to get AppPool processModel element"); + hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_MAXWRKPROCESSES, iData); + ExitOnFailure(hr, "Failed to set AppPool processModel maxProcesses value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_IDENTITY : + { + //"LocalSystem" 0 + //"LocalService" 1 + //"NetworkService" 2 + //"SpecificUser" 3 + //"ApplicationPoolIdentity" 4 + // /processModel | identityType + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read AppPool identity"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); + ExitOnFailure(hr, "Failed to get AppPool processModel element"); + if (iData == 0) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_LOCALSYSTEM); + } + else if (iData == 1) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_LOCALSERVICE); + } + else if (iData == 2) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_NETWORKSERVICE); + } + else if (iData == 3) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_SPECIFICUSER); + } + else if (iData == 4) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_IDENITITYTYPE, IIS_CONFIG_APPLICATIONPOOLIDENTITY); + } + ExitOnFailure(hr, "Failed to set AppPool processModel identityType value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_USER : + { + // /processModel | userName + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read AppPool user"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); + ExitOnFailure(hr, "Failed to get AppPool processModel element"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_USERNAME, pwzData); + ExitOnFailure(hr, "Failed to set AppPool processModel username value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_PWD : + { + // /processModel | password + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read AppPool pwd"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_PROCESSMODEL), &pElement); + ExitOnFailure(hr, "Failed to get AppPool processModel element"); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_PASSWORD, pwzData); + ExitOnFailure(hr, "Failed to set AppPool processModel password value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_RECYCLE_CPU_PCT: + { + // /cpu | limit + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read cpu pct"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_CPU), &pElement); + ExitOnFailure(hr, "Failed to get AppPool cpu element"); + // limit is maximum percentage of CPU time (in 1/1000ths of one percent) + hr = Iis7PutPropertyInteger(pElement, IIS_CONFIG_LIMIT, iData * 1000); + ExitOnFailure(hr, "Failed to set AppPool cpu limit"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_RECYCLE_CPU_REFRESH: + { + // /cpu | resetInterval + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read cpu refresh pwd"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_CPU), &pElement); + ExitOnFailure(hr, "Failed to get AppPool cpu element"); + *wcTime = '\0'; + ConvSecToHMS(iData * 60, wcTime, countof(wcTime)); + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_RESETINTERVAL, wcTime); + ExitOnFailure(hr, "Failed to set AppPool cpu resetInterval value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_RECYCLE_CPU_ACTION: + { + // /cpu | action + //"NoAction" 0 + //"KillW3wp" 1 + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read cpu action"); + hr = pAppPoolElement->GetElementByName(ScopeBSTR(IIS_CONFIG_CPU), &pElement); + ExitOnFailure(hr, "Failed to get AppPool cpu element"); + if (iData) + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CPU_ACTION, IIS_CONFIG_KILLW3WP); + } + else + { + hr = Iis7PutPropertyString(pElement, IIS_CONFIG_CPU_ACTION, IIS_CONFIG_NOACTION); + } + ExitOnFailure(hr, "Failed to set AppPool cpu action value"); + ReleaseNullObject(pElement); + break; + } + case IIS_APPPOOL_32BIT: + { + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iData); + ExitOnFailure(hr, "Failed to read enable32BitAppOnWin64 value"); + // enable32BitAppOnWin64 + hr = Iis7PutPropertyBool(pAppPoolElement, IIS_CONFIG_ENABLE32, iData ? TRUE : FALSE); + ExitOnFailure(hr, "Failed to set AppPool enable32BitAppOnWin64 value"); + break; + } + case IIS_APPPOOL_MANAGED_PIPELINE_MODE: + { + // managedPipelineMode + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read AppPool managedRuntimeVersion"); + hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_PIPELINEMODE, pwzData); + ExitOnFailure(hr, "Failed set AppPool managedPipelineMode property"); + break; + } + case IIS_APPPOOL_MANAGED_RUNTIME_VERSION: + { + // managedRuntimeVersion + hr = WcaReadStringFromCaData(ppwzCustomActionData, &pwzData); + ExitOnFailure(hr, "Failed to read AppPool managedRuntimeVersion"); + hr = Iis7PutPropertyString(pAppPoolElement, IIS_CONFIG_MANAGEDRUNTIMEVERSION, pwzData); + ExitOnFailure(hr, "Failed set AppPool managedRuntimeVersion property"); + break; + } + + default: + ExitOnFailure(hr = E_UNEXPECTED, "Unexpected IIS Config action specified for AppPool"); + break; + + } + // Get AppPool property action + hr = WcaReadIntegerFromCaData(ppwzCustomActionData, &iAction); + ExitOnFailure(hr, "Failed to read AppPool Property action"); + } + +LExit: + ReleaseObject(pAppPools); + ReleaseObject(pCollection); + ReleaseObject(pCollection2); + ReleaseObject(pAppPoolElement); + ReleaseObject(pElement); + ReleaseObject(pElement2); + ReleaseObject(pElement3); + + return hr; +} + +static HRESULT SetDirPropAuthentications(IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR wszConfigPath, + DWORD dwData) +{ + HRESULT hr = S_OK; + IAppHostElement *pSection = NULL; + + //dwData contains bit flags for /security/authentication/<...> + // Anonymous = 1 + // Basic = 2 + // Windows = 4 + // Digest =16 + // Passport =64 *not supported + //translation required from bit map to section name + // E.G security/authentication/windowsAuthentication [property enabled true|false] + + // AnonymousAuthentication = 1 + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/anonymousAuthentication"), ScopeBSTR(wszConfigPath), &pSection); + ExitOnFailure(hr, "Failed get AnonymousAuthentication section for DirProp"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get AnonymousAuthentication section object for DirProps"); + } + + hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x1)); + ExitOnFailure(hr, "Failed set AnonymousAuthentication enabled for DirProps"); + ReleaseNullObject(pSection); + + // basicAuthentication = 2 + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/basicAuthentication"), ScopeBSTR(wszConfigPath), &pSection); + ExitOnFailure(hr, "Failed get basicAuthentication section for DirProp"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get basicAuthentication section object for DirProps"); + } + + hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x2)); + ExitOnFailure(hr, "Failed set basicAuthentication enabled for DirProps"); + ReleaseNullObject(pSection); + + // WindowsAuthentication = 4 + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/windowsAuthentication"), ScopeBSTR(wszConfigPath), &pSection); + ExitOnFailure(hr, "Failed get windowsAuthentication section for DirProp"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get windowsAuthentication section object for DirProps"); + } + + hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x4)); + ExitOnFailure(hr, "Failed set windowsAuthentication enabled for DirProps"); + ReleaseNullObject(pSection); + + // digestAuthentication = 16 + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/digestAuthentication"), ScopeBSTR(wszConfigPath), &pSection); + ExitOnFailure(hr, "Failed get digestAuthentication section for DirProp"); + if (!pSection) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed get digestAuthentication section object for DirProps"); + } + + hr = Iis7PutPropertyBool(pSection, L"enabled", (BOOL)(dwData & 0x10)); + ExitOnFailure(hr, "Failed set digestAuthentication enabled for DirProps"); + ReleaseNullObject(pSection); + +LExit: + ReleaseObject(pSection); + + return hr; +} + +static HRESULT SetDirPropAuthProvider(IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR wszConfigPath, + __in LPWSTR wszData) +{ + HRESULT hr = S_OK; + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + IAppHostElement *pNewElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + WCHAR wcDelim[] = L","; + const WCHAR *wszToken = NULL; + WCHAR *wszNextToken = NULL; + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(L"system.webServer/security/authentication/windowsAuthentication"), ScopeBSTR(wszConfigPath), &pSection); + ExitOnFailure(hr, "Failed get windowsAuthentication section for DirProp providers"); + + hr = pSection->GetElementByName(ScopeBSTR(L"providers"), &pElement); + ExitOnFailure(hr, "Failed get win auth providers section"); + + hr = pElement->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get win auth providers collection"); + + hr = pCollection->Clear(); + ExitOnFailure(hr, "Failed to clear win auth providers collection"); + + //Clear out inherited items - add clear + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pNewElement); + ExitOnFailure(hr, "Failed to create win auth providers clear element"); + hr = pCollection->AddElement(pNewElement); + ExitOnFailure(hr, "Failed to add win auth providers clear element"); + ReleaseNullObject(pNewElement); + + wszToken = wcstok_s( wszData, wcDelim, &wszNextToken); + for (int i = 0; (wszToken); ++i) + { + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pNewElement); + ExitOnFailure(hr, "Failed to create win auth providers element"); + + hr = Iis7PutPropertyString( pNewElement, IIS_CONFIG_VALUE, wszToken); + ExitOnFailure(hr, "Failed to set win auth providers value"); + + hr = pCollection->AddElement(pNewElement, i); + ExitOnFailure(hr, "Failed to add win auth providers element"); + ReleaseNullObject(pNewElement); + + wszToken = wcstok_s( NULL, wcDelim, &wszNextToken); + } + +LExit: + ReleaseObject(pSection); + ReleaseObject(pCollection); + ReleaseObject(pElement); + ReleaseObject(pNewElement); + + return hr; +} + +static HRESULT SetDirPropDefDoc( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR wszConfigPath, + __in LPWSTR wszData) +{ + HRESULT hr = S_OK; + IAppHostElement *pSection = NULL; + IAppHostElement *pElement = NULL; + IAppHostElement *pNewElement = NULL; + IAppHostElementCollection *pCollection = NULL; + + WCHAR wcDelim[] = L","; + const WCHAR *wszToken = NULL; + WCHAR *wszNextToken = NULL; + + hr = pAdminMgr->GetAdminSection(ScopeBSTR(IIS_CONFIG_DEFAULTDOC_SECTION), ScopeBSTR(wszConfigPath), &pSection); + ExitOnFailure(hr, "Failed get defaultDocument section for DirProp"); + + hr = pSection->GetElementByName(ScopeBSTR(L"files"), &pElement); + ExitOnFailure(hr, "Failed get win files section"); + + hr = pElement->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get files collection"); + + hr = pCollection->Clear(); + ExitOnFailure(hr, "Failed clear files collection"); + + //Clear out inherited items - add clear + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_CLEAR), &pNewElement); + ExitOnFailure(hr, "Failed to create files clear element"); + hr = pCollection->AddElement(pNewElement); + ExitOnFailure(hr, "Failed to add files clear element"); + + wszToken = wcstok_s( wszData, wcDelim, &wszNextToken); + for (int i = 0; (wszToken); ++i) + { + hr = pCollection->CreateNewElement(ScopeBSTR(IIS_CONFIG_ADD), &pNewElement); + ExitOnFailure(hr, "Failed to create win auth providers element"); + + hr = Iis7PutPropertyString( pNewElement, IIS_CONFIG_VALUE, wszToken); + ExitOnFailure(hr, "Failed to set win auth providers value"); + + hr = pCollection->AddElement(pNewElement, i); + ExitOnFailure(hr, "Failed to add defaultDocument Files element"); + ReleaseNullObject(pNewElement); + + wszToken = wcstok_s( NULL, wcDelim, &wszNextToken); + } + +LExit: + ReleaseObject(pSection); + ReleaseObject(pCollection); + ReleaseObject(pNewElement); + + return hr; +} + +static HRESULT ClearLocationTag( + IAppHostWritableAdminManager *pAdminMgr, + LPCWSTR swLocationPath + ) +{ + HRESULT hr = S_OK; + IAppHostConfigManager *pConfigMgr = NULL; + IAppHostConfigFile *pConfigFile = NULL; + IAppHostConfigLocationCollection *pLocationCollection = NULL; + IAppHostConfigLocation *pLocation = NULL; + + DWORD dwCount = 0; + BSTR bstrLocationPath = NULL; + + hr = pAdminMgr->get_ConfigManager(&pConfigMgr); + ExitOnFailure(hr, "Failed to get IIS ConfigManager interface"); + + hr = pConfigMgr->GetConfigFile(ScopeBSTR(IIS_CONFIG_APPHOST_ROOT), &pConfigFile); + ExitOnFailure(hr, "Failed to get IIS ConfigFile interface"); + + hr = pConfigFile->get_Locations(&pLocationCollection); + ExitOnFailure(hr, "Failed to get IIS location tag collection"); + + hr = pLocationCollection->get_Count(&dwCount); + ExitOnFailure(hr, "Failed to get IIS location collection count"); + + VARIANT vtIndex; + vtIndex.vt = VT_UI4; + for (DWORD i = 0; i < dwCount; ++i) + { + vtIndex.ulVal = i; + hr = pLocationCollection->get_Item(vtIndex, &pLocation); + ExitOnFailure(hr, "Failed to get IIS location collection count"); + + hr = pLocation->get_Path(&bstrLocationPath); + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, swLocationPath, -1, bstrLocationPath, -1)) + { + hr = pLocationCollection->DeleteLocation(vtIndex); + ExitOnFailure(hr, "Failed to delete IIS location tag %ls",swLocationPath); + break; + } + + ReleaseNullObject(pLocation); + ::SysFreeString(bstrLocationPath); + bstrLocationPath = NULL; + } +LExit: + ReleaseObject(pConfigMgr); + ReleaseObject(pConfigFile); + ReleaseObject(pLocationCollection); + ReleaseObject(pLocation); + ReleaseBSTR(bstrLocationPath); + + return hr; + +} + +static HRESULT DeleteCollectionElement( + __in IAppHostElementCollection *pCollection, + __in LPCWSTR pwzElementName, + __in LPCWSTR pwzAttributeName, + __in LPCWSTR pwzAttributeValue + ) +{ + HRESULT hr = S_OK; + + DWORD dwIndex; + VARIANT vtIndex; + VariantInit(&vtIndex); + + hr = Iis7FindAppHostElementString(pCollection, pwzElementName, pwzAttributeName, pwzAttributeValue, NULL, &dwIndex); + ExitOnFailure(hr, "Failed while finding IAppHostElement %ls/@%ls=%ls", pwzElementName, pwzAttributeName, pwzAttributeValue); + + if (MAXDWORD != dwIndex) + { + vtIndex.vt = VT_UI4; + vtIndex.ulVal = dwIndex; + hr = pCollection->DeleteElement(vtIndex); + ExitOnFailure(hr, "Failed to delete IAppHostElement %ls/@%ls=%ls", pwzElementName, pwzAttributeName, pwzAttributeValue); + } + // else : nothing to do, already deleted +LExit: + ReleaseVariant(vtIndex); + + return hr; +} +static void ConvSecToHMS( int Sec, __out_ecount(cchDest) LPWSTR wcTime, size_t cchDest) +{ + int ZH, ZM, ZS = 0; + + ZH = (Sec / 3600); + Sec = Sec - ZH * 3600; + ZM = (Sec / 60) ; + Sec = Sec - ZM * 60; + ZS = Sec ; + + HRESULT hr = ::StringCchPrintfW(wcTime, cchDest, L"%02d:%02d:%02d", ZH, ZM, ZS); + if (S_OK != hr) + { + *wcTime = '\0'; + } +} +static void ConvSecToDHMS( unsigned int Sec, __out_ecount(cchDest) LPWSTR wcTime, size_t cchDest) +{ + int ZD, ZH, ZM, ZS = 0; + + ZD = Sec / 86400; + Sec = Sec - ZD * 86400; + ZH = (Sec / 3600); + Sec = Sec - ZH * 3600; + ZM = (Sec / 60) ; + Sec = Sec - ZM * 60; + ZS = Sec ; + + HRESULT hr = ::StringCchPrintfW(wcTime, cchDest, L"%d.%02d:%02d:%02d", ZD, ZH, ZM, ZS); + if (S_OK != hr) + { + *wcTime = '\0'; + } +} diff --git a/src/ext/Iis/ca/scaexecIIS7.h b/src/ext/Iis/ca/scaexecIIS7.h new file mode 100644 index 00000000..ec31f202 --- /dev/null +++ b/src/ext/Iis/ca/scaexecIIS7.h @@ -0,0 +1,5 @@ +#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 IIS7ConfigChanges(MSIHANDLE hInstall, __inout LPWSTR pwzData); diff --git a/src/ext/Iis/ca/scafilter.cpp b/src/ext/Iis/ca/scafilter.cpp new file mode 100644 index 00000000..9d9014fd --- /dev/null +++ b/src/ext/Iis/ca/scafilter.cpp @@ -0,0 +1,510 @@ +// 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" + +// prototypes +static HRESULT ReadFilterLoadOrder( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzFilterRoot, + __out LPWSTR *ppwzLoadOrder + ); +static HRESULT AddFilterToLoadOrder( + __in LPCWSTR wzFilter, + __in int iLoadOrder, + __inout LPWSTR *ppwzLoadOrder + ); +static HRESULT RemoveFilterFromLoadOrder( + __in LPCWSTR wzFilter, + __inout LPWSTR *ppwzLoadOrder + ); + + +UINT __stdcall ScaFiltersRead( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __inout SCA_FILTER** ppsfList, + __inout LPWSTR *ppwzCustomActionData + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + + LPWSTR pwzData = NULL; + + SCA_FILTER* psf = NULL; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaFiltersRead() - no IIsFilter table"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the filters + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + // Get the Component first. If the component is not being modified during + // this transaction, skip processing this whole record. + hr = WcaGetRecordString(hRec, fqComponent, &pwzData); + ExitOnFailure(hr, "failed to get IIsFilter.Component"); + + hr = WcaGetRecordInteger(hRec, fqInstalled, (int *)&isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for IIs filter"); + + hr = WcaGetRecordInteger(hRec, fqAction, (int *)&isAction); + ExitOnFailure(hr, "Failed to get Component action state for IIs filter"); + + if (!WcaIsInstalling(isInstalled, isAction) && + !WcaIsReInstalling(isInstalled, isAction) && + !WcaIsUninstalling(isInstalled, isAction)) + { + continue; // skip this record. + } + + hr = AddFilterToList(ppsfList); + ExitOnFailure(hr, "failed to add filter to list"); + + psf = *ppsfList; + + hr = ::StringCchCopyW(psf->wzComponent, countof(psf->wzComponent), pwzData); + ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); + + psf->isInstalled = isInstalled; + psf->isAction = isAction; + + hr = WcaGetRecordString(hRec, fqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web for VirtualDir"); + + if (*pwzData) + { + hr = ScaWebsGetBase(piMetabase, pswList, pwzData, psf->wzWebBase, countof(psf->wzWebBase), hWebBaseQuery); + if (FAILED(hr) && WcaIsUninstalling(isInstalled, isAction)) + { + // If we're uninstalling, don't bother finding the existing web, just leave the filter root empty + hr = S_OK; + } + ExitOnFailure(hr, "Failed to get base of web for Filter"); + + if (0 != lstrlenW(psf->wzWebBase)) + { + hr = ::StringCchPrintfW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"%s/Filters", psf->wzWebBase); + ExitOnFailure(hr, "Failed to allocate filter base string"); + } + } + else + { + hr = ::StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/LM/W3SVC/Filters"); + ExitOnFailure(hr, "Failed to allocate global filter base string"); + } + + // filter key + hr = WcaGetRecordString(hRec, fqFilter, &pwzData); + ExitOnFailure(hr, "Failed to get Filter.Filter"); + hr = ::StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to filter object"); + + // filter path + hr = WcaGetRecordString(hRec, fqPath, &pwzData); + ExitOnFailure(hr, "Failed to get Filter.Path"); + hr = ::StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData); + ExitOnFailure(hr, "Failed to copy path string to filter object"); + + // filter description + hr = WcaGetRecordString(hRec, fqDescription, &pwzData); + ExitOnFailure(hr, "Failed to get Filter.Description"); + hr = ::StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData); + ExitOnFailure(hr, "Failed to copy description string to filter object"); + + // filter flags + hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags); + ExitOnFailure(hr, "Failed to get Filter.Flags"); + + // filter load order + hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder); + ExitOnFailure(hr, "Failed to get Filter.LoadOrder"); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing filters"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + return hr; +} + + +HRESULT ScaFiltersInstall( + __in IMSAdminBase* piMetabase, + __in SCA_FILTER* psfList + ) +{ + HRESULT hr = S_OK; + SCA_FILTER* psf = psfList; + LPCWSTR wzPreviousFilterRoot = NULL; + LPWSTR pwzLoadOrder = NULL; + + while (psf) + { + if (WcaIsInstalling(psf->isInstalled, psf->isAction)) + { + if (!wzPreviousFilterRoot || CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, wzPreviousFilterRoot, -1, psf->wzFilterRoot, -1)) + { + if (pwzLoadOrder) + { + hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); + ExitOnFailure(hr, "Failed to write filter load order to metabase"); + + ReleaseNullStr(pwzLoadOrder); + } + + hr = ReadFilterLoadOrder(piMetabase, psf->wzFilterRoot, &pwzLoadOrder); + ExitOnFailure(hr, "Failed to read filter load order."); + + wzPreviousFilterRoot = psf->wzFilterRoot; + } + + hr = ScaCreateMetabaseKey(piMetabase, psf->wzFilterRoot, psf->wzKey); + ExitOnFailure(hr, "Failed to create key for filter '%ls'", psf->wzKey); + + hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsFilter"); + ExitOnFailure(hr, "Failed to write key type for filter '%ls'", psf->wzKey); + + // filter path + hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_IMAGE_PATH, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)psf->wzPath); + ExitOnFailure(hr, "Failed to write Path for filter '%ls'", psf->wzKey); + + // filter description + hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_DESCRIPTION, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)psf->wzDescription); + ExitOnFailure(hr, "Failed to write Description for filter '%ls'", psf->wzKey); + + // filter flags + if (MSI_NULL_INTEGER != psf->iFlags) + { + hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_FLAGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psf->iFlags)); + ExitOnFailure(hr, "Failed to write Flags for filter '%ls'", psf->wzKey); + } + + // filter load order + if (MSI_NULL_INTEGER != psf->iLoadOrder) + { + hr = AddFilterToLoadOrder(psf->wzKey, psf->iLoadOrder, &pwzLoadOrder); + ExitOnFailure(hr, "Failed to add filter '%ls' to load order.", psf->wzKey); + } + } + + psf = psf->psfNext; + } + + if (pwzLoadOrder) + { + Assert(wzPreviousFilterRoot && *wzPreviousFilterRoot); + + hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); + ExitOnFailure(hr, "Failed to write filter load order to metabase"); + } + +LExit: + ReleaseStr(pwzLoadOrder); + return hr; +} + + +HRESULT ScaFiltersUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_FILTER* psfList + ) +{ + HRESULT hr = S_OK; + SCA_FILTER* psf = psfList; + LPCWSTR wzPreviousFilterRoot = NULL; + LPWSTR pwzLoadOrder = NULL; + + while (psf) + { + if (WcaIsUninstalling(psf->isInstalled, psf->isAction)) + { + if (!wzPreviousFilterRoot || CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, wzPreviousFilterRoot, -1, psf->wzFilterRoot, -1)) + { + if (pwzLoadOrder) + { + hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); + ExitOnFailure(hr, "Failed to write filter load order to metabase"); + + ReleaseNullStr(pwzLoadOrder); + } + + hr = ReadFilterLoadOrder(piMetabase, psf->wzFilterRoot, &pwzLoadOrder); + ExitOnFailure(hr, "Failed to read filter load order."); + + wzPreviousFilterRoot = psf->wzFilterRoot; + } + + hr = RemoveFilterFromLoadOrder(psf->wzKey, &pwzLoadOrder); + ExitOnFailure(hr, "Failed to remove filter '%ls' from load order", psf->wzKey); + + // remove the filter from the load order and remove the filter's key + if (0 != lstrlenW(psf->wzFilterRoot)) + { + hr = ScaDeleteMetabaseKey(piMetabase, psf->wzFilterRoot, psf->wzKey); + ExitOnFailure(hr, "Failed to remove web '%ls' from metabase", psf->wzKey); + } + } + + psf = psf->psfNext; + } + + if (pwzLoadOrder) + { + Assert(wzPreviousFilterRoot && *wzPreviousFilterRoot); + + hr = ScaWriteMetabaseValue(piMetabase, wzPreviousFilterRoot, L"", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)pwzLoadOrder); + ExitOnFailure(hr, "Failed to write filter load order to metabase"); + } + +LExit: + return hr; +} + + +void ScaFiltersFreeList( + __in SCA_FILTER* psfList + ) +{ + SCA_FILTER* psfDelete = psfList; + while (psfList) + { + psfDelete = psfList; + psfList = psfList->psfNext; + + MemFree(psfDelete); + } +} + +HRESULT AddFilterToList( + __inout SCA_FILTER** ppsfList) +{ + HRESULT hr = S_OK; + SCA_FILTER* psf = static_cast(MemAlloc(sizeof(SCA_FILTER), TRUE)); + ExitOnNull(psf, hr, E_OUTOFMEMORY, "failed to add filter to filter list"); + + psf->psfNext = *ppsfList; + *ppsfList = psf; + +LExit: + return hr; +} + +// private helper functions + + +static HRESULT ReadFilterLoadOrder( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzFilterRoot, + __out LPWSTR *ppwzLoadOrder + ) +{ + HRESULT hr = S_OK; + METADATA_HANDLE mhRoot = NULL; + + METADATA_RECORD mr; + DWORD dwRequired = 0; + DWORD cchData = 255; + + ::ZeroMemory(&mr, sizeof(mr)); + mr.dwMDIdentifier = MD_FILTER_LOAD_ORDER; + mr.dwMDAttributes = METADATA_NO_ATTRIBUTES; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = ALL_METADATA; + mr.dwMDDataLen = cchData; + mr.pbMDData = static_cast(MemAlloc(mr.dwMDDataLen * sizeof(WCHAR), TRUE)); + ExitOnNull(mr.pbMDData, hr, E_OUTOFMEMORY, "failed to allocate memory for MDData in metadata record"); + + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, wzFilterRoot, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10, &mhRoot); + for (int i = 30; i > 0 && HRESULT_FROM_WIN32(ERROR_PATH_BUSY) == hr; i--) + { + ::Sleep(1000); + WcaLog(LOGMSG_STANDARD, "Failed to open root key, retrying %d time(s)...", i); + hr = piMetabase->OpenKey(METADATA_MASTER_ROOT_HANDLE, wzFilterRoot, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10, &mhRoot); + } + + if (SUCCEEDED(hr)) + { + hr = piMetabase->GetData(mhRoot, L"", &mr, &dwRequired); + if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) + { + mr.dwMDDataLen = cchData = dwRequired; + + LPVOID pv = MemReAlloc(mr.pbMDData, mr.dwMDDataLen * sizeof(WCHAR), TRUE); + ExitOnNull(pv, hr, E_OUTOFMEMORY, "failed to allocate memory for MDData in metadata record"); + mr.pbMDData = static_cast(pv); + + hr = piMetabase->GetData(mhRoot, L"", &mr, &dwRequired); + } + } + + // The /Filters node or /Filters/FilterLoadOrder property might not exist (yet). + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failed to get filter load order."); + + hr = StrAllocString(ppwzLoadOrder, reinterpret_cast(mr.pbMDData), 0); + ExitOnFailure(hr, "Failed to allocate string for filter load order."); + +LExit: + ReleaseMem(mr.pbMDData); + + if (mhRoot) + { + piMetabase->CloseKey(mhRoot); + } + + return hr; +} + + +static HRESULT AddFilterToLoadOrder( + __in LPCWSTR wzFilter, + __in int iLoadOrder, + __inout LPWSTR *ppwzLoadOrder + ) +{ + HRESULT hr = S_OK; + LPCWSTR wzLoadOrder = *ppwzLoadOrder; + int cchFilter = lstrlenW(wzFilter); + LPWSTR pwzTemp = NULL; + + // If the filter name ends with '\0' or ',' and + // the filter name begins at the beginning of the list or with ',' + // Then we've found the exact filter by name. + // + // If the filter isn't already in the load order, add it + if (wzLoadOrder && *wzLoadOrder) + { + LPCWSTR pwz = wcsstr(wzLoadOrder, wzFilter); + + if (NULL != pwz && + (L'\0' == *(pwz + cchFilter) || L',' == *(pwz + cchFilter)) && + (pwz == wzLoadOrder || L',' == *(pwz - 1))) + { + // Filter already in the load order, no work to do. + } + else + { + pwz = NULL; + if (0 <= iLoadOrder) + { + pwz = wzLoadOrder; + for (int i = 0; i < iLoadOrder && pwz; ++i) + { + pwz = wcsstr(pwz, L","); + } + } + + if (NULL == pwz) // put the filter at the end of the order + { + Assert(wzLoadOrder && *wzLoadOrder); + + // tack on a comma since there are other filters in the order + hr = StrAllocConcat(ppwzLoadOrder, L",", 1); + ExitOnFailure(hr, "Failed to append a comma to filter load order."); + + hr = StrAllocConcat(ppwzLoadOrder, wzFilter, cchFilter); + ExitOnFailure(hr, "Failed to append the filter on to the load order."); + } + else if (L',' == *pwz) // put the filter in the middle of the order + { + hr = StrAllocString(&pwzTemp, wzLoadOrder, pwz - wzLoadOrder + 1); + ExitOnFailure(hr, "Failed to copy first half of filter load order to temp string."); + + hr = StrAllocConcat(&pwzTemp, wzFilter, 0); + ExitOnFailure(hr, "Failed to copy filter into load order."); + + hr = StrAllocConcat(&pwzTemp, pwz, 0); + ExitOnFailure(hr, "Failed to copy remaining filter load order back onto load order."); + + hr = StrAllocString(ppwzLoadOrder, pwzTemp, 0); + ExitOnFailure(hr, "Failed to copy temp string to load order string."); + } + else // put the filter at the beginning of the order + { + hr = StrAllocPrefix(ppwzLoadOrder, L",", 1); + ExitOnFailure(hr, "Failed to prepend a comma to filter load order."); + + hr = StrAllocPrefix(ppwzLoadOrder, wzFilter, cchFilter); + ExitOnFailure(hr, "Failed to prepend the filter on to the load order."); + } + } + } + else + { + hr = StrAllocString(ppwzLoadOrder, wzFilter, cchFilter); + ExitOnFailure(hr, "Failed to add filter to load order."); + } + +LExit: + ReleaseStr(pwzTemp); + return hr; +} + + +static HRESULT RemoveFilterFromLoadOrder( + __in LPCWSTR wzFilter, + __inout LPWSTR *ppwzLoadOrder + ) +{ + HRESULT hr = S_OK; + int cchFilter = lstrlenW(wzFilter); + + LPCWSTR pwzStart = NULL; + LPWSTR pwzFind = NULL; + + pwzStart = pwzFind = *ppwzLoadOrder; + while (NULL != (pwzFind = wcsstr(pwzFind, wzFilter))) + { + // Make sure to only match [wzFilter] and NOT foo[wzFilter]bar + if (pwzFind == pwzStart || L',' == *(pwzFind - 1)) + { + int cchRemainder = lstrlenW(pwzFind) - cchFilter + 1; // add one to include the null terminator + + if (L'\0' == *(pwzFind + cchFilter)) + { + if (pwzFind == pwzStart) + { + memmove(pwzFind, pwzFind + cchFilter, cchRemainder * sizeof(WCHAR)); // copy down the null terminator + } + else + { + memmove(pwzFind - 1, pwzFind + cchFilter, cchRemainder * sizeof(WCHAR)); // copy down the null terminator over top the trailing "," + } + } + else if (L',' == *(pwzFind + cchFilter)) + { + memmove(pwzFind, pwzFind + cchFilter + 1, (cchRemainder - 1) * sizeof(WCHAR)); // skip copying the "," + } + else // skip past the partial match + { + pwzFind = pwzFind + cchFilter; + } + } + else // skip past the partial match + { + pwzFind = pwzFind + cchFilter; + } + } + +//LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scafilter.h b/src/ext/Iis/ca/scafilter.h new file mode 100644 index 00000000..d072bf22 --- /dev/null +++ b/src/ext/Iis/ca/scafilter.h @@ -0,0 +1,46 @@ +#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 "scaweb.h" + +enum eFilterQuery { fqWeb = 1, fqFilter, fqComponent , fqPath, fqDescription, fqFlags, fqLoadOrder, fqInstalled, fqAction }; + +struct SCA_FILTER +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + // metabase information + WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; + WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; + WCHAR wzFilterRoot[METADATA_MAX_NAME_LEN + 1]; + + // iis configuation information + WCHAR wzPath[MAX_PATH]; + WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; + int iFlags; + int iLoadOrder; + + SCA_FILTER* psfNext; +}; + + +// prototypes +HRESULT AddFilterToList( + __in SCA_FILTER** ppsfList + ); + +UINT __stdcall ScaFiltersRead(IMSAdminBase* piMetabase, + SCA_WEB* pswList, __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, SCA_FILTER** ppsfList, + __inout LPWSTR *ppwzCustomActionData); + +HRESULT ScaFiltersInstall(IMSAdminBase* piMetabase, SCA_FILTER* psfList); + +HRESULT ScaFiltersUninstall(IMSAdminBase* piMetabase, SCA_FILTER* psfList); + +void ScaFiltersFreeList(SCA_FILTER* psfList); + diff --git a/src/ext/Iis/ca/scafilter7.cpp b/src/ext/Iis/ca/scafilter7.cpp new file mode 100644 index 00000000..dda91c4d --- /dev/null +++ b/src/ext/Iis/ca/scafilter7.cpp @@ -0,0 +1,284 @@ +// 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" + +static HRESULT WriteFilter(const SCA_FILTER* psf); + +UINT __stdcall ScaFiltersRead7( + __in SCA_WEB7* pswList, + __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, + __inout SCA_FILTER** ppsfList, + __inout LPWSTR *ppwzCustomActionData + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + SCA_FILTER* psf; + + LPWSTR pwzData = NULL; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaFiltersRead() - no IIsFilter table"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the filters + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + // Get the Component first. If the component is not being modified during + // this transaction, skip processing this whole record. + // get the darwin information + hr = WcaGetRecordString(hRec, fqComponent, &pwzData); + ExitOnFailure(hr, "failed to get IIsFilter.Component"); + + hr = WcaGetRecordInteger(hRec, fqInstalled, (int *)&isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for IIs filter"); + + hr = WcaGetRecordInteger(hRec, fqAction, (int *)&isAction); + ExitOnFailure(hr, "Failed to get Component action state for IIs filter"); + + if (!WcaIsInstalling(isInstalled, isAction) && + !WcaIsReInstalling(isInstalled, isAction) && + !WcaIsUninstalling(isInstalled, isAction)) + { + continue; // skip this record. + } + + hr = AddFilterToList(ppsfList); + ExitOnFailure(hr, "failed to add filter to list"); + + psf = *ppsfList; + + hr = ::StringCchCopyW(psf->wzComponent, countof(psf->wzComponent), pwzData); + ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); + + psf->isInstalled = isInstalled; + psf->isAction = isAction; + + hr = WcaGetRecordString(hRec, fqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web for VirtualDir"); + + if (*pwzData) + { + hr = ScaWebsGetBase7(pswList, pwzData, psf->wzFilterRoot, countof(psf->wzFilterRoot)); + if (FAILED(hr)) + { + WcaLog(LOGMSG_VERBOSE, "Could not find site for filter: %ls. Result 0x%x ", psf->wzFilterRoot, hr); + hr = S_OK; + } + } + else + { + hr = ::StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/"); + ExitOnFailure(hr, "Failed to allocate global filter base string"); + } + + // filter Name key + hr = WcaGetRecordString(hRec, fqFilter, &pwzData); + ExitOnFailure(hr, "Failed to get Filter.Filter"); + hr = ::StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to filter object"); + + // filter path + hr = WcaGetRecordString(hRec, fqPath, &pwzData); + ExitOnFailure(hr, "Failed to get Filter.Path"); + hr = ::StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData); + ExitOnFailure(hr, "Failed to copy path string to filter object"); + + // filter description -- not supported in iis 7 + hr = WcaGetRecordString(hRec, fqDescription, &pwzData); + ExitOnFailure(hr, "Failed to get Filter.Description"); + hr = ::StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData); + ExitOnFailure(hr, "Failed to copy description string to filter object"); + + // filter flags + //What are these + hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags); + ExitOnFailure(hr, "Failed to get Filter.Flags"); + + // filter load order + hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder); + ExitOnFailure(hr, "Failed to get Filter.LoadOrder"); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing filters"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaFiltersInstall7( + __in SCA_FILTER* psfList + ) +{ + HRESULT hr = S_OK; + SCA_FILTER* psf = psfList; + + if (!psf) + { + ExitFunction(); + } + //write global filters + hr = ScaWriteConfigID(IIS_FILTER_GLOBAL_BEGIN); + ExitOnFailure(hr, "Failed to write filter begin ID"); + while (psf) + { + if (WcaIsInstalling(psf->isInstalled, psf->isAction)) + { + if (0 == wcscmp(psf->wzFilterRoot, L"/")) + { + hr = WriteFilter(psf); + } + } + psf = psf->psfNext; + } + hr = ScaWriteConfigID(IIS_FILTER_END); + ExitOnFailure(hr, "Failed to write filter ID"); + + psf = psfList; + + //Write Web Site Filters + hr = ScaWriteConfigID(IIS_FILTER_BEGIN); + ExitOnFailure(hr, "Failed to write filter begin ID"); + while (psf) + { + if (WcaIsInstalling(psf->isInstalled, psf->isAction)) + { + if (0 != wcscmp(psf->wzFilterRoot, L"/")) + { + hr = WriteFilter(psf); + } + } + psf = psf->psfNext; + } + hr = ScaWriteConfigID(IIS_FILTER_END); + ExitOnFailure(hr, "Failed to write filter ID"); + +LExit: + + return hr; +} +static HRESULT WriteFilter(const SCA_FILTER* psf) +{ + HRESULT hr = S_OK; + + hr = ScaWriteConfigID(IIS_FILTER); + ExitOnFailure(hr, "Failed to write filter begin ID"); + + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed to write filter create ID"); + + //filter Name key + hr = ScaWriteConfigString(psf->wzKey); + ExitOnFailure(hr, "Failed to write key name for filter '%ls'", psf->wzKey); + + //web site name + hr = ScaWriteConfigString(psf->wzFilterRoot); + ExitOnFailure(hr, "Failed to write filter web root "); + + // filter path + hr = ScaWriteConfigString(psf->wzPath); + ExitOnFailure(hr, "Failed to write Path for filter '%ls'", psf->wzKey); + + //filter load order + hr = ScaWriteConfigInteger(psf->iLoadOrder); + ExitOnFailure(hr, "Failed to write load order for filter '%ls'", psf->wzKey); + +LExit: + return hr; +} + + +HRESULT ScaFiltersUninstall7( + __in SCA_FILTER* psfList + ) +{ + HRESULT hr = S_OK; + SCA_FILTER* psf = psfList; + + if (!psf) + { + ExitFunction1(hr = S_OK); + } + + //Uninstall global filters + hr = ScaWriteConfigID(IIS_FILTER_GLOBAL_BEGIN); + ExitOnFailure(hr, "Failed to write filter begin ID"); + + while (psf) + { + if (WcaIsUninstalling(psf->isInstalled, psf->isAction)) + { + if (0 == wcscmp(psf->wzFilterRoot, L"/")) + { + hr = ScaWriteConfigID(IIS_FILTER); + ExitOnFailure(hr, "Failed to write filter begin ID"); + + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "Failed to write filter create ID"); + + //filter Name key + hr = ScaWriteConfigString(psf->wzKey); + ExitOnFailure(hr, "Failed to write key name for filter '%ls'", psf->wzKey); + + //web site name + hr = ScaWriteConfigString(psf->wzFilterRoot); + ExitOnFailure(hr, "Failed to write filter web root "); + + } + } + psf = psf->psfNext; + } + + hr = ScaWriteConfigID(IIS_FILTER_END); + ExitOnFailure(hr, "Failed to write filter ID"); + + psf = psfList; + + //Uninstall website filters + hr = ScaWriteConfigID(IIS_FILTER_BEGIN); + ExitOnFailure(hr, "Failed to write filter begin ID"); + while (psf) + { + if (WcaIsUninstalling(psf->isInstalled, psf->isAction)) + { + if (0 != wcscmp(psf->wzFilterRoot, L"/")) + { + hr = ScaWriteConfigID(IIS_FILTER); + ExitOnFailure(hr, "Failed to write filter begin ID"); + + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "Failed to write filter create ID"); + + //filter Name key + hr = ScaWriteConfigString(psf->wzKey); + ExitOnFailure(hr, "Failed to write key name for filter '%ls'", psf->wzKey); + + //web site name + hr = ScaWriteConfigString(psf->wzFilterRoot); + ExitOnFailure(hr, "Failed to write filter web root "); + } + } + psf = psf->psfNext; + } + hr = ScaWriteConfigID(IIS_FILTER_END); + ExitOnFailure(hr, "Failed to write filter ID"); + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scafilter7.h b/src/ext/Iis/ca/scafilter7.h new file mode 100644 index 00000000..50ff6652 --- /dev/null +++ b/src/ext/Iis/ca/scafilter7.h @@ -0,0 +1,21 @@ +#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 "scaweb.h" + +// prototypes +UINT __stdcall ScaFiltersRead7( + __in SCA_WEB7* pswList, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __inout SCA_FILTER** ppsfList, + __inout LPWSTR *ppwzCustomActionData + ); + +HRESULT ScaFiltersInstall7( + SCA_FILTER* psfList + ); + +HRESULT ScaFiltersUninstall7( + SCA_FILTER* psfList + ); diff --git a/src/ext/Iis/ca/scahttpheader.cpp b/src/ext/Iis/ca/scahttpheader.cpp new file mode 100644 index 00000000..1e134cea --- /dev/null +++ b/src/ext/Iis/ca/scahttpheader.cpp @@ -0,0 +1,323 @@ +// 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" + +enum eHttpHeaderQuery { hhqName = 1, hhqParentType, hhqParentValue, hhqValue, hhqAttributes}; + +static HRESULT AddHttpHeaderToList( + __in SCA_HTTP_HEADER** ppshhList + ); + + +void ScaHttpHeaderFreeList( + __in SCA_HTTP_HEADER* pshhList + ) +{ + SCA_HTTP_HEADER* pshhDelete = pshhList; + while (pshhList) + { + pshhDelete = pshhList; + pshhList = pshhList->pshhNext; + + MemFree(pshhDelete); + } +} + + +HRESULT ScaHttpHeaderRead( + __in SCA_HTTP_HEADER** ppshhList, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(ppshhList); + + HRESULT hr = S_OK; + MSIHANDLE hRec; + LPWSTR pwzData = NULL; + SCA_HTTP_HEADER* pshh = NULL; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaHttpHeaderRead() - required tables not present."); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the HTTP headers + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + hr = AddHttpHeaderToList(ppshhList); + ExitOnFailure(hr, "failed to add http header to list"); + + pshh = *ppshhList; + + hr = WcaGetRecordInteger(hRec, hhqParentType, &(pshh->iParentType)); + ExitOnFailure(hr, "failed to get IIsHttpHeader.ParentType"); + + hr = WcaGetRecordString(hRec, hhqParentValue, &pwzData); + ExitOnFailure(hr, "Failed to get IIsHttpHeader.ParentValue"); + hr = ::StringCchCopyW(pshh->wzParentValue, countof(pshh->wzParentValue), pwzData); + ExitOnFailure(hr, "Failed to copy IIsHttpHeader.ParentValue"); + + hr = WcaGetRecordString(hRec, hhqName, &pwzData); + ExitOnFailure(hr, "Failed to get IIsHttpHeader.Name"); + hr = ::StringCchCopyW(pshh->wzName, countof(pshh->wzName), pwzData); + ExitOnFailure(hr, "Failed to copy IIsHttpHeader.Name"); + + hr = WcaGetRecordString(hRec, hhqValue, &pwzData); + ExitOnFailure(hr, "Failed to get IIsHttpHeader.Value"); + hr = ::StringCchCopyW(pshh->wzValue, countof(pshh->wzValue), pwzData); + ExitOnFailure(hr, "Failed to copy IIsHttpHeader.Value"); + + hr = WcaGetRecordInteger(hRec, hhqAttributes, &(pshh->iAttributes)); + ExitOnFailure(hr, "failed to get IIsHttpHeader.Attributes"); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing web errors"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaGetHttpHeader( + __in int iParentType, + __in LPCWSTR wzParentValue, + __in SCA_HTTP_HEADER** ppshhList, + __out SCA_HTTP_HEADER** ppshhOut + ) +{ + HRESULT hr = S_OK; + SCA_HTTP_HEADER* pshhAdd = NULL; + SCA_HTTP_HEADER* pshhLast = NULL; + + *ppshhOut = NULL; + + if (!*ppshhList) + { + return hr; + } + + SCA_HTTP_HEADER* pshh = *ppshhList; + while (pshh) + { + if (iParentType == pshh->iParentType && CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, wzParentValue, -1, pshh->wzParentValue, -1)) + { + // Found a match, take this one out of the list and add it to the matched out list + pshhAdd = pshh; + + if (pshhLast) + { + // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) + pshhLast->pshhNext = pshhAdd->pshhNext; + } + else + { + // If we are at the beginning (no pshhLast) update the beginning (since we're taking it) + *ppshhList = pshh->pshhNext; + } + pshh = pshh->pshhNext; // move on + + // Add the one we've removed to the beginning of the out list + pshhAdd->pshhNext = *ppshhOut; + *ppshhOut = pshhAdd; + } + else + { + pshhLast = pshh; // remember the last we that didn't match + pshh = pshh->pshhNext; // move on + } + } + + return hr; +} + + +HRESULT ScaWriteHttpHeader( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzRoot, + __in SCA_HTTP_HEADER* pshhList + ) +{ + Assert(piMetabase && pshhList); + + HRESULT hr = S_OK; + METADATA_RECORD mr = { 0 }; + DWORD cchData = 0; + LPWSTR pwzSearchKey = NULL; + LPWSTR pwz = NULL; + LPWSTR pwzHeaders = NULL; + LPWSTR pwzNewHeader = NULL; + DWORD_PTR dwFoundHeaderIndex = 0; + LPCWSTR wzFoundHeader = NULL; + BOOL fOldValueFound = FALSE; + + ExitOnNull(wzRoot, hr, E_INVALIDARG, "Failed to write HTTP header, because no root was provided"); + + Assert(*wzRoot); + + // Check if HTTP header already exist here. + mr.dwMDIdentifier = MD_HTTP_CUSTOM; + mr.dwMDAttributes = METADATA_INHERIT; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = ALL_METADATA; + mr.dwMDDataLen = cchData = 0; + mr.pbMDData = NULL; + + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzRoot, &mr); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) + { + // + // If we don't have any HTTP Headers already, move up to get the parent headers. + // TODO: Make it configurable to not inherit HTTP Headers + // + hr = StrAllocConcat(&pwzSearchKey, wzRoot, 0); + ExitOnFailure(hr, "Failed to copy root string: %ls", wzRoot); + + pwz = pwzSearchKey + lstrlenW(pwzSearchKey); + while (NULL == pwzHeaders) + { + // find the last slash + while (*pwz != '/' && pwz != pwzSearchKey) + { + --pwz; + } + + if (pwz == pwzSearchKey) + { + break; + } + + *pwz = L'\0'; + + // Try here. If it's not found, keep walking up the path + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, pwzSearchKey, &mr); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) + { + hr = S_FALSE; + } + ExitOnFailure(hr, "Failed to find search for HTTP headers for web root: %ls while walking up the tree", wzRoot); + + if (S_OK == hr) + { + hr = StrAllocString(&pwzHeaders, reinterpret_cast(mr.pbMDData), 0); + ExitOnFailure(hr, "Failed to allocate parent HTTP header string"); + break; + } + } + } + else + { + hr = StrAllocString(&pwzHeaders, reinterpret_cast(mr.pbMDData), 0); + ExitOnFailure(hr, "Failed to allocate HTTP header string"); + } + ExitOnFailure(hr, "Failed while searching for default HTTP headers to start with for web root: %ls", wzRoot); + + // Loop through the HTTP headers + for (SCA_HTTP_HEADER* pshh = pshhList; pshh; pshh = pshh->pshhNext) + { + fOldValueFound = FALSE; // assume a HTTP Header match will not be found + + hr = StrAllocFormatted(&pwzNewHeader, L"%s: ", pshh->wzName); + ExitOnFailure(hr, "Failed to allocate header name"); + + if (NULL != pwzHeaders && *pwzHeaders) + { + // Try to find a matching header already in the list + hr = MultiSzFindSubstring(pwzHeaders, pwzNewHeader, &dwFoundHeaderIndex, &wzFoundHeader); + ExitOnFailure(hr, "Failed while searching for existing HTTP header."); + + // If there was a substring HTTP header match, make sure the match was at the beginning + // of the string because that is the HTTP header name. + if (S_OK == hr) + { + DWORD cchMatch = lstrlenW(pwzNewHeader); + if (CSTR_EQUAL == ::CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pwzNewHeader, cchMatch, wzFoundHeader, cchMatch)) + { + fOldValueFound = TRUE; + break; + } + } + } + + // Add the value on to the header name now. + hr = StrAllocConcat(&pwzNewHeader, pshh->wzValue, 0); + ExitOnFailure(hr, "Failed to add value on to HTTP header name."); + + // If we have something to replace, replace it, otherwise, put it at the beginning (order shouldn't matter) + if (fOldValueFound) + { + if (NULL == pwzHeaders) + { + ExitOnFailure(hr = E_INVALIDARG, "While attempting to replace old HTTP header with new HTTP header, it was discovered that the old HTTP header was NULL!"); + } + hr = MultiSzReplaceString(&pwzHeaders, dwFoundHeaderIndex, pwzNewHeader); + ExitOnFailure(hr, "Failed to replace old HTTP header with new HTTP header"); + } + else + { + hr = MultiSzPrepend(&pwzHeaders, NULL, pwzNewHeader); + ExitOnFailure(hr, "Failed to prepend new HTTP header"); + } + } + + // now write the HttpCustom to the metabase + hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_HTTP_CUSTOM, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzHeaders); + ExitOnFailure(hr, "Failed to write HTTP Headers to metabase"); + +LExit: + MetaFreeValue(&mr); + + ReleaseStr(pwzNewHeader); + ReleaseStr(pwzHeaders); + ReleaseStr(pwzSearchKey); + + return hr; +} + + +HRESULT ScaHttpHeaderCheckList( + __in SCA_HTTP_HEADER* pshhList + ) +{ + if (!pshhList) + { + return S_OK; + } + + while (pshhList) + { + WcaLog(LOGMSG_STANDARD, "Http Header: %ls for parent: %ls not used!", pshhList->wzName, pshhList->wzParentValue); + pshhList = pshhList->pshhNext; + } + + return E_FAIL; +} + + +static HRESULT AddHttpHeaderToList( + __in SCA_HTTP_HEADER** ppshhList + ) +{ + HRESULT hr = S_OK; + + SCA_HTTP_HEADER* pshh = static_cast(MemAlloc(sizeof(SCA_HTTP_HEADER), TRUE)); + ExitOnNull(pshh, hr, E_OUTOFMEMORY, "failed to allocate memory for new http header list element"); + + pshh->pshhNext = *ppshhList; + *ppshhList = pshh; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scahttpheader.h b/src/ext/Iis/ca/scahttpheader.h new file mode 100644 index 00000000..a4c407a4 --- /dev/null +++ b/src/ext/Iis/ca/scahttpheader.h @@ -0,0 +1,40 @@ +#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. + + +enum eHttpHeaderParentType { hhptVDir = 1, hhptWeb }; + +struct SCA_HTTP_HEADER +{ + int iParentType; + WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; + + WCHAR wzName[MAX_PATH]; + WCHAR wzValue[MAX_PATH]; + int iAttributes; + + SCA_HTTP_HEADER* pshhNext; +}; + +// prototypes +HRESULT ScaHttpHeaderRead( + __in SCA_HTTP_HEADER **ppshhList, + __inout LPWSTR *ppwzCustomActionData + ); +void ScaHttpHeaderFreeList( + __in SCA_HTTP_HEADER *pshhList + ); +HRESULT ScaHttpHeaderCheckList( + __in SCA_HTTP_HEADER* pshhList + ); +HRESULT ScaGetHttpHeader( + __in int iParentType, + __in LPCWSTR wzParentValue, + __in SCA_HTTP_HEADER** ppshhList, + __out SCA_HTTP_HEADER** ppshhOut + ); +HRESULT ScaWriteHttpHeader( + __in IMSAdminBase* piMetabase, + LPCWSTR wzRoot, + SCA_HTTP_HEADER* pshhList + ); diff --git a/src/ext/Iis/ca/scahttpheader7.cpp b/src/ext/Iis/ca/scahttpheader7.cpp new file mode 100644 index 00000000..645dd8d4 --- /dev/null +++ b/src/ext/Iis/ca/scahttpheader7.cpp @@ -0,0 +1,130 @@ +// 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" + +HRESULT ScaGetHttpHeader7( + __in int iParentType, + __in_z LPCWSTR wzParentValue, + __in SCA_HTTP_HEADER** ppshhList, + __out SCA_HTTP_HEADER** ppshhOut + ) +{ + HRESULT hr = S_OK; + SCA_HTTP_HEADER* pshhAdd = NULL; + SCA_HTTP_HEADER* pshhLast = NULL; + + *ppshhOut = NULL; + + if (!*ppshhList) + { + return hr; + } + + SCA_HTTP_HEADER* pshh = *ppshhList; + while (pshh) + { + if (iParentType == pshh->iParentType && 0 == wcscmp(wzParentValue, pshh->wzParentValue)) + { + // Found a match, take this one out of the list and add it to the matched out list + pshhAdd = pshh; + + if (pshhLast) + { + // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) + pshhLast->pshhNext = pshhAdd->pshhNext; + } + else + { + // If we are at the beginning (no pshhLast) update the beginning (since we're taking it) + *ppshhList = pshh->pshhNext; + } + pshh = pshh->pshhNext; // move on + + // Add the one we've removed to the beginning of the out list + pshhAdd->pshhNext = *ppshhOut; + *ppshhOut = pshhAdd; + } + else + { + pshhLast = pshh; // remember the last we that didn't match + pshh = pshh->pshhNext; // move on + } + } + + return hr; +} + + +HRESULT ScaWriteHttpHeader7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRoot, + SCA_HTTP_HEADER* pshhList + ) +{ + + HRESULT hr = S_OK; + + hr = ScaWriteConfigID(IIS_HTTP_HEADER_BEGIN); + ExitOnFailure(hr, "Fail to write httpHeader begin ID"); + + hr = ScaWriteConfigString(wzWebName); + ExitOnFailure(hr, "Fail to write httpHeader Web Key"); + + hr = ScaWriteConfigString(wzRoot); + ExitOnFailure(hr, "Fail to write httpHeader Vdir key"); + + // Loop through the HTTP headers + for (SCA_HTTP_HEADER* pshh = pshhList; pshh; pshh = pshh->pshhNext) + { + hr = ScaWriteConfigID(IIS_HTTP_HEADER); + ExitOnFailure(hr, "Fail to write httpHeader ID"); + + hr = ScaWriteConfigString(pshh->wzName); + ExitOnFailure(hr, "Fail to write httpHeader name"); + + hr = ScaWriteConfigString(pshh->wzValue); + ExitOnFailure(hr, "Fail to write httpHeader value"); + } + + hr = ScaWriteConfigID(IIS_HTTP_HEADER_END); + ExitOnFailure(hr, "Fail to write httpHeader end ID"); + +LExit: + return hr; +} + + +HRESULT ScaHttpHeaderCheckList7( + __in SCA_HTTP_HEADER* pshhList + ) +{ + if (!pshhList) + { + return S_OK; + } + + while (pshhList) + { + WcaLog(LOGMSG_STANDARD, "Http Header: %ls for parent: %ls not used!", pshhList->wzName, pshhList->wzParentValue); + pshhList = pshhList->pshhNext; + } + + return E_FAIL; +} + + +//static HRESULT AddHttpHeaderToList( +// __in SCA_HTTP_HEADER** ppshhList +// ) +//{ +// HRESULT hr = S_OK; +// +// SCA_HTTP_HEADER* pshh = static_cast(MemAlloc(sizeof(SCA_HTTP_HEADER), TRUE)); +// ExitOnNull(pshh, hr, E_OUTOFMEMORY, "failed to allocate memory for new http header list element"); +// +// pshh->pshhNext = *ppshhList; +// *ppshhList = pshh; +// +//LExit: +// return hr; +//} diff --git a/src/ext/Iis/ca/scahttpheader7.h b/src/ext/Iis/ca/scahttpheader7.h new file mode 100644 index 00000000..7a873c16 --- /dev/null +++ b/src/ext/Iis/ca/scahttpheader7.h @@ -0,0 +1,15 @@ +#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 ScaGetHttpHeader7( + __in int iParentType, + __in_z LPCWSTR wzParentValue, + __in SCA_HTTP_HEADER** ppshhList, + __out SCA_HTTP_HEADER** ppshhOut + ); +HRESULT ScaWriteHttpHeader7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRoot, + SCA_HTTP_HEADER* pshhList + ); diff --git a/src/ext/Iis/ca/scaiis.cpp b/src/ext/Iis/ca/scaiis.cpp new file mode 100644 index 00000000..958051ed --- /dev/null +++ b/src/ext/Iis/ca/scaiis.cpp @@ -0,0 +1,481 @@ +// 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" + +// globals +LPWSTR vpwzCustomActionData = NULL; +DWORD vdwCustomActionCost = 0; + +HRESULT ScaMetabaseTransaction(__in_z LPCWSTR wzBackup) +{ + HRESULT hr = S_OK; + + // TODO: These functions have been reported to hang IIS (O11:51709). They may have been fixed in IIS6, but if not, need to be re-written the hard way + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"StartMetabaseTransaction"), wzBackup, COST_IIS_TRANSACTIONS); + ExitOnFailure(hr, "Failed to schedule StartMetabaseTransaction"); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackMetabaseTransaction"), wzBackup, 0); // rollback cost is irrelevant + ExitOnFailure(hr, "Failed to schedule RollbackMetabaseTransaction"); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CommitMetabaseTransaction"), wzBackup, 0); // commit is free + ExitOnFailure(hr, "Failed to schedule StartMetabaseTransaction"); + +LExit: + return hr; +} + + +HRESULT ScaCreateWeb(IMSAdminBase* piMetabase, LPCWSTR /*wzWeb*/, LPCWSTR wzWebBase) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + UINT ui = 0; + + hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L""); + ExitOnFailure(hr, "Failed to create web"); + + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebServer"); + ExitOnFailure(hr, "Failed to set key type for web"); + + hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L"Root"); + ExitOnFailure(hr, "Failed to create web root"); + + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Root", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); + ExitOnFailure(hr, "Failed to set key type for web root"); + + ui = 0x4000003e; // 1073741886; // default directory browsing rights + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Root", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); + ExitOnFailure(hr, "Failed to set directory browsing for web"); + + hr = ScaCreateMetabaseKey(piMetabase, wzWebBase, L"Filters"); + ExitOnFailure(hr, "Failed to create web filters root"); + + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Filters", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsFilters"); + ExitOnFailure(hr, "Failed to set key for web filters root"); + + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"Filters", MD_FILTER_LOAD_ORDER, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L""); + ExitOnFailure(hr, "Failed to set empty load order for web"); + +LExit: + return hr; +} + + +HRESULT ScaDeleteApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot) +{ + Assert(piMetabase); + Unused(piMetabase); + + HRESULT hr = S_OK; + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteIntegerToCaData(MBA_DELETEAPP, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase delete app directive to CustomActionData"); + + hr = ::StringCchCopyW(wzKey, countof(wzKey), wzWebRoot); + ExitOnFailure(hr, "Failed to copy webroot string to key"); + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEAPP); + ExitOnFailure(hr, "Failed to add ScaDeleteApp action data: %ls cost: %d", pwzCustomActionData, COST_IIS_DELETEAPP); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + + +HRESULT ScaCreateApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot, + DWORD dwIsolation) +{ + Assert(piMetabase); + Unused(piMetabase); + + HRESULT hr = S_OK; + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + BOOL fInProc = FALSE; + + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteIntegerToCaData(MBA_CREATEAPP, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase create app directive to CustomActionData"); + + hr = ::StringCchCopyW(wzKey, countof(wzKey), wzWebRoot); + ExitOnFailure(hr, "Failed to copy webroot string to key"); + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); + + if (0 == dwIsolation) + fInProc = TRUE; + else + fInProc = FALSE; + + hr = WcaWriteIntegerToCaData(fInProc, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add isolation value to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_CREATEAPP); + ExitOnFailure(hr, "Failed to add ScaCreateApp action data: %ls cost: %d", pwzCustomActionData, COST_IIS_CREATEAPP); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + + +HRESULT ScaCreateMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey) +{ + Assert(piMetabase); + Unused(piMetabase); + + HRESULT hr = S_OK; + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + WCHAR* pwzCustomActionData = NULL; + + hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); + ExitOnFailure(hr, "Failed to copy root key string to key"); + if (L'/' != *(wzKey + lstrlenW(wzRootKey))) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); + ExitOnFailure(hr, "Failed to concatenate / to key string"); + } + if (wzSubKey && *wzSubKey) + { + if (L'/' == *wzSubKey) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); + ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); + } + else + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); + ExitOnFailure(hr, "Failed to concatenate subkey to key string"); + } + } + + hr = WcaWriteIntegerToCaData(MBA_CREATEKEY, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); + + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_CREATEKEY); + ExitOnFailure(hr, "Failed to add ScaCreateMetabaseKey action data: %ls cost: %d", pwzCustomActionData, COST_IIS_CREATEKEY); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + + +HRESULT ScaDeleteMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey) +{ + Assert(piMetabase); + Unused(piMetabase); + + HRESULT hr = S_OK; + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + WCHAR* pwzCustomActionData = NULL; + + hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); + ExitOnFailure(hr, "Failed to copy root key string to key"); + if (L'/' != *(wzKey + lstrlenW(wzRootKey))) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); + ExitOnFailure(hr, "Failed to concatenate / to key string"); + } + if (*wzSubKey) + { + if (L'/' == *wzSubKey) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); + ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); + } + else + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); + ExitOnFailure(hr, "Failed to concatenate subkey to key string"); + } + } + + hr = WcaWriteIntegerToCaData(MBA_DELETEKEY, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); + + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEKEY); + ExitOnFailure(hr, "Failed to add ScaDeleteMetabaseKey action data: %ls cost: %d", pwzCustomActionData, COST_IIS_DELETEKEY); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + + +HRESULT ScaDeleteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey, DWORD dwIdentifier, + DWORD dwDataType) +{ + Assert(piMetabase); + Unused(piMetabase); + + HRESULT hr = S_OK; + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + WCHAR* pwzCustomActionData = NULL; + + hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); + ExitOnFailure(hr, "Failed to copy root key string to key"); + if (L'/' != *(wzKey + lstrlenW(wzRootKey))) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); + ExitOnFailure(hr, "Failed to concatenate / to key string"); + } + + if (wzSubKey && *wzSubKey) + { + if (L'/' == *wzSubKey) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); + ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); + } + else + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); + ExitOnFailure(hr, "Failed to concatenate subkey to key string"); + } + } + + hr = WcaWriteIntegerToCaData(MBA_DELETEVALUE, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase write value directive to CustomActionData"); + + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); + + hr = WcaWriteIntegerToCaData(dwIdentifier, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase identifier to CustomActionData"); + + hr = WcaWriteIntegerToCaData(dwDataType, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase data type to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_DELETEVALUE); + ExitOnFailure(hr, "Failed to add ScaDeleteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_DELETEVALUE); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + + +#pragma prefast(push) +#pragma prefast(disable:25120) // Disable "requires count parameter" warning - we do have a way to distinguish buffer sizes in all situations, + // it just depends on the dwDataType, and there's no way to annotate the situation in SAL +HRESULT ScaWriteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey, DWORD dwIdentifier, + DWORD dwAttributes, DWORD dwUserType, + DWORD dwDataType, LPVOID pvData) +#pragma prefast(pop) +{ + Assert(piMetabase && (pvData || (DWORD_METADATA == dwDataType))); // pvData may be 0 if it is DWORD data + Unused(piMetabase); + + HRESULT hr = S_OK; + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + WCHAR* pwzCustomActionData = NULL; + + if (BINARY_METADATA == dwDataType) + { + ExitOnNull(pvData, hr, E_INVALIDARG, "Failed to write binary metadata - no data available to write"); + } + + hr = ::StringCchCopyW(wzKey, countof(wzKey), wzRootKey); + ExitOnFailure(hr, "Failed to copy root key string to key"); + if (L'/' != *(wzKey + lstrlenW(wzRootKey))) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), L"/"); + ExitOnFailure(hr, "Failed to concatenate / to key string"); + } + if (wzSubKey && *wzSubKey) + { + if (L'/' == *wzSubKey) + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey + 1); + ExitOnFailure(hr, "Failed to concatenate subkey (minus slash) to key string"); + } + else + { + hr = ::StringCchCatW(wzKey, countof(wzKey), wzSubKey); + ExitOnFailure(hr, "Failed to concatenate subkey to key string"); + } + } + + hr = WcaWriteIntegerToCaData(MBA_WRITEVALUE, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase write value directive to CustomActionData"); + + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase key to CustomActionData"); + + hr = WcaWriteIntegerToCaData(dwIdentifier, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase identifier to CustomActionData"); + + hr = WcaWriteIntegerToCaData(dwAttributes, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase attributes to CustomActionData"); + + hr = WcaWriteIntegerToCaData(dwUserType, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase user type to CustomActionData"); + + hr = WcaWriteIntegerToCaData(dwDataType, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase data type to CustomActionData"); + + switch (dwDataType) + { + case DWORD_METADATA: + hr = WcaWriteIntegerToCaData((DWORD)((DWORD_PTR)pvData), &pwzCustomActionData); + break; + case STRING_METADATA: + hr = WcaWriteStringToCaData((LPCWSTR)pvData, &pwzCustomActionData); + break; + case MULTISZ_METADATA: + { + // change NULLs to unprintable character to create a 'safe' MULTISZ string + LPWSTR pwz = (LPWSTR)pvData; + for (;;) + { + if ('\0' == *pwz) + { + *pwz = MAGIC_MULTISZ_CHAR; + if ('\0' == *(pwz + 1)) // second null back to back means end of string + break; + } + + ++pwz; + } + + hr = WcaWriteStringToCaData((LPCWSTR)pvData, &pwzCustomActionData); + } + break; + case BINARY_METADATA: + hr = WcaWriteStreamToCaData(((BLOB*) pvData)->pBlobData, ((BLOB*) pvData)->cbSize, &pwzCustomActionData); + break; + default: + hr = E_UNEXPECTED; + } + ExitOnFailure(hr, "Failed to add metabase data to CustomActionData"); + + // TODO: maybe look the key up and make sure we're not just writing the same value that already there + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEVALUE); + ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEVALUE); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + + +HRESULT ScaAddToIisConfiguration(LPCWSTR pwzData, DWORD dwCost) +{ + HRESULT hr = S_OK; + + hr = WcaWriteStringToCaData(pwzData, &vpwzCustomActionData); + ExitOnFailure(hr, "failed to add to metabase configuration data string: %ls", pwzData); + + vdwCustomActionCost += dwCost; + +LExit: + return hr; +} + + +HRESULT ScaWriteConfigurationScript(__in LPCWSTR pwzCaScriptKey) +{ + HRESULT hr = S_OK; + WCA_CASCRIPT_HANDLE hScript = NULL; + LPWSTR pwzHashString = NULL; + BYTE rgbActualHash[SHA1_HASH_LEN] = { }; + DWORD dwHashedBytes = SHA1_HASH_LEN; + + // Create CaScript for communication with WriteMetabaseChanges + hr = WcaCaScriptCreate(WCA_ACTION_INSTALL, WCA_CASCRIPT_SCHEDULED, FALSE, pwzCaScriptKey, FALSE, &hScript); + ExitOnFailure(hr, "Failed to write ca script for WriteMetabaseChanges script."); + + if (vpwzCustomActionData && *vpwzCustomActionData) + { + // Write the actual custom action data to the ca script + WcaCaScriptWriteString(hScript, vpwzCustomActionData); + + hr = CrypHashBuffer((BYTE*)vpwzCustomActionData, sizeof(vpwzCustomActionData) * sizeof(WCHAR), PROV_RSA_AES, CALG_SHA1, rgbActualHash, dwHashedBytes); + ExitOnFailure(hr, "Failed to calculate hash of CustomAction data."); + + hr = StrAlloc(&pwzHashString, ((dwHashedBytes * 2) + 1)); + ExitOnFailure(hr, "Failed to allocate string for script hash"); + + hr = StrHexEncode(rgbActualHash, dwHashedBytes, pwzHashString, ((dwHashedBytes * 2) + 1)); + ExitOnFailure(hr, "Failed to convert hash bytes to string."); + + WcaLog(LOGMSG_VERBOSE, "Custom action data hash: %ls", pwzHashString); + WcaLog(LOGMSG_TRACEONLY, "Custom action data being written to ca script: %ls", vpwzCustomActionData); + } + else + hr = S_FALSE; + +LExit: + // Release the string + ReleaseStr(vpwzCustomActionData); + ReleaseStr(pwzHashString); + + // Flush the ca script to disk as best we can + WcaCaScriptFlush(hScript); + + WcaCaScriptClose(hScript, WCA_CASCRIPT_CLOSE_PRESERVE); + + return hr; +} + + +HRESULT ScaLoadMetabase(IMSAdminBase** ppiMetabase) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the + // user to still uninstall this package by clicking "Ignore" + do + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)ppiMetabase); + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object"); + er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); + switch (er) + { + case IDABORT: + ExitFunction(); // bail with the error result from the CoCreate to kick off a rollback + case IDRETRY: + hr = S_FALSE; // hit me, baby, one more time + break; + case IDIGNORE: + hr = S_OK; // pretend everything is okay and bail + break; + default: // For failure on uninstall continue + hr = S_OK; + break; + } + } + } while (S_FALSE == hr); + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scaiis.h b/src/ext/Iis/ca/scaiis.h new file mode 100644 index 00000000..4c743edf --- /dev/null +++ b/src/ext/Iis/ca/scaiis.h @@ -0,0 +1,33 @@ +#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 ScaMetabaseTransaction(__in_z LPCWSTR wzBackup); + +HRESULT ScaCreateWeb(IMSAdminBase* piMetabase, LPCWSTR wzWeb, LPCWSTR wzWebBase); + +HRESULT ScaDeleteApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot); + +HRESULT ScaCreateApp(IMSAdminBase* piMetabase, LPCWSTR wzWebRoot, + DWORD dwIsolation); + +HRESULT ScaCreateMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey); + +HRESULT ScaDeleteMetabaseKey(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey); + +HRESULT ScaWriteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey, DWORD dwIdentifier, + DWORD dwAttributes, DWORD dwUserType, + DWORD dwDataType, LPVOID pvData); + +HRESULT ScaDeleteMetabaseValue(IMSAdminBase* piMetabase, LPCWSTR wzRootKey, + LPCWSTR wzSubKey, DWORD dwIdentifier, + DWORD dwDataType); + +HRESULT ScaWriteConfigurationScript(LPCWSTR pwzCaScriptKey); + +HRESULT ScaAddToIisConfiguration(LPCWSTR pwzData, DWORD dwCost); + +HRESULT ScaLoadMetabase(IMSAdminBase** piMetabase); diff --git a/src/ext/Iis/ca/scaiis7.cpp b/src/ext/Iis/ca/scaiis7.cpp new file mode 100644 index 00000000..aaf307d7 --- /dev/null +++ b/src/ext/Iis/ca/scaiis7.cpp @@ -0,0 +1,74 @@ +// 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" + +#define COST_IIS_WRITEKEY 10 + +HRESULT ScaIIS7ConfigTransaction(LPCWSTR wzBackup) +{ + HRESULT hr = S_OK; + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"StartIIS7ConfigTransaction"), wzBackup, COST_IIS_TRANSACTIONS); + ExitOnFailure(hr, "Failed to schedule StartIIS7ConfigTransaction"); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackIIS7ConfigTransaction"), wzBackup, 0); // rollback cost is irrelevant + ExitOnFailure(hr, "Failed to schedule RollbackIIS7ConfigTransaction"); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CommitIIS7ConfigTransaction"), wzBackup, 0); // commit is free + ExitOnFailure(hr, "Failed to schedule StartIIS7ConfigTransaction"); + +LExit: + return hr; +} + +HRESULT ScaWriteConfigString(const LPCWSTR wzValue) +{ + HRESULT hr = S_OK; + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteStringToCaData(wzValue, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEKEY); + ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEKEY); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + +HRESULT ScaWriteConfigInteger(DWORD dwValue) +{ + HRESULT hr = S_OK; + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteIntegerToCaData(dwValue, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEKEY); + ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEKEY); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + +HRESULT ScaWriteConfigID(IIS_CONFIG_ACTION emID) +{ + HRESULT hr = S_OK; + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteIntegerToCaData(emID, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add metabase delete key directive to CustomActionData"); + + hr = ScaAddToIisConfiguration(pwzCustomActionData, COST_IIS_WRITEKEY); + ExitOnFailure(hr, "Failed to add ScaWriteMetabaseValue action data: %ls, cost: %d", pwzCustomActionData, COST_IIS_WRITEKEY); + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} + diff --git a/src/ext/Iis/ca/scaiis7.h b/src/ext/Iis/ca/scaiis7.h new file mode 100644 index 00000000..f398deca --- /dev/null +++ b/src/ext/Iis/ca/scaiis7.h @@ -0,0 +1,17 @@ +#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 ScaScheduleIIS7Configuration(); + +HRESULT ScaIIS7ConfigTransaction(__in_z LPCWSTR wzBackup); + +HRESULT ScaCreateApp7(__in_z LPCWSTR wzWebRoot, DWORD dwIsolation); + +HRESULT ScaDeleteConfigElement(IIS_CONFIG_ACTION emElement, LPCWSTR wzSubKey); + +HRESULT ScaWriteConfigString(__in_z const LPCWSTR wzValue); + +HRESULT ScaWriteConfigID(IIS_CONFIG_ACTION emID); + +HRESULT ScaWriteConfigInteger(DWORD dwValue); diff --git a/src/ext/Iis/ca/scamimemap.cpp b/src/ext/Iis/ca/scamimemap.cpp new file mode 100644 index 00000000..8afe99f9 --- /dev/null +++ b/src/ext/Iis/ca/scamimemap.cpp @@ -0,0 +1,200 @@ +// 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" + +enum eMimeMapQuery { mmqMimeMap = 1, mmqParentType, mmqParentValue, + mmqMimeType, mmqExtension}; + +// prototypes +static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList); + + +void ScaMimeMapFreeList(SCA_MIMEMAP* psmmList) +{ + SCA_MIMEMAP* psmmDelete = psmmList; + while (psmmList) + { + psmmDelete = psmmList; + psmmList = psmmList->psmmNext; + + MemFree(psmmDelete); + } +} + + +HRESULT __stdcall ScaMimeMapRead( + SCA_MIMEMAP** ppsmmList, + __inout LPWSTR *ppwzCustomActionData + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + LPWSTR pwzData = NULL; + SCA_MIMEMAP* psmm; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaMimeMapRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaMimeMapRead() - required table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the mimemappings + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + hr = AddMimeMapToList(ppsmmList); + ExitOnFailure(hr, "failed to add mime map to list"); + + psmm = *ppsmmList; + + hr = WcaGetRecordString(hRec, mmqMimeMap, &pwzData); + ExitOnFailure(hr, "Failed to get MimeMap.MimeMap"); + hr = ::StringCchCopyW(psmm->wzMimeMap, countof(psmm->wzMimeMap), pwzData); + ExitOnFailure(hr, "Failed to copy mimemap string to mimemap object"); + + hr = WcaGetRecordInteger(hRec, mmqParentType, &psmm->iParentType); + ExitOnFailure(hr, "Failed to get MimeMap.iParentType"); + + hr = WcaGetRecordString(hRec, mmqParentValue, &pwzData); + ExitOnFailure(hr, "Failed to get MimeMap.ParentValue"); + hr = ::StringCchCopyW(psmm->wzParentValue, countof(psmm->wzParentValue), pwzData); + ExitOnFailure(hr, "Failed to copy parent value string to mimemap object"); + + hr = WcaGetRecordString(hRec, mmqExtension, &pwzData); + ExitOnFailure(hr, "Failed to get MimeMap.Extension"); + hr = ::StringCchCopyW(psmm->wzExtension, countof(psmm->wzExtension), pwzData); + ExitOnFailure(hr, "Failed to copy extension string to mimemap object"); + + hr = WcaGetRecordString(hRec, mmqMimeType, &pwzData); + ExitOnFailure(hr, "Failed to get MimeMap.MimeType"); + hr = ::StringCchCopyW(psmm->wzMimeType, countof(psmm->wzMimeType), pwzData); + ExitOnFailure(hr, "Failed to copy mimetype string to mimemap object"); + } + + if (E_NOMOREITEMS == hr) + hr = S_OK; + ExitOnFailure(hr, "Failure while processing mimemappings"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaGetMimeMap(int iParentType, LPCWSTR wzParentValue, SCA_MIMEMAP **ppsmmList, SCA_MIMEMAP **ppsmmOut) +{ + HRESULT hr = S_OK; + SCA_MIMEMAP* psmmAdd = NULL; + SCA_MIMEMAP* psmmLast = NULL; + + *ppsmmOut = NULL; + + if (!*ppsmmList) + return hr; + + SCA_MIMEMAP* psmm = *ppsmmList; + while (psmm) + { + if (iParentType == psmm->iParentType && 0 == lstrcmpW(wzParentValue, psmm->wzParentValue)) + { + // Found a match, take this one out of the list and add it to the matched out list + psmmAdd = psmm; + + if (psmmLast) + { + // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) + psmmLast->psmmNext = psmmAdd->psmmNext; + } + else + { + // If we are at the beginning (no psmmLast) update the beginning (since we're taking it) + *ppsmmList = psmm->psmmNext; + } + psmm = psmm->psmmNext; // move on + + // Add the one we've removed to the beginning of the out list + psmmAdd->psmmNext = *ppsmmOut; + *ppsmmOut = psmmAdd; + } + else + { + psmmLast = psmm; // remember the last we that didn't match + psmm = psmm->psmmNext; // move on + } + } + + return hr; +} + +HRESULT ScaMimeMapCheckList(SCA_MIMEMAP* psmmList) +{ + if (!psmmList) + return S_OK; + + while (psmmList) + { + WcaLog(LOGMSG_STANDARD, "MimeMapping of %ls with ParentType=%d and ParentValue=%ls not used!", psmmList->wzMimeMap, psmmList->iParentType, psmmList->wzParentValue); + psmmList = psmmList->psmmNext; + } + + return E_FAIL; +} + + +HRESULT ScaWriteMimeMap(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, + SCA_MIMEMAP* psmmList) +{ + HRESULT hr = S_OK; + + WCHAR wzMimeMap[8192]; + WCHAR *pwzNext = wzMimeMap; + const WCHAR *pwzMac = wzMimeMap + countof(wzMimeMap); // used to properly create the MULTI_SZ + + // fill the MULTI_SZ wzMimeMap buffer for the MimeMap attribute + ::ZeroMemory(wzMimeMap, sizeof(wzMimeMap)); + + for (SCA_MIMEMAP* psmm = psmmList; psmm; psmm = psmm->psmmNext) + { + hr = ::StringCchPrintfW(pwzNext, max(0, pwzMac - pwzNext), L"%s,%s", psmm->wzExtension, psmm->wzMimeType); + ExitOnFailure(hr, "Failed to set MimeMap string"); + + pwzNext += lstrlenW(pwzNext) + 1; // reserve space for null + Assert(pwzNext <= pwzMac); + } + + if (pwzNext != wzMimeMap) + { + // now write the CustomErrors to the metabase + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_MIME_MAP, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzMimeMap); + ExitOnFailure(hr, "Failed to write MimeMap"); + } + else + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWriteMimeMap() - no mappings found."); + ExitFunction1(hr = S_FALSE); + } + +LExit: + return hr; +} + + +static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList) +{ + HRESULT hr = S_OK; + + SCA_MIMEMAP* psmm = static_cast(MemAlloc(sizeof(SCA_MIMEMAP), TRUE)); + ExitOnNull(psmm, hr, E_OUTOFMEMORY, "failed to allocate memory for new mime map list element"); + + psmm->psmmNext = *ppsmmList; + *ppsmmList = psmm; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scamimemap.h b/src/ext/Iis/ca/scamimemap.h new file mode 100644 index 00000000..b50e82e9 --- /dev/null +++ b/src/ext/Iis/ca/scamimemap.h @@ -0,0 +1,33 @@ +#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. + + +enum eMimeMapParentType { mmptVDir = 1, mmptWeb = 2 }; + +struct SCA_MIMEMAP +{ + // iis configuation information + WCHAR wzMimeMap[MAX_DARWIN_KEY + 1]; + int iParentType; + WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; + WCHAR wzMimeType[MAX_DARWIN_KEY + 1]; + WCHAR wzExtension[MAX_DARWIN_KEY + 1]; + + + SCA_MIMEMAP* psmmNext; +}; + + +// prototypes + +HRESULT __stdcall ScaMimeMapRead(SCA_MIMEMAP** ppsmmList, __inout LPWSTR *ppwzCustomActionData); + +HRESULT ScaGetMimeMap(int iParentType, LPCWSTR wzParentValue, SCA_MIMEMAP **psmmList, SCA_MIMEMAP **ppsmmOut); + +HRESULT ScaMimeMapCheckList(SCA_MIMEMAP* psmmList); + +void ScaMimeMapFreeList(SCA_MIMEMAP* psmmList); + +HRESULT ScaWriteMimeMap(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, + SCA_MIMEMAP* psmmList); + diff --git a/src/ext/Iis/ca/scamimemap7.cpp b/src/ext/Iis/ca/scamimemap7.cpp new file mode 100644 index 00000000..f6689720 --- /dev/null +++ b/src/ext/Iis/ca/scamimemap7.cpp @@ -0,0 +1,68 @@ +// 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" + +// prototypes +HRESULT ScaWriteMimeMap7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + SCA_MIMEMAP* psmmList + ) +{ + HRESULT hr = S_OK; + SCA_MIMEMAP* psmm; + + //create the mimemap list for this vdir application + //all go to same web/root location tag + hr = ScaWriteConfigID(IIS_MIMEMAP_BEGIN); + ExitOnFailure(hr, "Failed to write mimemap begin id"); + hr = ScaWriteConfigString(wzWebName); //site name key + ExitOnFailure(hr, "Failed to write mimemap web key"); + hr = ScaWriteConfigString(wzRootOfWeb); //app path key + ExitOnFailure(hr, "Failed to write mimemap app key"); + + psmm = psmmList; + + while (psmm) + { + //create the Extension for this vdir application + hr = ScaWriteConfigID(IIS_MIMEMAP); + ExitOnFailure(hr, "Failed to write mimemap id"); + + if (*psmm->wzExtension) + { + hr = ScaWriteConfigString(psmm->wzExtension); + } + else // blank means "*" (all) + { + hr = ScaWriteConfigString(L"*"); + } + ExitOnFailure(hr, "Failed to write mimemap extension"); + + hr = ScaWriteConfigString(psmm->wzMimeType); + ExitOnFailure(hr, "Failed to write mimemap type"); + + psmm = psmm->psmmNext; + } + + hr = ScaWriteConfigID(IIS_MIMEMAP_END); + ExitOnFailure(hr, "Failed to write mimemap end id"); + +LExit: + return hr; +} + + +//static HRESULT AddMimeMapToList(SCA_MIMEMAP** ppsmmList) +//{ +// HRESULT hr = S_OK; +// +// SCA_MIMEMAP* psmm = static_cast(MemAlloc(sizeof(SCA_MIMEMAP), TRUE)); +// ExitOnNull(psmm, hr, E_OUTOFMEMORY, "failed to allocate memory for new mime map list element"); +// +// psmm->psmmNext = *ppsmmList; +// *ppsmmList = psmm; +// +//LExit: +// return hr; +//} diff --git a/src/ext/Iis/ca/scamimemap7.h b/src/ext/Iis/ca/scamimemap7.h new file mode 100644 index 00000000..88fcdc39 --- /dev/null +++ b/src/ext/Iis/ca/scamimemap7.h @@ -0,0 +1,10 @@ +#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 ScaWriteMimeMap7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + SCA_MIMEMAP* psmmList + ); + diff --git a/src/ext/Iis/ca/scaproperty.cpp b/src/ext/Iis/ca/scaproperty.cpp new file mode 100644 index 00000000..d0e0d8a4 --- /dev/null +++ b/src/ext/Iis/ca/scaproperty.cpp @@ -0,0 +1,252 @@ +// 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" + +/*------------------------------------------------------------------ +IIsProperty table: + +Property Component_ Attributes Value +s72 s72 i4 s255 +------------------------------------------------------------------*/ + +// sql queries +enum ePropertyQuery { pqProperty = 1, pqComponent, pqAttributes, pqValue, pqInstalled, pqAction }; + + +// prototypes +static HRESULT AddPropertyToList( + SCA_PROPERTY** ppspList + ); + + +// functions +void ScaPropertyFreeList( + SCA_PROPERTY* pspList + ) +{ + SCA_PROPERTY* pspDelete = pspList; + while (pspList) + { + pspDelete = pspList; + pspList = pspList->pspNext; + + MemFree(pspDelete); + } +} + + +HRESULT ScaPropertyRead( + SCA_PROPERTY** ppspList, + __inout LPWSTR *ppwzCustomActionData + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + + LPWSTR pwzData = NULL; + SCA_PROPERTY* pss; + + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + ExitOnNull(ppspList, hr, E_INVALIDARG, "Failed to read property, because no property to read was provided"); + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallProperty() - required table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the Settings + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + hr = AddPropertyToList(ppspList); + ExitOnFailure(hr, "failed to add property to list"); + + pss = *ppspList; + + hr = WcaGetRecordString(hRec, pqProperty, &pwzData); + ExitOnFailure(hr, "failed to get IIsProperty.Property"); + hr = ::StringCchCopyW(pss->wzProperty, countof(pss->wzProperty), pwzData); + ExitOnFailure(hr, "failed to copy Property name: %ls", pwzData); + + hr = WcaGetRecordString(hRec, pqValue, &pwzData); + ExitOnFailure(hr, "failed to get IIsProperty.Value"); + hr = ::StringCchCopyW(pss->wzValue, countof(pss->wzValue), pwzData); + ExitOnFailure(hr, "failed to copy Property value: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, pqAttributes, &pss->iAttributes); + ExitOnFailure(hr, "failed to get IIsProperty.Attributes"); + + hr = WcaGetRecordString(hRec, pqComponent, &pwzData); + ExitOnFailure(hr, "failed to get IIsProperty.Component"); + hr = ::StringCchCopyW(pss->wzComponent, countof(pss->wzComponent), pwzData); + ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, pqInstalled, (int *)&pss->isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for filter"); + + hr = WcaGetRecordInteger(hRec, pqAction, (int *)&pss->isAction); + ExitOnFailure(hr, "Failed to get Component action state for filter"); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "failure while processing IIsProperty table"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaPropertyInstall( + IMSAdminBase* piMetabase, + SCA_PROPERTY* pspList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + + for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) + { + // if we are installing the web site + if (WcaIsInstalling(psp->isInstalled, psp->isAction)) + { + hr = ScaWriteProperty(piMetabase, psp); + ExitOnFailure(hr, "failed to write Property '%ls' to metabase", psp->wzProperty); + } + } + +LExit: + return hr; +} + + +HRESULT ScaPropertyUninstall( + IMSAdminBase* piMetabase, + SCA_PROPERTY* pspList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + + for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) + { + // if we are uninstalling the web site + if (WcaIsUninstalling(psp->isInstalled, psp->isAction)) + { + hr = ScaRemoveProperty(piMetabase, psp); + ExitOnFailure(hr, "Failed to remove Property '%ls' from metabase", psp->wzProperty); + } + } + +LExit: + return hr; +} + + +HRESULT ScaWriteProperty( + IMSAdminBase* piMetabase, + SCA_PROPERTY* psp + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + DWORD dwValue; + LPWSTR wz = NULL; + + ExitOnNull(psp, hr, E_INVALIDARG, "Failed to write property because no property to write was given"); + + // + // Figure out what setting we're writing and write it + // + if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) + { + dwValue = 1; + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_STANDARD_APP_MODE_ENABLED, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to set IIs5IsolationMode"); + } + else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) + { + dwValue = wcstoul(psp->wzValue, &wz, 10) * 1024; // remember, the value shown is in kilobytes, the value saved is in bytes + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_MAX_GLOBAL_BANDWIDTH, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to set MaxGlobalBandwidth"); + } + else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) + { + dwValue = 1; + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_LOG_IN_UTF_8, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to set LogInUTF8"); + } + else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_ETAG_CHANGENUMBER)) + { + dwValue = wcstoul(psp->wzValue, &wz, 10); + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, /*MD_ETAG_CHANGENUMBER*/ 2039, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to set EtagChangenumber"); + } +LExit: + return hr; +} + + +HRESULT ScaRemoveProperty( + IMSAdminBase* piMetabase, + SCA_PROPERTY* psp + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + DWORD dwValue; + + ExitOnNull(psp, hr, E_INVALIDARG, "Failed to remove property because no property to remove was given"); + + if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) + { + dwValue = 0; + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_STANDARD_APP_MODE_ENABLED, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to clear IIs5IsolationMode"); + } + else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) + { + dwValue = 0xFFFFFFFF; // This unchecks the box + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_MAX_GLOBAL_BANDWIDTH, METADATA_NO_ATTRIBUTES , IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to clear MaxGlobalBandwidth"); + } + else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) + { + dwValue = 0; + hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_LOG_IN_UTF_8, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); + ExitOnFailure(hr, "failed to clear LogInUTF8"); + } + +LExit: + return hr; +} + + +static HRESULT AddPropertyToList( + SCA_PROPERTY** ppspList + ) +{ + HRESULT hr = S_OK; + SCA_PROPERTY* psp = static_cast(MemAlloc(sizeof(SCA_PROPERTY), TRUE)); + ExitOnNull(psp, hr, E_OUTOFMEMORY, "failed to allocate memory for new property list element"); + + psp->pspNext = *ppspList; + *ppspList = psp; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scaproperty.h b/src/ext/Iis/ca/scaproperty.h new file mode 100644 index 00000000..21e7cfc7 --- /dev/null +++ b/src/ext/Iis/ca/scaproperty.h @@ -0,0 +1,54 @@ +#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 wzIISPROPERTY_IIS5_ISOLATION_MODE L"IIs5IsolationMode" +#define wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH L"MaxGlobalBandwidth" +#define wzIISPROPERTY_LOG_IN_UTF8 L"LogInUTF8" +#define wzIISPROPERTY_ETAG_CHANGENUMBER L"ETagChangeNumber" + +struct SCA_PROPERTY +{ + // iis configuation information + WCHAR wzProperty[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + INT iAttributes; + WCHAR wzValue[MAX_DARWIN_COLUMN + 1]; + + SCA_PROPERTY *pspNext; +}; + + +// prototypes + +HRESULT ScaPropertyRead( + SCA_PROPERTY** ppspList, + __inout LPWSTR *ppwzCustomActionData + ); + +void ScaPropertyFreeList( + SCA_PROPERTY* pspList + ); + +HRESULT ScaPropertyInstall( + IMSAdminBase* piMetabase, + SCA_PROPERTY* pspList + ); + +HRESULT ScaPropertyUninstall( + IMSAdminBase* piMetabase, + SCA_PROPERTY* pspList + ); + +HRESULT ScaWriteProperty( + IMSAdminBase* piMetabase, + SCA_PROPERTY* psp + ); + +HRESULT ScaRemoveProperty( + IMSAdminBase* piMetabase, + SCA_PROPERTY* psp + ); + diff --git a/src/ext/Iis/ca/scaproperty7.cpp b/src/ext/Iis/ca/scaproperty7.cpp new file mode 100644 index 00000000..d17eeb68 --- /dev/null +++ b/src/ext/Iis/ca/scaproperty7.cpp @@ -0,0 +1,108 @@ +// 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" + +HRESULT ScaPropertyInstall7( + SCA_PROPERTY* pspList + ) +{ + HRESULT hr = S_OK; + + for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) + { + // if we are installing the web site + if (WcaIsInstalling(psp->isInstalled, psp->isAction)) + { + hr = ScaWriteProperty7(psp); + ExitOnFailure(hr, "failed to write Property '%ls' ", psp->wzProperty); + } + } + +LExit: + return hr; +} + + +HRESULT ScaPropertyUninstall7( + SCA_PROPERTY* pspList + ) +{ + HRESULT hr = S_OK; + + for (SCA_PROPERTY* psp = pspList; psp; psp = psp->pspNext) + { + // if we are uninstalling the web site + if (WcaIsUninstalling(psp->isInstalled, psp->isAction)) + { + hr = ScaRemoveProperty7(psp); + ExitOnFailure(hr, "Failed to remove Property '%ls'", psp->wzProperty); + } + } + +LExit: + return hr; +} + + +HRESULT ScaWriteProperty7( + const SCA_PROPERTY* psp + ) +{ + HRESULT hr = S_OK; + DWORD dwValue; + LPWSTR wz = NULL; + + ExitOnNull(psp, hr, E_INVALIDARG, "Failed to write property because no property to write was given"); + // + // Figure out what setting we're writing and write it + // + if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) + { + // IIs5IsolationMode not supported + WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: IIs5IsolationMode, ignoring"); + } + else if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) + { + dwValue = wcstoul(psp->wzValue, &wz, 10) * 1024; // remember, the value shown is in kilobytes, the value saved is in bytes + hr = ScaWriteConfigID(IIS_PROPERTY); + ExitOnFailure(hr, "failed to set Property ID"); + hr = ScaWriteConfigID(IIS_PROPERTY_MAXBAND); + ExitOnFailure(hr, "failed to set Property MSXBAND ID"); + hr = ScaWriteConfigInteger(dwValue); + ExitOnFailure(hr, "failed to set Property MSXBAND value"); + } + else if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) + { + dwValue = 1; + hr = ScaWriteConfigID(IIS_PROPERTY); + ExitOnFailure(hr, "failed to set Property ID"); + hr = ScaWriteConfigID(IIS_PROPERTY_LOGUTF8); + ExitOnFailure(hr, "failed to set Property LOG ID"); + hr = ScaWriteConfigInteger(dwValue); + ExitOnFailure(hr, "failed to set Property Log value"); + } + else if (0 == wcscmp(psp->wzProperty, wzIISPROPERTY_ETAG_CHANGENUMBER)) + { + //EtagChangenumber not supported + WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: EtagChangenumber, ignoring"); + } + +LExit: + return hr; +} + +HRESULT ScaRemoveProperty7( + __in SCA_PROPERTY* /*psp*/ + ) +{ + + // NOP function for now + //The two global values being set by WebProperty: + // + // + // should should not be removed on uninstall. + + HRESULT hr = S_OK; + + return hr; +} diff --git a/src/ext/Iis/ca/scaproperty7.h b/src/ext/Iis/ca/scaproperty7.h new file mode 100644 index 00000000..bbf811e8 --- /dev/null +++ b/src/ext/Iis/ca/scaproperty7.h @@ -0,0 +1,26 @@ +#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 wzIISPROPERTY_IIS5_ISOLATION_MODE L"IIs5IsolationMode" +#define wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH L"MaxGlobalBandwidth" +#define wzIISPROPERTY_LOG_IN_UTF8 L"LogInUTF8" +#define wzIISPROPERTY_ETAG_CHANGENUMBER L"ETagChangeNumber" + +// prototypes +HRESULT ScaPropertyInstall7( + SCA_PROPERTY* pspList + ); + +HRESULT ScaPropertyUninstall7( + SCA_PROPERTY* pspList + ); + +HRESULT ScaWriteProperty7( + const SCA_PROPERTY* psp + ); + +HRESULT ScaRemoveProperty7( + SCA_PROPERTY* psp + ); + diff --git a/src/ext/Iis/ca/scasched.cpp b/src/ext/Iis/ca/scasched.cpp new file mode 100644 index 00000000..de021275 --- /dev/null +++ b/src/ext/Iis/ca/scasched.cpp @@ -0,0 +1,823 @@ +// 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" + +const int ConfigureIIsCost = 8; +const int WriteMetabaseChangesCost = 20; +const int WriteIIS7ConfigChangesCost = 20; + +// sql queries +LPCWSTR vcsUserDeferredQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `User`"; + +LPCWSTR vcsWebSvcExtQuery = L"SELECT `Component_`, `File`, `Description`, `Group`, `Attributes` FROM `IIsWebServiceExtension`"; + +LPCWSTR vcsAppPoolQuery = L"SELECT `AppPool`, `Name`, `Component_`, `Attributes`, `User_`, `RecycleMinutes`, `RecycleRequests`, `RecycleTimes`, `VirtualMemory`, `PrivateMemory`, `IdleTimeout`, `QueueLimit`, `CPUMon`, `MaxProc`, `ManagedRuntimeVersion`, `ManagedPipelineMode` FROM `IIsAppPool`"; + +LPCWSTR vcsComponentAttrQuery = L"SELECT `Component`,`Attributes` FROM `Component`"; + +LPCWSTR vcsMimeMapQuery = L"SELECT `MimeMap`, `ParentType`, `ParentValue`, `MimeType`, `Extension` FROM `IIsMimeMap`"; + +LPCWSTR vcsHttpHeaderQuery = L"SELECT `Name`, `ParentType`, `ParentValue`, `Value`, `Attributes` FROM `IIsHttpHeader` ORDER BY `Sequence`"; + +LPCWSTR vcsWebErrorQuery = + L"SELECT `ErrorCode`, `SubCode`, `ParentType`, `ParentValue`, `File`, `URL` " + L"FROM `IIsWebError` ORDER BY `ErrorCode`, `SubCode`"; + +LPCWSTR vcsWebDirPropertiesQuery = L"SELECT `DirProperties`, `Access`, `Authorization`, `AnonymousUser_`, `IIsControlledPassword`, `LogVisits`, `Index`, `DefaultDoc`, `AspDetailedError`, `HttpExpires`, `CacheControlMaxAge`, `CacheControlCustom`, `NoCustomError`, `AccessSSLFlags`, `AuthenticationProviders` " + L"FROM `IIsWebDirProperties`"; + +LPCWSTR vcsSslCertificateQuery = L"SELECT `Certificate`.`StoreName`, `CertificateHash`.`Hash`, `IIsWebSiteCertificates`.`Web_` FROM `Certificate`, `CertificateHash`, `IIsWebSiteCertificates` WHERE `Certificate`.`Certificate`=`CertificateHash`.`Certificate_` AND `CertificateHash`.`Certificate_`=`IIsWebSiteCertificates`.`Certificate_`"; + +LPCWSTR vcsWebLogQuery = L"SELECT `Log`, `Format` " + L"FROM `IIsWebLog`"; + +LPCWSTR vcsWebApplicationQuery = L"SELECT `Name`, `Isolation`, `AllowSessions`, `SessionTimeout`, " + L"`Buffer`, `ParentPaths`, `DefaultScript`, `ScriptTimeout`, " + L"`ServerDebugging`, `ClientDebugging`, `AppPool_`, `Application` " + L"FROM `IIsWebApplication`"; + +LPCWSTR vcsWebAppExtensionQuery = L"SELECT `Extension`, `Verbs`, `Executable`, `Attributes`, `Application_` FROM `IIsWebApplicationExtension`"; + +LPCWSTR vcsWebQuery = L"SELECT `Web`, `Component_`, `Id`, `Description`, `ConnectionTimeout`, `Directory_`, `State`, `Attributes`, `DirProperties_`, `Application_`, " + L"`Address`, `IP`, `Port`, `Header`, `Secure`, `Log_` FROM `IIsWebSite`, `IIsWebAddress` " + L"WHERE `KeyAddress_`=`Address` ORDER BY `Sequence`"; + +LPCWSTR vcsWebAddressQuery = L"SELECT `Address`, `Web_`, `IP`, `Port`, `Header`, `Secure` " + L"FROM `IIsWebAddress`"; + +LPCWSTR vcsWebBaseQuery = L"SELECT `Web`, `Id`, `IP`, `Port`, `Header`, `Secure`, `Description` " + L"FROM `IIsWebSite`, `IIsWebAddress` " + L"WHERE `KeyAddress_`=`Address`"; + +LPCWSTR vcsWebDirQuery = L"SELECT `Web_`, `WebDir`, `Component_`, `Path`, `DirProperties_`, `Application_` " + L"FROM `IIsWebDir`"; + +LPCWSTR vcsVDirQuery = L"SELECT `Web_`, `VirtualDir`, `Component_`, `Alias`, `Directory_`, `DirProperties_`, `Application_` " + L"FROM `IIsWebVirtualDir`"; + +LPCWSTR vcsFilterQuery = L"SELECT `Web_`, `Name`, `Component_`, `Path`, `Description`, `Flags`, `LoadOrder` FROM `IIsFilter` ORDER BY `Web_`"; + +LPCWSTR vcsPropertyQuery = L"SELECT `Property`, `Component_`, `Attributes`, `Value` " + L"FROM `IIsProperty`"; + +#define IIS7CONDITION L"VersionNT >= 600" +#define USEIIS7CONDITION IIS7CONDITION L"AND NOT UseIis6Compatibility" + +/******************************************************************** +ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings + +********************************************************************/ +extern "C" UINT __stdcall ConfigureIIs( + __in MSIHANDLE hInstall + ) +{ + //AssertSz(FALSE, "debug ConfigureIIs here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + LPWSTR pwzScriptKey = NULL; + LPWSTR pwzBackupId = NULL; + LPWSTR pwzCustomActionData = NULL; // CustomActionData for ConfigureIIs custom action + + // initialize + hr = WcaInitialize(hInstall, "ConfigureIIs"); + ExitOnFailure(hr, "Failed to initialize"); + + // check for the prerequsite tables + if (S_OK != WcaTableExists(L"IIsWebSite") && S_OK != WcaTableExists(L"IIsFilter") && S_OK != WcaTableExists(L"IIsProperty") && + S_OK != WcaTableExists(L"IIsWebServiceExtension") && S_OK != WcaTableExists(L"IIsAppPool")) + { + WcaLog(LOGMSG_VERBOSE, "skipping IIs CustomAction, no IIsWebSite table, no IIsFilter table, no IIsProperty table, no IIsWebServiceExtension, and no IIsAppPool table"); + ExitFunction1(hr = S_FALSE); + } + + // Get a CaScript key + hr = WcaCaScriptCreateKey(&pwzScriptKey); + ExitOnFailure(hr, "Failed to get encoding key."); + + // Generate a unique string to be used for this product's transaction + // This prevents a name collision when doing a major upgrade + hr = WcaGetProperty(L"ProductCode", &pwzBackupId); + ExitOnFailure(hr, "failed to get ProductCode"); + + hr = StrAllocConcat(&pwzBackupId, L"ScaConfigureIIs", 0); + ExitOnFailure(hr, "failed to concat ScaConfigureIIs"); + + // make sure the operations below are wrapped in a "transaction" + // use IIS7 transaction logic even if using Iis6 compat because Backup/Restore don't work with metabase compatibility + if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, IIS7CONDITION)) + { + hr = ScaIIS7ConfigTransaction(pwzBackupId); + MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS7 transaction"); + } + else + { + hr = ScaMetabaseTransaction(pwzBackupId); + MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS transaction"); + } + + // Write the CaScript key to the ConfigureIIS custom action data + hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add encoding key to CustomActionData."); + + // Wrap vcsUserDeferredQuery to send to deferred CA + if (S_OK == WcaTableExists(L"User")) + { + hr = WcaWrapQuery(vcsUserDeferredQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap User query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap User empty query"); + } + + // Wrap vcsWebSvcExtQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebServiceExtension")) + { + hr = WcaWrapQuery(vcsWebSvcExtQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4, 1, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension empty query"); + } + + // Wrap vcsAppPoolQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsAppPool")) + { + hr = WcaWrapQuery(vcsAppPoolQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn15 | efmcColumn16, 3, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsAppPool query"); + + hr = WcaWrapQuery(vcsComponentAttrQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap Component query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsAppPool empty query"); + } + + // Wrap vcsMimeMapQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsMimeMap")) + { + hr = WcaWrapQuery(vcsMimeMapQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsMimeMap query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsMimeMap empty query"); + } + + // Wrap vcsHttpHeaderQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsHttpHeader")) + { + hr = WcaWrapQuery(vcsHttpHeaderQuery, &pwzCustomActionData, efmcColumn1 | efmcColumn4, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsHttpHeader query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsHttpHeader empty query"); + } + + // Wrap vcsWebErrorQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebError")) + { + hr = WcaWrapQuery(vcsWebErrorQuery, &pwzCustomActionData, efmcColumn5 | efmcColumn6, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebError query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebError empty query"); + } + + // Wrap vcsWebDirPropertiesQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebDirProperties")) + { + hr = WcaWrapQuery(vcsWebDirPropertiesQuery, &pwzCustomActionData, efmcColumn8 | efmcColumn10 | efmcColumn12 | efmcColumn15, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties empty query"); + } + + // Wrap vcsSslCertificateQuery to send to deferred CA + if (S_OK == WcaTableExists(L"Certificate") && S_OK == WcaTableExists(L"CertificateHash") && S_OK == WcaTableExists(L"IIsWebSiteCertificates")) + { + hr = WcaWrapQuery(vcsSslCertificateQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap SslCertificate query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap SslCertificate empty query"); + } + + // Wrap vcsWebLogQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebLog")) + { + hr = WcaWrapQuery(vcsWebLogQuery, &pwzCustomActionData, efmcColumn2, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebLog query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebLog empty query"); + } + + // Wrap vcsWebApplicationQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebApplication")) + { + hr = WcaWrapQuery(vcsWebApplicationQuery, &pwzCustomActionData, efmcColumn1, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebApplication query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebApplication empty query"); + } + + // Wrap vcsWebAppExtensionQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebApplicationExtension")) + { + hr = WcaWrapQuery(vcsWebAppExtensionQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension empty query"); + } + + // Wrap vcsWebQuery, vcsWebAddressQuery, and vcsWebBaseQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebAddress") && S_OK == WcaTableExists(L"IIsWebSite")) + { + hr = WcaWrapQuery(vcsWebQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn12 | efmcColumn13 | efmcColumn14, 2, 6); + ExitOnFailure(hr, "Failed to wrap IIsWebSite query"); + + hr = WcaWrapQuery(vcsWebAddressQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebAddress query"); + + hr = WcaWrapQuery(vcsWebBaseQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4 | efmcColumn5 | efmcColumn7, 0xFFFFFFFF, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebBase query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebSite empty query"); + + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebAddress empty query"); + + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebBase empty query"); + } + + // Wrap vcsWebDirQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebDir")) + { + hr = WcaWrapQuery(vcsWebDirQuery, &pwzCustomActionData, efmcColumn4, 3, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsWebDir query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebDir empty query"); + } + + // Wrap vcsVDirQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsWebVirtualDir")) + { + hr = WcaWrapQuery(vcsVDirQuery, &pwzCustomActionData, efmcColumn4, 3, 5); + ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir empty query"); + } + + // Wrap vcsFilterQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsFilter")) + { + hr = WcaWrapQuery(vcsFilterQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 3, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsFilter query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsFilter empty query"); + } + + // Wrap vcsPropertyQuery to send to deferred CA + if (S_OK == WcaTableExists(L"IIsProperty")) + { + hr = WcaWrapQuery(vcsPropertyQuery, &pwzCustomActionData, efmcColumn4, 2, 0xFFFFFFFF); + ExitOnFailure(hr, "Failed to wrap IIsProperty query"); + } + else + { + hr = WcaWrapEmptyQuery(&pwzCustomActionData); + ExitOnFailure(hr, "Failed to wrap IIsProperty empty query"); + } + + if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, USEIIS7CONDITION)) + { + // This must remain trace only, CA data may contain password + WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIIS7Exec will be: %ls", pwzCustomActionData); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ConfigureIIs7Exec"), pwzCustomActionData, ConfigureIIsCost); + ExitOnFailure(hr, "Failed to schedule ConfigureIIs7Exec custom action"); + + ReleaseNullStr(pwzCustomActionData); + + // Write the CaScript key to the ConfigureIIS custom action data + hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add script key to CustomActionData."); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WriteIIS7ConfigChanges"), pwzCustomActionData, WriteIIS7ConfigChangesCost); + ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action"); + } + else + { + // This must remain trace only, CA data may contain password + WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIISExec will be: %ls", pwzCustomActionData); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ConfigureIIsExec"), pwzCustomActionData, ConfigureIIsCost); + ExitOnFailure(hr, "Failed to schedule ConfigureIISExec custom action"); + + ReleaseNullStr(pwzCustomActionData); + + // Write the CaScript key to the ConfigureIIS custom action data + hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add script key to CustomActionData."); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"WriteMetabaseChanges"), pwzCustomActionData, WriteMetabaseChangesCost); + ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action"); + } + +LExit: + ReleaseStr(pwzScriptKey); + ReleaseStr(pwzBackupId); + ReleaseStr(pwzCustomActionData); + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + +/******************************************************************** +ConfigureIIsExec - custom action for installing IIs settings - table +data will be wrapped and passed in from immediate CA +ReadIIsTables + +********************************************************************/ +extern "C" UINT __stdcall ConfigureIIsExec( + __in MSIHANDLE hInstall + ) +{ + //AssertSz(FALSE, "debug ConfigureIIsExec here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + BOOL fInitializedCom = FALSE; + IMSAdminBase* piMetabase = NULL; + + SCA_WEB* pswList = NULL; + SCA_WEBDIR* pswdList = NULL; + SCA_VDIR* psvdList = NULL; + SCA_FILTER* psfList = NULL; + SCA_APPPOOL *psapList = NULL; + SCA_MIMEMAP* psmmList = NULL; + SCA_HTTP_HEADER* pshhList = NULL; + SCA_PROPERTY *pspList = NULL; + SCA_WEBSVCEXT* psWseList = NULL; + SCA_WEB_ERROR* psweList = NULL; + + LPWSTR pwzScriptKey = NULL; + LPWSTR pwzCustomActionData = NULL; + + WCA_WRAPQUERY_HANDLE hUserQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL; + WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL; + + // initialize + hr = WcaInitialize(hInstall, "ConfigureIIsExec"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + // Get the CaScript key + hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey); + ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to initialize COM"); + fInitializedCom = TRUE; + + // if IIS was uninstalled (thus no IID_IMSAdminBase) allow the + // user to still uninstall this package by clicking "Ignore" + do + { + hr = ::CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase, (void**)&piMetabase); + if (FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "failed to get IID_IMSAdminBase Object"); + er = WcaErrorMessage(msierrIISCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); + switch (er) + { + case IDABORT: + ExitFunction(); // bail with the error result from the CoCreate to kick off a rollback + case IDRETRY: + hr = S_FALSE; // hit me, baby, one more time + break; + case IDIGNORE: + __fallthrough; + default: + WcaLog(LOGMSG_STANDARD, "ignoring absent IIS"); + // We need to write the empty script to communicate to other deferred CA that there is noting to do. + hr = ScaWriteConfigurationScript(pwzScriptKey); + ExitOnFailure(hr, "failed to schedule metabase configuration"); + + ExitFunction1(hr = S_OK); // pretend everything is okay + break; + } + } + } while (S_FALSE == hr); + + // read the msi tables + hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap user query"); + + hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions"); + + hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools"); + + // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read + hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps"); + + hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders"); + + hr = ScaWebErrorRead(&psweList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors"); + + hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web dir properties query"); + + hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap ssl certificate query"); + + hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web log query"); + + hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web application query"); + + hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web application extension query"); + + hr = ScaWebsRead(piMetabase, &psmmList, &pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites"); + + hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web base query"); + + hr = ScaWebDirsRead(piMetabase, pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList); + MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs"); + + hr = ScaVirtualDirsRead(piMetabase, pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs"); + + hr = ScaFiltersRead(piMetabase, pswList, hWebBaseQuery, &psfList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters"); + + hr = ScaPropertyRead(&pspList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties"); + + // do uninstall actions (order is important!) + hr = ScaPropertyUninstall(piMetabase, pspList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties"); + + hr = ScaFiltersUninstall(piMetabase, psfList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters"); + + hr = ScaVirtualDirsUninstall(piMetabase, psvdList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories"); + + hr = ScaWebDirsUninstall(piMetabase, pswdList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories"); + + hr = ScaWebsUninstall(piMetabase, pswList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs"); + + hr = ScaAppPoolUninstall(piMetabase, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools"); + + + // do install actions (order is important!) + // ScaWebSvcExtCommit contains both uninstall and install actions. + hr = ScaWebSvcExtCommit(piMetabase, psWseList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt"); + + hr = ScaAppPoolInstall(piMetabase, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools"); + + hr = ScaWebsInstall(piMetabase, pswList, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs"); + + hr = ScaWebDirsInstall(piMetabase, pswdList, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories"); + + hr = ScaVirtualDirsInstall(piMetabase, psvdList, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories"); + + hr = ScaFiltersInstall(piMetabase, psfList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters"); + + hr = ScaPropertyInstall(piMetabase, pspList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties"); + + hr = ScaWriteConfigurationScript(pwzScriptKey); + ExitOnFailure(hr, "failed to schedule metabase configuration"); + +LExit: + ReleaseStr(pwzScriptKey); + ReleaseStr(pwzCustomActionData); + + WcaFinishUnwrapQuery(hUserQuery); + WcaFinishUnwrapQuery(hWebBaseQuery); + WcaFinishUnwrapQuery(hWebDirPropQuery); + WcaFinishUnwrapQuery(hSslCertQuery); + WcaFinishUnwrapQuery(hWebLogQuery); + WcaFinishUnwrapQuery(hWebAppQuery); + WcaFinishUnwrapQuery(hWebAppExtQuery); + + if (psWseList) + { + ScaWebSvcExtFreeList(psWseList); + } + + if (psfList) + { + ScaFiltersFreeList(psfList); + } + + if (psvdList) + { + ScaVirtualDirsFreeList(psvdList); + } + + if (pswdList) + { + ScaWebDirsFreeList(pswdList); + } + + if (pswList) + { + ScaWebsFreeList(pswList); + } + + if (psmmList) + { + ScaMimeMapCheckList(psmmList); + ScaMimeMapFreeList(psmmList); + } + + if (pshhList) + { + ScaHttpHeaderCheckList(pshhList); + ScaHttpHeaderFreeList(pshhList); + } + + if (psweList) + { + ScaWebErrorCheckList(psweList); + ScaWebErrorFreeList(psweList); + } + + ReleaseObject(piMetabase); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/******************************************************************** +ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings + +********************************************************************/ +extern "C" UINT __stdcall ConfigureIIs7Exec( + __in MSIHANDLE hInstall + ) +{ + //AssertSz(FALSE, "debug ConfigureIIs7Exec here"); + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzScriptKey = NULL; + LPWSTR pwzCustomActionData = NULL; + + SCA_WEB7* pswList = NULL; + SCA_WEBDIR7* pswdList = NULL; + SCA_VDIR7* psvdList = NULL; + SCA_FILTER* psfList = NULL; + SCA_APPPOOL *psapList = NULL; + SCA_MIMEMAP* psmmList = NULL; + SCA_HTTP_HEADER* pshhList = NULL; + SCA_PROPERTY *pspList = NULL; + SCA_WEBSVCEXT* psWseList = NULL; + SCA_WEB_ERROR* psweList = NULL; + + WCA_WRAPQUERY_HANDLE hUserQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebBaseQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebDirPropQuery = NULL; + WCA_WRAPQUERY_HANDLE hSslCertQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebLogQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebAppQuery = NULL; + WCA_WRAPQUERY_HANDLE hWebAppExtQuery = NULL; + + // initialize + hr = WcaInitialize(hInstall, "ConfigureIIs7Exec"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + // Get the CaScript key + hr = WcaReadStringFromCaData(&pwzCustomActionData, &pwzScriptKey); + ExitOnFailure(hr, "Failed to get CaScript key from custom action data"); + + // read the msi tables + hr = WcaBeginUnwrapQuery(&hUserQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap user query"); + + hr = ScaWebSvcExtRead(&psWseList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadWebSvcExt, "failed while processing WebServiceExtensions"); + + hr = ScaAppPoolRead(&psapList, hUserQuery, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed while processing WebAppPools"); + + // MimeMap, Error and HttpHeader need to be read before the virtual directory and web read + hr = ScaMimeMapRead(&psmmList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed while processing MimeMaps"); + + hr = ScaHttpHeaderRead(&pshhList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadHttpHeader, "failed while processing HttpHeaders"); + + hr = ScaWebErrorRead(&psweList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed while processing WebErrors"); + + hr = WcaBeginUnwrapQuery(&hWebDirPropQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web dir properties query"); + + hr = WcaBeginUnwrapQuery(&hSslCertQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap ssl certificate query"); + + hr = WcaBeginUnwrapQuery(&hWebLogQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web log query"); + + hr = WcaBeginUnwrapQuery(&hWebAppQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web application query"); + + hr = WcaBeginUnwrapQuery(&hWebAppExtQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web application extension query"); + + hr = ScaWebsRead7(&pswList, &pshhList, &psweList, hUserQuery, hWebDirPropQuery, hSslCertQuery, hWebLogQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadWebSite, "failed while processing WebSites"); + + hr = WcaBeginUnwrapQuery(&hWebBaseQuery, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap web base query"); + + hr = ScaWebDirsRead7(pswList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData, &pswdList); + MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed while processing WebDirs"); + + hr = ScaVirtualDirsRead7(pswList, &psvdList, &psmmList, &pshhList, &psweList, hUserQuery, hWebBaseQuery, hWebDirPropQuery, hWebAppQuery, hWebAppExtQuery, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed while processing WebVirtualDirs"); + + hr = ScaFiltersRead7(pswList, hWebBaseQuery, &psfList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadFilters, "failed while processing WebFilters"); + + hr = ScaPropertyRead(&pspList, &pwzCustomActionData); + MessageExitOnFailure(hr, msierrIISFailedReadProp, "failed while processing WebProperties"); + + // do uninstall actions (order is important!) + hr = ScaPropertyUninstall7(pspList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallProp, "failed to uninstall IIS properties"); + + hr = ScaFiltersUninstall7(psfList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallFilters, "failed to schedule uninstall of filters"); + + hr = ScaVirtualDirsUninstall7(psvdList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallVDirs, "failed to schedule uninstall of virtual directories"); + + hr = ScaWebDirsUninstall7(pswdList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebDirs, "failed to schedule uninstall of web directories"); + + hr = ScaWebsUninstall7(pswList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallWebs, "failed to schedule uninstall of webs"); + + hr = ScaAppPoolUninstall7(psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedUninstallAppPool, "failed to schedule uninstall of AppPools"); + + + // do install actions (order is important!) + // ScaWebSvcExtCommit contains both uninstall and install actions. + hr = ScaWebSvcExtCommit7(psWseList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebSvcExt, "failed to schedule install/uninstall of WebSvcExt"); + + hr = ScaAppPoolInstall7(psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallAppPool, "failed to schedule install of AppPools"); + + hr = ScaWebsInstall7(pswList, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebs, "failed to schedule install of webs"); + + hr = ScaWebDirsInstall7(pswdList, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallWebDirs, "failed to schedule install of web directories"); + + hr = ScaVirtualDirsInstall7(psvdList, psapList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallVDirs, "failed to schedule install of virtual directories"); + + hr = ScaFiltersInstall7(psfList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallFilters, "failed to schedule install of filters"); + + hr = ScaPropertyInstall7(pspList); + MessageExitOnFailure(hr, msierrIISFailedSchedInstallProp, "failed to schedule install of properties"); + + hr = ScaWriteConfigurationScript(pwzScriptKey); + ExitOnFailure(hr, "failed to schedule metabase configuration"); + +LExit: + ReleaseNullStr(pwzScriptKey); + ReleaseNullStr(pwzCustomActionData); + + WcaFinishUnwrapQuery(hUserQuery); + WcaFinishUnwrapQuery(hWebBaseQuery); + WcaFinishUnwrapQuery(hWebDirPropQuery); + WcaFinishUnwrapQuery(hSslCertQuery); + WcaFinishUnwrapQuery(hWebLogQuery); + WcaFinishUnwrapQuery(hWebAppQuery); + WcaFinishUnwrapQuery(hWebAppExtQuery); + + if (psWseList) + { + ScaWebSvcExtFreeList(psWseList); + } + + if (psfList) + { + ScaFiltersFreeList(psfList); + } + + if (psvdList) + { + ScaVirtualDirsFreeList7(psvdList); + } + + if (pswdList) + { + ScaWebDirsFreeList7(pswdList); + } + + if (pswList) + { + ScaWebsFreeList7(pswList); + } + + if (psmmList) + { + ScaMimeMapFreeList(psmmList); + } + + if (pshhList) + { + ScaHttpHeaderCheckList(pshhList); + ScaHttpHeaderFreeList(pshhList); + } + + if (psweList) + { + ScaWebErrorCheckList(psweList); + ScaWebErrorFreeList(psweList); + } + + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} diff --git a/src/ext/Iis/ca/scassl.cpp b/src/ext/Iis/ca/scassl.cpp new file mode 100644 index 00000000..4a06b77e --- /dev/null +++ b/src/ext/Iis/ca/scassl.cpp @@ -0,0 +1,115 @@ +// 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" + +enum eSslCertificateQuery { scqStoreName = 1, scqHash, scqWeb }; + +static HRESULT AddSslCertificateToList( + __in SCA_WEB_SSL_CERTIFICATE** ppswscList + ); + + +HRESULT ScaSslCertificateRead( + __in LPCWSTR wzWebId, + __in WCA_WRAPQUERY_HANDLE hSslCertQuery, + __inout SCA_WEB_SSL_CERTIFICATE** ppswscList + ) +{ + HRESULT hr = S_OK; + + MSIHANDLE hRec; + SCA_WEB_SSL_CERTIFICATE* pswsc = NULL; + LPWSTR pwzData = NULL; + + WcaFetchWrappedReset(hSslCertQuery); + + // Get the certificate information. + while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hSslCertQuery, scqWeb, wzWebId, &hRec))) + { + hr = AddSslCertificateToList(ppswscList); + ExitOnFailure(hr, "failed to add ssl certificate to list"); + + pswsc = *ppswscList; + + hr = WcaGetRecordString(hRec, scqStoreName, &pwzData); + ExitOnFailure(hr, "Failed to get web ssl certificate store name."); + + hr = ::StringCchCopyW(pswsc->wzStoreName, countof(pswsc->wzStoreName), pwzData); + ExitOnFailure(hr, "Failed to copy web ssl certificate store name."); + + hr = WcaGetRecordString(hRec, scqHash, &pwzData); + ExitOnFailure(hr, "Failed to get hash for web ssl certificate."); + + hr = StrHexDecode(pwzData, pswsc->rgbSHA1Hash, countof(pswsc->rgbSHA1Hash)); + ExitOnFailure(hr, "Failed to decode certificate hash for web: %ls, data: %ls", wzWebId, pwzData); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failed to read IIsWebSiteCertificates table."); + +LExit: + ReleaseStr(pwzData); + return hr; +} + + +HRESULT ScaSslCertificateWriteMetabase( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzWebBase, + __in SCA_WEB_SSL_CERTIFICATE* pswscList + ) +{ + HRESULT hr = S_OK; + BLOB blob; + + for (SCA_WEB_SSL_CERTIFICATE* pswsc = pswscList; pswsc; pswsc = pswsc->pNext) + { + // Write: /W3SVC/1:SslCertStoreName = "MY", "CA", "Root", etc. + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_SSL_CERT_STORE_NAME, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, static_cast(pswsc->wzStoreName)); + ExitOnFailure(hr, "Failed to write SslCertStoreName"); + + // Write: /W3SVC/1:SslCertHash = + blob.pBlobData = pswsc->rgbSHA1Hash; + blob.cbSize = countof(pswsc->rgbSHA1Hash); + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_SSL_CERT_HASH, METADATA_INHERIT, IIS_MD_UT_SERVER, BINARY_METADATA, static_cast(&blob)); + ExitOnFailure(hr, "Failed to write SslCertHash"); + } + +LExit: + return hr; +} + + +void ScaSslCertificateFreeList( + __in SCA_WEB_SSL_CERTIFICATE* pswscList + ) +{ + SCA_WEB_SSL_CERTIFICATE* pswscDelete = pswscList; + while (pswscList) + { + pswscDelete = pswscList; + pswscList = pswscList->pNext; + + MemFree(pswscDelete); + } +} + + +static HRESULT AddSslCertificateToList( + __in SCA_WEB_SSL_CERTIFICATE** ppswscList + ) +{ + HRESULT hr = S_OK; + + SCA_WEB_SSL_CERTIFICATE* pswsc = static_cast(MemAlloc(sizeof(SCA_WEB_SSL_CERTIFICATE), TRUE)); + ExitOnNull(pswsc, hr, E_OUTOFMEMORY, "failed to allocate memory for new SSL certificate list element"); + + pswsc->pNext = *ppswscList; + *ppswscList = pswsc; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scassl.h b/src/ext/Iis/ca/scassl.h new file mode 100644 index 00000000..df7c473d --- /dev/null +++ b/src/ext/Iis/ca/scassl.h @@ -0,0 +1,36 @@ +#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 MD_SSL_CERT_HASH ( IIS_MD_SSL_BASE+6 ) +#define MD_SSL_CERT_STORE_NAME ( IIS_MD_SSL_BASE+11 ) +//#define WIDE(x) WIDE2(x) +//#define WIDE2(x) L ## x + + +// structs +struct SCA_WEB_SSL_CERTIFICATE +{ + WCHAR wzStoreName[65]; + BYTE rgbSHA1Hash[CB_CERTIFICATE_HASH]; + + SCA_WEB_SSL_CERTIFICATE* pNext; +}; + + +// prototypes +HRESULT ScaSslCertificateRead( + __in LPCWSTR wzWebId, + __in WCA_WRAPQUERY_HANDLE hSslCertQuery, + __inout SCA_WEB_SSL_CERTIFICATE** ppswscList + ); + +HRESULT ScaSslCertificateWriteMetabase( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzWebBase, + __in SCA_WEB_SSL_CERTIFICATE* pswscList + ); + +void ScaSslCertificateFreeList( + __in SCA_WEB_SSL_CERTIFICATE* pswscList + ); diff --git a/src/ext/Iis/ca/scassl7.cpp b/src/ext/Iis/ca/scassl7.cpp new file mode 100644 index 00000000..47c16a9d --- /dev/null +++ b/src/ext/Iis/ca/scassl7.cpp @@ -0,0 +1,34 @@ +// 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" + +HRESULT ScaSslCertificateWrite7( + __in_z LPCWSTR wzWebBase, + __in SCA_WEB_SSL_CERTIFICATE* pswscList + ) +{ + HRESULT hr = S_OK; + WCHAR wzEncodedCertificateHash[CB_CERTIFICATE_HASH * 2 + 1] = { 0 }; + + for (SCA_WEB_SSL_CERTIFICATE* pswsc = pswscList; pswsc; pswsc = pswsc->pNext) + { + hr = ScaWriteConfigID(IIS_SSL_BINDING); + ExitOnFailure(hr, "Failed write SSL binding ID"); + hr = ScaWriteConfigID(IIS_CREATE); // Need to determine site action + ExitOnFailure(hr, "Failed write binding action"); + + hr = ScaWriteConfigString(wzWebBase); //site name key + ExitOnFailure(hr, "Failed to write SSL website"); + hr = ScaWriteConfigString(pswsc->wzStoreName); //ssl store name + ExitOnFailure(hr, "Failed to write SSL store name"); + + hr = StrHexEncode(pswsc->rgbSHA1Hash, countof(pswsc->rgbSHA1Hash), wzEncodedCertificateHash, countof(wzEncodedCertificateHash)); + ExitOnFailure(hr, "Failed to encode SSL hash"); + + hr = ScaWriteConfigString(wzEncodedCertificateHash); //ssl hash + ExitOnFailure(hr, "Failed to write SSL hash"); + } +LExit: + + return hr; +} diff --git a/src/ext/Iis/ca/scassl7.h b/src/ext/Iis/ca/scassl7.h new file mode 100644 index 00000000..1a4b09af --- /dev/null +++ b/src/ext/Iis/ca/scassl7.h @@ -0,0 +1,8 @@ +#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 ScaSslCertificateWrite7( + __in_z LPCWSTR wzWebBase, + __in SCA_WEB_SSL_CERTIFICATE* pswscList + ); diff --git a/src/ext/Iis/ca/scauser.cpp b/src/ext/Iis/ca/scauser.cpp new file mode 100644 index 00000000..0b99edff --- /dev/null +++ b/src/ext/Iis/ca/scauser.cpp @@ -0,0 +1,91 @@ +// 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" + +LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `User` WHERE `User`=?"; +enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqPassword }; + +LPCWSTR vcsGroupQuery = L"SELECT `Group`, `Component_`, `Name`, `Domain` FROM `Group` WHERE `Group`=?"; +enum eGroupQuery { vgqGroup = 1, vgqComponent, vgqName, vgqDomain }; + +LPCWSTR vcsUserGroupQuery = L"SELECT `User_`, `Group_` FROM `UserGroup` WHERE `User_`=?"; +enum eUserGroupQuery { vugqUser = 1, vugqGroup }; + +LPCWSTR vActionableQuery = L"SELECT `User`,`Component_`,`Name`,`Domain`,`Password`,`Attributes` FROM `User` WHERE `Component_` IS NOT NULL"; +enum eActionableQuery { vaqUser = 1, vaqComponent, vaqName, vaqDomain, vaqPassword, vaqAttributes }; + +HRESULT __stdcall ScaGetUserDeferred( + __in LPCWSTR wzUser, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __out SCA_USER* pscau + ) +{ + if (!wzUser || !pscau) + { + return E_INVALIDARG; + } + + HRESULT hr = S_OK; + MSIHANDLE hRec, hRecTest; + + LPWSTR pwzData = NULL; + + // clear struct and bail right away if no user key was passed to search for + ::ZeroMemory(pscau, sizeof(*pscau)); + if (!*wzUser) + { + ExitFunction1(hr = S_OK); + } + + // Reset back to the first record + WcaFetchWrappedReset(hUserQuery); + + hr = WcaFetchWrappedRecordWhereString(hUserQuery, vuqUser, wzUser, &hRec); + if (S_OK == hr) + { + hr = WcaFetchWrappedRecordWhereString(hUserQuery, vuqUser, wzUser, &hRecTest); + if (S_OK == hr) + { + AssertSz(FALSE, "Found multiple matching User rows"); + } + + hr = WcaGetRecordString(hRec, vuqUser, &pwzData); + ExitOnFailure(hr, "Failed to get User.User"); + hr = ::StringCchCopyW(pscau->wzKey, countof(pscau->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to user object (in deferred CA)"); + + hr = WcaGetRecordString(hRec, vuqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get User.Component_"); + hr = ::StringCchCopyW(pscau->wzComponent, countof(pscau->wzComponent), pwzData); + ExitOnFailure(hr, "Failed to copy component string to user object (in deferred CA)"); + + hr = WcaGetRecordString(hRec, vuqName, &pwzData); + ExitOnFailure(hr, "Failed to get User.Name"); + hr = ::StringCchCopyW(pscau->wzName, countof(pscau->wzName), pwzData); + ExitOnFailure(hr, "Failed to copy name string to user object (in deferred CA)"); + + hr = WcaGetRecordString(hRec, vuqDomain, &pwzData); + ExitOnFailure(hr, "Failed to get User.Domain"); + hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); + ExitOnFailure(hr, "Failed to copy domain string to user object (in deferred CA)"); + + hr = WcaGetRecordString(hRec, vuqPassword, &pwzData); + ExitOnFailure(hr, "Failed to get User.Password"); + hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); + ExitOnFailure(hr, "Failed to copy password string to user object (in deferred CA)"); + } + else if (E_NOMOREITEMS == hr) + { + WcaLog(LOGMSG_STANDARD, "Error: Cannot locate User.User='%ls'", wzUser); + hr = E_FAIL; + } + else + { + ExitOnFailure(hr, "Error fetching single User row"); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} diff --git a/src/ext/Iis/ca/scauser.h b/src/ext/Iis/ca/scauser.h new file mode 100644 index 00000000..b2b94650 --- /dev/null +++ b/src/ext/Iis/ca/scauser.h @@ -0,0 +1,39 @@ +#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. + +// structs +struct SCA_GROUP +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + + WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; + WCHAR wzName[MAX_DARWIN_COLUMN + 1]; + + SCA_GROUP *psgNext; +}; + +struct SCA_USER +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; + WCHAR wzName[MAX_DARWIN_COLUMN + 1]; + WCHAR wzPassword[MAX_DARWIN_COLUMN + 1]; + INT iAttributes; + + SCA_GROUP *psgGroups; + + SCA_USER *psuNext; +}; + + +// prototypes +HRESULT __stdcall ScaGetUserDeferred( + __in LPCWSTR wzUser, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __out SCA_USER* pscau + ); diff --git a/src/ext/Iis/ca/scavdir.cpp b/src/ext/Iis/ca/scavdir.cpp new file mode 100644 index 00000000..d388ce97 --- /dev/null +++ b/src/ext/Iis/ca/scavdir.cpp @@ -0,0 +1,331 @@ +// 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" + +// prototypes +static HRESULT AddVirtualDirToList( + __in SCA_VDIR** psvdList + ); + + +HRESULT __stdcall ScaVirtualDirsRead( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in SCA_VDIR** ppsvdList, + __in SCA_MIMEMAP** ppsmmList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(piMetabase && ppsvdList); + + HRESULT hr = S_OK; + MSIHANDLE hRec; + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + + SCA_VDIR* pvdir = NULL; + LPWSTR pwzData = NULL; + + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the vdirs + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + // Get the Component first. If there is a Component and it is not being modified during + // this transaction, skip processing this whole record. + hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); + ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); + + hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); + + hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&isAction); + ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); + + if (!WcaIsInstalling(isInstalled, isAction) && + !WcaIsReInstalling(isInstalled, isAction) && + !WcaIsUninstalling(isInstalled, isAction)) + { + continue; // skip this record. + } + + hr = AddVirtualDirToList(ppsvdList); + ExitOnFailure(hr, "failed to add virtual dir to list"); + + pvdir = *ppsvdList; + + hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); + ExitOnFailure(hr, "failed to copy component name: %ls", pwzData); + + pvdir->isInstalled = isInstalled; + pvdir->isAction = isAction; + + // get the web key + hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web for VirtualDir"); + + hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pvdir->wzWebBase, countof(pvdir->wzWebBase), hWebBaseQuery); + if (WcaIsUninstalling(isInstalled, isAction)) + { + // If we're uninstalling, ignore any failure to find the existing web + hr = S_OK; + } + ExitOnFailure(hr, "Failed to get base of web: %ls for VirtualDir", pwzData); + + hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); + ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); + + if (0 != lstrlenW(pvdir->wzWebBase)) + { + hr = ::StringCchPrintfW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), L"%s/Root/%s", pvdir->wzWebBase, pwzData); + ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); + } + + // get the vdir's directory + hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); + ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); + + // get the web's directory + if (INSTALLSTATE_SOURCE == pvdir->isAction) + { + hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); + } + else + { + hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); + } + ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); + + // remove trailing backslash(es) + while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') + { + pwzData[lstrlenW(pwzData)-1] = 0; + } + hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); + ExitOnFailure(hr, "Failed to copy directory string to vdir object"); + + // get the security information for this web + hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); + if (*pwzData) + { + hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); + ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); + + pvdir->fHasProperties = TRUE; + } + + // get the application information for this web + hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); + ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); + if (*pwzData) + { + hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); + ExitOnFailure(hr, "Failed to get application for VirtualDir"); + + pvdir->fHasApplication = TRUE; + } + + hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); + ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); + + if (*pwzData && *ppsmmList) + { + hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); + ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); + } + + if (*pwzData && *ppshhList) + { + hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); + ExitOnFailure(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); + } + + if (*pwzData && *ppsweList) + { + hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); + ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); + } + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing VirtualDirs"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + return hr; +} + + +HRESULT ScaVirtualDirsInstall( + __in IMSAdminBase* piMetabase, + __in SCA_VDIR* psvdList, + __in SCA_APPPOOL * psapList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + SCA_VDIR* psvd = psvdList; + int i; + + while (psvd) + { + // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created + if (WcaIsReInstalling(psvd->isInstalled, psvd->isAction)) + { + if (psvd->fHasApplication) + { + hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); + ExitOnFailure(hr, "Failed to remove application for WebVDir as part of a reinstall"); + } + } + + if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) + { + hr = ScaCreateMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); + ExitOnFailure(hr, "Failed to create key for VirtualDir"); + hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); + ExitOnFailure(hr, "Failed to write key type for for VirtualDir"); + i = 0x4000003e; // 1073741886; // default directory browsing rights + hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); + ExitOnFailure(hr, "Failed to set directory browsing for VirtualDir"); + + hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psvd->wzDirectory); + ExitOnFailure(hr, "Failed to write Directory for VirtualDir"); + + if (psvd->fHasProperties) + { + ScaWriteWebDirProperties(piMetabase, psvd->wzVDirRoot, &psvd->swp); + ExitOnFailure(hr, "Failed to write directory properties for VirtualDir"); + } + + if (psvd->fHasApplication) + { + hr = ScaWriteWebApplication(piMetabase, psvd->wzVDirRoot, &psvd->swapp, psapList); + ExitOnFailure(hr, "Failed to write application for VirtualDir"); + } + + if (psvd->psmm) + { + hr = ScaWriteMimeMap(piMetabase, psvd->wzVDirRoot, psvd->psmm); + ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); + } + + if (psvd->pshh) + { + hr = ScaWriteHttpHeader(piMetabase, psvd->wzVDirRoot, psvd->pshh); + ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir"); + } + + if (psvd->pswe) + { + hr = ScaWriteWebError(piMetabase, weptVDir, psvd->wzVDirRoot, psvd->pswe); + ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); + } + } + + psvd = psvd->psvdNext; + } + +LExit: + return hr; +} + + +HRESULT ScaVirtualDirsUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_VDIR* psvdList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + SCA_VDIR* psvd = psvdList; + + while (psvd) + { + if (WcaIsUninstalling(psvd->isInstalled, psvd->isAction)) + { + // delete the application for this virtual directory + if (psvd->fHasApplication) + { + hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); + ExitOnFailure(hr, "Failed to remove application for WebVDir"); + } + + if (0 != lstrlenW(psvd->wzVDirRoot)) + { + hr = ScaDeleteMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); + ExitOnFailure(hr, "Failed to remove VirtualDir '%ls' from metabase", psvd->wzKey); + } + } + + psvd = psvd->psvdNext; + } + +LExit: + return hr; +} + + +void ScaVirtualDirsFreeList( + __in SCA_VDIR* psvdList + ) +{ + SCA_VDIR* psvdDelete = psvdList; + while (psvdList) + { + psvdDelete = psvdList; + psvdList = psvdList->psvdNext; + + if (psvdDelete->psmm) + { + ScaMimeMapFreeList(psvdDelete->psmm); + } + + if (psvdDelete->pswe) + { + ScaWebErrorFreeList(psvdDelete->pswe); + } + + MemFree(psvdDelete); + } +} + + +static HRESULT AddVirtualDirToList( + __in SCA_VDIR** ppsvdList + ) +{ + HRESULT hr = S_OK; + SCA_VDIR* psvd = static_cast(MemAlloc(sizeof(SCA_VDIR), TRUE)); + ExitOnNull(psvd, hr, E_OUTOFMEMORY, "failed to allocate memory for new vdir list element"); + + psvd->psvdNext= *ppsvdList; + *ppsvdList = psvd; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scavdir.h b/src/ext/Iis/ca/scavdir.h new file mode 100644 index 00000000..c7e9661b --- /dev/null +++ b/src/ext/Iis/ca/scavdir.h @@ -0,0 +1,71 @@ +#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 "scawebprop.h" +#include "scawebapp.h" +#include "scamimemap.h" +#include "scaapppool.h" + +enum eVDirQuery { vdqWeb = 1, vdqVDir, vdqComponent , vdqAlias, vdqDirectory, vdqProperties, vdqApplication, vdqInstalled, vdqAction, vdqSourcePath, vdqTargetPath }; + +struct SCA_VDIR +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + // metabase information + WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; + WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; + WCHAR wzVDirRoot[METADATA_MAX_NAME_LEN + 1]; + + // iis configuation information + WCHAR wzDirectory[MAX_PATH]; + + BOOL fHasProperties; + SCA_WEB_PROPERTIES swp; + + BOOL fHasApplication; + SCA_WEB_APPLICATION swapp; + + SCA_MIMEMAP* psmm; // mime mappings + SCA_HTTP_HEADER* pshh; // custom web errors + SCA_WEB_ERROR* pswe; // custom web errors + + SCA_VDIR* psvdNext; +}; + + +// prototypes +HRESULT __stdcall ScaVirtualDirsRead( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in SCA_VDIR** ppsvdList, + __in SCA_MIMEMAP** ppsmmList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ); + +HRESULT ScaVirtualDirsInstall( + __in IMSAdminBase* piMetabase, + __in SCA_VDIR* psvdList, + __in SCA_APPPOOL * psapList + ); + +HRESULT ScaVirtualDirsUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_VDIR* psvdList + ); + +void ScaVirtualDirsFreeList( + __in SCA_VDIR* psvdList + ); diff --git a/src/ext/Iis/ca/scavdir7.cpp b/src/ext/Iis/ca/scavdir7.cpp new file mode 100644 index 00000000..3f675357 --- /dev/null +++ b/src/ext/Iis/ca/scavdir7.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" + +// prototypes +static HRESULT AddVirtualDirToList7( + __in SCA_VDIR7** psvdList + ); + + +HRESULT __stdcall ScaVirtualDirsRead7( + __in SCA_WEB7* pswList, + __in SCA_VDIR7** ppsvdList, + __in SCA_MIMEMAP** ppsmmList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(ppsvdList); + + HRESULT hr = S_OK; + MSIHANDLE hRec; + + SCA_VDIR7* pvdir = NULL; + LPWSTR pwzData = NULL; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaVirtualDirsRead() because IIsWebVirtualDir table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the vdirs + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + // Add this record's information into the list of things to process. + hr = AddVirtualDirToList7(ppsvdList); + ExitOnFailure(hr, "failed to add vdir to vdir list"); + + pvdir = *ppsvdList; + + // get the darwin information + hr = WcaGetRecordString(hRec, vdqComponent, &pwzData); + ExitOnFailure(hr, "failed to get IIsWebVirtualDir.Component"); + + hr = WcaGetRecordInteger(hRec, vdqInstalled, (int *)&pvdir->isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for virtual dir"); + + hr = WcaGetRecordInteger(hRec, vdqAction, (int *)&pvdir->isAction); + ExitOnFailure(hr, "Failed to get Component action state for virtual dir"); + + // get vdir properties + hr = ::StringCchCopyW(pvdir->wzComponent, countof(pvdir->wzComponent), pwzData); + ExitOnFailure(hr, "failed to copy vdir component name: %ls", pwzData); + + hr = WcaGetRecordString(hRec, vdqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web for VirtualDir"); + + hr = ScaWebsGetBase7(pswList, pwzData, pvdir->wzWebName , countof(pvdir->wzWebName)); + if (S_FALSE == hr) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + ExitOnFailure(hr, "Failed to get Web Base for VirtualDir"); + } + if (WcaIsUninstalling(pvdir->isInstalled, pvdir->isAction)) + { + // If we're uninstalling, ignore any failure to find the existing web + hr = S_OK; + } + + hr = WcaGetRecordString(hRec, vdqAlias, &pwzData); + ExitOnFailure(hr, "Failed to get Alias for VirtualDir"); + + hr = ::StringCchCopyW(pvdir->wzVDirRoot, countof(pvdir->wzVDirRoot), pwzData); + ExitOnFailure(hr, "Failed to set VDirRoot for VirtualDir"); + + // get the vdir's directory + hr = WcaGetRecordString(hRec, vdqDirectory, &pwzData); + ExitOnFailure(hr, "Failed to get Directory for VirtualDir"); + + // get the web's directory + if (INSTALLSTATE_SOURCE == pvdir->isAction) + { + hr = WcaGetRecordString(hRec, vdqSourcePath, &pwzData); + } + else + { + hr = WcaGetRecordString(hRec, vdqTargetPath, &pwzData); + } + ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); + + // remove trailing backslash(es) + while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') + { + pwzData[lstrlenW(pwzData)-1] = 0; + } + hr = ::StringCchCopyW(pvdir->wzDirectory, countof(pvdir->wzDirectory), pwzData); + ExitOnFailure(hr, "Failed to copy directory string to vdir object"); + + // get the security information for this web + hr = WcaGetRecordString(hRec, vdqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get web directory identifier for VirtualDir"); + if (*pwzData) + { + hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pvdir->swp); + ExitOnFailure(hr, "Failed to get web directory for VirtualDir"); + + pvdir->fHasProperties = TRUE; + } + + // get the application information for this web + hr = WcaGetRecordString(hRec, vdqApplication, &pwzData); + ExitOnFailure(hr, "Failed to get application identifier for VirtualDir"); + if (*pwzData) + { + hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pvdir->swapp); + ExitOnFailure(hr, "Failed to get application for VirtualDir"); + + pvdir->fHasApplication = TRUE; + } + + hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); + ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); + + if (*pwzData && *ppsmmList) + { + hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); + ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); + } + + if (*pwzData && *ppshhList) + { + hr = ScaGetHttpHeader(hhptVDir, pwzData, ppshhList, &pvdir->pshh); + ExitOnFailure(hr, "Failed to get custom HTTP headers for VirtualDir: %ls", pwzData); + } + + if (*pwzData && *ppsweList) + { + hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); + ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir: %ls", pwzData); + } + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing VirtualDirs"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaVirtualDirsInstall7( + __in SCA_VDIR7* psvdList, + __in SCA_APPPOOL * psapList + ) +{ + HRESULT hr = S_OK; + SCA_VDIR7* psvd = psvdList; + LPWSTR wzPath = NULL; + WCHAR wzAppPoolName[MAX_PATH]; + while (psvd) + { + if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) + { + // First write all applications, this is necessary since vdirs must be nested under the applications. + if (psvd->fHasApplication) + { + //create the application for this vdir application + hr = ScaWriteConfigID(IIS_APPLICATION); + ExitOnFailure(hr, "Failed to write app ID"); + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed to write app action"); +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaWriteConfigString(psvd->wzWebName); //site name key + ExitOnFailure(hr, "Failed to write app web key"); + hr = StrAllocFormatted(&wzPath, L"/%s", psvd->wzVDirRoot); + ExitOnFailure(hr, "Failed to create app path"); + hr = ScaWriteConfigString(wzPath); // App Path + ExitOnFailure(hr, "Failed to write app path root "); + + if (!*psvd->swapp.wzAppPool) + { + //This Application goes in default appPool + hr = ScaWriteConfigString(L""); // App Pool + } + else + { + //get apppool from WebApplication +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaFindAppPool7(psvd->swapp.wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); + ExitOnFailure(hr, "Failed to read app pool from application"); + hr = ScaWriteConfigString(wzAppPoolName); // App Pool + ExitOnFailure(hr, "Failed to write appPool for vdir"); + + } + } + } + + psvd = psvd->psvdNext; + } + + // Reset our linked list and write all the VDirs + psvd = psvdList; + while (psvd) + { + if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) + { + //create the Vdir + hr = ScaWriteConfigID(IIS_VDIR); + ExitOnFailure(hr, "Failed write VirDir ID") + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed write VirDir action") +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaWriteConfigString(psvd->wzWebName); //site name key + ExitOnFailure(hr, "Failed write VirDir web name"); + hr = StrAllocFormatted(&wzPath, L"/%s", psvd->wzVDirRoot); + ExitOnFailure(hr, "Failed to create vdir path"); + hr = ScaWriteConfigString(wzPath); //vdir path + ExitOnFailure(hr, "Failed write VirDir path") +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaWriteConfigString(psvd->wzDirectory); //physical dir + ExitOnFailure(hr, "Failed write VirDir dir"); + + if (psvd->fHasProperties) + { + ScaWriteWebDirProperties7(psvd->wzWebName, psvd->wzVDirRoot, &psvd->swp); + ExitOnFailure(hr, "Failed to write directory properties for VirtualDir"); + } + + if (psvd->fHasApplication) + { + hr = ScaWriteWebApplication7(psvd->wzWebName, psvd->wzVDirRoot, &psvd->swapp, psapList); + ExitOnFailure(hr, "Failed to write application for VirtualDir"); + } + + if (psvd->psmm) + { + hr = ScaWriteMimeMap7(psvd->wzWebName, psvd->wzVDirRoot, psvd->psmm); + ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); + } + + if (psvd->pshh) + { + hr = ScaWriteHttpHeader7(psvd->wzWebName, psvd->wzVDirRoot, psvd->pshh); + ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir"); + } + + if (psvd->pswe) + { + hr = ScaWriteWebError7(psvd->wzWebName, psvd->wzVDirRoot, psvd->pswe); + ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); + } + } + + psvd = psvd->psvdNext; + } + +LExit: + ReleaseStr(wzPath); + return hr; +} + + +HRESULT ScaVirtualDirsUninstall7( + __in SCA_VDIR7* psvdList + ) +{ + + HRESULT hr = S_OK; + SCA_VDIR7* psvd = psvdList; + LPWSTR wzPath = NULL; + + while (psvd) + { + if (WcaIsUninstalling(psvd->isInstalled, psvd->isAction)) + { + //init path + hr = StrAllocFormatted(&wzPath, L"/%s", psvd->wzVDirRoot); + ExitOnFailure(hr, "Failed to create vdir path"); + + if (psvd->fHasApplication) + { + //delete Application + hr = ScaWriteConfigID(IIS_APPLICATION); + ExitOnFailure(hr, "Failed to write app ID "); + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "Failed to write delete app ID "); +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaWriteConfigString(psvd->wzWebName); //site name key + ExitOnFailure(hr, "Failed to write App site Name"); +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaWriteConfigString(wzPath); // App Path + ExitOnFailure(hr, "Failed to write app path root "); + hr = ScaWriteConfigString(L"NOP"); // App pool + ExitOnFailure(hr, "Failed to write app path app pool "); + } + else + { + //delete VDir + hr = ScaWriteConfigID(IIS_VDIR); + ExitOnFailure(hr, "Failed to write vDir ID "); + hr = ScaWriteConfigID(IIS_DELETE); +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ScaWriteConfigString(psvd->wzWebName); //site name key + ExitOnFailure(hr, "Failed to write App site Name"); + hr = ScaWriteConfigString(wzPath); // Vdir Path + ExitOnFailure(hr, "Failed to write app vdir "); + hr = ScaWriteConfigString(L"NOP"); // Phy Path + ExitOnFailure(hr, "Failed to write vdir path"); + } + + ExitOnFailure(hr, "Failed to remove VirtualDir '%ls' from config", psvd->wzKey); + } + + psvd = psvd->psvdNext; + } + +LExit: + ReleaseStr(wzPath); + return hr; +} + + +void ScaVirtualDirsFreeList7( + __in SCA_VDIR7* psvdList + ) +{ + SCA_VDIR7* psvdDelete = psvdList; + while (psvdList) + { + psvdDelete = psvdList; + psvdList = psvdList->psvdNext; + + if (psvdDelete->psmm) + { + ScaMimeMapFreeList(psvdDelete->psmm); + } + + if (psvdDelete->pswe) + { + ScaWebErrorFreeList(psvdDelete->pswe); + } + + MemFree(psvdDelete); + } +} + + +static HRESULT AddVirtualDirToList7( + __in SCA_VDIR7** ppsvdList + ) +{ + HRESULT hr = S_OK; + + SCA_VDIR7* psvd = static_cast(MemAlloc(sizeof(SCA_VDIR7), TRUE)); + ExitOnNull(psvd, hr, E_OUTOFMEMORY, "failed to allocate memory for new vdir list element"); + + psvd->psvdNext= *ppsvdList; + *ppsvdList = psvd; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scavdir7.h b/src/ext/Iis/ca/scavdir7.h new file mode 100644 index 00000000..dba25431 --- /dev/null +++ b/src/ext/Iis/ca/scavdir7.h @@ -0,0 +1,66 @@ +#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 "scawebprop.h" +#include "scawebapp.h" +#include "scamimemap.h" +#include "scaapppool.h" + +struct SCA_VDIR7 +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + // metabase information + WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; + WCHAR wzWebName[METADATA_MAX_NAME_LEN + 1]; + WCHAR wzVDirRoot[METADATA_MAX_NAME_LEN + 1]; + + // iis configuation information + WCHAR wzDirectory[MAX_PATH]; + + BOOL fHasProperties; + SCA_WEB_PROPERTIES swp; + + BOOL fHasApplication; + SCA_WEB_APPLICATION swapp; + + SCA_MIMEMAP* psmm; // mime mappings + SCA_HTTP_HEADER* pshh; // custom web errors + SCA_WEB_ERROR* pswe; // custom web errors + + SCA_VDIR7* psvdNext; +}; + + +// prototypes +HRESULT __stdcall ScaVirtualDirsRead7( + __in SCA_WEB7* pswList, + __in SCA_VDIR7** ppsvdList, + __in SCA_MIMEMAP** ppsmmList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ); + +HRESULT ScaVirtualDirsInstall7( + __in SCA_VDIR7* psvdList, + __in SCA_APPPOOL * psapList + ); + +HRESULT ScaVirtualDirsUninstall7( + __in SCA_VDIR7* psvdList + ); + +void ScaVirtualDirsFreeList7( + __in SCA_VDIR7* psvdList + ); diff --git a/src/ext/Iis/ca/scaweb.cpp b/src/ext/Iis/ca/scaweb.cpp new file mode 100644 index 00000000..0452fb0b --- /dev/null +++ b/src/ext/Iis/ca/scaweb.cpp @@ -0,0 +1,1187 @@ +// 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" + +//Adding this because delivery doesn't have the updated specstrings.h that windows build does +#ifndef __in_xcount +#define __in_xcount(size) +#endif + +// sql queries + +enum eWebBaseQuery { wbqWeb = 1, wbqId, wbqIP, wbqPort, wbqHeader, wbqSecure, wbqDescription }; + + +// prototypes for private helper functions +static SCA_WEB* NewWeb(); +static void FreeWeb(SCA_WEB *pswDelete); +static SCA_WEB* AddWebToList( + __in SCA_WEB* pswList, + __in SCA_WEB* psw + ); +static HRESULT ScaWebFindBase( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in_z LPCWSTR wzWeb, + __in int iSiteId, + __in_z LPCWSTR wzIP, + __in int iPort, + __in_z LPCWSTR wzHeader, + __in BOOL fSecure, + __in_z LPCWSTR wzDescription, + __out_ecount(cchWebBase) LPWSTR wzWebBase, + __in DWORD cchWebBase + ); +static HRESULT ScaWebFindFreeBase( + __in IMSAdminBase* piMetabase, + __in_xcount(unknown) SCA_WEB* pswList, + __in int iSiteId, + __in_z LPCWSTR wzDescription, + __out_ecount(cchWebBase) LPWSTR wzWebBase, + __in DWORD cchWebBase + ); +static HRESULT ScaWebWrite( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* psw, + __in SCA_APPPOOL * psapList + ); +static HRESULT ScaWebRemove( + __in IMSAdminBase* piMetabase, + __in const SCA_WEB* psw); +static DWORD SiteIdFromDescription( + __in_z LPCWSTR wzDescription + ); +static void Sort( + __in_ecount(cArray) DWORD dwArray[], + __in int cArray + ); + + +HRESULT ScaWebsRead( + __in IMSAdminBase* piMetabase, + __in SCA_MIMEMAP** ppsmmList, + __in SCA_WEB** ppswList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hSslCertQuery, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(piMetabase && ppswList); + + HRESULT hr = S_OK; + + MSIHANDLE hRec; + MSIHANDLE hRecAddresses; + + SCA_WEB* psw = NULL; + LPWSTR pwzData = NULL; + int iSiteId; + + DWORD dwLen = 0; + WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL; + WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL; + + hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); + + hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); + + if (0 == WcaGetQueryRecords(hQueryWebSite)) + { + WcaLog(LOGMSG_VERBOSE, "Required tables not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the webs + while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec))) + { + psw = NewWeb(); + ExitOnNull(psw, hr, E_OUTOFMEMORY, "Failed to allocate memory for web object in memory"); + + // get the darwin information + hr = WcaGetRecordString(hRec, wqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web"); + hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to web object"); + + if (*pwzData && *ppsmmList) + { + hr = ScaGetMimeMap(mmptWeb, pwzData, ppsmmList, &psw->psmm); + ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); + } + + // get component install state + hr = WcaGetRecordString(hRec, wqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get Component for Web"); + hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); + ExitOnFailure(hr, "Failed to copy component string to web object"); + if (*(psw->wzComponent)) + { + psw->fHasComponent = TRUE; + + hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled); + ExitOnFailure(hr, "Failed to get web Component's installed state"); + + WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction); + ExitOnFailure(hr, "Failed to get web Component's action state"); + + if (!WcaIsInstalling(psw->isInstalled, psw->isAction) && !WcaIsUninstalling(psw->isInstalled, psw->isAction) + && !WcaIsReInstalling(psw->isInstalled, psw->isAction)) + { + FreeWeb(psw); + psw = NULL; + + continue; // If we aren't acting on this component, skip it + } + } + + hr = WcaGetRecordInteger(hRec, wqId, &iSiteId); + ExitOnFailure(hr, "Failed to get SiteId for Web"); + + // Get the web's key address. + hr = WcaGetRecordString(hRec, wqAddress, &pwzData); + ExitOnFailure(hr, "Failed to get Address for Web"); + hr = ::StringCchCopyW(psw->swaKey.wzKey, countof(psw->swaKey.wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to web object"); + + hr = WcaGetRecordString(hRec, wqIP, &pwzData); + ExitOnFailure(hr, "Failed to get IP for Web"); + hr = ::StringCchCopyW(psw->swaKey.wzIP, countof(psw->swaKey.wzIP), pwzData); + ExitOnFailure(hr, "Failed to copy IP string to web object"); + + hr = WcaGetRecordString(hRec, wqPort, &pwzData); + ExitOnFailure(hr, "Failed to get Web Address port"); + psw->swaKey.iPort = wcstol(pwzData, NULL, 10); + + hr = WcaGetRecordString(hRec, wqHeader, &pwzData); + ExitOnFailure(hr, "Failed to get Header for Web"); + hr = ::StringCchCopyW(psw->swaKey.wzHeader, countof(psw->swaKey.wzHeader), pwzData); + ExitOnFailure(hr, "Failed to copy header string to web object"); + + hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaKey.fSecure); + ExitOnFailure(hr, "Failed to get if Web is secure"); + if (S_FALSE == hr) + { + psw->swaKey.fSecure = FALSE; + } + + // Get the web's description. + hr = WcaGetRecordString(hRec, wqDescription, &pwzData); + ExitOnFailure(hr, "Failed to get Description for Web"); + hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); + ExitOnFailure(hr, "Failed to copy description string to web object"); + + // Try to find the web root in case it already exists. + dwLen = METADATA_MAX_NAME_LEN; + hr = ScaWebFindBase(piMetabase, *ppswList, + psw->wzKey, + iSiteId, + psw->swaKey.wzIP, + psw->swaKey.iPort, + psw->swaKey.wzHeader, + psw->swaKey.fSecure, + psw->wzDescription, + psw->wzWebBase, dwLen); + if (S_OK == hr) + { + psw->fBaseExists = TRUE; + } + else if (S_FALSE == hr) // didn't find the web site. + { + psw->fBaseExists = FALSE; + + // If we're actually configuring the web site. + if (psw->fHasComponent) + { + if (WcaIsInstalling(psw->isInstalled, psw->isAction)) + { + hr = ScaWebFindFreeBase(piMetabase, *ppswList, iSiteId, psw->wzDescription, psw->wzWebBase, countof(psw->wzWebBase)); + ExitOnFailure(hr, "Failed to find free web root."); + } + else if (WcaIsUninstalling(psw->isInstalled, psw->isAction)) + { + WcaLog(LOGMSG_VERBOSE, "Web site: '%ls' was already removed, skipping.", psw->wzKey); + + hr = S_OK; + continue; + } + } + } + ExitOnFailure(hr, "Failed to find web root"); + + // get any extra web addresses + WcaFetchWrappedReset(hQueryWebAddress); + while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses))) + { + if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); + } + + hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); + ExitOnFailure(hr, "Failed to get extra web Address"); + + // if this isn't the key address add it + if (0 != lstrcmpW(pwzData, psw->swaKey.wzKey)) + { + hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy extra addresses key string to web object"); + + hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData); + ExitOnFailure(hr, "Failed to get extra web IP"); + hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); + ExitOnFailure(hr, "Failed to copy extra addresses IP string to web object"); + + hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData); + ExitOnFailure(hr, "Failed to get port for extra web IP"); + psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); + + hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData); + ExitOnFailure(hr, "Failed to get header for extra web IP"); + hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); + ExitOnFailure(hr, "Failed to copy extra addresses header string to web object"); + + hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); + ExitOnFailure(hr, "Failed to get if secure extra web IP"); + if (S_FALSE == hr) + psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; + + ++psw->cExtraAddresses; + } + } + + if (E_NOMOREITEMS == hr) + hr = S_OK; + ExitOnFailure(hr, "Failure occured while getting extra web addresses"); + + hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); + ExitOnFailure(hr, "Failed to get connection timeout for Web"); + + if (psw->fHasComponent) // If we're installing it, it needs a dir + { + // get the web's directory + if (INSTALLSTATE_SOURCE == psw->isAction) + { + hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData); + } + else + { + hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData); + } + ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); + + // remove trailing backslashes + while (lstrlenW(pwzData) > 0 && pwzData[lstrlenW(pwzData)-1] == L'\\') + { + pwzData[lstrlenW(pwzData)-1] = 0; + } + hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData); + ExitOnFailure(hr, "Failed to copy directory string to web object"); + } + + hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); + ExitOnFailure(hr, "Failed to get state for Web"); + + hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); + ExitOnFailure(hr, "Failed to get attributes for Web"); + + // get the dir properties for this web + hr = WcaGetRecordString(hRec, wqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get directory property record for Web"); + if (*pwzData) + { + hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp); + ExitOnFailure(hr, "Failed to get directory properties for Web"); + + psw->fHasProperties = TRUE; + } + + // get the application information for this web + hr = WcaGetRecordString(hRec, wqApplication, &pwzData); + ExitOnFailure(hr, "Failed to get application identifier for Web"); + if (*pwzData) + { + hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp); + ExitOnFailure(hr, "Failed to get application for Web"); + + psw->fHasApplication = TRUE; + } + + // get the SSL certificates + hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList)); + ExitOnFailure(hr, "Failed to get SSL Certificates."); + + // get the custom headers + if (*ppshhList) + { + hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); + ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); + } + + // get the errors + if (*ppsweList) + { + hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); + ExitOnFailure(hr, "Failed to get Custom Errors"); + } + + // get the log information for this web + hr = WcaGetRecordString(hRec, wqLog, &pwzData); + ExitOnFailure(hr, "Failed to get log identifier for Web"); + if (*pwzData) + { + hr = ScaGetWebLog(piMetabase, pwzData, hWebLogQuery, &psw->swl); + ExitOnFailure(hr, "Failed to get Log for Web."); + + psw->fHasLog = TRUE; + } + + *ppswList = AddWebToList(*ppswList, psw); + psw = NULL; // set the web NULL so it doesn't accidentally get freed below + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + +LExit: + // if anything was left over after an error clean it all up + WcaFinishUnwrapQuery(hQueryWebSite); + WcaFinishUnwrapQuery(hQueryWebAddress); + + if (psw) + { + ScaWebsFreeList(psw); + } + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaWebsGetBase( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in LPCWSTR wzWeb, + __out_ecount(cchWebBase) LPWSTR wzWebBase, + __in DWORD cchWebBase, + __in WCA_WRAPQUERY_HANDLE hWrapQuery + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + + int iSiteId; + WCHAR wzIP[MAX_PATH]; + int iPort = -1; + WCHAR wzHeader[MAX_PATH]; + BOOL fSecure = FALSE; + + LPWSTR pwzData = NULL; + + // get the web information + WcaFetchWrappedReset(hWrapQuery); + + hr = WcaFetchWrappedRecordWhereString(hWrapQuery, 1, wzWeb, &hRec); + if (S_OK == hr) + { + // get the data to search for + hr = WcaGetRecordInteger(hRec, wbqId, &iSiteId); + ExitOnFailure(hr, "Failed to get SiteId for Web for VirtualDir"); + + hr = WcaGetRecordString(hRec, wbqIP, &pwzData); + ExitOnFailure(hr, "Failed to get IP for Web for VirtualDir"); + hr = ::StringCchCopyW(wzIP, countof(wzIP), pwzData); + ExitOnFailure(hr, "Failed to copy IP for Web for VirtualDir"); + + hr = WcaGetRecordString(hRec, wbqPort, &pwzData); + ExitOnFailure(hr, "Failed to get port for extra web IP"); + iPort = wcstol(pwzData, NULL, 10); + + hr = WcaGetRecordString(hRec, wbqHeader, &pwzData); + ExitOnFailure(hr, "Failed to get Header for Web for VirtualDir"); + hr = ::StringCchCopyW(wzHeader, countof(wzHeader), pwzData); + ExitOnFailure(hr, "Failed to copy Header for Web for VirtualDir"); + + hr = WcaGetRecordInteger(hRec, wbqSecure, &fSecure); + if (S_FALSE == hr) + fSecure = FALSE; + + hr = WcaGetRecordString(hRec, wbqDescription, &pwzData); + ExitOnFailure(hr, "Failed to get Description for Web"); + + // find the web or find the next free web location + hr = ScaWebFindBase(piMetabase, pswList, wzWeb, iSiteId, wzIP, iPort, wzHeader, fSecure, pwzData, wzWebBase, cchWebBase); + if (S_FALSE == hr) + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + ExitOnFailure(hr, "Failed to find Web base"); + } + else if (S_FALSE == hr) + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would + HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWrapQuery, 1, wzWeb, &hRec); + if (SUCCEEDED(hrTemp)) + { + AssertSz(E_NOMOREITEMS == hrTemp, "ScaWebsGetBase found more than one record"); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaWebsInstall( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in SCA_APPPOOL * psapList + ) +{ + HRESULT hr = S_OK; + SCA_WEB* psw = pswList; + + while (psw) + { + // if we are installing the web site + if (psw->fHasComponent && WcaIsInstalling(psw->isInstalled, psw->isAction)) + { + hr = ScaWebWrite(piMetabase, psw, psapList); + ExitOnFailure(hr, "failed to write web '%ls' to metabase", psw->wzKey); + } + + psw = psw->pswNext; + } + +LExit: + return hr; +} + + +HRESULT ScaWebsUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList + ) +{ + HRESULT hr = S_OK; + SCA_WEB* psw = pswList; + + while (psw) + { + // if we are uninstalling the web site + if (psw->fHasComponent && WcaIsUninstalling(psw->isInstalled, psw->isAction)) + { + hr = ScaWebRemove(piMetabase, psw); + ExitOnFailure(hr, "Failed to remove web '%ls' from metabase", psw->wzKey); + } + + psw = psw->pswNext; + } + +LExit: + return hr; +} + + +void ScaWebsFreeList( + __in SCA_WEB* pswList + ) +{ + SCA_WEB* pswDelete = pswList; + while (pswList) + { + pswDelete = pswList; + pswList = pswList->pswNext; + + // Free the SSL, headers and errors list first + FreeWeb(pswDelete); + } +} + + +// private helper functions + +static void FreeWeb(SCA_WEB *pswDelete) +{ + ScaSslCertificateFreeList(pswDelete->pswscList); + ScaHttpHeaderFreeList(pswDelete->pshhList); + ScaWebErrorFreeList(pswDelete->psweList); + MemFree(pswDelete); +} + +static SCA_WEB* NewWeb() +{ + SCA_WEB* psw = static_cast(MemAlloc(sizeof(SCA_WEB), TRUE)); + Assert(psw); + return psw; +} + + +static SCA_WEB* AddWebToList( + __in SCA_WEB* pswList, + __in SCA_WEB* psw + ) +{ + if (pswList) + { + SCA_WEB* pswTemp = pswList; + while (pswTemp->pswNext) + { + pswTemp = pswTemp->pswNext; + } + + pswTemp->pswNext = psw; + } + else + { + pswList = psw; + } + + return pswList; +} + + +static HRESULT ScaWebFindBase( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in_z LPCWSTR wzWeb, + __in int iSiteId, + __in_z LPCWSTR wzIP, + __in int iPort, + __in_z LPCWSTR wzHeader, + __in BOOL fSecure, + __in_z LPCWSTR wzDescription, + __out_ecount(cchWebBase) LPWSTR wzWebBase, + __in DWORD cchWebBase + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + WCHAR wzSubkey[METADATA_MAX_NAME_LEN]; + LPWSTR wzFoundKey = NULL; + + METADATA_RECORD mr; + ::ZeroMemory(&mr, sizeof(mr)); + + METADATA_RECORD mrCompare; + ::ZeroMemory(&mrCompare, sizeof(mrCompare)); + + // try to find the web in memory first + for (SCA_WEB* psw = pswList; psw; psw = psw->pswNext) + { + if (0 == lstrcmpW(wzWeb, psw->wzKey)) + { + if ((0 == lstrcmpW(wzIP, psw->swaKey.wzIP) || 0 == lstrcmpW(wzIP, L"*") || 0 == lstrcmpW(psw->swaKey.wzIP, L"*")) && + iPort == psw->swaKey.iPort && + 0 == lstrcmpW(wzHeader, psw->swaKey.wzHeader) && + fSecure == psw->swaKey.fSecure) + { + if (0 == lstrlenW(psw->wzWebBase)) + { + WcaLog(LOGMSG_STANDARD, "A matching web object in memory was found, but the web object in memory has no associated base"); + ExitFunction1(hr = S_FALSE); + } + + hr = ::StringCchCopyW(wzKey, countof(wzKey), psw->wzWebBase); + ExitOnFailure(hr, "Failed to copy web base into key."); + + wzFoundKey = wzKey; + break; + } + else + { + WcaLog(LOGMSG_STANDARD, "Found web `%ls` but data did not match.", wzWeb); + hr = E_UNEXPECTED; + break; + } + } + } + ExitOnFailure(hr, "Failure occured while searching for web in memory"); + + // If we didn't find a web in memory matching look in the metabase. + if (!wzFoundKey) + { + mr.dwMDIdentifier = MD_KEY_TYPE; + mr.dwMDAttributes = METADATA_INHERIT; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = ALL_METADATA; + mr.dwMDDataLen = 0; + mr.pbMDData = NULL; + + // If we're looking based on the old WebAddress detection (NULL) or the new + // Web description detection (-1) + if (MSI_NULL_INTEGER == iSiteId || -1 == iSiteId) + { + if (MSI_NULL_INTEGER == iSiteId) + { + mrCompare.dwMDIdentifier = (fSecure) ? MD_SECURE_BINDINGS : MD_SERVER_BINDINGS; + } + else + { + mrCompare.dwMDIdentifier = MD_SERVER_COMMENT; + } + mrCompare.dwMDAttributes = METADATA_INHERIT; + mrCompare.dwMDUserType = IIS_MD_UT_SERVER; + mrCompare.dwMDDataType = ALL_METADATA; + mrCompare.dwMDDataLen = 0; + mrCompare.pbMDData = NULL; + + // Loop through the "web keys" looking for the "IIsWebServer" key that matches our search criteria. + for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex) + { + hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC", wzSubkey, dwIndex); + if (SUCCEEDED(hr)) + { + hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/W3SVC/%s", wzSubkey); + ExitOnFailure(hr, "Failed to copy web subkey."); + + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mr); + if (MD_ERROR_DATA_NOT_FOUND == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) + { + hr = S_FALSE; // didn't find anything, try next one + continue; + } + ExitOnFailure(hr, "Failed to get key from metabase while searching for web servers"); + + // If we have an IIsWebServer check to see if this is the site we are searching for. + if (0 == lstrcmpW(L"IIsWebServer", (LPCWSTR)mr.pbMDData)) + { + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrCompare); + if (MD_ERROR_DATA_NOT_FOUND == hr || NULL == mrCompare.pbMDData) + { + hr = S_FALSE; + continue; + } + ExitOnFailure(hr, "Failed to get address/description from metabase while searching for web servers"); + + LPWSTR pwzExists = (LPWSTR)mrCompare.pbMDData; + if (MSI_NULL_INTEGER == iSiteId) + { + // Break down the address into its constituent parts (IP:Port:Header). + while (S_OK == hr && *pwzExists) + { + LPCWSTR pwzIPExists = pwzExists; + pwzExists = const_cast(wcsstr(pwzIPExists, L":")); + ExitOnNull(pwzExists, hr, E_INVALIDARG, "Invalid web address. IP was not separated by a colon."); + *pwzExists = L'\0'; + + LPCWSTR pwzPortExists = pwzExists + 1; + pwzExists = const_cast(wcsstr(pwzPortExists, L":")); + ExitOnNull(pwzExists, hr, E_INVALIDARG, "Invalid web address. Port was not separated by a colon."); + *pwzExists = L'\0'; + int iPortExists = wcstol(pwzPortExists, NULL, 10); + + LPCWSTR pwzHeaderExists = pwzExists + 1; + + // compare the passed in address with the address listed for this web + if ((0 == lstrcmpW(wzIP, pwzIPExists) || 0 == lstrcmpW(wzIP, L"*")) && + iPort == iPortExists && + 0 == lstrcmpW(wzHeader, pwzHeaderExists)) + { + wzFoundKey = wzKey; + break; + } + + // move to the next block of data, this may move beyond the available + // data and exit the while loop above. + pwzExists = const_cast(pwzHeaderExists + lstrlenW(pwzHeaderExists) + 1); + } + } + else + { + if (0 == lstrcmpW(wzDescription, pwzExists)) + { + wzFoundKey = wzKey; + } + } + + // If we found the key we were looking for, no point in continuing to search. + if (wzFoundKey) + { + break; + } + } + } + } + + if (E_NOMOREITEMS == hr) + { + Assert(!wzFoundKey); + hr = S_FALSE; + } + } + else // we're looking a specific SiteId + { + hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/W3SVC/%d", iSiteId); + ExitOnFailure(hr, "Failed to allocate metabase key string."); + + // if we have an IIsWebServer store the key + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mr); + + if (SUCCEEDED(hr) && NULL != mr.pbMDData && 0 == lstrcmpW(L"IIsWebServer", (LPCWSTR)mr.pbMDData)) + { + wzFoundKey = wzKey; + } + else if (MD_ERROR_DATA_NOT_FOUND == hr || NULL == mrCompare.pbMDData || NULL == mr.pbMDData) + { + hr = S_FALSE; + } + } + } + + if (wzFoundKey) + { + Assert(S_OK == hr); + + hr = ::StringCchCopyW(wzWebBase, cchWebBase, wzFoundKey); + ExitOnFailure(hr, "Buffer not larger enough for found base key."); + } + +LExit: + MetaFreeValue(&mr); + MetaFreeValue(&mrCompare); + + if (!wzFoundKey && SUCCEEDED(hr)) + { + hr = S_FALSE; + } + + return hr; +} + + +static HRESULT ScaWebFindFreeBase( + __in IMSAdminBase* piMetabase, + __in_xcount(unknown) SCA_WEB* pswList, + __in int iSiteId, + __in_z LPCWSTR wzDescription, + __out_ecount(cchWebBase) LPWSTR wzWebBase, + __in DWORD cchWebBase + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + WCHAR wzSubkey[METADATA_MAX_NAME_LEN]; + DWORD* prgdwSubKeys = NULL; + DWORD cSubKeys = 128; + DWORD cSubKeysFilled = 0; + + DWORD dwKey; + + METADATA_RECORD mr; + ::ZeroMemory(&mr, sizeof(METADATA_RECORD)); + mr.dwMDIdentifier = MD_KEY_TYPE; + mr.dwMDAttributes = 0; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = STRING_METADATA; + mr.dwMDDataLen = 0; + mr.pbMDData = NULL; + + if (MSI_NULL_INTEGER == iSiteId || -1 == iSiteId) + { + prgdwSubKeys = static_cast(MemAlloc(cSubKeys * sizeof(DWORD), TRUE)); + ExitOnNull(prgdwSubKeys, hr, E_OUTOFMEMORY, "failed to allocate space for web site keys"); + + // loop through the "web keys" looking for the "IIsWebServer" key that matches wzWeb + for (DWORD dwIndex = 0; SUCCEEDED(hr); ++dwIndex) + { + hr = piMetabase->EnumKeys(METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC", wzSubkey, dwIndex); + if (SUCCEEDED(hr)) + { + hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/W3SVC/%s", wzSubkey); + ExitOnFailure(hr, "Failed remember key."); + + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mr); + if (MD_ERROR_DATA_NOT_FOUND == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) + { + hr = S_FALSE; // didn't find anything, try next one + continue; + } + ExitOnFailure(hr, "Failed to get key from metabase while searching for free web root"); + + // if we have a IIsWebServer get the address information + if (0 == lstrcmpW(L"IIsWebServer", (LPCWSTR)mr.pbMDData)) + { + if (cSubKeysFilled >= cSubKeys) + { + cSubKeys = cSubKeys * 2; + prgdwSubKeys = static_cast(MemReAlloc(prgdwSubKeys, cSubKeys * sizeof(DWORD), FALSE)); + ExitOnNull(prgdwSubKeys, hr, E_OUTOFMEMORY, "failed to allocate space for web site keys"); + } + + prgdwSubKeys[cSubKeysFilled] = wcstol(wzSubkey, NULL, 10); + ++cSubKeysFilled; + Sort(prgdwSubKeys, cSubKeysFilled); + } + } + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failed to find free web root"); + + // Add all the webs created in memory. + CONST WCHAR *pcchSlash; + for (SCA_WEB* psw = pswList; psw; psw = psw->pswNext) + { + // Don't process webs that don't have a base + if (!*psw->wzWebBase) + { + continue; + } + + // find the last slash in the web root because the root # is after it + pcchSlash = NULL; + for (CONST WCHAR *pcch = psw->wzWebBase; pcch && *pcch; ++pcch) + { + if (L'/' == *pcch) + { + pcchSlash = pcch; + } + } + // In case we don't find a slash, error out + ExitOnNull(pcchSlash, hr, E_INVALIDARG, "Failed to find a slash in the web root: %ls", psw->wzWebBase); + + prgdwSubKeys[cSubKeysFilled] = wcstol(pcchSlash + 1, NULL, 10); + ++cSubKeysFilled; + Sort(prgdwSubKeys, cSubKeysFilled); + + if (cSubKeysFilled >= cSubKeys) + { + cSubKeys = cSubKeys * 2; + prgdwSubKeys = static_cast(MemReAlloc(prgdwSubKeys, cSubKeys * sizeof(DWORD), FALSE)); + ExitOnNull(prgdwSubKeys, hr, E_OUTOFMEMORY, "failed to allocate space for web site keys"); + } + } + + // Find the lowest free web root. + dwKey = (-1 == iSiteId) ? SiteIdFromDescription(wzDescription) : 1; + for (DWORD i = 0; i < cSubKeysFilled; ++i) + { + if (dwKey == prgdwSubKeys[i]) + { + ++dwKey; + } + else if (dwKey < prgdwSubKeys[i]) + { + break; + } + } + } + else + { + dwKey = iSiteId; + } + + hr = ::StringCchPrintfW(wzWebBase, cchWebBase, L"/LM/W3SVC/%u", dwKey); + ExitOnFailure(hr, "failed to format web base with key: %u", dwKey); + +LExit: + MetaFreeValue(&mr); + + if (prgdwSubKeys) + { + MemFree(prgdwSubKeys); + } + + return hr; +} + + +static HRESULT ScaWebWrite( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* psw, + __in SCA_APPPOOL * psapList) +{ + HRESULT hr = S_OK; + + UINT ui = 0; + WCHAR wzIP[64]; + WCHAR wzBindings[1024]; + WCHAR wzSecureBindings[1024]; + WCHAR* pcchNext; // used to properly create the MULTI_SZ + DWORD cchPcchNext; + WCHAR* pcchSecureNext ; // used to properly create the MULTI_SZ + DWORD cchPcchSecureNext; + + // if the web root doesn't exist create it + if (!psw->fBaseExists) + { + hr = ScaCreateWeb(piMetabase, psw->wzKey, psw->wzWebBase); + ExitOnFailure(hr, "Failed to create web"); + } + else if (psw->iAttributes & SWATTRIB_NOCONFIGUREIFEXISTS) // if we're not supposed to configure existing webs, bail + { + Assert(psw->fBaseExists); + + hr = S_FALSE; + WcaLog(LOGMSG_VERBOSE, "Skipping configuration of existing web: %ls", psw->wzKey); + ExitFunction(); + } + + // put the secure and non-secure bindings together as MULTI_SZs + ::ZeroMemory(wzBindings, sizeof(wzBindings)); + pcchNext = wzBindings; + cchPcchNext = countof(wzBindings); + ::ZeroMemory(wzSecureBindings, sizeof(wzSecureBindings)); + pcchSecureNext = wzSecureBindings; + cchPcchSecureNext = countof(wzSecureBindings); + + // set the IP address appropriately + if (0 == lstrcmpW(psw->swaKey.wzIP, L"*")) + { + ::ZeroMemory(wzIP, sizeof(wzIP)); + } + else + { + hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaKey.wzIP); + ExitOnFailure(hr, "Failed to copy IP string"); + } + + WCHAR wzBinding[256]; + hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaKey.iPort, psw->swaKey.wzHeader); + ExitOnFailure(hr, "Failed to format IP:Port:Header binding string"); + if (psw->swaKey.fSecure) + { + hr = ::StringCchCopyW(pcchSecureNext, cchPcchSecureNext, wzBinding); + ExitOnFailure(hr, "Failed to copy binding string to securenext string"); + pcchSecureNext += lstrlenW(wzBinding) + 1; + cchPcchSecureNext -= lstrlenW(wzBinding) + 1; + } + else + { + hr = ::StringCchCopyW(pcchNext, cchPcchNext, wzBinding); + ExitOnFailure(hr, "Failed to copy binding string to next string"); + pcchNext += lstrlenW(wzBinding) + 1; + cchPcchNext -= lstrlenW(wzBinding) + 1; + } + + for (ui = 0; ui < psw->cExtraAddresses; ++ui) + { + // set the IP address appropriately + if (0 == lstrcmpW(psw->swaExtraAddresses[ui].wzIP, L"*")) + { + ::ZeroMemory(wzIP, sizeof(wzIP)); + } + else + { + hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaExtraAddresses[ui].wzIP); + ExitOnFailure(hr, "Failed to copy extra addresses IP to IP string"); + } + + hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaExtraAddresses[ui].iPort, psw->swaExtraAddresses[ui].wzHeader); + ExitOnFailure(hr, "Failed to format IP:Port:Header binding string for extra address"); + if (psw->swaExtraAddresses[ui].fSecure) + { + hr = ::StringCchCopyW(pcchSecureNext, cchPcchSecureNext, wzBinding); + ExitOnFailure(hr, "Failed to copy binding string to securenext string for extra address"); + pcchSecureNext += lstrlenW(wzBinding) + 1; + cchPcchSecureNext -= lstrlenW(wzBinding) + 1; + } + else + { + hr = ::StringCchCopyW(pcchNext, cchPcchNext, wzBinding); + ExitOnFailure(hr, "Failed to copy binding string to next string for extra address"); + pcchNext += lstrlenW(wzBinding) + 1; + cchPcchNext -= lstrlenW(wzBinding) + 1; + } + } + + // Delete the existing secure bindings metabase value, as having one while SSLCertHash and SSLStoreName aren't both set correctly can result in + // 0x80070520 (ERROR_NO_SUCH_LOGON_SESSION) errors in some situations on IIS7. Clearing this value first and then setting it after the install has completed + // allows the two aforementioned properties to exist in an intermediate state without errors + hr = ScaDeleteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SECURE_BINDINGS, MULTISZ_METADATA); + ExitOnFailure(hr, "Failed to temporarily delete secure bindings for Web"); + + // now write the bindings to the metabase + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_BINDINGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, MULTISZ_METADATA, wzBindings); + ExitOnFailure(hr, "Failed to write server bindings for Web"); + + // write the target path for the web's directory to the metabase + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"/Root", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, psw->wzDirectory); + ExitOnFailure(hr, "Failed to write virtual root path for Web"); + + // write the description for the web to the metabase + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_COMMENT, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, psw->wzDescription); + ExitOnFailure(hr, "Failed to write description for Web"); + + ui = psw->iConnectionTimeout; + if (MSI_NULL_INTEGER != ui) + { + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_CONNECTION_TIMEOUT, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); + ExitOnFailure(hr, "Failed to write connection timeout for Web"); + } + + ui = psw->iState; + if (MSI_NULL_INTEGER != ui) + { + if (2 == ui) + { + ui = 1; + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_AUTOSTART, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); + ExitOnFailure(hr, "Failed to write auto start flag for Web"); + ui = 2; + } + + if (1 == ui || 2 == ui) + { + ui = 1; // start command + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_COMMAND, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); + ExitOnFailure(hr, "Failed to start Web"); + } + else if (0 == ui) + { + ui = 2; // stop command + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SERVER_COMMAND, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)ui)); + ExitOnFailure(hr, "Failed to stop Web"); + } + else + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Unexpected value for Web State"); + } + } + + WCHAR wzRootOfWeb[METADATA_MAX_NAME_LEN]; + hr = ::StringCchPrintfW(wzRootOfWeb, countof(wzRootOfWeb), L"%s/Root", psw->wzWebBase); + ExitOnFailure(hr, "Failed to allocate WebBase/Root string for root of web"); + + // write the web dirproperties information + if (psw->fHasProperties) + { + hr = ScaWriteWebDirProperties(piMetabase, wzRootOfWeb, &psw->swp); + ExitOnFailure(hr, "Failed to write web security information to metabase"); + } + + // write the application information + if (psw->fHasApplication) + { + // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created + if (WcaIsReInstalling(psw->isInstalled, psw->isAction)) + { + hr = ScaDeleteApp(piMetabase, wzRootOfWeb); + ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); + } + + hr = ScaWriteWebApplication(piMetabase, wzRootOfWeb, &psw->swapp, psapList); + ExitOnFailure(hr, "Failed to write web application information to metabase"); + } + + // write the SSL certificate information + if (psw->pswscList) + { + hr = ScaSslCertificateWriteMetabase(piMetabase, psw->wzWebBase, psw->pswscList); + ExitOnFailure(hr, "Failed to write SSL certificates for Web site: %ls", psw->wzKey); + } + + hr = ScaWriteMetabaseValue(piMetabase, psw->wzWebBase, L"", MD_SECURE_BINDINGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, MULTISZ_METADATA, wzSecureBindings); + ExitOnFailure(hr, "Failed to write secure bindings for Web"); + + // write the headers + if (psw->pshhList) + { + hr = ScaWriteHttpHeader(piMetabase, wzRootOfWeb, psw->pshhList); + ExitOnFailure(hr, "Failed to write custom HTTP headers for Web site: %ls", psw->wzKey); + } + + // write the errors + if (psw->psweList) + { + hr = ScaWriteWebError(piMetabase, weptWeb, psw->wzWebBase, psw->psweList); + ExitOnFailure(hr, "Failed to write custom web errors for Web site: %ls", psw->wzKey); + } + + // write the mimetypes + if (psw->psmm) + { + hr = ScaWriteMimeMap(piMetabase, wzRootOfWeb, psw->psmm); + ExitOnFailure(hr, "Failed to write mimemap for Web site: %ls", psw->wzKey); + } + + // write the log information to the metabase + if (psw->fHasLog) + { + hr = ScaWriteWebLog(piMetabase, psw->wzWebBase, &psw->swl); + ExitOnFailure(hr, "Failed to write web log information to metabase"); + } + +LExit: + return hr; +} + + +static HRESULT ScaWebRemove( + __in IMSAdminBase* piMetabase, + __in const SCA_WEB* psw + ) +{ + HRESULT hr = S_OK; + + // simply remove the root key and everything else is pulled at the same time + hr = ScaDeleteMetabaseKey(piMetabase, psw->wzWebBase, L""); + ExitOnFailure(hr, "Failed to remove web '%ls' from metabase", psw->wzKey); + +LExit: + return hr; +} + + +static DWORD SiteIdFromDescription( + __in_z LPCWSTR wzDescription + ) +{ + LPCWSTR pwz = wzDescription; + DWORD dwSiteId = 0; + while (pwz && *pwz) + { + WCHAR ch = *pwz & 0xdf; + dwSiteId = (dwSiteId * 101) + ch; + ++pwz; + } + + return (dwSiteId % INT_MAX) + 1; +} + + +// insertion sort +static void Sort( + __in_ecount(cArray) DWORD dwArray[], + __in int cArray + ) +{ + int i, j; + DWORD dwData; + + for (i = 1; i < cArray; ++i) + { + dwData = dwArray[i]; + + j = i - 1; + while (0 <= j && dwArray[j] > dwData) + { + dwArray[j + 1] = dwArray[j]; + j--; + } + + dwArray[j + 1] = dwData; + } +} diff --git a/src/ext/Iis/ca/scaweb.h b/src/ext/Iis/ca/scaweb.h new file mode 100644 index 00000000..294030b4 --- /dev/null +++ b/src/ext/Iis/ca/scaweb.h @@ -0,0 +1,123 @@ +#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 "scawebapp.h" +#include "scawebprop.h" +#include "scahttpheader.h" +#include "scaweberr.h" +#include "scassl.h" +#include "scaapppool.h" +#include "scaweblog.h" +#include "scamimemap.h" + +// globals +#define MAX_ADDRESSES_PER_WEB 10 + +enum eWebQuery { wqWeb = 1, wqComponent, wqId, wqDescription, wqConnectionTimeout, wqDirectory, + wqState, wqAttributes, wqProperties, wqApplication, wqAddress, wqIP, wqPort, wqHeader, wqSecure, wqLog, wqInstalled, wqAction, wqSourcePath, wqTargetPath}; + +enum eWebAddressQuery { waqAddress = 1, waqWeb, waqIP, waqPort, waqHeader, waqSecure }; + +enum SCA_WEB_ATTRIBUTES +{ + SWATTRIB_NOCONFIGUREIFEXISTS = 2 +}; + +// structs +struct SCA_WEB_ADDRESS +{ + WCHAR wzKey [MAX_DARWIN_KEY + 1]; + + WCHAR wzIP[MAX_DARWIN_COLUMN + 1]; + int iPort; + WCHAR wzHeader[MAX_DARWIN_COLUMN + 1]; + BOOL fSecure; +}; + +struct SCA_WEB +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + BOOL fHasComponent; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + // metabase information + WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; + BOOL fBaseExists; + + // iis configuation information + SCA_WEB_ADDRESS swaKey; + + SCA_WEB_ADDRESS swaExtraAddresses[MAX_ADDRESSES_PER_WEB + 1]; + DWORD cExtraAddresses; + + WCHAR wzDirectory[MAX_PATH]; + WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; + + int iState; + int iAttributes; + + BOOL fHasProperties; + SCA_WEB_PROPERTIES swp; + + BOOL fHasApplication; + SCA_WEB_APPLICATION swapp; + + BOOL fHasSecurity; + int dwAccessPermissions; + int iConnectionTimeout; + + SCA_MIMEMAP* psmm; // mime mappings + SCA_WEB_SSL_CERTIFICATE* pswscList; + SCA_HTTP_HEADER* pshhList; + SCA_WEB_ERROR* psweList; + + BOOL fHasLog; + SCA_WEB_LOG swl; + + SCA_WEB* pswNext; +}; + + +// prototypes +HRESULT ScaWebsRead( + __in IMSAdminBase* piMetabase, + __in SCA_MIMEMAP** ppsmmList, + __in SCA_WEB** ppswList, + __in SCA_HTTP_HEADER** pshhList, + __in SCA_WEB_ERROR** psweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hSslCertQuery, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ); + +HRESULT ScaWebsGetBase( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in LPCWSTR wzWeb, + __out_ecount(cchWebBase) LPWSTR wzWebBase, + __in DWORD cchWebBase, + __in WCA_WRAPQUERY_HANDLE hWrapQuery + ); + +HRESULT ScaWebsInstall( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in SCA_APPPOOL * psapList + ); + +HRESULT ScaWebsUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList + ); + +void ScaWebsFreeList( + __in SCA_WEB* pswHead + ); diff --git a/src/ext/Iis/ca/scaweb7.cpp b/src/ext/Iis/ca/scaweb7.cpp new file mode 100644 index 00000000..3ee781f2 --- /dev/null +++ b/src/ext/Iis/ca/scaweb7.cpp @@ -0,0 +1,953 @@ +// 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" + +//Adding this because delivery doesn't have the updated specstrings.h that windows build does +#ifndef __in_xcount +#define __in_xcount(size) +#endif + +// prototypes for private helper functions +static SCA_WEB7* NewWeb7(); +static SCA_WEB7* AddWebToList7( + __in SCA_WEB7* pswList, + __in SCA_WEB7* psw + ); + +static HRESULT ScaWebFindBase7( + __in SCA_WEB7* pswList, + LPCWSTR wzDescription + ); + +static HRESULT ScaWebWrite7( + __in SCA_WEB7* psw, + __in SCA_APPPOOL * psapList + ); + +static HRESULT ScaWebRemove7(__in const SCA_WEB7* psw); + + +HRESULT ScaWebsRead7( + __in SCA_WEB7** ppswList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hSslCertQuery, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(ppswList); + WcaLog(LOGMSG_VERBOSE, "Entering ScaWebsRead7()"); + + HRESULT hr = S_OK; + + MSIHANDLE hRec; + MSIHANDLE hRecAddresses; + + WCA_WRAPQUERY_HANDLE hQueryWebSite = NULL; + WCA_WRAPQUERY_HANDLE hQueryWebAddress = NULL; + + SCA_WEB7* psw = NULL; + LPWSTR pwzData = NULL; + + DWORD dwLen = 0; + errno_t error = EINVAL; + + // check to see what tables are available + hr = WcaBeginUnwrapQuery(&hQueryWebSite, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); + + hr = WcaBeginUnwrapQuery(&hQueryWebAddress, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebsRead"); + + + if (0 == WcaGetQueryRecords(hQueryWebSite) || 0 == WcaGetQueryRecords(hQueryWebAddress)) + { + WcaLog(LOGMSG_VERBOSE, "Required tables not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the webs + while (S_OK == (hr = WcaFetchWrappedRecord(hQueryWebSite, &hRec))) + { + psw = NewWeb7(); + if (!psw) + { + hr = E_OUTOFMEMORY; + break; + } + + // get the darwin information + hr = WcaGetRecordString(hRec, wqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web"); + hr = ::StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to web object"); + + // get component install state + hr = WcaGetRecordString(hRec, wqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get Component for Web"); + hr = ::StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); + ExitOnFailure(hr, "Failed to copy component string to web object"); + if (*(psw->wzComponent)) + { + psw->fHasComponent = TRUE; + + hr = WcaGetRecordInteger(hRec, wqInstalled, (int *)&psw->isInstalled); + ExitOnFailure(hr, "Failed to get web Component's installed state"); + + WcaGetRecordInteger(hRec, wqAction, (int *)&psw->isAction); + ExitOnFailure(hr, "Failed to get web Component's action state"); + } + + // Get the web's description. + hr = WcaGetRecordString(hRec, wqDescription, &pwzData); + ExitOnFailure(hr, "Failed to get Description for Web"); + hr = ::StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); + ExitOnFailure(hr, "Failed to copy description string to web object"); + + //get web's site Id + hr = WcaGetRecordInteger(hRec, wqId, &psw->iSiteId); + ExitOnFailure(hr, "Failed to get SiteId for Web"); + + // get the web's key address (Bindings) + hr = WcaGetRecordString(hRec, wqAddress, &pwzData); + ExitOnFailure(hr, "Failed to get Address for Web"); + hr = ::StringCchCopyW(psw->swaBinding.wzKey, countof(psw->swaBinding.wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy web binding key"); + + hr = WcaGetRecordString(hRec, wqIP, &pwzData); + ExitOnFailure(hr, "Failed to get IP for Web"); + hr = ::StringCchCopyW(psw->swaBinding.wzIP, countof(psw->swaBinding.wzIP), pwzData); + ExitOnFailure(hr, "Failed to copy web IP"); + + hr = WcaGetRecordString(hRec, wqPort, &pwzData); + ExitOnFailure(hr, "Failed to get Web Address port"); + psw->swaBinding.iPort = wcstol(pwzData, NULL, 10); + + hr = WcaGetRecordString(hRec, wqHeader, &pwzData); + ExitOnFailure(hr, "Failed to get Header for Web"); + hr = ::StringCchCopyW(psw->swaBinding.wzHeader, countof(psw->swaBinding.wzHeader), pwzData); + ExitOnFailure(hr, "Failed to copy web header"); + + hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaBinding.fSecure); + ExitOnFailure(hr, "Failed to get if Web is secure"); + if (S_FALSE == hr) + { + psw->swaBinding.fSecure = FALSE; + } + + // look to see if site exists + dwLen = METADATA_MAX_NAME_LEN; + hr = ScaWebFindBase7(*ppswList, psw->wzDescription); + + // If we didn't find a web in memory, ignore it - during execute CA + // if the site truly does not exist then there will be an error. + if (S_OK == hr) + { + // site exists in config + psw->fBaseExists = TRUE; + } + else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) + { + hr = S_OK; + + // site does not exists in config + psw->fBaseExists = FALSE; + } + ExitOnFailure(hr, "Failed to find web site"); + + // get any extra web addresses + WcaFetchWrappedReset(hQueryWebAddress); + + while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hQueryWebAddress, 2, psw->wzKey, &hRecAddresses))) + { + if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); + } + + hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); + ExitOnFailure(hr, "Failed to get extra web Address"); + + // if this isn't the key address add it + if (0 != lstrcmpW(pwzData, psw->swaBinding.wzKey)) + { + hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, + countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy web binding key"); + + hr = WcaGetRecordString(hRecAddresses, waqIP, &pwzData); + ExitOnFailure(hr, "Failed to get extra web IP"); + hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); + ExitOnFailure(hr, "Failed to copy web binding IP"); + + hr = WcaGetRecordString(hRecAddresses, waqPort, &pwzData); + ExitOnFailure(hr, "Failed to get port for extra web IP"); + psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); + + // errno is set to ERANGE if overflow or underflow occurs + _get_errno(&error); + + if (ERANGE == error) + { + hr = E_INVALIDARG; + ExitOnFailure(hr, "Failed to convert web Port address"); + } + + hr = WcaGetRecordString(hRecAddresses, waqHeader, &pwzData); + ExitOnFailure(hr, "Failed to get header for extra web IP"); + hr = ::StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); + ExitOnFailure(hr, "Failed to copy web binding header"); + + hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); + ExitOnFailure(hr, "Failed to get if secure extra web IP"); + if (S_FALSE == hr) + { + psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; + } + + ++psw->cExtraAddresses; + } + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure occured while getting extra web addresses"); + + // + // Connection time out + // + hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); + ExitOnFailure(hr, "Failed to get connection timeout for Web"); + + if (psw->fHasComponent) // If we're installing it, it needs a dir + { + // get the web's directory + if (INSTALLSTATE_SOURCE == psw->isAction) + { + hr = WcaGetRecordString(hRec, wqSourcePath, &pwzData); + } + else + { + hr = WcaGetRecordString(hRec, wqTargetPath, &pwzData); + } + ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); + + dwLen = lstrlenW(pwzData); + // remove trailing backslash + if (dwLen > 0 && pwzData[dwLen-1] == L'\\') + { + pwzData[dwLen-1] = 0; + } + hr = ::StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), pwzData); + ExitOnFailure(hr, "Failed to copy web dir: '%ls'", pwzData); + + } + + hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); + ExitOnFailure(hr, "Failed to get state for Web"); + + hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); + ExitOnFailure(hr, "Failed to get attributes for Web"); + + // get the dir properties for this web + hr = WcaGetRecordString(hRec, wqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get directory properties for Web"); + if (*pwzData) + { + hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &psw->swp); + ExitOnFailure(hr, "Failed to get directory properties for Web"); + + psw->fHasProperties = TRUE; + } + + // get the application information for this web + hr = WcaGetRecordString(hRec, wqApplication, &pwzData); + ExitOnFailure(hr, "Failed to get application identifier for Web"); + if (*pwzData) + { + hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &psw->swapp); + ExitOnFailure(hr, "Failed to get application for Web"); + + psw->fHasApplication = TRUE; + } + + // get the SSL certificates + hr = ScaSslCertificateRead(psw->wzKey, hSslCertQuery, &(psw->pswscList)); + ExitOnFailure(hr, "Failed to get SSL Certificates."); + + // get the custom headers + if (*ppshhList) + { + hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); + ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); + } + + // get the errors + if (*ppsweList) + { + hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); + ExitOnFailure(hr, "Failed to get Custom Errors"); + } + + // get the log information for this web + hr = WcaGetRecordString(hRec, wqLog, &pwzData); + ExitOnFailure(hr, "Failed to get log identifier for Web"); + if (*pwzData) + { + hr = ScaGetWebLog7(pwzData, hWebLogQuery, &psw->swl); + ExitOnFailure(hr, "Failed to get Log for Web."); + psw->fHasLog = TRUE; + } + + *ppswList = AddWebToList7(*ppswList, psw); + psw = NULL; // set the web NULL so it doesn't accidentally get freed below + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + +LExit: + // if anything was left over after an error clean it all up + WcaFinishUnwrapQuery(hQueryWebSite); + WcaFinishUnwrapQuery(hQueryWebAddress); + + ScaWebsFreeList7(psw); + + ReleaseStr(pwzData); + WcaLog(LOGMSG_VERBOSE, "Exiting ScaWebsRead7()"); + + return hr; +} + +BOOL CompareBinding( + __in IAppHostElement* pBinding, + __in LPVOID pContext + ) +{ + BOOL fFound = FALSE; + HRESULT hr = S_OK; + LPWSTR pwzBindingInfo = NULL; + SCA_WEB7* psw = (SCA_WEB7*)pContext; + + hr = Iis7GetPropertyString(pBinding, IIS_CONFIG_BINDINGINFO, &pwzBindingInfo); + ExitOnFailure(hr, "Failed to get bindinginfo for binding element"); + + LPWSTR pwzExists = pwzBindingInfo; + // Break down the address into its constituent parts (IP:Port:Header). + // Taken from IIS6 CA code for compatibility + while (S_OK == hr && *pwzExists) + { + LPCWSTR pwzIPExists = pwzExists; + pwzExists = const_cast(wcsstr(pwzIPExists, L":")); + if (NULL == pwzExists) + { + ExitFunction(); + } + *pwzExists = L'\0'; + + LPCWSTR pwzPortExists = pwzExists + 1; + pwzExists = const_cast(wcsstr(pwzPortExists, L":")); + if (NULL == pwzExists) + { + ExitFunction(); + } + *pwzExists = L'\0'; + int iPortExists = wcstol(pwzPortExists, NULL, 10); + + LPCWSTR pwzHeaderExists = pwzExists + 1; + + BOOL fIpMatches = (0 == lstrcmpW(psw->swaBinding.wzIP, pwzIPExists)); // Explicit IP match + fIpMatches |= (0 == lstrcmpW(psw->swaBinding.wzIP, L"*")); // Authored * matches any IP + fIpMatches |= ('\0' != psw->swaBinding.wzIP) && // Unauthored IP + (0 == lstrcmpW(pwzIPExists, L"*")); // matches the All Unassigned IP : '*' + + // compare the passed in address with the address listed for this web + if (fIpMatches && psw->swaBinding.iPort == iPortExists && + 0 == lstrcmpW(psw->swaBinding.wzHeader, pwzHeaderExists)) + { + fFound = TRUE; + break; + } + + // move to the next block of data, this may move beyond the available + // data and exit the while loop above. + pwzExists = const_cast(pwzHeaderExists + lstrlenW(pwzHeaderExists)); + } + +LExit: + WcaLog(LOGMSG_VERBOSE, "Site with binding %ls %s a match", pwzBindingInfo, fFound ? "is" : "is not"); + ReleaseNullStr(pwzBindingInfo); + return fFound; +} + +BOOL EnumSiteCompareBinding( + __in IAppHostElement* pSite, + __in LPVOID pContext + ) +{ + BOOL fFound = FALSE; + HRESULT hr = S_OK; + SCA_WEB7* psw = (SCA_WEB7*)pContext; + IAppHostChildElementCollection *pSiteChildren = NULL; + IAppHostElement *pBindings = NULL; + IAppHostElementCollection *pBindingsCollection = NULL; + IAppHostElement *pBinding = NULL; + VARIANT vtProp; + VariantInit(&vtProp); + + hr = pSite->get_ChildElements(&pSiteChildren); + ExitOnFailure(hr, "Failed get site child elements collection"); + + vtProp.vt = VT_BSTR; + vtProp.bstrVal = ::SysAllocString(IIS_CONFIG_BINDINGS); + hr = pSiteChildren->get_Item(vtProp, &pBindings); + ExitOnFailure(hr, "Failed get bindings element"); + + hr = pBindings->get_Collection(&pBindingsCollection); + ExitOnFailure(hr, "Failed get bindings collection"); + + WcaLog(LOGMSG_VERBOSE, "Searching for site with binding %ls:%d:%ls", psw->swaBinding.wzIP, psw->swaBinding.iPort, psw->swaBinding.wzHeader); + + hr = Iis7EnumAppHostElements(pBindingsCollection, CompareBinding, psw, &pBinding, NULL); + ExitOnFailure(hr, "Failed search bindings collection"); + + fFound = NULL != pBinding; +LExit: + VariantClear(&vtProp); + ReleaseNullObject(pSiteChildren); + ReleaseNullObject(pBindings); + ReleaseNullObject(pBindingsCollection); + ReleaseNullObject(pBinding); + return fFound; +} + +HRESULT ScaWebSearch7( + __in SCA_WEB7* psw, + __deref_out_z_opt LPWSTR* pswWeb, + __out_opt BOOL* pfFound + ) +{ + HRESULT hr = S_OK; + BOOL fInitializedCom = FALSE; + BSTR bstrSites = NULL; + BSTR bstrAppHostRoot = NULL; + IAppHostAdminManager *pAdminMgr = NULL; + IAppHostElement *pSites = NULL; + IAppHostElementCollection *pCollection = NULL; + IAppHostElement *pSite = NULL; + + if (NULL != pswWeb) + { + ReleaseNullStr(*pswWeb); + } + + if (NULL != pfFound) + { + *pfFound = FALSE; + } + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "Failed to initialize COM"); + fInitializedCom = TRUE; + + hr = CoCreateInstance(__uuidof(AppHostAdminManager), NULL, CLSCTX_INPROC_SERVER, __uuidof(IAppHostAdminManager), reinterpret_cast (&pAdminMgr)); + if (REGDB_E_CLASSNOTREG == hr) + { + WcaLog(LOGMSG_VERBOSE, "AppHostAdminManager was not registered, cannot find site."); + hr = S_OK; + ExitFunction(); + } + ExitOnFailure(hr, "Failed to CoCreate IAppHostAdminManager"); + + bstrSites = ::SysAllocString(IIS_CONFIG_SITES_SECTION); + ExitOnNull(bstrSites, hr, E_OUTOFMEMORY, "Failed to allocate sites string."); + + bstrAppHostRoot = ::SysAllocString(IIS_CONFIG_APPHOST_ROOT); + ExitOnNull(bstrAppHostRoot, hr, E_OUTOFMEMORY, "Failed to allocate host root string."); + + hr = pAdminMgr->GetAdminSection(bstrSites, bstrAppHostRoot, &pSites); + ExitOnFailure(hr, "Failed get sites section"); + ExitOnNull(pSites, hr, ERROR_FILE_NOT_FOUND, "Failed get sites section object"); + + hr = pSites->get_Collection(&pCollection); + ExitOnFailure(hr, "Failed get sites collection"); + + // not explicitly doing a Description search + if (-1 != psw->iSiteId) + { + if (MSI_NULL_INTEGER == psw->iSiteId) + { + // Enumerate sites & determine if the binding matches + hr = Iis7EnumAppHostElements(pCollection, EnumSiteCompareBinding, psw, &pSite, NULL); + ExitOnFailure(hr, "Failed locate site by ID"); + } + else + { + // Find a site with ID matches + hr = Iis7FindAppHostElementInteger(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_ID, psw->iSiteId, &pSite, NULL); + ExitOnFailure(hr, "Failed locate site by ID"); + } + } + + if (NULL == pSite) + { + // Find a site with Name that matches + hr = Iis7FindAppHostElementString(pCollection, IIS_CONFIG_SITE, IIS_CONFIG_NAME, psw->wzDescription, &pSite, NULL); + ExitOnFailure(hr, "Failed locate site by ID"); + } + + if (NULL != pSite) + { + if (NULL != pfFound) + { + *pfFound = TRUE; + } + + if (NULL != pswWeb) + { + // We found a site, return its description + hr = Iis7GetPropertyString(pSite, IIS_CONFIG_NAME, pswWeb); + ExitOnFailure(hr, "Failed get site name"); + } + } +LExit: + ReleaseNullObject(pAdminMgr); + ReleaseNullObject(pSites); + ReleaseNullObject(pCollection); + ReleaseNullObject(pSite); + ReleaseBSTR(bstrAppHostRoot); + ReleaseBSTR(bstrSites); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + return hr; +} + + +HRESULT ScaWebsGetBase7( + __in SCA_WEB7* pswList, + __in LPCWSTR pswWebKey, + __out_ecount(cchDest) LPWSTR pswWeb, + __in DWORD_PTR cchDest + ) +{ + HRESULT hr = S_OK; + BOOL fFound = FALSE; + SCA_WEB7* psw = pswList; + LPWSTR wzSiteName = NULL; + + *pswWeb = '/0'; + + //looking for psw->wzKey == pswWebKey + while(psw) + { + if (0 == wcscmp(pswWebKey, psw->wzKey)) + { + fFound = TRUE; + break; + } + psw = psw->pswNext; + } + + if (!fFound) + { + ExitFunction1(hr = S_FALSE); + } + + // Search if we're not installing the site + if (!psw->fHasComponent || (psw->iAttributes & SWATTRIB_NOCONFIGUREIFEXISTS)) + { + // We are not installing this website. Search for it in IIS config + hr = ScaWebSearch7(psw, &wzSiteName, NULL); + ExitOnFailure(hr, "Failed to search for Website"); + + if (NULL != wzSiteName) + { + hr = ::StringCchCopyW(pswWeb, cchDest, wzSiteName); + ExitOnFailure(hr, "Failed to set Website description for located Website"); + } + } + + if ('/0' == *pswWeb) + { + WcaLog(LOGMSG_VERBOSE, "Could not find Web: %ls, defaulting to %ls", psw->wzKey, psw->wzDescription); + // Default to the provided description, the Exec CA will locate by description + hr = ::StringCchCopyW(pswWeb, cchDest, psw->wzDescription); + ExitOnFailure(hr, "Failed to set Website description to default"); + } +LExit: + ReleaseNullStr(wzSiteName); + return hr; +} + +HRESULT ScaWebsInstall7( + __in SCA_WEB7* pswList, + __in SCA_APPPOOL * psapList + ) +{ + HRESULT hr = S_OK; + SCA_WEB7* psw = pswList; + + while (psw) + { + // if we are installing the web site + if (psw->fHasComponent && WcaIsInstalling(psw->isInstalled, psw->isAction)) + { + hr = ScaWebWrite7(psw, psapList); + ExitOnFailure(hr, "failed to write web '%ls' to metabase", psw->wzKey); + } + + psw = psw->pswNext; + } + +LExit: + return hr; +} + + +HRESULT ScaWebsUninstall7( + __in SCA_WEB7* pswList + ) +{ + HRESULT hr = S_OK; + SCA_WEB7* psw = pswList; + + while (psw) + { + if (psw->fHasComponent && WcaIsUninstalling(psw->isInstalled, psw->isAction)) + { + // If someone + hr = ScaWebRemove7(psw); + ExitOnFailure(hr, "Failed to remove web '%ls' ", psw->wzKey); + } + + psw = psw->pswNext; + } + +LExit: + return hr; +} + + +void ScaWebsFreeList7(__in SCA_WEB7* pswList) +{ + SCA_WEB7* pswDelete = pswList; + while (pswList) + { + pswDelete = pswList; + pswList = pswList->pswNext; + + // Free the SSL, headers and errors list first + ScaSslCertificateFreeList(pswDelete->pswscList); + ScaHttpHeaderFreeList(pswDelete->pshhList); + ScaWebErrorFreeList(pswDelete->psweList); + + MemFree(pswDelete); + } +} + + +// private helper functions + +static SCA_WEB7* NewWeb7() +{ + SCA_WEB7* psw = (SCA_WEB7*)MemAlloc(sizeof(SCA_WEB7), TRUE); + Assert(psw); + return psw; +} + + +static SCA_WEB7* AddWebToList7( + __in SCA_WEB7* pswList, + __in SCA_WEB7* psw + ) +{ + if (pswList) + { + SCA_WEB7* pswTemp = pswList; + while (pswTemp->pswNext) + { + pswTemp = pswTemp->pswNext; + } + + pswTemp->pswNext = psw; + } + else + { + pswList = psw; + } + + return pswList; +} + + +static HRESULT ScaWebFindBase7( + __in SCA_WEB7* pswList, + __in_z LPCWSTR wzDescription + ) +{ + HRESULT hr = S_OK; + BOOL fFound = FALSE; + + // try to find the web in memory first + for (SCA_WEB7* psw = pswList; psw; psw = psw->pswNext) + { + if (0 == wcscmp(wzDescription, psw->wzDescription)) + { + fFound = TRUE; + break; + } + } + + if (!fFound) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + } + + return hr; +} + + +static HRESULT ScaWebWrite7( + __in SCA_WEB7* psw, + __in SCA_APPPOOL * psapList + ) +{ + HRESULT hr = S_OK; + + BOOL fExists = FALSE; + UINT ui = 0; + WCHAR wzIP[64]; + WCHAR wzBinding[1024]; + WCHAR wzAppPoolName[MAX_PATH]; + + // + // determine if site must be new + // + if (psw->iAttributes & SWATTRIB_NOCONFIGUREIFEXISTS) + { + // Check if site already exists. + hr = ScaWebSearch7(psw, NULL, &fExists); + ExitOnFailure(hr, "Failed to search for web: %ls", psw->wzKey); + + if (fExists) + { + hr = S_FALSE; + WcaLog(LOGMSG_VERBOSE, "Skipping configuration of existing web: %ls", psw->wzKey); + ExitFunction(); + } + } + + //create a site + hr = ScaWriteConfigID(IIS_SITE); + ExitOnFailure(hr, "Failed write site ID"); + + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed write site ID create action"); + + //Site Name + hr = ScaWriteConfigString(psw->wzDescription); //Site Name + ExitOnFailure(hr, "Failed write site desc"); + + //Site Id -- value is MSI_NULL_INTEGER if not set in WIX + hr = ScaWriteConfigInteger(psw->iSiteId); //SiteID + ExitOnFailure(hr, "Failed write site id value"); + + //Site Auto Start -- value is MSI_NULL_INTEGER if not set in WIX + hr = ScaWriteConfigInteger(psw->iState); // serverAutoStart + ExitOnFailure(hr, "Failed write site autostart"); + + hr = ScaWriteConfigInteger(psw->iConnectionTimeout); //limits/connectionTimeout + ExitOnFailure(hr, "Failed write site timeout"); + + //create default application + hr = ScaWriteConfigID(IIS_APPLICATION); + ExitOnFailure(hr, "Failed write app ID"); + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed write app action ID"); + hr = ScaWriteConfigString(psw->wzDescription); //site name key + ExitOnFailure(hr, "Failed write app desc"); + hr = ScaWriteConfigString(L"/"); // App Path (default) + ExitOnFailure(hr, "Failed write app def path /"); + + if (psw->fHasApplication && *psw->swapp.wzAppPool) + { + hr = ScaFindAppPool7(psw->swapp.wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); + ExitOnFailure(hr, "Failed to read app pool from application"); + + hr = ScaWriteConfigString(wzAppPoolName); + ExitOnFailure(hr, "Failed write app appPool"); + } + else + { + hr = ScaWriteConfigString(L""); + ExitOnFailure(hr, "Failed write app appPool"); + } + + //create vdir for default application + hr = ScaWriteConfigID(IIS_VDIR); + ExitOnFailure(hr, "Failed write vdir ID"); + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed write vdir action"); + hr = ScaWriteConfigString(psw->wzDescription); //site name key + ExitOnFailure(hr, "Failed write vdir desc"); + hr = ScaWriteConfigString(L"/"); //vdir path (default) + ExitOnFailure(hr, "Failed write vdir app"); + hr = ScaWriteConfigString(psw->wzDirectory); //physical dir + ExitOnFailure(hr, "Failed write vdir dir"); + + //create bindings for site + hr = ScaWriteConfigID(IIS_BINDING); + ExitOnFailure(hr, "Failed write binding ID"); + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed write binding action ID"); + hr = ScaWriteConfigString(psw->wzDescription); //site name key + ExitOnFailure(hr, "Failed write binding site key"); + + if (psw->swaBinding.fSecure) + { + hr = ScaWriteConfigString(L"https"); // binding protocol + ExitOnFailure(hr, "Failed write binding https"); + } + else + { + hr = ScaWriteConfigString(L"http"); // binding protocol + ExitOnFailure(hr, "Failed write binding http"); + } + + // set the IP address appropriately + if (0 == wcscmp(psw->swaBinding.wzIP, L"")) + { + hr = ::StringCchCopyW(wzIP, countof(wzIP), L"*"); // if no IP specified = add * + } + else + { +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaBinding.wzIP); // else leave untouched + } + ExitOnFailure(hr, "Failed to copy IP string"); + + hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaBinding.iPort, psw->swaBinding.wzHeader); + ExitOnFailure(hr, "Failed to format IP:Port:Header binding string"); + + // write bindings CAData + hr = ScaWriteConfigString(wzBinding) ; //binding info + ExitOnFailure(hr, "Failed to create web bindings"); + + for (ui = 0; (ui < MAX_ADDRESSES_PER_WEB) && (ui < psw->cExtraAddresses); ++ui) + { + // set the IP address appropriately + if (0 == wcscmp(psw->swaExtraAddresses[ui].wzIP, L"")) + { + hr = ::StringCchCopyW(wzIP, countof(wzIP), L"*"); // if no IP specified = add * + } + else + { +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ::StringCchCopyW(wzIP, countof(wzIP), psw->swaExtraAddresses[ui].wzIP); //else leave untouched + } + ExitOnFailure(hr, "Failed to copy web IP string"); + + hr = ::StringCchPrintfW(wzBinding, countof(wzBinding), L"%s:%d:%s", wzIP, psw->swaExtraAddresses[ui].iPort, psw->swaExtraAddresses[ui].wzHeader); + ExitOnFailure(hr, "Failed to copy web IP"); + + //create bindings for site + hr = ScaWriteConfigID(IIS_BINDING); + ExitOnFailure(hr, "Failed write binding ID"); + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed write binding action"); + hr = ScaWriteConfigString(psw->wzDescription); //site name key + ExitOnFailure(hr, "Failed write binding web name"); + + if (psw->swaExtraAddresses[ui].fSecure) + { + hr = ScaWriteConfigString(L"https"); // binding protocol + } + else + { + hr = ScaWriteConfigString(L"http"); // binding protocol + } + ExitOnFailure(hr, "Failed write binding http(s)"); + + // write bindings CAData + hr = ScaWriteConfigString(wzBinding) ; //binding info + ExitOnFailure(hr, "Failed write binding info"); + } + + // write the web dirproperties information + if (psw->fHasProperties) + { + // dir properties are for the default application of the web + // with location '/' + hr = ScaWriteWebDirProperties7(psw->wzDescription, L"/", &psw->swp); + ExitOnFailure(hr, "Failed to write web security information to metabase"); + } + + //// write the application information + if (psw->fHasApplication) + { + hr = ScaWriteWebApplication7(psw->wzDescription, L"/", &psw->swapp, psapList); + ExitOnFailure(hr, "Failed to write web application information to metabase"); + } + + // write the SSL certificate information + if (psw->pswscList) + { + hr = ScaSslCertificateWrite7(psw->wzDescription, psw->pswscList); + ExitOnFailure(hr, "Failed to write SSL certificates for Web site: %ls", psw->wzKey); + } + + // write the headers + if (psw->pshhList) + { + hr = ScaWriteHttpHeader7(psw->wzDescription, L"/", psw->pshhList); + ExitOnFailure(hr, "Failed to write custom HTTP headers for Web site: %ls", psw->wzKey); + } + + // write the errors + if (psw->psweList) + { + hr = ScaWriteWebError7(psw->wzDescription, L"/", psw->psweList); + ExitOnFailure(hr, "Failed to write custom web errors for Web site: %ls", psw->wzKey); + } + + // write the log information to the metabase + if (psw->fHasLog) + { + hr = ScaWriteWebLog7(psw->wzDescription, &psw->swl); + ExitOnFailure(hr, "Failed to write web log information to metabase"); + } + +LExit: + return hr; +} + + +static HRESULT ScaWebRemove7( + __in const SCA_WEB7* psw + ) +{ + HRESULT hr = S_OK; + + hr = ScaWriteConfigID(IIS_SITE); + ExitOnFailure(hr, "Failed write site ID"); + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "Failed write site action"); + hr = ScaWriteConfigString(psw->wzDescription); //Site Name + ExitOnFailure(hr, "Failed write site name"); + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scaweb7.h b/src/ext/Iis/ca/scaweb7.h new file mode 100644 index 00000000..78946756 --- /dev/null +++ b/src/ext/Iis/ca/scaweb7.h @@ -0,0 +1,97 @@ +#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 "scawebapp.h" +#include "scawebprop.h" +#include "scahttpheader.h" +#include "scaweberr.h" +#include "scassl.h" +#include "scaapppool.h" +#include "scaweblog.h" + +// globals +#define MAX_ADDRESSES_PER_WEB 10 + +// structs +struct SCA_WEB7 +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + BOOL fHasComponent; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + int iSiteId; + + // metabase information + WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; + BOOL fBaseExists; + + // iis configuation information + SCA_WEB_ADDRESS swaBinding; + + SCA_WEB_ADDRESS swaExtraAddresses[MAX_ADDRESSES_PER_WEB + 1]; + DWORD cExtraAddresses; + + WCHAR wzDirectory[MAX_PATH]; + WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; + + int iState; + int iAttributes; + + BOOL fHasProperties; + SCA_WEB_PROPERTIES swp; + + BOOL fHasApplication; + SCA_WEB_APPLICATION swapp; + + BOOL fHasSecurity; + int dwAccessPermissions; + int iConnectionTimeout; + + SCA_WEB_SSL_CERTIFICATE* pswscList; + SCA_HTTP_HEADER* pshhList; + SCA_WEB_ERROR* psweList; + + BOOL fHasLog; + SCA_WEB_LOG swl; + + SCA_WEB7* pswNext; +}; + + +// prototypes +HRESULT ScaWebsRead7( + __in SCA_WEB7** ppswList, + __in SCA_HTTP_HEADER** ppshhList, + __in SCA_WEB_ERROR** ppsweList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hSslCertQuery, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData + ); + +HRESULT ScaWebsGetBase7( + __in SCA_WEB7* pswList, + __in LPCWSTR pswWebKey, + __out_ecount(cchDest) LPWSTR pswWeb, + __in DWORD_PTR cchDest + ); + +HRESULT ScaWebsInstall7( + __in SCA_WEB7* pswList, + __in SCA_APPPOOL * psapList + ); + +HRESULT ScaWebsUninstall7( + __in SCA_WEB7* pswList + ); + +void ScaWebsFreeList7( + __in SCA_WEB7* pswHead + ); diff --git a/src/ext/Iis/ca/scawebapp.cpp b/src/ext/Iis/ca/scawebapp.cpp new file mode 100644 index 00000000..a7e9cf82 --- /dev/null +++ b/src/ext/Iis/ca/scawebapp.cpp @@ -0,0 +1,194 @@ +// 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 +enum eWebApplicationQuery { wappqName = 1, wappqIsolation, wappqAllowSession, + wappqSessionTimeout, wappqBuffer, wappqParentPaths, + wappqDefaultScript, wappqScriptTimeout, + wappqServerDebugging, wappqClientDebugging, wappqAppPool, wappqApplication}; + + +HRESULT ScaGetWebApplication(MSIHANDLE /*hViewApplications*/, + LPCWSTR pwzApplication, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + SCA_WEB_APPLICATION* pswapp) +{ + HRESULT hr = S_OK; + + MSIHANDLE hRec; + LPWSTR pwzData = NULL; + + // Reset back to the first record + WcaFetchWrappedReset(hWebAppQuery); + + // get the application information + hr = WcaFetchWrappedRecordWhereString(hWebAppQuery, wappqApplication, pwzApplication, &hRec); + if (S_OK == hr) + { + // application name + hr = WcaGetRecordString(hRec, wappqName, &pwzData); + ExitOnFailure(hr, "Failed to get Name of App"); + hr = ::StringCchCopyW(pswapp->wzName, countof(pswapp->wzName), pwzData); + if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) + { + // The application name is sometimes truncated to IIS's supported length, so ignore insufficient buffer errors here + WcaLog(LOGMSG_VERBOSE, "Application name \"%ls\" truncated to fit IIS's supported %d-character length", pwzData, MAX_APP_NAME); + hr = S_OK; + } + ExitOnFailure(hr, "Failed to copy name string to webapp object"); + + hr = WcaGetRecordInteger(hRec, wappqIsolation, &pswapp->iIsolation); + ExitOnFailure(hr, "Failed to get App isolation: '%ls'", pswapp->wzName); + + hr = WcaGetRecordInteger(hRec, wappqAllowSession, &pswapp->fAllowSessionState); + + hr = WcaGetRecordInteger(hRec, wappqSessionTimeout, &pswapp->iSessionTimeout); + + hr = WcaGetRecordInteger(hRec, wappqBuffer, &pswapp->fBuffer); + + hr = WcaGetRecordInteger(hRec, wappqParentPaths, &pswapp->fParentPaths); + + hr = WcaGetRecordString(hRec, wappqDefaultScript, &pwzData); + ExitOnFailure(hr, "Failed to get default scripting language for App: '%ls'", pswapp->wzName); + hr = ::StringCchCopyW(pswapp->wzDefaultScript, countof(pswapp->wzDefaultScript), pwzData); + ExitOnFailure(hr, "Failed to copy default script string to webapp object"); + + // asp script timeout + hr = WcaGetRecordInteger(hRec, wappqScriptTimeout, &pswapp->iScriptTimeout); + ExitOnFailure(hr, "Failed to get scripting timeout for App: '%ls'", pswapp->wzName); + + // asp server-side script debugging + hr = WcaGetRecordInteger(hRec, wappqServerDebugging, &pswapp->fServerDebugging); + + // asp client-side script debugging + hr = WcaGetRecordInteger(hRec, wappqClientDebugging, &pswapp->fClientDebugging); + + hr = WcaGetRecordString(hRec, wappqAppPool, &pwzData); + ExitOnFailure(hr, "Failed to get AppPool for App: '%ls'", pswapp->wzName); + hr = ::StringCchCopyW(pswapp->wzAppPool, countof(pswapp->wzAppPool), pwzData); + ExitOnFailure(hr, "failed to copy AppPool: '%ls' for App: '%ls'", pwzData, pswapp->wzName); + + // app extensions + hr = ScaWebAppExtensionsRead(pwzApplication, hWebAppExtQuery, &pswapp->pswappextList); + ExitOnFailure(hr, "Failed to read AppExtensions for App: '%ls'", pswapp->wzName); + + hr = S_OK; + } + else if (E_NOMOREITEMS == hr) + { + WcaLog(LOGMSG_STANDARD, "Error: Cannot locate IIsWebApplication.Application='%ls'", pwzApplication); + hr = E_FAIL; + } + else + ExitOnFailure(hr, "Error matching Application rows"); + + // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would + HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebAppQuery, wappqApplication, pwzApplication, &hRec); + if (SUCCEEDED(hrTemp)) + { + AssertSz(E_NOMOREITEMS == hrTemp, "ScaGetWebApplication found more than one record"); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaWriteWebApplication(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, + SCA_WEB_APPLICATION* pswapp, SCA_APPPOOL * psapList) +{ + HRESULT hr = S_OK; + WCHAR wzAppPoolName[MAX_PATH]; + + hr = ScaCreateApp(piMetabase, wzRootOfWeb, pswapp->iIsolation); + ExitOnFailure(hr, "Failed to create ASP App"); + + // Medium Isolation seems to have to be set through the metabase + if (2 == pswapp->iIsolation) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_ISOLATED, METADATA_INHERIT, IIS_MD_UT_WAM, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iIsolation)); + ExitOnFailure(hr, "Failed to write isolation value for App: '%ls'", pswapp->wzName); + } + + // application name + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_FRIENDLY_NAME, METADATA_INHERIT, IIS_MD_UT_WAM, STRING_METADATA, pswapp->wzName); + ExitOnFailure(hr, "Failed to write Name of App: '%ls'", pswapp->wzName); + + // allow session state + if (MSI_NULL_INTEGER != pswapp->fAllowSessionState) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ALLOWSESSIONSTATE, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fAllowSessionState)); + ExitOnFailure(hr, "Failed to write allow session information for App: '%ls'", pswapp->wzName); + } + + // session timeout + if (MSI_NULL_INTEGER != pswapp->iSessionTimeout) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SESSIONTIMEOUT, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iSessionTimeout)); + ExitOnFailure(hr, "Failed to write session timeout for App: '%ls'", pswapp->wzName); + } + + // asp buffering + if (MSI_NULL_INTEGER != pswapp->fBuffer) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_BUFFERINGON, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fBuffer)); + ExitOnFailure(hr, "Failed to write buffering flag for App: '%ls'", pswapp->wzName); + } + + // asp parent paths + if (MSI_NULL_INTEGER != pswapp->fParentPaths) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLEPARENTPATHS, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fParentPaths)); + ExitOnFailure(hr, "Failed to write parent paths flag for App: '%ls'", pswapp->wzName); + } + + // default scripting language + if (*pswapp->wzDefaultScript) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTLANGUAGE, METADATA_INHERIT, ASP_MD_UT_APP, STRING_METADATA, pswapp->wzDefaultScript); + ExitOnFailure(hr, "Failed to write default scripting language for App: '%ls'", pswapp->wzName); + } + + // asp script timeout + if (MSI_NULL_INTEGER != pswapp->iScriptTimeout) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTTIMEOUT, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iScriptTimeout)); + ExitOnFailure(hr, "Failed to write script timeout for App: '%ls'", pswapp->wzName); + } + + // asp server-side script debugging + if (MSI_NULL_INTEGER != pswapp->fServerDebugging) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLESERVERDEBUG, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fServerDebugging)); + ExitOnFailure(hr, "Failed to write ASP server-side script debugging flag for App: '%ls'", pswapp->wzName); + } + + // asp server-side script debugging + if (MSI_NULL_INTEGER != pswapp->fClientDebugging) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLECLIENTDEBUG, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fClientDebugging)); + ExitOnFailure(hr, "Failed to write ASP client-side script debugging flag for App: '%ls'", pswapp->wzName); + } + + // AppPool + if (*pswapp->wzAppPool && NULL != psapList) + { + hr = ScaFindAppPool(piMetabase, pswapp->wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); + ExitOnFailure(hr, "failed to find app pool: %ls", pswapp->wzAppPool); + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_APPPOOL_ID, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, wzAppPoolName); + ExitOnFailure(hr, "Failed to write default AppPool for App: '%ls'", pswapp->wzName); + } + + if (pswapp->pswappextList) + { + hr = ScaWebAppExtensionsWrite(piMetabase, wzRootOfWeb, pswapp->pswappextList); + ExitOnFailure(hr, "Failed to write AppExtensions for App: '%ls'", pswapp->wzName); + } + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebapp.h b/src/ext/Iis/ca/scawebapp.h new file mode 100644 index 00000000..a4152116 --- /dev/null +++ b/src/ext/Iis/ca/scawebapp.h @@ -0,0 +1,42 @@ +#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 "scaapppool.h" +#include "scawebappext.h" + +// global sql queries provided for optimization +extern LPCWSTR vcsWebApplicationQuery; +const int MAX_APP_NAME = 255; + +// structs +struct SCA_WEB_APPLICATION +{ + WCHAR wzName[MAX_APP_NAME + 1]; + + int iIsolation; + BOOL fAllowSessionState; + int iSessionTimeout; + BOOL fBuffer; + BOOL fParentPaths; + + WCHAR wzDefaultScript[MAX_DARWIN_COLUMN + 1]; + int iScriptTimeout; + BOOL fServerDebugging; + BOOL fClientDebugging; + WCHAR wzAppPool[MAX_DARWIN_COLUMN + 1]; + + SCA_WEB_APPLICATION_EXTENSION* pswappextList; +}; + + +// prototypes +HRESULT ScaGetWebApplication(MSIHANDLE hViewApplications, + LPCWSTR pwzApplication, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + SCA_WEB_APPLICATION* pswapp); + +HRESULT ScaWriteWebApplication(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, + SCA_WEB_APPLICATION* pswapp, SCA_APPPOOL * psapList); + diff --git a/src/ext/Iis/ca/scawebapp7.cpp b/src/ext/Iis/ca/scawebapp7.cpp new file mode 100644 index 00000000..94e6bb18 --- /dev/null +++ b/src/ext/Iis/ca/scawebapp7.cpp @@ -0,0 +1,120 @@ +// 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" +HRESULT ScaWriteWebApplication7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + SCA_WEB_APPLICATION* pswapp, + SCA_APPPOOL * /*psapList*/ + ) +{ + HRESULT hr = S_OK; + + //all go to same web/root location tag + hr = ScaWriteConfigID(IIS_ASP_BEGIN); + ExitOnFailure(hr, "Failed to write WebApp ASP begin id"); + hr = ScaWriteConfigString(wzWebName); //site name key + ExitOnFailure(hr, "Failed to write app web key"); + hr = ScaWriteConfigString(wzRootOfWeb); //app path key + ExitOnFailure(hr, "Failed to write app web root"); + + // IIS7 Not Supported: Isolation + if (MSI_NULL_INTEGER != pswapp->iIsolation) + { + WcaLog(LOGMSG_TRACEONLY, "Not supported by IIS7: Isolation Mode, ignoring"); + } + + // allow session state + if (MSI_NULL_INTEGER != pswapp->fAllowSessionState) + { + //system.webServer/asp /session | allowSessionState + hr = ScaWriteConfigID(IIS_ASP_SESSIONSTATE); + ExitOnFailure(hr, "Failed to write WebApp ASP sessionstate id"); + hr = ScaWriteConfigInteger(pswapp->fAllowSessionState); + ExitOnFailure(hr, "Failed to write allow session information for App: '%ls'", pswapp->wzName); + } + + // session timeout + if (MSI_NULL_INTEGER != pswapp->iSessionTimeout) + { + //system.webServer/asp /session | timeout + hr = ScaWriteConfigID(IIS_ASP_SESSIONTIMEOUT); + ExitOnFailure(hr, "Failed to write WebApp ASP sessiontimepot id"); + hr = ScaWriteConfigInteger(pswapp->iSessionTimeout); + ExitOnFailure(hr, "Failed to write session timeout for App: '%ls'", pswapp->wzName); + } + + // asp buffering + if (MSI_NULL_INTEGER != pswapp->fBuffer) + { + //system.webServer/asp | bufferingOn + hr = ScaWriteConfigID(IIS_ASP_BUFFER); + ExitOnFailure(hr, "Failed to write WebApp ASP buffer id"); + hr = ScaWriteConfigInteger(pswapp->fBuffer); + ExitOnFailure(hr, "Failed to write buffering flag for App: '%ls'", pswapp->wzName); + } + + // asp parent paths + if (MSI_NULL_INTEGER != pswapp->fParentPaths) + { + //system.webServer/asp | enableParentPaths + hr = ScaWriteConfigID(IIS_ASP_PARENTPATHS); + ExitOnFailure(hr, "Failed to write WebApp ASP parentpaths id"); + hr = ScaWriteConfigInteger(pswapp->fParentPaths); + ExitOnFailure(hr, "Failed to write parent paths flag for App: '%ls'", pswapp->wzName); + } + + // default scripting language + if (*pswapp->wzDefaultScript) + { + //system.webServer/asp | scriptLanguage + hr = ScaWriteConfigID(IIS_ASP_SCRIPTLANG); + ExitOnFailure(hr, "Failed to write WebApp ASP script lang id"); + hr = ScaWriteConfigString(pswapp->wzDefaultScript); + ExitOnFailure(hr, "Failed to write default scripting language for App: '%ls'", pswapp->wzName); + } + + // asp script timeout + if (MSI_NULL_INTEGER != pswapp->iScriptTimeout) + { + //system.webServer/asp /limits | scriptTimeout + hr = ScaWriteConfigID(IIS_ASP_SCRIPTTIMEOUT); + ExitOnFailure(hr, "Failed to write WebApp ASP script timeout id"); + hr = ScaWriteConfigInteger(pswapp->iScriptTimeout); + ExitOnFailure(hr, "Failed to write script timeout for App: '%ls'", pswapp->wzName); + } + + // asp server-side script debugging + if (MSI_NULL_INTEGER != pswapp->fServerDebugging) + { + //system.webServer/asp | appAllowDebugging + hr = ScaWriteConfigID(IIS_ASP_SCRIPTSERVERDEBUG); + ExitOnFailure(hr, "Failed to write WebApp ASP script debug id"); + hr = ScaWriteConfigInteger(pswapp->fServerDebugging); + ExitOnFailure(hr, "Failed to write ASP server-side script debugging flag for App: '%ls'", pswapp->wzName); + } + + // asp client-side script debugging + if (MSI_NULL_INTEGER != pswapp->fClientDebugging) + { + //system.webServer/asp | appAllowClientDebug + hr = ScaWriteConfigID(IIS_ASP_SCRIPTCLIENTDEBUG); + ExitOnFailure(hr, "Failed to write WebApp ASP script debug id"); + hr = ScaWriteConfigInteger(pswapp->fClientDebugging); + ExitOnFailure(hr, "Failed to write ASP client-side script debugging flag for App: '%ls'", pswapp->wzName); + } + + //done with ASP application properties + hr = ScaWriteConfigID(IIS_ASP_END); + ExitOnFailure(hr, "Failed to write WebApp ASP begin id"); + + //write out app estensions + if (pswapp->pswappextList) + { + hr = ScaWebAppExtensionsWrite7(wzWebName, wzRootOfWeb, pswapp->pswappextList); + ExitOnFailure(hr, "Failed to write AppExtensions for App: '%ls'", pswapp->wzName); + } + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebapp7.h b/src/ext/Iis/ca/scawebapp7.h new file mode 100644 index 00000000..e1d87f53 --- /dev/null +++ b/src/ext/Iis/ca/scawebapp7.h @@ -0,0 +1,10 @@ +#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 ScaWriteWebApplication7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + SCA_WEB_APPLICATION* pswapp, + SCA_APPPOOL * psapList + ); diff --git a/src/ext/Iis/ca/scawebappext.cpp b/src/ext/Iis/ca/scawebappext.cpp new file mode 100644 index 00000000..cf3b9dd3 --- /dev/null +++ b/src/ext/Iis/ca/scawebappext.cpp @@ -0,0 +1,207 @@ +// 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" + +enum eWebAppExtensionQuery { wappextqExtension = 1, wappextqVerbs, wappextqExecutable, wappextqAttributes, wappextqApplication }; + +// prototypes for private helper functions +static HRESULT NewAppExt( + __out SCA_WEB_APPLICATION_EXTENSION** ppswappext + ); +static SCA_WEB_APPLICATION_EXTENSION* AddAppExtToList( + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList, + __in SCA_WEB_APPLICATION_EXTENSION* pswappext + ); + + + +HRESULT ScaWebAppExtensionsRead( + __in LPCWSTR wzApplication, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout SCA_WEB_APPLICATION_EXTENSION** ppswappextList + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + + SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; + LPWSTR pwzData = NULL; + + // Reset back to the first record + WcaFetchWrappedReset(hWebAppExtQuery); + + // get the application extension information + while (S_OK == (hr = WcaFetchWrappedRecordWhereString(hWebAppExtQuery, wappextqApplication, wzApplication, &hRec))) + { + hr = NewAppExt(&pswappext); + ExitOnFailure(hr, "failed to create new web app extension"); + + // get the extension + hr = WcaGetRecordString(hRec, wappextqExtension, &pwzData); + ExitOnFailure(hr, "Failed to get Web Application Extension"); + hr = ::StringCchCopyW(pswappext->wzExtension, countof(pswappext->wzExtension), pwzData); + ExitOnFailure(hr, "Failed to copy extension string to webappext object"); + + // application extension verbs + hr = WcaGetRecordString(hRec, wappextqVerbs, &pwzData); + ExitOnFailure(hr, "Failed to get Verbs for Application: '%ls'", wzApplication); + hr = ::StringCchCopyW(pswappext->wzVerbs, countof(pswappext->wzVerbs), pwzData); + ExitOnFailure(hr, "Failed to copy verbs string to webappext object"); + + // extension executeable + hr = WcaGetRecordString(hRec, wappextqExecutable, &pwzData); + ExitOnFailure(hr, "Failed to get Executable for Application: '%ls'", wzApplication); + hr = ::StringCchCopyW(pswappext->wzExecutable, countof(pswappext->wzExecutable), pwzData); + ExitOnFailure(hr, "Failed to copy executable string to webappext object"); + + hr = WcaGetRecordInteger(hRec, wappextqAttributes, &pswappext->iAttributes); + if (S_FALSE == hr) + { + pswappext->iAttributes = 0; + hr = S_OK; + } + ExitOnFailure(hr, "Failed to get App isolation"); + + *ppswappextList = AddAppExtToList(*ppswappextList, pswappext); + pswappext = NULL; // set the appext NULL so it doesn't accidentally get freed below + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + +LExit: + // if anything was left over after an error clean it all up + if (pswappext) + { + ScaWebAppExtensionsFreeList(pswappext); + } + + ReleaseStr(pwzData); + + return hr; +} + + + +HRESULT ScaWebAppExtensionsWrite( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzRootOfWeb, + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList + ) +{ + HRESULT hr = S_OK; + + LPWSTR wzAppExt = NULL; + DWORD cchAppExt; + WCHAR wzAppExtension[1024]; + WCHAR wzAppExtensions[65536]; + SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; + + if (!pswappextList) + { + ExitFunction(); + } + + ::ZeroMemory(wzAppExtensions, sizeof(wzAppExtensions)); + wzAppExt = wzAppExtensions; + cchAppExt = countof(wzAppExtensions); + pswappext = pswappextList; + + while (pswappext) + { + // if all (represented by "*" or blank) + if (0 == lstrcmpW(pswappext->wzExtension, L"*") || 0 == lstrlenW(pswappext->wzExtension)) + { + hr = ::StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L"*,%s,%d", pswappext->wzExecutable, pswappext->iAttributes); + ExitOnFailure(hr, "Failed to format *,executable,attributes string"); + } + else + { + hr = ::StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L".%s,%s,%d", pswappext->wzExtension, pswappext->wzExecutable, pswappext->iAttributes); + ExitOnFailure(hr, "Failed to format extension,executable,attributes string"); + } + + // if verbs were specified and not the keyword "all" + if (pswappext->wzVerbs[0] && CSTR_EQUAL != CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pswappext->wzVerbs, -1, L"all", -1)) + { + hr = ::StringCchCatW(wzAppExtension, countof(wzAppExtension), L","); + ExitOnFailure(hr, "Failed to concatenate comma to app extension string"); + hr = ::StringCchCatW(wzAppExtension, countof(wzAppExtension), pswappext->wzVerbs); + ExitOnFailure(hr, "Failed to concatenate verb to app extension string"); + } + + hr = ::StringCchCopyW(wzAppExt, cchAppExt, wzAppExtension); + ExitOnFailure(hr, "Failed to copy app extension string"); + wzAppExt += lstrlenW(wzAppExtension) + 1; + cchAppExt -= lstrlenW(wzAppExtension) + 1; + pswappext = pswappext->pswappextNext; + } + + if (*wzAppExtensions) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SCRIPT_MAPS, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzAppExtensions); + ExitOnFailure(hr, "Failed to write AppExtension: '%ls'", wzAppExtension); + } + +LExit: + return hr; +} + + +void ScaWebAppExtensionsFreeList( + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList + ) +{ + SCA_WEB_APPLICATION_EXTENSION* pswappextDelete = pswappextList; + while (pswappextList) + { + pswappextDelete = pswappextList; + pswappextList = pswappextList->pswappextNext; + + MemFree(pswappextDelete); + } +} + + + +// private helper functions + +static HRESULT NewAppExt( + __out SCA_WEB_APPLICATION_EXTENSION** ppswappext + ) +{ + HRESULT hr = S_OK; + SCA_WEB_APPLICATION_EXTENSION* pswappext = static_cast(MemAlloc(sizeof(SCA_WEB_APPLICATION_EXTENSION), TRUE)); + ExitOnNull(pswappext, hr, E_OUTOFMEMORY, "failed to allocate memory for new web app ext element"); + + *ppswappext = pswappext; + +LExit: + return hr; +} + + +static SCA_WEB_APPLICATION_EXTENSION* AddAppExtToList( + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList, + __in SCA_WEB_APPLICATION_EXTENSION* pswappext + ) +{ + if (pswappextList) + { + SCA_WEB_APPLICATION_EXTENSION* pswappextT = pswappextList; + while (pswappextT->pswappextNext) + { + pswappextT = pswappextT->pswappextNext; + } + + pswappextT->pswappextNext = pswappext; + } + else + { + pswappextList = pswappext; + } + + return pswappextList; +} diff --git a/src/ext/Iis/ca/scawebappext.h b/src/ext/Iis/ca/scawebappext.h new file mode 100644 index 00000000..71adfd00 --- /dev/null +++ b/src/ext/Iis/ca/scawebappext.h @@ -0,0 +1,32 @@ +#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 SCA_WEB_APPLICATION_EXTENSION +{ + WCHAR wzExtension[MAX_DARWIN_COLUMN + 1]; + + WCHAR wzVerbs[MAX_DARWIN_COLUMN + 1]; + WCHAR wzExecutable[MAX_DARWIN_COLUMN + 1]; + int iAttributes; + + SCA_WEB_APPLICATION_EXTENSION* pswappextNext; +}; + + +// prototypes +HRESULT ScaWebAppExtensionsRead( + __in LPCWSTR wzApplication, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout SCA_WEB_APPLICATION_EXTENSION** ppswappextList + ); + +HRESULT ScaWebAppExtensionsWrite( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzRootOfWeb, + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList + ); + +void ScaWebAppExtensionsFreeList( + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList + ); diff --git a/src/ext/Iis/ca/scawebappext7.cpp b/src/ext/Iis/ca/scawebappext7.cpp new file mode 100644 index 00000000..50d3172f --- /dev/null +++ b/src/ext/Iis/ca/scawebappext7.cpp @@ -0,0 +1,61 @@ +// 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" + +HRESULT ScaWebAppExtensionsWrite7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList + ) +{ + HRESULT hr = S_OK; + SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; + + if (!pswappextList) + { + ExitFunction1(hr = S_OK); + } + + //create the Extension for this vdir application + //all go to same web/root location tag + hr = ScaWriteConfigID(IIS_APPEXT_BEGIN); + ExitOnFailure(hr, "Failed to write webappext begin id"); + hr = ScaWriteConfigString(wzWebName); //site name key + ExitOnFailure(hr, "Failed to write app web key"); + hr = ScaWriteConfigString(wzRootOfWeb); //app path key + ExitOnFailure(hr, "Failed to write app web key"); + + pswappext = pswappextList; + + while (pswappext) + { + //create the Extension for this vdir application + hr = ScaWriteConfigID(IIS_APPEXT); + ExitOnFailure(hr, "Failed to write webappext begin id"); + + if (*pswappext->wzExtension) + { + hr = ScaWriteConfigString(pswappext->wzExtension); + } + else // blank means "*" (all) + { + hr = ScaWriteConfigString(L"*"); + } + ExitOnFailure(hr, "Failed to write extension"); + + hr = ScaWriteConfigString(pswappext->wzExecutable); + ExitOnFailure(hr, "Failed to write extension executable"); + + hr = ScaWriteConfigString(pswappext->wzVerbs); + ExitOnFailure(hr, "Failed to write extension verbs"); + + pswappext = pswappext->pswappextNext; + } + + hr = ScaWriteConfigID(IIS_APPEXT_END); + ExitOnFailure(hr, "Failed to write webappext begin id"); + +LExit: + return hr; +} + diff --git a/src/ext/Iis/ca/scawebappext7.h b/src/ext/Iis/ca/scawebappext7.h new file mode 100644 index 00000000..55c8b5fc --- /dev/null +++ b/src/ext/Iis/ca/scawebappext7.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 ScaWebAppExtensionsWrite7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + __in SCA_WEB_APPLICATION_EXTENSION* pswappextList + ); diff --git a/src/ext/Iis/ca/scawebdir.cpp b/src/ext/Iis/ca/scawebdir.cpp new file mode 100644 index 00000000..26a7b32b --- /dev/null +++ b/src/ext/Iis/ca/scawebdir.cpp @@ -0,0 +1,241 @@ +// 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 +enum eWebDirQuery { wdqWeb = 1, wdqWebDir, wdqComponent , wdqPath, wdqProperties, wdqApplication, wdqInstalled, wdqAction }; + +// prototypes +static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd); + +static SCA_WEBDIR* NewWebDir(); +static void FreeWebDir(SCA_WEBDIR *pswd); + + +UINT __stdcall ScaWebDirsRead( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData, + __out SCA_WEBDIR** ppswdList + ) +{ + Assert(piMetabase && ppswdList); + + HRESULT hr = S_OK; + MSIHANDLE hRec; + + LPWSTR pwzData = NULL; + SCA_WEBDIR* pswd; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs() because IIsWebDir table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the web directories + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + pswd = NewWebDir(); + ExitOnNull(pswd, hr, E_OUTOFMEMORY, "Failed to allocate memory for web dir object in memory"); + + // get component install state + hr = WcaGetRecordString(hRec, wdqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get Component for WebDirs"); + hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData); + ExitOnFailure(hr, "Failed to copy component string to webdir object"); + + hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for webdir"); + + hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction); + ExitOnFailure(hr, "Failed to get Component action state for webdir"); + + // If this record has a component and no action is being taken for it, skip processing it entirely + if (0 < lstrlenW(pswd->wzComponent) && !WcaIsInstalling(pswd->isInstalled, pswd->isAction) + && !WcaIsUninstalling(pswd->isInstalled, pswd->isAction) && !WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) + { + FreeWebDir(pswd); + pswd = NULL; + continue; + } + + hr = WcaGetRecordString(hRec, wdqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web for WebDir"); + + hr = ScaWebsGetBase(piMetabase, pswList, pwzData, pswd->wzWebBase, countof(pswd->wzWebBase), hWebBaseQuery); + if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) + { + // If we're uninstalling, ignore any failure to find the existing web + hr = S_OK; + } + + ExitOnFailure(hr, "Failed to get base of web for WebDir"); + + hr = WcaGetRecordString(hRec, wdqPath, &pwzData); + ExitOnFailure(hr, "Failed to get Path for WebDir"); + + hr = ::StringCchPrintfW(pswd->wzWebDirRoot, countof(pswd->wzWebDirRoot), L"%s/Root/%s", pswd->wzWebBase, pwzData); + ExitOnFailure(hr, "Failed to format webdir root string"); + + // get the directory properties for this web + hr = WcaGetRecordString(hRec, wdqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get security identifier for WebDir"); + if (*pwzData) + { + hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp); + ExitOnFailure(hr, "Failed to get properties for WebDir"); + + pswd->fHasProperties = TRUE; + } + + // get the application information for this web directory + hr = WcaGetRecordString(hRec, wdqApplication, &pwzData); + ExitOnFailure(hr, "Failed to get application identifier for WebDir"); + if (*pwzData) + { + hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp); + ExitOnFailure(hr, "Failed to get application for WebDir"); + + pswd->fHasApplication = TRUE; + } + + AddWebDirToList(ppswdList, pswd); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing WebDirs"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaWebDirsInstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList, SCA_APPPOOL * psapList) +{ + HRESULT hr = S_OK; + SCA_WEBDIR* pswd = pswdList; + int i; + + while (pswd) + { + // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created + if (WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) + { + if (pswd->fHasApplication) + { + hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); + ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); + } + } + + // if we are installing the web site + if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) + { + hr = ScaCreateMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); + ExitOnFailure(hr, "Failed to create key for WebDir"); + hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebDirectory"); + ExitOnFailure(hr, "Failed to write key type for for WebDir"); + i = 0x4000003e; // 1073741886: default directory browsing rights + hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); + ExitOnFailure(hr, "Failed to set directory browsing for WebDir"); + + // get the security information for this web + if (pswd->fHasProperties) + { + ScaWriteWebDirProperties(piMetabase, pswd->wzWebDirRoot, &pswd->swp); + ExitOnFailure(hr, "Failed to write properties for WebDir"); + } + + // get the application information for this web directory + if (pswd->fHasApplication) + { + hr = ScaWriteWebApplication(piMetabase, pswd->wzWebDirRoot, &pswd->swapp, psapList); + ExitOnFailure(hr, "Failed to write application for WebDir"); + } + } + + pswd = pswd->pswdNext; + } + +LExit: + return hr; +} + + +HRESULT ScaWebDirsUninstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + SCA_WEBDIR* pswd = pswdList; + + while (pswd) + { + if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) + { + // remove the application from this web directory + if (pswd->fHasApplication) + { + hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); + ExitOnFailure(hr, "Failed to remove application for WebDir"); + } + + hr = ScaDeleteMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); + ExitOnFailure(hr, "Failed to remove WebDir '%ls' from metabase", pswd->wzKey); + } + + pswd = pswd->pswdNext; + } + +LExit: + return hr; +} + + +static SCA_WEBDIR* NewWebDir() +{ + SCA_WEBDIR* pswd = static_cast(MemAlloc(sizeof(SCA_WEBDIR), TRUE)); + Assert(pswd); + return pswd; +} + +static void FreeWebDir(SCA_WEBDIR *pswd) +{ + MemFree(pswd); +} + +void ScaWebDirsFreeList(SCA_WEBDIR* pswdList) +{ + SCA_WEBDIR* pswdDelete = pswdList; + while (pswdList) + { + pswdDelete = pswdList; + pswdList = pswdList->pswdNext; + + FreeWebDir(pswdDelete); + } +} + + +static void AddWebDirToList(SCA_WEBDIR** ppswdList, SCA_WEBDIR *pswd) +{ + pswd->pswdNext = *ppswdList; + *ppswdList = pswd; +} diff --git a/src/ext/Iis/ca/scawebdir.h b/src/ext/Iis/ca/scawebdir.h new file mode 100644 index 00000000..0b594532 --- /dev/null +++ b/src/ext/Iis/ca/scawebdir.h @@ -0,0 +1,57 @@ +#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 SCA_WEBDIR +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + // metabase information + WCHAR wzWebKey[MAX_DARWIN_KEY + 1]; + WCHAR wzWebBase[METADATA_MAX_NAME_LEN + 1]; + WCHAR wzWebDirRoot[METADATA_MAX_NAME_LEN + 1]; + + // iis configuation information + WCHAR wzDirectory[MAX_PATH]; + + BOOL fHasProperties; + SCA_WEB_PROPERTIES swp; + + BOOL fHasApplication; + SCA_WEB_APPLICATION swapp; + + SCA_WEBDIR* pswdNext; +}; + + +// prototypes +UINT __stdcall ScaWebDirsRead( + __in IMSAdminBase* piMetabase, + __in SCA_WEB* pswList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData, + __out SCA_WEBDIR** ppswdList + ); + +HRESULT ScaWebDirsInstall( + __in IMSAdminBase* piMetabase, + __in SCA_WEBDIR* pswdList, + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaWebDirsUninstall( + __in IMSAdminBase* piMetabase, + __in SCA_WEBDIR* pswdList + ); + +void ScaWebDirsFreeList( + __in SCA_WEBDIR* pswdList + ); diff --git a/src/ext/Iis/ca/scawebdir7.cpp b/src/ext/Iis/ca/scawebdir7.cpp new file mode 100644 index 00000000..5ead0470 --- /dev/null +++ b/src/ext/Iis/ca/scawebdir7.cpp @@ -0,0 +1,219 @@ +// 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 +static LPCWSTR vcsWebDirQuery7 = L"SELECT `Web_`, `WebDir`, `Component_`, `Path`, `DirProperties_`, `Application_`" + L"FROM `IIsWebDir`"; + +enum eWebDirQuery { wdqWeb = 1, wdqWebDir, wdqComponent , wdqPath, wdqProperties, wdqApplication, wdqInstalled, wdqAction }; + +// prototypes +static HRESULT AddWebDirToList(SCA_WEBDIR7** ppswdList); + + +UINT __stdcall ScaWebDirsRead7( + __in SCA_WEB7* pswList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE /*hWebBaseQuery*/, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData, + __out SCA_WEBDIR7** ppswdList + ) +{ + HRESULT hr = S_OK; + MSIHANDLE hRec; + + LPWSTR pwzData = NULL; + SCA_WEBDIR7* pswd; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebDirsRead7"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebDirs7() because IIsWebDir table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the web directories + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + hr = AddWebDirToList(ppswdList); + ExitOnFailure(hr, "failed to add web dir to list"); + + pswd = *ppswdList; + ExitOnNull(pswd, hr, E_INVALIDARG, "No web dir provided"); + + // get component install state + hr = WcaGetRecordString(hRec, wdqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get Component for WebDirs"); + hr = ::StringCchCopyW(pswd->wzComponent, countof(pswd->wzComponent), pwzData); + ExitOnFailure(hr, "Failed to copy component string to webdir object"); + + hr = WcaGetRecordInteger(hRec, wdqInstalled, (int *)&pswd->isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for webdir"); + + hr = WcaGetRecordInteger(hRec, wdqAction, (int *)&pswd->isAction); + ExitOnFailure(hr, "Failed to get Component action state for webdir"); + + hr = WcaGetRecordString(hRec, wdqWeb, &pwzData); + ExitOnFailure(hr, "Failed to get Web for WebDir"); + + // get the web key + hr = ScaWebsGetBase7(pswList, pwzData, pswd->wzWebSite, countof(pswd->wzWebSite)); + if (S_FALSE == hr) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + ExitOnFailure(hr, "Failed to get base of web for WebDir"); + } + ExitOnFailure(hr, "Failed to format webdir root string"); + + hr = WcaGetRecordString(hRec, wdqPath, &pwzData); + ExitOnFailure(hr, "Failed to get Path for WebDir"); + + hr = ::StringCchCopyW(pswd->wzPath, countof(pswd->wzPath), pwzData); + ExitOnFailure(hr, "Failed to copy path for WebDir"); + + // get the directory properties for this web + hr = WcaGetRecordString(hRec, wdqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get security identifier for WebDir"); + if (*pwzData) + { + hr = ScaGetWebDirProperties(pwzData, hUserQuery, hWebDirPropQuery, &pswd->swp); + ExitOnFailure(hr, "Failed to get properties for WebDir"); + + pswd->fHasProperties = TRUE; + } + + // get the application information for this web directory + hr = WcaGetRecordString(hRec, wdqApplication, &pwzData); + ExitOnFailure(hr, "Failed to get application identifier for WebDir"); + if (*pwzData) + { + hr = ScaGetWebApplication(NULL, pwzData, hWebAppQuery, hWebAppExtQuery, &pswd->swapp); + ExitOnFailure(hr, "Failed to get application for WebDir"); + + pswd->fHasApplication = TRUE; + } + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing WebDirs"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaWebDirsInstall7(SCA_WEBDIR7* pswdList, SCA_APPPOOL * psapList) +{ + HRESULT hr = S_OK; + SCA_WEBDIR7* pswd = pswdList; + + while (pswd) + { + // if we are installing the web site + if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) + { + hr = ScaWriteConfigID(IIS_WEBDIR); + ExitOnFailure(hr, "Failed to write WebDir ID"); + + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "Failed to write WebDir action ID"); + + hr = ScaWriteConfigString(pswd->wzWebSite); + ExitOnFailure(hr, "Failed to write WebDir site"); + + hr = ScaWriteConfigString(pswd->wzPath); + ExitOnFailure(hr, "Failed to write WebDir path"); + + // get the security information for this web + if (pswd->fHasProperties) + { + ScaWriteWebDirProperties7(pswd->wzWebSite, pswd->wzPath, &pswd->swp); + ExitOnFailure(hr, "Failed to write properties for WebDir"); + } + + // get the application information for this web directory + if (pswd->fHasApplication) + { + hr = ScaWriteWebApplication7(pswd->wzWebSite, pswd->wzPath, &pswd->swapp, psapList); + ExitOnFailure(hr, "Failed to write application for WebDir"); + } + } + + pswd = pswd->pswdNext; + } + +LExit: + return hr; +} + + +HRESULT ScaWebDirsUninstall7(SCA_WEBDIR7* pswdList) +{ + HRESULT hr = S_OK; + SCA_WEBDIR7* pswd = pswdList; + + while (pswd) + { + if (WcaIsUninstalling(pswd->isInstalled, pswd->isAction)) + { + hr = ScaWriteConfigID(IIS_WEBDIR); + ExitOnFailure(hr, "Failed to write WebDir ID"); + + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "Failed to write WebDir action ID"); + + hr = ScaWriteConfigString(pswd->wzWebSite); + ExitOnFailure(hr, "Failed to write WebDir site"); + + hr = ScaWriteConfigString(pswd->wzPath); + ExitOnFailure(hr, "Failed to write WebDir path"); + } + + pswd = pswd->pswdNext; + } + +LExit: + return hr; +} + + +void ScaWebDirsFreeList7(SCA_WEBDIR7* pswdList) +{ + SCA_WEBDIR7* pswdDelete = pswdList; + while (pswdList) + { + pswdDelete = pswdList; + pswdList = pswdList->pswdNext; + + MemFree(pswdDelete); + } +} + + +static HRESULT AddWebDirToList(SCA_WEBDIR7** ppswdList) +{ + HRESULT hr = S_OK; + + SCA_WEBDIR7* pswd = static_cast(MemAlloc(sizeof(SCA_WEBDIR7), TRUE)); + ExitOnNull(pswd, hr, E_OUTOFMEMORY, "failed to allocate element for web dir list"); + + pswd->pswdNext = *ppswdList; + *ppswdList = pswd; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebdir7.h b/src/ext/Iis/ca/scawebdir7.h new file mode 100644 index 00000000..c5c87e17 --- /dev/null +++ b/src/ext/Iis/ca/scawebdir7.h @@ -0,0 +1,51 @@ +#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 SCA_WEBDIR7 +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + + // iis configuation information + WCHAR wzPath[MAX_PATH]; + WCHAR wzWebSite[MAX_PATH]; + + BOOL fHasProperties; + SCA_WEB_PROPERTIES swp; + + BOOL fHasApplication; + SCA_WEB_APPLICATION swapp; + + SCA_WEBDIR7* pswdNext; +}; + + +// prototypes +UINT __stdcall ScaWebDirsRead7( + __in SCA_WEB7* pswList, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebBaseQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppQuery, + __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, + __inout LPWSTR *ppwzCustomActionData, + __out SCA_WEBDIR7** ppswdList + ); + +HRESULT ScaWebDirsInstall7( + __in SCA_WEBDIR7* pswdList, + __in SCA_APPPOOL* psapList + ); + +HRESULT ScaWebDirsUninstall7( + __in SCA_WEBDIR7* pswdList + ); + +void ScaWebDirsFreeList7( + __in SCA_WEBDIR7* pswdList + ); diff --git a/src/ext/Iis/ca/scaweberr.cpp b/src/ext/Iis/ca/scaweberr.cpp new file mode 100644 index 00000000..2441f006 --- /dev/null +++ b/src/ext/Iis/ca/scaweberr.cpp @@ -0,0 +1,371 @@ +// 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" + +enum eWebErrorQuery { weqErrorCode = 1, weqSubCode, weqParentType, weqParentValue, weqFile, weqURL }; + +static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList); + +void ScaWebErrorFreeList(SCA_WEB_ERROR *psweList) +{ + SCA_WEB_ERROR *psweDelete = psweList; + while (psweList) + { + psweDelete = psweList; + psweList = psweList->psweNext; + + MemFree(psweDelete); + } +} + +HRESULT ScaWebErrorRead( + SCA_WEB_ERROR **ppsweList, + __inout LPWSTR *ppwzCustomActionData + ) +{ +// AssertSz(0, "Debug ScaWebErrorRead here"); + HRESULT hr = S_OK; + MSIHANDLE hRec; + LPWSTR pwzData = NULL; + SCA_WEB_ERROR* pswe; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + ExitOnNull(ppsweList, hr, E_INVALIDARG, "Failed to read web error, because no web error was provided to read"); + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaAppPoolRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebErrorRead() - required tables not present."); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the web errors + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + hr = AddWebErrorToList(ppsweList); + ExitOnFailure(hr, "failed to add web error to list"); + + pswe = *ppsweList; + + hr = WcaGetRecordInteger(hRec, weqErrorCode, &(pswe->iErrorCode)); + ExitOnFailure(hr, "failed to get IIsWebError.ErrorCode"); + + hr = WcaGetRecordInteger(hRec, weqSubCode, &(pswe->iSubCode)); + ExitOnFailure(hr, "failed to get IIsWebError.SubCode"); + + hr = WcaGetRecordInteger(hRec, weqParentType, &(pswe->iParentType)); + ExitOnFailure(hr, "failed to get IIsWebError.ParentType"); + + hr = WcaGetRecordString(hRec, weqParentValue, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebError.ParentValue"); + hr = ::StringCchCopyW(pswe->wzParentValue, countof(pswe->wzParentValue), pwzData); + ExitOnFailure(hr, "Failed to copy IIsWebError.ParentValue"); + + hr = WcaGetRecordString(hRec, weqFile, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebError.File"); + hr = ::StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), pwzData); + ExitOnFailure(hr, "Failed to copy IIsWebError.File"); + + hr = WcaGetRecordString(hRec, weqURL, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebError.URL"); + hr = ::StringCchCopyW(pswe->wzURL, countof(pswe->wzURL), pwzData); + ExitOnFailure(hr, "Failed to copy IIsWebError.URL"); + + // If they've specified both a file and a URL, that's invalid + if (*(pswe->wzFile) && *(pswe->wzURL)) + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Both File and URL specified for web error. File: %ls, URL: %ls", pswe->wzFile, pswe->wzURL); + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure while processing web errors"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + +HRESULT ScaGetWebError(int iParentType, LPCWSTR wzParentValue, SCA_WEB_ERROR **ppsweList, SCA_WEB_ERROR **ppsweOut) +{ + HRESULT hr = S_OK; + SCA_WEB_ERROR* psweAdd = NULL; + SCA_WEB_ERROR* psweLast = NULL; + + *ppsweOut = NULL; + + if (!*ppsweList) + return hr; + + SCA_WEB_ERROR* pswe = *ppsweList; + while (pswe) + { + if (iParentType == pswe->iParentType && 0 == lstrcmpW(wzParentValue, pswe->wzParentValue)) + { + // Found a match, take this one out of the list and add it to the matched out list + psweAdd = pswe; + + if (psweLast) + { + // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) + psweLast->psweNext = psweAdd->psweNext; + } + else + { + // If we are at the beginning (no psweLast) update the beginning (since we're taking it) + *ppsweList = pswe->psweNext; + } + pswe = pswe->psweNext; // move on + + // Add the one we've removed to the beginning of the out list + psweAdd->psweNext = *ppsweOut; + *ppsweOut = psweAdd; + } + else + { + psweLast = pswe; // remember the last we that didn't match + pswe = pswe->psweNext; // move on + } + } + + return hr; +} + +HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList) +{ +// AssertSz(0, "Debug ScaWriteWebError here"); + Assert(*wzRoot && psweList); + + HRESULT hr = S_OK; + + DWORD cchData = 0; + LPWSTR pwzSearchKey = NULL; + LPWSTR pwz = NULL; + LPWSTR pwzErrors = NULL; + + LPWSTR pwzCodeSubCode = NULL; + LPWSTR pwzAcceptableCodeSubCode = NULL; + LPCWSTR wzFoundCodeSubCode = NULL; + DWORD_PTR dwFoundCodeSubCodeIndex = 0xFFFFFFFF; + BOOL fOldValueFound = FALSE; + LPWSTR pwzAcceptableErrors = NULL; + + LPWSTR pwzNewError = NULL; + + METADATA_RECORD mr; + ::ZeroMemory(&mr, sizeof(mr)); + + ExitOnNull(piMetabase, hr, E_INVALIDARG, "Failed to write web error, because no metabase was provided"); + ExitOnNull(wzRoot, hr, E_INVALIDARG, "Failed to write web error, because no root was provided"); + + // get the set of all valid custom errors from the metabase + mr.dwMDIdentifier = MD_CUSTOM_ERROR_DESC; + mr.dwMDAttributes = METADATA_INHERIT; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = ALL_METADATA; + mr.dwMDDataLen = cchData = 0; + mr.pbMDData = NULL; + + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/Info", &mr); + ExitOnFailure(hr, "Unable to get set of acceptable error codes for this server."); + + pwzAcceptableErrors = reinterpret_cast(mr.pbMDData); + + // Check if web errors already exist here + mr.dwMDIdentifier = MD_CUSTOM_ERROR; + mr.dwMDAttributes = METADATA_INHERIT; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = ALL_METADATA; + mr.dwMDDataLen = cchData = 0; + mr.pbMDData = NULL; + + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzRoot, &mr); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) + { + // + // If we don't have one already, find an appropriate one to start with + // + + // we can walk up key by key and look for custom errors to inherit + + hr = StrAllocConcat(&pwzSearchKey, wzRoot, 0); + ExitOnFailure(hr, "Failed to copy root string: %ls", wzRoot); + + pwz = pwzSearchKey + lstrlenW(pwzSearchKey); + + while (NULL == pwzErrors) + { + // find the last slash + while (*pwz != '/' && pwz != pwzSearchKey) + pwz --; + + if (pwz == pwzSearchKey) + break; + + *pwz = L'\0'; + + // Try here. If it's not found, keep walking up the path + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, pwzSearchKey, &mr); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr) + hr = S_FALSE; + ExitOnFailure(hr, "failed to discover default error values to start with for web root: %ls while walking up the tree", wzRoot); + + if (S_OK == hr) + { + pwzErrors = reinterpret_cast(mr.pbMDData); + break; + } + + // Don't keep going if we're at the root + if (0 == lstrcmpW(pwz + 1, L"W3SVC")) + break; + } + } + else + { + pwzErrors = reinterpret_cast(mr.pbMDData); + } + ExitOnFailure(hr, "failed to discover default error values to start with for web root: %ls", wzRoot); + + // The above code should have come up with some value to start pwzErrors off with. Make sure it did. + if (NULL == pwzErrors) + { + ExitOnFailure(hr = E_UNEXPECTED, "failed to discover default error values to start with for web root: %ls", wzRoot); + } + + // Loop through the web errors + for (SCA_WEB_ERROR* pswe = psweList; pswe; pswe = pswe->psweNext) + { + // Assume that we will have to replace + fOldValueFound = TRUE; + + // If the subcode is 0, that means "*" in MD_CUSTOM_ERROR (thus the special formatting logic) + if (0 == pswe->iSubCode) + { + hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,*", pswe->iErrorCode); + ExitOnFailure(hr, "failed to create error code string while installing web error"); + } + else + { + hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode); + ExitOnFailure(hr, "failed to create error code,subcode string while installing web error"); + } + + hr = MultiSzFindSubstring(pwzErrors, pwzCodeSubCode, &dwFoundCodeSubCodeIndex, &wzFoundCodeSubCode); + ExitOnFailure(hr, "failed to find existing error code,subcode: %ls", pwzCodeSubCode); + + // If we didn't find this error code/sub code pair in the list already, make sure it's acceptable to add + if (S_FALSE == hr) + { + // + // Make sure this error code/sub code pair is in the "acceptable" list + // + + // If the subcode is 0, that means "0" in MD_CUSTOM_ERROR_DESC (no special formatting logic needed) + hr = StrAllocFormatted(&pwzAcceptableCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode); + ExitOnFailure(hr, "failed to create error code,subcode string while installing web error"); + + // We don't care where it is, just whether it's there or not + hr = MultiSzFindSubstring(pwzAcceptableErrors, pwzAcceptableCodeSubCode, NULL, NULL); + ExitOnFailure(hr, "failed to find whether or not error code, subcode: %ls is supported", pwzCodeSubCode); + + if (S_FALSE == hr) + { + WcaLog(LOGMSG_VERBOSE, "Skipping error code, subcode: %ls because it is not supported by the server.", pwzCodeSubCode); + continue; + } + + // If we didn't find it (and its an acceptable error) then we have nothing to replace + fOldValueFound = FALSE; + } + + // Set up the new error string if needed + if (*(pswe->wzFile)) + { + hr = StrAllocFormatted(&pwzNewError, L"%s,FILE,%s", pwzCodeSubCode, pswe->wzFile); + ExitOnFailure(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile); + } + else if (*(pswe->wzURL)) + { + hr = StrAllocFormatted(&pwzNewError, L"%s,URL,%s", pwzCodeSubCode, pswe->wzURL); + ExitOnFailure(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile); + } + else if (fOldValueFound) + { + // If no File or URL was specified, they want a default error so remove the old value from the MULTISZ and move on + hr = MultiSzRemoveString(&pwzErrors, dwFoundCodeSubCodeIndex); + ExitOnFailure(hr, "failed to remove string for error code sub code: %ls in order to make it 'default'", pwzCodeSubCode); + continue; + } + + // If we have something to replace, replace it, otherwise, put it at the beginning (order shouldn't matter) + if (fOldValueFound) + { + hr = MultiSzReplaceString(&pwzErrors, dwFoundCodeSubCodeIndex, pwzNewError); + ExitOnFailure(hr, "failed to replace old error string with new error string for error code,subcode: %ls", pwzCodeSubCode); + } + else + { + hr = MultiSzPrepend(&pwzErrors, NULL, pwzNewError); + ExitOnFailure(hr, "failed to prepend new error string for error code,subcode: %ls", pwzCodeSubCode); + } + } + + // now write the CustomErrors to the metabase + if (weptWeb == iParentType) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRoot, L"/Root", MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors); + ExitOnFailure(hr, "Failed to write Web Error to /Root"); + } + else + { + hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors); + ExitOnFailure(hr, "Failed to write Web Error"); + } + +LExit: + ReleaseStr(pwzErrors); + ReleaseStr(pwzSearchKey); + ReleaseStr(pwzCodeSubCode); + ReleaseStr(pwzAcceptableCodeSubCode); + ReleaseStr(pwzAcceptableErrors); + + return hr; +} + +static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList) +{ + HRESULT hr = S_OK; + + SCA_WEB_ERROR* pswe = static_cast(MemAlloc(sizeof(SCA_WEB_ERROR), TRUE)); + ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); + + pswe->psweNext = *ppsweList; + *ppsweList = pswe; + +LExit: + return hr; +} + +HRESULT ScaWebErrorCheckList(SCA_WEB_ERROR* psweList) +{ + if (!psweList) + { + return S_OK; + } + + while (psweList) + { + WcaLog(LOGMSG_STANDARD, "WebError code: %d subcode: %d for parent: %ls not used!", psweList->iErrorCode, psweList->iSubCode, psweList->wzParentValue); + psweList = psweList->psweNext; + } + + return E_FAIL; +} + diff --git a/src/ext/Iis/ca/scaweberr.h b/src/ext/Iis/ca/scaweberr.h new file mode 100644 index 00000000..ad8ff4f5 --- /dev/null +++ b/src/ext/Iis/ca/scaweberr.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. + + +enum eWebErrorParentType { weptVDir = 1, weptWeb }; + +struct SCA_WEB_ERROR +{ + int iErrorCode; + int iSubCode; + + int iParentType; + WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; + + WCHAR wzFile[MAX_PATH]; + WCHAR wzURL[MAX_PATH]; // TODO: this needs to be bigger than MAX_PATH + + SCA_WEB_ERROR *psweNext; +}; + +// prototypes +HRESULT ScaWebErrorRead( + SCA_WEB_ERROR **ppsweList, + __inout LPWSTR *ppwzCustomActionData + ); +void ScaWebErrorFreeList(SCA_WEB_ERROR *psweList); +HRESULT ScaWebErrorCheckList(SCA_WEB_ERROR* psweList); +HRESULT ScaGetWebError(int iParentType, LPCWSTR wzParentValue, SCA_WEB_ERROR **ppsweList, SCA_WEB_ERROR **ppsweOut); +HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList); + diff --git a/src/ext/Iis/ca/scaweberr7.cpp b/src/ext/Iis/ca/scaweberr7.cpp new file mode 100644 index 00000000..33c2f1bd --- /dev/null +++ b/src/ext/Iis/ca/scaweberr7.cpp @@ -0,0 +1,88 @@ +// 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" + +HRESULT ScaWriteWebError7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRoot, + SCA_WEB_ERROR* psweList + ) +{ + HRESULT hr = S_OK; + + hr = ScaWriteConfigID(IIS_WEBERROR_BEGIN); + ExitOnFailure(hr, "Fail to write webError begin ID"); + + hr = ScaWriteConfigString(wzWebName); + ExitOnFailure(hr, "Fail to write webError Web Key"); + + hr = ScaWriteConfigString(wzRoot); + ExitOnFailure(hr, "Fail to write webError Vdir key"); + + // Loop through the HTTP headers + for (SCA_WEB_ERROR* pswe = psweList; pswe; pswe = pswe->psweNext) + { + hr = ScaWriteConfigID(IIS_WEBERROR); + ExitOnFailure(hr, "Fail to write webError ID"); + + hr = ScaWriteConfigInteger(pswe->iErrorCode); + ExitOnFailure(hr, "Fail to write webError code"); + + hr = ScaWriteConfigInteger(pswe->iSubCode); + ExitOnFailure(hr, "Fail to write webError subcode"); + + //just write one + if (*(pswe->wzFile)) + { + hr = ScaWriteConfigString(pswe->wzFile); + ExitOnFailure(hr, "Fail to write webError file"); + hr = ScaWriteConfigInteger(0); + ExitOnFailure(hr, "Fail to write webError file code"); + } + else if (*(pswe->wzURL)) + { + hr = ScaWriteConfigString(pswe->wzURL); + ExitOnFailure(hr, "Fail to write webError URL"); + hr = ScaWriteConfigInteger(1); + ExitOnFailure(hr, "Fail to write webError URL code"); + } + } + + hr = ScaWriteConfigID(IIS_WEBERROR_END); + ExitOnFailure(hr, "Fail to write httpHeader end ID"); + +LExit: + return hr; + +} + +//static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList) +//{ +// HRESULT hr = S_OK; +// +// SCA_WEB_ERROR* pswe = static_cast(MemAlloc(sizeof(SCA_WEB_ERROR), TRUE)); +// ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); +// +// pswe->psweNext = *ppsweList; +// *ppsweList = pswe; +// +//LExit: +// return hr; +//} + +HRESULT ScaWebErrorCheckList7(SCA_WEB_ERROR* psweList) +{ + if (!psweList) + { + return S_OK; + } + + while (psweList) + { + WcaLog(LOGMSG_STANDARD, "WebError code: %d subcode: %d for parent: %ls not used!", psweList->iErrorCode, psweList->iSubCode, psweList->wzParentValue); + psweList = psweList->psweNext; + } + + return E_FAIL; +} + diff --git a/src/ext/Iis/ca/scaweberr7.h b/src/ext/Iis/ca/scaweberr7.h new file mode 100644 index 00000000..62448211 --- /dev/null +++ b/src/ext/Iis/ca/scaweberr7.h @@ -0,0 +1,10 @@ +#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 ScaWriteWebError7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRoot, + SCA_WEB_ERROR* psweList + ); + diff --git a/src/ext/Iis/ca/scaweblog.cpp b/src/ext/Iis/ca/scaweblog.cpp new file mode 100644 index 00000000..01147848 --- /dev/null +++ b/src/ext/Iis/ca/scaweblog.cpp @@ -0,0 +1,177 @@ +// 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" + +enum eWebLogQuery { wlqLog = 1, wlqFormat }; + +/* **************************************************************** + * LookupLogFormatGUID -Looks up a given IIS Log format type in + * the metabase and returns the GUID for it. + * ****************************************************************/ +static HRESULT LookupLogFormatGUID( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzLogFormat, + __out_ecount(cchGUID) LPWSTR wzGUID, + __in int cchGUID + ) +{ + WCHAR wzKey[METADATA_MAX_NAME_LEN]; + HRESULT hr = S_OK; + + METADATA_RECORD mrKeyType; + ::ZeroMemory(&mrKeyType, sizeof(mrKeyType)); + + mrKeyType.dwMDIdentifier = MD_KEY_TYPE; + mrKeyType.dwMDAttributes = METADATA_NO_ATTRIBUTES; + mrKeyType.dwMDUserType = IIS_MD_UT_SERVER; + mrKeyType.dwMDDataType = ALL_METADATA; + mrKeyType.dwMDDataLen = 0; + mrKeyType.pbMDData = NULL; + + METADATA_RECORD mrPluginId; + ::ZeroMemory(&mrPluginId, sizeof(mrPluginId)); + + mrPluginId.dwMDIdentifier = MD_LOG_PLUGIN_MOD_ID; + mrPluginId.dwMDAttributes = METADATA_INHERIT; + mrPluginId.dwMDUserType = IIS_MD_UT_SERVER; + mrPluginId.dwMDDataType = ALL_METADATA; + mrPluginId.dwMDDataLen = 0; + mrPluginId.pbMDData = NULL; + + hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/Logging/%s", wzLogFormat); + ExitOnFailure(hr, "failed to format logging metabase key name"); + + // verify that we have this log format available in IIS + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrKeyType); + ExitOnFailure(hr, "Failed to find specified Log format key in IIS for log format: %ls", wzLogFormat); + ExitOnNull(mrKeyType.pbMDData, hr, E_POINTER, "Request for Log format key in IIS for log format returned success, but value was NULL"); + + if (0 != lstrcmpW(L"IIsLogModule", (LPCWSTR)mrKeyType.pbMDData)) + { + ExitOnFailure(hr = E_UNEXPECTED, "Found invalid log format in IIS: %ls", (LPCWSTR)mrKeyType.pbMDData); + } + + // find the GUID for that log format + hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrPluginId); + ExitOnFailure(hr, "Failed to retrieve IISLog format GUID. Key: %ls", wzKey); + ExitOnNull(mrPluginId.pbMDData, hr, E_POINTER, "Retrieval of IISLog format GUID returned success, but value was NULL"); + + hr = ::StringCchCopyW(wzGUID, cchGUID, (LPCWSTR)mrPluginId.pbMDData); + ExitOnFailure(hr, "failed to copy metabase value: %ls", (LPCWSTR)mrPluginId.pbMDData); + +LExit: + + if (mrKeyType.pbMDData) + { + MetaFreeValue(&mrKeyType); + } + + if (mrPluginId.pbMDData) + { + MetaFreeValue(&mrPluginId); + } + + return hr; +} + + +/* **************************************************************** + * ScaGetWebLog -Retrieves Log table data for the specified Log key + * + * ****************************************************************/ +HRESULT ScaGetWebLog( + IMSAdminBase* piMetabase, + LPCWSTR wzLog, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + SCA_WEB_LOG* pswl + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzData = NULL; + MSIHANDLE hRec; + + if (0 == WcaGetQueryRecords(hWebLogQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaGetWebLog() - no records to process"); + ExitFunction1(hr = S_FALSE); + } + + WcaFetchWrappedReset(hWebLogQuery); + + hr = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); + if (E_NOMOREITEMS == hr) + { + ExitOnFailure(hr, "cannot locate IIsWebLog.Log='%ls'", wzLog); + } + HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); + + if (SUCCEEDED(hrTemp)) + { + ExitOnFailure(hr, "error - found multiple matching IIsWebLog rows"); + } + + ::ZeroMemory(pswl, sizeof(SCA_WEB_LOG)); + + // check that log key matches + hr = WcaGetRecordString(hRec, wlqLog, &pwzData); + ExitOnFailure(hr, "failed to get IIsWebLog.Log for Log: %ls", wzLog); + hr = ::StringCchCopyW(pswl->wzLog, countof(pswl->wzLog), pwzData); + ExitOnFailure(hr, "failed to copy log name: %ls", pwzData); + + hr = WcaGetRecordString(hRec, wlqFormat, &pwzData); + ExitOnFailure(hr, "failed to get IIsWebLog.Format for Log:", wzLog); + hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), pwzData); + ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); + + // if they specified a log format, look up its GUID in the metabase + if (*pswl->wzFormat && 0 != lstrcmpW(pswl->wzFormat, L"none")) + { + hr = LookupLogFormatGUID(piMetabase, pswl->wzFormat, pswl->wzFormatGUID, countof(pswl->wzFormatGUID)); + ExitOnFailure(hr, "Failed to get Log Format GUID for Log: %ls", wzLog); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} + + +/* **************************************************************** + * ScaWriteWebLog -Writes the IIS log values to the metabase. + * + * ****************************************************************/ +HRESULT ScaWriteWebLog( + IMSAdminBase* piMetabase, + LPCWSTR wzWebBase, + SCA_WEB_LOG *pswl + ) +{ + HRESULT hr = S_OK; + + if (*pswl->wzFormat) + { + if (0 == lstrcmpW(pswl->wzFormat, L"none")) + { + // user wishes for Logging to be turned 'off' + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_TYPE, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)0)); + ExitOnFailure(hr, "Failed to write Log Type for Web: %ls", wzWebBase); + } + else + { + Assert(*pswl->wzFormatGUID); + + // write the GUID for the log format for the web to the metabase + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_PLUGIN_ORDER, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, pswl->wzFormatGUID); + ExitOnFailure(hr, "Failed to write Log GUID for Web: %ls", wzWebBase); + + hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_TYPE, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)1)); + ExitOnFailure(hr, "Failed to write Log Type for Web: %ls", wzWebBase); + } + } + +LExit: + return hr; +} + + diff --git a/src/ext/Iis/ca/scaweblog.h b/src/ext/Iis/ca/scaweblog.h new file mode 100644 index 00000000..1a690cce --- /dev/null +++ b/src/ext/Iis/ca/scaweblog.h @@ -0,0 +1,27 @@ +#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 SCA_WEB_LOG +{ + // iis configuation information + WCHAR wzLog[MAX_DARWIN_KEY + 1]; + + // for specifying the log format + WCHAR wzFormat[MAX_DARWIN_KEY + 1]; + WCHAR wzFormatGUID[MAX_DARWIN_KEY + 1]; +}; + + +// prototypes +HRESULT ScaGetWebLog( + IMSAdminBase* piMetabase, + LPCWSTR wzLog, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + SCA_WEB_LOG* pswl + ); +HRESULT ScaWriteWebLog( + IMSAdminBase* piMetabase, + LPCWSTR wzRootOfWeb, + SCA_WEB_LOG *pswl + ); diff --git a/src/ext/Iis/ca/scaweblog7.cpp b/src/ext/Iis/ca/scaweblog7.cpp new file mode 100644 index 00000000..c857c46f --- /dev/null +++ b/src/ext/Iis/ca/scaweblog7.cpp @@ -0,0 +1,120 @@ +// 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 vcsWebLogQuery7 = L"SELECT `Log`, `Format` " + L"FROM `IIsWebLog` WHERE `Log`=?"; + +enum eWebLogQuery { wlqLog = 1, wlqFormat }; + +/* **************************************************************** + * ScaGetWebLog7 -Retrieves Log table data for the specified Log key + * + * ****************************************************************/ +HRESULT ScaGetWebLog7( + __in_z LPCWSTR wzLog, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + __out SCA_WEB_LOG* pswl + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzData = NULL; + MSIHANDLE hRec; + + if (0 == WcaGetQueryRecords(hWebLogQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaGetWebLog() - no records to process"); + ExitFunction1(hr = S_FALSE); + } + + WcaFetchWrappedReset(hWebLogQuery); + + hr = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); + if (E_NOMOREITEMS == hr) + { + ExitOnFailure(hr, "cannot locate IIsWebLog.Log='%ls'", wzLog); + } + HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebLogQuery, wlqLog, wzLog, &hRec); + + if (SUCCEEDED(hrTemp)) + { + ExitOnFailure(hr, "error - found multiple matching IIsWebLog rows"); + } + + ::ZeroMemory(pswl, sizeof(SCA_WEB_LOG)); + + // check that log key matches + hr = WcaGetRecordString(hRec, wlqLog, &pwzData); + ExitOnFailure(hr, "failed to get IIsWebLog.Log for Log: %ls", wzLog); + hr = ::StringCchCopyW(pswl->wzLog, countof(pswl->wzLog), pwzData); + ExitOnFailure(hr, "failed to copy log name: %ls", pwzData); + + hr = WcaGetRecordString(hRec, wlqFormat, &pwzData); + ExitOnFailure(hr, "failed to get IIsWebLog.Format for Log:", wzLog); + + //translate WIX log format name strings to IIS7 + if (0 == lstrcmpW(pwzData, L"Microsoft IIS Log File Format")) + { + hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"IIS"); + ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); + } + else if (0 == lstrcmpW(pwzData, L"NCSA Common Log File Format")) + { + hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"NCSA"); + ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); + } + else if (0 == lstrcmpW(pwzData, L"none")) + { + hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"none"); + ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); + } + else if (0 == lstrcmpW(pwzData, L"ODBC Logging")) + { + hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"W3C"); + ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); + } + else if (0 == lstrcmpW(pwzData, L"W3C Extended Log File Format")) + { + hr = ::StringCchCopyW(pswl->wzFormat, countof(pswl->wzFormat), L"W3C"); + ExitOnFailure(hr, "failed to copy log format: %ls", pwzData); + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_INDEX); + ExitOnFailure(hr, "Invalid log file format: %ls", pwzData); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} + + +/* **************************************************************** + * ScaWriteWebLog -Writes the IIS log values to the metabase. + * + * ****************************************************************/ +HRESULT ScaWriteWebLog7( + LPCWSTR wzWebBase, + const SCA_WEB_LOG *pswl + ) +{ + HRESULT hr = S_OK; + + if (*pswl->wzFormat) + { + //write pswl->wzFormat + hr = ScaWriteConfigID(IIS_WEBLOG); + ExitOnFailure(hr, "Failed to write log format id"); + hr = ScaWriteConfigString(wzWebBase); + ExitOnFailure(hr, "Failed to write log web key"); + hr = ScaWriteConfigString(pswl->wzFormat); + ExitOnFailure(hr, "Failed to write log format string"); + } + +LExit: + return hr; +} + + diff --git a/src/ext/Iis/ca/scaweblog7.h b/src/ext/Iis/ca/scaweblog7.h new file mode 100644 index 00000000..f2bb60d7 --- /dev/null +++ b/src/ext/Iis/ca/scaweblog7.h @@ -0,0 +1,14 @@ +#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 ScaGetWebLog7( + __in_z LPCWSTR wzLog, + __in WCA_WRAPQUERY_HANDLE hWebLogQuery, + __out SCA_WEB_LOG* pswl + ); + +HRESULT ScaWriteWebLog7( + __in_z LPCWSTR wzRootOfWeb, + const SCA_WEB_LOG *pswl + ); diff --git a/src/ext/Iis/ca/scawebprop.cpp b/src/ext/Iis/ca/scawebprop.cpp new file mode 100644 index 00000000..b5e38467 --- /dev/null +++ b/src/ext/Iis/ca/scawebprop.cpp @@ -0,0 +1,301 @@ +// 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 +enum eWebDirPropertiesQuery { wpqProperties = 1, wpqAccess, wpqAuthorization, wpqUser, wpqControlledPassword, wpqLogVisits, wpqIndex, wpqDefaultDoc, wpqAspDetailedError, wpqHttpExp, wpqCCMaxAge, wpqCCCustom, wpqNoCustomError, wpqAccessSSLFlags, wpqAuthenticationProviders }; + +HRESULT ScaGetWebDirProperties( + __in LPCWSTR wzProperties, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __inout SCA_WEB_PROPERTIES* pswp + ) +{ + Assert(*wzProperties && pswp); + + HRESULT hr = S_OK; + MSIHANDLE hRec; + LPWSTR pwzData = NULL; + + ExitOnNull(wzProperties, hr, E_INVALIDARG, "Failed to get web directory properties because no properties were provided to get"); + + WcaFetchWrappedReset(hWebDirPropQuery); + + hr = WcaFetchWrappedRecordWhereString(hWebDirPropQuery, 1, wzProperties, &hRec); + if (S_OK == hr) + { + hr = WcaGetRecordString(hRec, wpqProperties, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.DirProperties"); + hr = ::StringCchCopyW(pswp->wzKey, countof(pswp->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to webdirproperties object"); + + Assert(0 == lstrcmpW(pswp->wzKey, wzProperties)); + + hr = WcaGetRecordInteger(hRec, wpqAccess, &pswp->iAccess); + ExitOnFailure(hr, "Failed to get access value"); + + hr = WcaGetRecordInteger(hRec, wpqAuthorization, &pswp->iAuthorization); + ExitOnFailure(hr, "Failed to get authorization value"); + + // if allow anonymous users + if (S_OK == hr && pswp->iAuthorization & 1) + { + // if there is an anonymous user specified + hr = WcaGetRecordString(hRec, wpqUser, &pwzData); + ExitOnFailure(hr, "Failed to get AnonymousUser_"); + if (pwzData && *pwzData) + { + hr = WcaGetRecordInteger(hRec, wpqControlledPassword, &pswp->fIIsControlledPassword); + ExitOnFailure(hr, "Failed to get IIsControlledPassword"); + if (S_FALSE == hr) + { + pswp->fIIsControlledPassword = FALSE; + hr = S_OK; + } + + hr = ScaGetUserDeferred(pwzData, hUserQuery, &pswp->scau); + ExitOnFailure(hr, "Failed to get User information for Web"); + + pswp->fHasUser = TRUE; + } + else + pswp->fHasUser = FALSE; + } + + hr = WcaGetRecordInteger(hRec, wpqLogVisits, &pswp->fLogVisits); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.LogVisits"); + + hr = WcaGetRecordInteger(hRec, wpqIndex, &pswp->fIndex); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.Index"); + + hr = WcaGetRecordString(hRec, wpqDefaultDoc, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.DefaultDoc"); + if (pwzData && *pwzData) + { + pswp->fHasDefaultDoc = TRUE; + if (0 == lstrcmpW(L"-", pwzData)) // remove any existing default documents by setting them blank + { + pswp->wzDefaultDoc[0] = L'\0'; + } + else // set the default documents + { + hr = ::StringCchCopyW(pswp->wzDefaultDoc, countof(pswp->wzDefaultDoc), pwzData); + ExitOnFailure(hr, "Failed to copy default document string to webdirproperties object"); + } + } + else + { + pswp->fHasDefaultDoc = FALSE; + } + + hr = WcaGetRecordInteger(hRec, wpqAspDetailedError, &pswp->fAspDetailedError); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.AspDetailedError"); + + hr = WcaGetRecordString(hRec, wpqHttpExp, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.HttpExp"); + if (pwzData && *pwzData) + { + pswp->fHasHttpExp = TRUE; + if (0 == lstrcmpW(L"-", pwzData)) // remove any existing default expiration settings by setting them blank + { + pswp->wzHttpExp[0] = L'\0'; + } + else // set the expiration setting + { + hr = ::StringCchCopyW(pswp->wzHttpExp, countof(pswp->wzHttpExp), pwzData); + ExitOnFailure(hr, "Failed to copy http expiration string to webdirproperties object"); + } + } + else + { + pswp->fHasHttpExp = FALSE; + } + + hr = WcaGetRecordInteger(hRec, wpqCCMaxAge, &pswp->iCacheControlMaxAge); + ExitOnFailure(hr, "failed to get IIsWebDirProperties.CacheControlMaxAge"); + + hr = WcaGetRecordString(hRec, wpqCCCustom, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.CacheControlCustom"); + if (pwzData && *pwzData) + { + pswp->fHasCacheControlCustom = TRUE; + if (0 == lstrcmpW(L"-", pwzData)) // remove any existing default cache control custom settings by setting them blank + { + pswp->wzCacheControlCustom[0] = L'\0'; + } + else // set the custom cache control setting + { + hr = ::StringCchCopyW(pswp->wzCacheControlCustom, countof(pswp->wzCacheControlCustom), pwzData); + ExitOnFailure(hr, "Failed to copy cache control custom settings to webdirproperites object"); + } + } + else + { + pswp->fHasCacheControlCustom = FALSE; + } + + hr = WcaGetRecordInteger(hRec, wpqNoCustomError, &pswp->fNoCustomError); + ExitOnFailure(hr, "failed to get IIsWebDirProperties.NoCustomError"); + if (MSI_NULL_INTEGER == pswp->fNoCustomError) + pswp->fNoCustomError = FALSE; + + hr = WcaGetRecordInteger(hRec, wpqAccessSSLFlags, &pswp->iAccessSSLFlags); + ExitOnFailure(hr, "failed to get IIsWebDirProperties.AccessSSLFlags"); + + hr = WcaGetRecordString(hRec, wpqAuthenticationProviders, &pwzData); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.AuthenticationProviders"); + if (pwzData && *pwzData) + { + hr = ::StringCchCopyW(pswp->wzAuthenticationProviders, countof(pswp->wzAuthenticationProviders), pwzData); + ExitOnFailure(hr, "Failed to copy authentication providers string to webdirproperties object"); + } + else + { + pswp->wzAuthenticationProviders[0] = L'\0'; + } + } + else if (E_NOMOREITEMS == hr) + { + WcaLog(LOGMSG_STANDARD, "Error: Cannot locate IIsWebDirProperties.DirProperties='%ls'", wzProperties); + hr = E_FAIL; + } + else + { + ExitOnFailure(hr, "Error getting appropriate webdirproperty"); + } + + // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would + HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebDirPropQuery, 1, wzProperties, &hRec); + if (SUCCEEDED(hrTemp)) + { + AssertSz(E_NOMOREITEMS == hrTemp, "ScaGetWebDirProperties found more than one record"); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} + + +HRESULT ScaWriteWebDirProperties( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzRootOfWeb, + __inout SCA_WEB_PROPERTIES* pswp + ) +{ + HRESULT hr = S_OK; + DWORD dw = 0; + WCHAR wz[METADATA_MAX_NAME_LEN + 1]; + + // write the access permissions to the metabase + if (MSI_NULL_INTEGER != pswp->iAccess) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ACCESS_PERM, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAccess)); + ExitOnFailure(hr, "Failed to write access permissions for Web"); + } + + if (MSI_NULL_INTEGER != pswp->iAuthorization) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_AUTHORIZATION, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAuthorization)); + ExitOnFailure(hr, "Failed to write authorization for Web"); + } + + if (pswp->fHasUser) + { + Assert(pswp->scau.wzName); + // write the user name + if (*pswp->scau.wzDomain) + { + hr = ::StringCchPrintfW(wz, countof(wz), L"%s\\%s", pswp->scau.wzDomain, pswp->scau.wzName); + ExitOnFailure(hr, "Failed to format domain\\username string"); + } + else + { + hr = ::StringCchCopyW(wz, countof(wz), pswp->scau.wzName); + ExitOnFailure(hr, "Failed to copy user name"); + } + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_USER_NAME, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)wz); + ExitOnFailure(hr, "Failed to write anonymous user name for Web"); + + // write the password + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_PWD, METADATA_INHERIT | METADATA_SECURE, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->scau.wzPassword); + ExitOnFailure(hr, "Failed to write anonymous user password for Web"); + + // store whether IIs controls password + dw = (pswp->fIIsControlledPassword) ? TRUE : FALSE; + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_USE_SUBAUTH, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); + ExitOnFailure(hr, "Failed to write if IIs controls user password for Web"); + } + + if (MSI_NULL_INTEGER != pswp->fLogVisits) + { + // The sense of this boolean value is reversed - it is "don't log", not "log visits." + dw = (pswp->fLogVisits) ? FALSE : TRUE; + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_DONT_LOG, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); + ExitOnFailure(hr, "Failed to write authorization for Web"); + } + + if (MSI_NULL_INTEGER != pswp->fIndex) + { + dw = (pswp->fIndex) ? TRUE : FALSE; + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_IS_CONTENT_INDEXED, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); + ExitOnFailure(hr, "Failed to write authorization for Web"); + } + + if (pswp->fHasDefaultDoc) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_DEFAULT_LOAD_FILE, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzDefaultDoc); + ExitOnFailure(hr, "Failed to write default documents for Web"); + } + + if (MSI_NULL_INTEGER != pswp->fAspDetailedError) + { + dw = (pswp->fAspDetailedError) ? TRUE : FALSE; + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTERRORSSENTTOBROWSER, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); + ExitOnFailure(hr, "Failed to write ASP script error for Web"); + } + + if (pswp->fHasHttpExp) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_HTTP_EXPIRES, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzHttpExp); + ExitOnFailure(hr, "Failed to write HTTP Expiration for Web"); + } + + if (MSI_NULL_INTEGER != pswp->iCacheControlMaxAge) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CC_MAX_AGE, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iCacheControlMaxAge)); + ExitOnFailure(hr, "Failed to write Cache Control Max Age for Web"); + } + + if (pswp->fHasCacheControlCustom) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CC_OTHER, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzCacheControlCustom); + ExitOnFailure(hr, "Failed to write Cache Control Custom for Web"); + } + + if (pswp->fNoCustomError) + { + memset(wz, 0, sizeof(wz)); + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wz); + ExitOnFailure(hr, "Failed to write Custom Error for Web"); + } + + if (MSI_NULL_INTEGER != pswp->iAccessSSLFlags) + { + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SSL_ACCESS_PERM, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAccessSSLFlags)); + ExitOnFailure(hr, "Failed to write AccessSSLFlags for Web"); + } + + if (*pswp->wzAuthenticationProviders) + { + hr = ::StringCchCopyW(wz, countof(wz), pswp->wzAuthenticationProviders); + ExitOnFailure(hr, "Failed to copy authentication providers string"); + hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_NTAUTHENTICATION_PROVIDERS, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)wz); + ExitOnFailure(hr, "Failed to write AuthenticationProviders for Web"); + } + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebprop.h b/src/ext/Iis/ca/scawebprop.h new file mode 100644 index 00000000..7a3ae5c9 --- /dev/null +++ b/src/ext/Iis/ca/scawebprop.h @@ -0,0 +1,60 @@ +#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 "scauser.h" + +// global sql queries provided for optimization +extern LPCWSTR vcsWebDirPropertiesQuery; + + +// structs +struct SCA_WEB_PROPERTIES +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + + int iAccess; + + int iAuthorization; + BOOL fHasUser; + SCA_USER scau; + BOOL fIIsControlledPassword; + + BOOL fLogVisits; + BOOL fIndex; + + BOOL fHasDefaultDoc; + WCHAR wzDefaultDoc[MAX_DARWIN_COLUMN + 1]; + + BOOL fHasHttpExp; + WCHAR wzHttpExp[MAX_DARWIN_COLUMN + 1]; + + BOOL fAspDetailedError; + + int iCacheControlMaxAge; + + BOOL fHasCacheControlCustom; + WCHAR wzCacheControlCustom[MAX_DARWIN_COLUMN + 1]; + + BOOL fNoCustomError; + + int iAccessSSLFlags; + + WCHAR wzAuthenticationProviders[MAX_DARWIN_COLUMN + 1]; +}; + + +// prototypes +HRESULT ScaGetWebDirProperties( + __in LPCWSTR pwzProperties, + __in WCA_WRAPQUERY_HANDLE hUserQuery, + __in WCA_WRAPQUERY_HANDLE hWebDirPropQuery, + __inout SCA_WEB_PROPERTIES* pswp + ); + +HRESULT ScaWriteWebDirProperties( + __in IMSAdminBase* piMetabase, + __in LPCWSTR wzRootOfWeb, + __inout SCA_WEB_PROPERTIES* pswp + ); + diff --git a/src/ext/Iis/ca/scawebprop7.cpp b/src/ext/Iis/ca/scawebprop7.cpp new file mode 100644 index 00000000..b8d99b0a --- /dev/null +++ b/src/ext/Iis/ca/scawebprop7.cpp @@ -0,0 +1,155 @@ +// 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" + +HRESULT ScaWriteWebDirProperties7( + __in_z LPCWSTR wzWebName, + __in_z LPCWSTR wzRootOfWeb, + __in const SCA_WEB_PROPERTIES* pswp + ) +{ + HRESULT hr = S_OK; + WCHAR wz[METADATA_MAX_NAME_LEN + 1]; + + //all go to same web/root location tag + hr = ScaWriteConfigID(IIS_DIRPROP_BEGIN); + ExitOnFailure(hr, "Failed to write DirProp begin id"); + hr = ScaWriteConfigString(wzWebName); //site name key + ExitOnFailure(hr, "Failed to write DirProp web key"); + hr = ScaWriteConfigString(wzRootOfWeb); //app path key + ExitOnFailure(hr, "Failed to write DirProp app key"); + + // write the access permissions to the metabase + if (MSI_NULL_INTEGER != pswp->iAccess) + { + hr = ScaWriteConfigID(IIS_DIRPROP_ACCESS); + ExitOnFailure(hr, "Failed to write DirProp access id"); + hr = ScaWriteConfigInteger(pswp->iAccess); + ExitOnFailure(hr, "Failed to write access permissions for Web"); + } + + if (MSI_NULL_INTEGER != pswp->iAuthorization) + { + hr = ScaWriteConfigID(IIS_DIRPROP_AUTH); + ExitOnFailure(hr, "Failed to write DirProp auth id"); + hr = ScaWriteConfigInteger(pswp->iAuthorization); + ExitOnFailure(hr, "Failed to write authorization for Web"); + } + + if (pswp->fHasUser) + { + Assert(pswp->scau.wzName); + // write the user name + if (*pswp->scau.wzDomain) + { + hr = ::StringCchPrintfW(wz, countof(wz), L"%s\\%s", pswp->scau.wzDomain, pswp->scau.wzName); + ExitOnFailure(hr, "Failed to format domain\\username string"); + } + else + { +#pragma prefast(suppress:26037, "Source string is null terminated - it is populated as target of ::StringCchCopyW") + hr = ::StringCchCopyW(wz, countof(wz), pswp->scau.wzName); + ExitOnFailure(hr, "Failed to copy user name"); + } + hr = ScaWriteConfigID(IIS_DIRPROP_USER); + ExitOnFailure(hr, "Failed to write DirProp user id"); + hr = ScaWriteConfigString(wz); + ExitOnFailure(hr, "Failed to write anonymous user name for Web"); + + // write the password + hr = ScaWriteConfigID(IIS_DIRPROP_PWD); + ExitOnFailure(hr, "Failed to write DirProp pwd id"); + hr = ScaWriteConfigString(pswp->scau.wzPassword); + ExitOnFailure(hr, "Failed to write anonymous user password for Web"); + + if (pswp->fIIsControlledPassword) + { + //Not Supported by IIS7 : pswp->fIIsControlledPassword + WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: WebDirProperties.IIsControlledPassword, ignoring"); + } + } + + if (MSI_NULL_INTEGER != pswp->fLogVisits) + { + hr = ScaWriteConfigID(IIS_DIRPROP_LOGVISITS); + ExitOnFailure(hr, "Failed to write DirProp logVisits id"); + hr = ScaWriteConfigInteger(pswp->fLogVisits ? FALSE : TRUE); // we capture "should log" but IIS7 wants "should not log" + ExitOnFailure(hr, "Failed to write DirProp logVisits"); + } + + if (MSI_NULL_INTEGER != pswp->fIndex) + { + //Not Supported by IIS7 : pswp->fIndex + WcaLog(LOGMSG_VERBOSE, "Not supported by IIS7: WebDirProperties.Index, ignoring"); + } + + if (pswp->fHasDefaultDoc) + { + hr = ScaWriteConfigID(IIS_DIRPROP_DEFDOCS); + ExitOnFailure(hr, "Failed to write DirProp defdocs id"); + hr = ScaWriteConfigString(pswp->wzDefaultDoc); + ExitOnFailure(hr, "Failed to write default documents for Web"); + } + + if (MSI_NULL_INTEGER != pswp->fAspDetailedError) + { + hr = ScaWriteConfigID(IIS_DIRPROP_ASPERROR); + ExitOnFailure(hr, "Failed to write ASP script error id"); + hr = ScaWriteConfigInteger(pswp->fAspDetailedError); + ExitOnFailure(hr, "Failed to write ASP script error for Web"); + } + + if (pswp->fHasHttpExp) + { + hr = ScaWriteConfigID(IIS_DIRPROP_HTTPEXPIRES); + ExitOnFailure(hr, "Failed to write DirProp HttpExpires id"); + hr = ScaWriteConfigString(pswp->wzHttpExp); + ExitOnFailure(hr, "Failed to write DirProp HttpExpires value"); + } + + if (MSI_NULL_INTEGER != pswp->iCacheControlMaxAge) + { + hr = ScaWriteConfigID(IIS_DIRPROP_MAXAGE); + ExitOnFailure(hr, "Failed to write DirProp MaxAge id"); + hr = ScaWriteConfigInteger(pswp->iCacheControlMaxAge); + ExitOnFailure(hr, "Failed to write DirProp MaxAge value"); + } + + if (pswp->fHasCacheControlCustom) + { + hr = ScaWriteConfigID(IIS_DIRPROP_CACHECUST); + ExitOnFailure(hr, "Failed to write DirProp Cache Control Custom id"); + hr = ScaWriteConfigString(pswp->wzCacheControlCustom); + ExitOnFailure(hr, "Failed to write Cache Control Custom for Web"); + } + + if (pswp->fNoCustomError) + { + hr = ScaWriteConfigID(IIS_DIRPROP_NOCUSTERROR); + ExitOnFailure(hr, "Failed to write DirProp clear Cust Errors id"); + } + + if (MSI_NULL_INTEGER != pswp->iAccessSSLFlags) + { + hr = ScaWriteConfigID(IIS_DIRPROP_SSLFLAGS); + ExitOnFailure(hr, "Failed to write DirProp sslFlags id"); + hr = ScaWriteConfigInteger(pswp->iAccessSSLFlags); + ExitOnFailure(hr, "Failed to write AccessSSLFlags for Web"); + } + + if (*pswp->wzAuthenticationProviders) + { + hr = ::StringCchCopyW(wz, countof(wz), pswp->wzAuthenticationProviders); + ExitOnFailure(hr, "Failed to copy authentication providers string"); + hr = ScaWriteConfigID(IIS_DIRPROP_AUTHPROVID); + ExitOnFailure(hr, "Failed to write DirProp AuthProvid id"); + hr = ScaWriteConfigString(wz); + ExitOnFailure(hr, "Failed to write AuthenticationProviders for Web"); + } + //End of Dir Properties + hr = ScaWriteConfigID(IIS_DIRPROP_END); + ExitOnFailure(hr, "Failed to write DirProp end id"); + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebprop7.h b/src/ext/Iis/ca/scawebprop7.h new file mode 100644 index 00000000..a97e8679 --- /dev/null +++ b/src/ext/Iis/ca/scawebprop7.h @@ -0,0 +1,12 @@ +#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 "scauser.h" + +HRESULT ScaWriteWebDirProperties7( + __in_z LPCWSTR wzwWebName, + __in_z LPCWSTR wzRootOfWeb, + const SCA_WEB_PROPERTIES* pswp + ); + diff --git a/src/ext/Iis/ca/scawebsvcext.cpp b/src/ext/Iis/ca/scawebsvcext.cpp new file mode 100644 index 00000000..369e951b --- /dev/null +++ b/src/ext/Iis/ca/scawebsvcext.cpp @@ -0,0 +1,343 @@ +// 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 +enum eWebSvcExtQuery { ldqComponent=1 , ldqFile, ldqDescription, ldqGroup, ldqAttributes, ldqInstalled, ldqAction }; + + +LPCWSTR vcsWebSvcExtRoot = L"/LM/W3SVC"; + +// prototypes for private helper functions +static HRESULT AddWebSvcExtToList( + __in SCA_WEBSVCEXT** ppsWseList + ); + +//static HRESULT ScaCheckWebSvcExtValue( +// __in IMSAdminBase* piMetabase, +// __in DWORD dwMDIdentifier +// ); + +static HRESULT ScaWebSvcExtInstall( + __in LPWSTR *pwzWebSvcExtList, + __in DWORD_PTR *pcchWebSvcExtList, + __in SCA_WEBSVCEXT* psWseList + ); + +static HRESULT ScaWebSvcExtUninstall( + __in LPWSTR *pwzWebSvcExtList, + __in const DWORD *pcchWebSvcExtList, + __in SCA_WEBSVCEXT* psWseList + ); + +// functions + +HRESULT __stdcall ScaWebSvcExtRead( + __in SCA_WEBSVCEXT** ppsWseList, + __inout LPWSTR *ppwzCustomActionData + ) +{ + Assert(ppsWseList); + + HRESULT hr = S_OK; + MSIHANDLE hRec; + LPWSTR pwzData = NULL; + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + SCA_WEBSVCEXT* psWebSvcExt = NULL; + WCA_WRAPQUERY_HANDLE hWrapQuery = NULL; + + hr = WcaBeginUnwrapQuery(&hWrapQuery, ppwzCustomActionData); + ExitOnFailure(hr, "Failed to unwrap query for ScaWebSvcExtRead"); + + if (0 == WcaGetQueryRecords(hWrapQuery)) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtRead() because IIsWebServiceExtension data not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the web service extensions + while (S_OK == (hr = WcaFetchWrappedRecord(hWrapQuery, &hRec))) + { + // Get the Component first. If the Component is not being modified during + // this transaction, skip processing this whole record. + hr = WcaGetRecordString(hRec, ldqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get Component for WebSvcExt"); + + hr = WcaGetRecordInteger(hRec, ldqInstalled, (int *)&isInstalled); + ExitOnFailure(hr, "Failed to get Component installed state for WebSvcExt"); + + hr = WcaGetRecordInteger(hRec, ldqAction, (int *)&isAction); + ExitOnFailure(hr, "Failed to get Component action state for WebSvcExt"); + + if (!WcaIsInstalling(isInstalled, isAction) && + !WcaIsReInstalling(isInstalled, isAction) && + !WcaIsUninstalling(isInstalled, isAction)) + { + continue; // skip this record. + } + + hr = AddWebSvcExtToList(ppsWseList); + ExitOnFailure(hr, "failed to add element to web svc ext list"); + + psWebSvcExt = *ppsWseList; + Assert(psWebSvcExt); + + psWebSvcExt->isInstalled = isInstalled; + psWebSvcExt->isAction = isAction; + + hr = WcaGetRecordString(hRec, ldqFile, &pwzData); + ExitOnFailure(hr, "Failed to get File for WebSvcExt"); + hr = ::StringCchCopyW(psWebSvcExt->wzFile, countof(psWebSvcExt->wzFile), pwzData); + ExitOnFailure(hr, "Failed to copy File for WebSvcExt"); + + hr = WcaGetRecordString(hRec, ldqDescription, &pwzData); + ExitOnFailure(hr, "Failed to get Description for WebSvcExt"); + hr = ::StringCchCopyW(psWebSvcExt->wzDescription, countof(psWebSvcExt->wzDescription), pwzData); + ExitOnFailure(hr, "Failed to copy Description for WebSvcExt"); + + hr = WcaGetRecordString(hRec, ldqGroup, &pwzData); + ExitOnFailure(hr, "Failed to get Group for WebSvcExt"); + hr = ::StringCchCopyW(psWebSvcExt->wzGroup, countof(psWebSvcExt->wzGroup), pwzData); + ExitOnFailure(hr, "Failed to copy Group for WebSvcExt"); + + hr = WcaGetRecordInteger(hRec, ldqAttributes, &psWebSvcExt->iAttributes); + ExitOnFailure(hr, "Failed to get Attributes for WebSvcExt"); + } + + if (E_NOMOREITEMS == hr) + hr = S_OK; + ExitOnFailure(hr, "Failure while processing WebSvcExt"); + +LExit: + WcaFinishUnwrapQuery(hWrapQuery); + + ReleaseStr(pwzData); + + return hr; +} + + +// Commit does both install and uninstall +HRESULT __stdcall ScaWebSvcExtCommit( + __in IMSAdminBase* piMetabase, + __in SCA_WEBSVCEXT* psWseList + ) +{ + Assert(piMetabase); + + HRESULT hr = S_OK; + METADATA_RECORD mr; + + LPWSTR wzWebSvcExtList = NULL; + DWORD cbWebSvcExtList = 0; + DWORD_PTR cchWebSvcExtList = 0; + + if (!psWseList) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because there are no web service extensions in the list"); + ExitFunction(); + } + + // Get current set of web service extensions. + ::ZeroMemory(&mr, sizeof(mr)); + mr.dwMDIdentifier = MD_WEB_SVC_EXT_RESTRICTION_LIST; + mr.dwMDAttributes = 0; + mr.dwMDUserType = IIS_MD_UT_SERVER; + mr.dwMDDataType = ALL_METADATA; + mr.pbMDData = NULL; + mr.dwMDDataLen = 0; + + hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, vcsWebSvcExtRoot, &mr, &cbWebSvcExtList); + if (MD_ERROR_DATA_NOT_FOUND == hr) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because WebSvcExtRestrictionList value is not present"); + ExitFunction1(hr = S_FALSE); + } + else if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) + { + // cchWebSvcExtList is returned in bytes. Convert to WCHAR size to call StrAlloc + cchWebSvcExtList = cbWebSvcExtList / sizeof(WCHAR); + hr = StrAlloc(&wzWebSvcExtList, cchWebSvcExtList); + ExitOnFailure(hr, "Failed allocating space for web service extensions"); + } + else + { + ExitOnFailure(hr, "Failed retrieving web service extensions"); + } + + mr.pbMDData = (unsigned char*)wzWebSvcExtList; + mr.dwMDDataLen = cbWebSvcExtList; + + hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, vcsWebSvcExtRoot, &mr, &cbWebSvcExtList); + ExitOnFailure(hr, "Failed retrieving web service extensions"); + + // Make changes to local copy of metabase + while (psWseList) + { + if (WcaIsInstalling(psWseList->isInstalled, psWseList->isAction)) + { + hr = ScaWebSvcExtInstall(&wzWebSvcExtList, &cchWebSvcExtList, psWseList); + ExitOnFailure(hr, "Failed to install Web Service extension"); + } + else if (WcaIsUninstalling(psWseList->isInstalled, psWseList->isAction)) + { + hr = ScaWebSvcExtUninstall(&wzWebSvcExtList, (DWORD *)&cchWebSvcExtList, psWseList); + ExitOnFailure(hr, "Failed to uninstall Web Service extension"); + } + + psWseList = psWseList->psWseNext; + } + + // Write Metabase + hr = ScaWriteMetabaseValue(piMetabase, vcsWebSvcExtRoot, NULL, MD_WEB_SVC_EXT_RESTRICTION_LIST, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzWebSvcExtList); + ExitOnFailure(hr, "Failed to write WebServiceExtensions: '%ls'", wzWebSvcExtList); + +LExit: + ReleaseStr(wzWebSvcExtList); + + return hr; +} + + +static HRESULT ScaWebSvcExtInstall( + __in LPWSTR *ppwzWebSvcExtList, + __in DWORD_PTR *pcchWebSvcExtList, + __in SCA_WEBSVCEXT* psWseList + ) +{ + Assert( ppwzWebSvcExtList && pcchWebSvcExtList && psWseList); + Assert(*ppwzWebSvcExtList); + + HRESULT hr = S_OK; + + LPWSTR pwzWebSvcExt = NULL; + int iAllow; + int iUiDeletable; + + BOOL fAlreadyExists = FALSE; + DWORD_PTR dwIndex = 0xFFFFFFFF; + LPCWSTR wzFoundString = NULL; + + // Check if it's already in there + hr = MultiSzFindSubstring(*ppwzWebSvcExtList, psWseList->wzFile, &dwIndex, &wzFoundString); + ExitOnFailure(hr, "failed to search for string:%ls in web service extension MULTISZ", psWseList->wzFile); + + if (S_FALSE != hr && NULL != wcsstr(wzFoundString, psWseList->wzGroup) && NULL != wcsstr(wzFoundString, psWseList->wzDescription)) + { + fAlreadyExists = TRUE; + } + + // Construct the single string in the format required for the WebSvc Ext list in metabase + iAllow = (psWseList->iAttributes & 1); + iUiDeletable = ((psWseList->iAttributes >> 1) & 1); + hr = StrAllocFormatted(&pwzWebSvcExt, L"%d,%s,%d,%s,%s", iAllow, psWseList->wzFile, iUiDeletable, psWseList->wzGroup, psWseList->wzDescription); + ExitOnFailure(hr, "Failure allocating space for web service extensions"); + + if (fAlreadyExists) + { + hr = MultiSzReplaceString(ppwzWebSvcExtList, dwIndex, pwzWebSvcExt); + ExitOnFailure(hr, "failed to update web service extension string: %ls", pwzWebSvcExt); + } + else + { + hr = MultiSzPrepend(ppwzWebSvcExtList, pcchWebSvcExtList, pwzWebSvcExt); + ExitOnFailure(hr, "failed to prepend web service extension string: %ls", pwzWebSvcExt); + } + +LExit: + ReleaseStr(pwzWebSvcExt); + + return hr; +} + + +static HRESULT ScaWebSvcExtUninstall( + __in LPWSTR *ppwzWebSvcExtList, + __in const DWORD* /*pcchWebSvcExtList*/, + __in SCA_WEBSVCEXT* psWseList + ) +{ + Assert(ppwzWebSvcExtList && *ppwzWebSvcExtList && psWseList); + Assert(*ppwzWebSvcExtList); + + HRESULT hr = S_OK; + DWORD_PTR dwIndex = 0xFFFFFFFF; + LPCWSTR wzFoundString = NULL; + + // Find the string to remove + hr = MultiSzFindSubstring(*ppwzWebSvcExtList, psWseList->wzFile, &dwIndex, &wzFoundString); + ExitOnFailure(hr, "failed to search for string:%ls in web service extension MULTISZ", psWseList->wzFile); + + // If we found a match (ignoring the Allow and Deletable flags) + if (S_FALSE != hr && NULL != wcsstr(wzFoundString, psWseList->wzGroup) && NULL != wcsstr(wzFoundString, psWseList->wzDescription)) + { + hr = MultiSzRemoveString(ppwzWebSvcExtList, dwIndex); + ExitOnFailure(hr, "failed to remove string: %d from web service extension MULTISZ", dwIndex); + } + +LExit: + return hr; +} + + +//static HRESULT ScaCheckWebSvcExtValue( +// __in IMSAdminBase* piMetabase, +// __in DWORD dwMDIdentifier +// ) +//{ +// if (!piMetabase) +// { +// return E_INVALIDARG; +// } +// +// HRESULT hr = S_OK; +// METADATA_RECORD mr = { 0 }; +// DWORD cch = 0; +// +// mr.dwMDIdentifier = dwMDIdentifier; +// mr.dwMDUserType = IIS_MD_UT_SERVER; +// +// hr = piMetabase->GetData(METADATA_MASTER_ROOT_HANDLE, vcsWebSvcExtRoot, &mr, &cch); +// if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) +// { +// hr = S_OK; +// } +// else if (MD_ERROR_DATA_NOT_FOUND == hr) +// { +// hr = S_FALSE; +// } +// +// return hr; +//} + + +void ScaWebSvcExtFreeList( + __in SCA_WEBSVCEXT* psWseList + ) +{ + SCA_WEBSVCEXT* psWseDelete = psWseList; + while (psWseList) + { + psWseDelete = psWseList; + psWseList = psWseList->psWseNext; + MemFree(psWseDelete); + } +} + + +static HRESULT AddWebSvcExtToList( + __in SCA_WEBSVCEXT** ppsWseList + ) +{ + HRESULT hr = S_OK; + + SCA_WEBSVCEXT* psWse = static_cast(MemAlloc(sizeof(SCA_WEBSVCEXT), TRUE)); + ExitOnNull(psWse, hr, E_OUTOFMEMORY, "failed to allocate element for web svc ext list"); + + psWse->psWseNext = *ppsWseList; + *ppsWseList = psWse; + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebsvcext.h b/src/ext/Iis/ca/scawebsvcext.h new file mode 100644 index 00000000..4d225b09 --- /dev/null +++ b/src/ext/Iis/ca/scawebsvcext.h @@ -0,0 +1,35 @@ +#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. + + +enum SCA_WEBSVCEXT_ATTRIBUTES { SWSEATTRIB_ALLOW = 1, SWSEATTRIB_UIDELETABLE = 2 }; + +struct SCA_WEBSVCEXT +{ + // darwin information + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + // iis configuation information + WCHAR wzFile[MAX_PATH + 1]; + WCHAR wzDescription[MAX_DARWIN_COLUMN + 1]; + WCHAR wzGroup[MAX_DARWIN_COLUMN + 1]; + + int iAttributes; + + SCA_WEBSVCEXT* psWseNext; +}; + +HRESULT __stdcall ScaWebSvcExtRead( + __in SCA_WEBSVCEXT** ppsWseList, + __inout LPWSTR *ppwzCustomActionData + ); + +HRESULT ScaWebSvcExtCommit( + __in IMSAdminBase* piMetabase, + __in SCA_WEBSVCEXT* psWseList + ); + +void ScaWebSvcExtFreeList( + __in SCA_WEBSVCEXT* psWseList + ); diff --git a/src/ext/Iis/ca/scawebsvcext7.cpp b/src/ext/Iis/ca/scawebsvcext7.cpp new file mode 100644 index 00000000..dcf2f7f8 --- /dev/null +++ b/src/ext/Iis/ca/scawebsvcext7.cpp @@ -0,0 +1,106 @@ +// 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" + +static HRESULT ScaWebSvcExtInstall( + const SCA_WEBSVCEXT* psWseList + ); + +static HRESULT ScaWebSvcExtUninstall( + const SCA_WEBSVCEXT* psWseList + ); + +// functions +// Commit does both install and uninstall +HRESULT __stdcall ScaWebSvcExtCommit7( + __in SCA_WEBSVCEXT* psWseList + ) +{ + HRESULT hr = S_OK; + + if (!psWseList) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because there are no web service extensions in the list"); + ExitFunction(); + } + + // Make changes to local copy of metabase + while (psWseList) + { + if (WcaIsInstalling(psWseList->isInstalled, psWseList->isAction)) + { + hr = ScaWebSvcExtInstall(psWseList); + ExitOnFailure(hr, "Failed to install Web Service extension"); + } + else if (WcaIsUninstalling(psWseList->isInstalled, psWseList->isAction)) + { + hr = ScaWebSvcExtUninstall(psWseList); + ExitOnFailure(hr, "Failed to uninstall Web Service extension"); + } + + psWseList = psWseList->psWseNext; + } + + +LExit: + + return hr; +} + + +static HRESULT ScaWebSvcExtInstall( + const SCA_WEBSVCEXT* psWseList + ) +{ + HRESULT hr = S_OK; + int iAllow; + + //Write CAData actions + hr = ScaWriteConfigID(IIS_WEB_SVC_EXT); + ExitOnFailure(hr, "failed add web svc ext ID"); + hr = ScaWriteConfigID(IIS_CREATE); + ExitOnFailure(hr, "failed add web svc ext action"); + + // write File path + hr = ScaWriteConfigString(psWseList->wzFile); + ExitOnFailure(hr, "failed add web svc ext file path"); + + // write allowed + // unDeleatable n/a in IIS7 + iAllow = (psWseList->iAttributes & 1); + hr = ScaWriteConfigInteger(iAllow); + ExitOnFailure(hr, "failed add web svc ext Allowed"); + + //write group + hr = ScaWriteConfigString(psWseList->wzGroup); + ExitOnFailure(hr, "failed add web svc ext group"); + + //write description + hr = ScaWriteConfigString(psWseList->wzDescription); + ExitOnFailure(hr, "failed add web svc ext description"); + +LExit: + + return hr; +} + + +static HRESULT ScaWebSvcExtUninstall( + const SCA_WEBSVCEXT* psWseList + ) +{ + HRESULT hr = S_OK; + + //Write CAData actions + hr = ScaWriteConfigID(IIS_WEB_SVC_EXT); + ExitOnFailure(hr, "failed add web svc ext ID"); + hr = ScaWriteConfigID(IIS_DELETE); + ExitOnFailure(hr, "failed add web svc ext action"); + + // write File path (Key) + hr = ScaWriteConfigString(psWseList->wzFile); + ExitOnFailure(hr, "failed add web svc ext file path"); + +LExit: + return hr; +} diff --git a/src/ext/Iis/ca/scawebsvcext7.h b/src/ext/Iis/ca/scawebsvcext7.h new file mode 100644 index 00000000..1a686aed --- /dev/null +++ b/src/ext/Iis/ca/scawebsvcext7.h @@ -0,0 +1,8 @@ +#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 ScaWebSvcExtCommit7( + __in SCA_WEBSVCEXT* psWseList + ); + diff --git a/src/ext/Iis/nuget.config b/src/ext/Iis/nuget.config new file mode 100644 index 00000000..db7aba29 --- /dev/null +++ b/src/ext/Iis/nuget.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/IisExtensionFixture.cs b/src/ext/Iis/test/WixToolsetTest.Iis/IisExtensionFixture.cs new file mode 100644 index 00000000..685e7126 --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/IisExtensionFixture.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.Iis +{ + using System.Linq; + using WixBuildTools.TestSupport; + using WixToolset.Core.TestPackage; + using WixToolset.Iis; + using Xunit; + + public class IisExtensionFixture + { + [Fact] + public void CanBuildUsingIIsWebAddress() + { + var folder = TestData.Get(@"TestData\UsingIis"); + var build = new Builder(folder, typeof(IisExtensionFactory), new[] { folder }); + + var results = build.BuildAndQuery(Build, "IIsWebAddress"); + Assert.Equal(new[] + { + "IIsWebAddress:TestAddress\tTest\t\t[PORT]\t\t0", + }, results); + } + + private static void Build(string[] args) + { + var result = WixRunner.Execute(args) + .AssertSuccess(); + } + } +} diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl new file mode 100644 index 00000000..38c12ac1 --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl @@ -0,0 +1,11 @@ + + + + + + A newer version of [ProductName] is already installed. + MsiPackage + + diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs new file mode 100644 index 00000000..f36aafef --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs new file mode 100644 index 00000000..03203b50 --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt new file mode 100644 index 00000000..1b4ffe8a --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt @@ -0,0 +1 @@ +This is example.txt. \ No newline at end of file diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj b/src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj new file mode 100644 index 00000000..49ed89bc --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj @@ -0,0 +1,41 @@ + + + + + + netcoreapp3.1 + false + + + + NU1701 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject b/src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject new file mode 100644 index 00000000..7b5b2139 --- /dev/null +++ b/src/ext/Iis/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/src/ext/Iis/wix.snk b/src/ext/Iis/wix.snk new file mode 100644 index 00000000..3908a66a Binary files /dev/null and b/src/ext/Iis/wix.snk differ diff --git a/src/ext/Iis/wixext/IIsCompiler.cs b/src/ext/Iis/wixext/IIsCompiler.cs new file mode 100644 index 00000000..cb573ad1 --- /dev/null +++ b/src/ext/Iis/wixext/IIsCompiler.cs @@ -0,0 +1,2620 @@ +// 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.Iis +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Xml.Linq; + using WixToolset.Data; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Data; + using WixToolset.Iis.Symbols; + + /// + /// The compiler for the WiX Toolset Internet Information Services Extension. + /// + public sealed class IIsCompiler : BaseCompilerExtension + { + public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/iis"; + + /// + /// Types of objects that custom HTTP Headers can be applied to. + /// + /// Note that this must be kept in sync with the eHttpHeaderParentType in scahttpheader.h. + private enum HttpHeaderParentType + { + /// Custom HTTP Header is to be applied to a Web Virtual Directory. + WebVirtualDir = 1, + /// Custom HTTP Header is to be applied to a Web Site. + WebSite = 2, + } + + /// + /// Types of objects that MimeMaps can be applied to. + /// + /// Note that this must be kept in sync with the eMimeMapParentType in scamimemap.h. + private enum MimeMapParentType + { + /// MimeMap is to be applied to a Web Virtual Directory. + WebVirtualDir = 1, + WebSite = 2, + } + + /// + /// Types of objects that custom WebErrors can be applied to. + /// + /// Note that this must be kept in sync with the eWebErrorParentType in scaweberror.h. + private enum WebErrorParentType + { + /// Custom WebError is to be applied to a Web Virtual Directory. + WebVirtualDir = 1, + + /// Custom WebError is to be applied to a Web Site. + WebSite = 2, + } + + /// + /// Processes an element for the Compiler. + /// + /// Source line number for the parent element. + /// 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 "Certificate": + this.ParseCertificateElement(intermediate, section, element, componentId); + break; + case "WebAppPool": + this.ParseWebAppPoolElement(intermediate, section, element, componentId); + break; + case "WebDir": + this.ParseWebDirElement(intermediate, section, element, componentId, null); + break; + case "WebFilter": + this.ParseWebFilterElement(intermediate, section, element, componentId, null); + break; + case "WebProperty": + this.ParseWebPropertyElement(intermediate, section, element, componentId); + break; + case "WebServiceExtension": + this.ParseWebServiceExtensionElement(intermediate, section, element, componentId); + break; + case "WebSite": + this.ParseWebSiteElement(intermediate, section, element, componentId); + break; + case "WebVirtualDir": + this.ParseWebVirtualDirElement(intermediate, section, element, componentId, null, null); + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + break; + case "Fragment": + case "Module": + case "Package": + switch (element.Name.LocalName) + { + case "WebApplication": + this.ParseWebApplicationElement(intermediate, section, element); + break; + case "WebAppPool": + this.ParseWebAppPoolElement(intermediate, section, element, null); + break; + case "WebDirProperties": + this.ParseWebDirPropertiesElement(intermediate, section, element, null); + break; + case "WebLog": + this.ParseWebLogElement(intermediate, section, element); + break; + case "WebSite": + this.ParseWebSiteElement(intermediate, section, element, null); + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + } + + /// + /// Parses a certificate element. + /// + /// Element to parse. + /// Identifier for parent component. + private void ParseCertificateElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int attributes = 8; // SCA_CERT_ATTRIBUTE_VITAL + string binaryRef = null; + string certificatePath = null; + string name = null; + string pfxPassword = null; + int storeLocation = 0; + string storeName = null; + + foreach (var attrib in element.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 "BinaryRef": + attributes |= 2; // SCA_CERT_ATTRIBUTE_BINARYDATA + binaryRef = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Binary, binaryRef); + break; + case "CertificatePath": + certificatePath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Name": + name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Overwrite": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 4; // SCA_CERT_ATTRIBUTE_OVERWRITE + } + else + { + attributes &= ~4; // SCA_CERT_ATTRIBUTE_OVERWRITE + } + break; + case "PFXPassword": + pfxPassword = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Request": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 1; // SCA_CERT_ATTRIBUTE_REQUEST + } + else + { + attributes &= ~1; // SCA_CERT_ATTRIBUTE_REQUEST + } + break; + case "StoreLocation": + var storeLocationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < storeLocationValue.Length) + { + switch (storeLocationValue) + { + case "currentUser": + storeLocation = 1; // SCA_CERTSYSTEMSTORE_CURRENTUSER + break; + case "localMachine": + storeLocation = 2; // SCA_CERTSYSTEMSTORE_LOCALMACHINE + break; + default: + storeLocation = -1; + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "StoreLocation", storeLocationValue, "currentUser", "localMachine")); + break; + } + } + break; + case "StoreName": + var storeNameValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < storeNameValue.Length) + { + switch (storeNameValue) + { + case "ca": + storeName = "CA"; + break; + case "my": + case "personal": + storeName = "MY"; + break; + case "request": + storeName = "REQUEST"; + break; + case "root": + storeName = "Root"; + break; + case "otherPeople": + storeName = "AddressBook"; + break; + case "trustedPeople": + storeName = "TrustedPeople"; + break; + case "trustedPublisher": + storeName = "TrustedPublisher"; + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "StoreName", storeNameValue, "ca", "my", "request", "root", "otherPeople", "trustedPeople", "trustedPublisher")); + break; + } + } + break; + case "Vital": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 8; // SCA_CERT_ATTRIBUTE_VITAL + } + else + { + attributes &= ~8; // SCA_CERT_ATTRIBUTE_VITAL + } + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("crt", componentId, binaryRef, certificatePath); + } + + if (null == name) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); + } + + if (0 == storeLocation) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "StoreLocation")); + } + + if (null == storeName) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "StoreName")); + } + + if (null != binaryRef && null != certificatePath) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "BinaryRef", "CertificatePath", certificatePath)); + } + else if (null == binaryRef && null == certificatePath) + { + this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, element.Name.LocalName, "BinaryRef", "CertificatePath")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference InstallCertificates and UninstallCertificates since nothing will happen without them + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4InstallCertificates", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4UninstallCertificates", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + this.ParseHelper.EnsureTable(section, sourceLineNumbers, IisTableDefinitions.CertificateHash); // Certificate CustomActions require the CertificateHash table + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new CertificateSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + Name = name, + StoreLocation = storeLocation, + StoreName = storeName, + Attributes = attributes, + BinaryRef = binaryRef, + CertificatePath = certificatePath, + PFXPassword = pfxPassword, + }); + } + } + + /// + /// Parses a CertificateRef extension element. + /// + /// Element to parse. + /// Identifier for parent web site. + private void ParseCertificateRefElement(Intermediate intermediate, IntermediateSection section, XElement element, string webId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.Certificate, id.Id); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("wsc", webId); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.Certificate, id.Id); + + section.AddSymbol(new IIsWebSiteCertificatesSymbol(sourceLineNumbers) + { + WebRef = webId, + CertificateRef = id.Id, + }); + } + } + + /// + /// Parses a mime map element. + /// + /// Element to parse. + /// Identifier for parent symbol. + /// Type that parentId refers to. + private void ParseMimeMapElement(Intermediate intermediate, IntermediateSection section, XElement element, string parentId, MimeMapParentType parentType) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string extension = null; + string type = null; + + foreach (var attrib in element.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 "Extension": + extension = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Type": + type = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("imm", parentId, type, extension); + } + + if (null == extension) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Extension")); + } + else if (0 < extension.Length) + { + if (!extension.StartsWith(".", StringComparison.Ordinal)) + { + this.Messaging.Write(IIsErrors.MimeMapExtensionMissingPeriod(sourceLineNumbers, element.Name.LocalName, "Extension", extension)); + } + } + + if (null == type) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Type")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsMimeMapSymbol(sourceLineNumbers, id) + { + ParentType = (int)parentType, + ParentValue = parentId, + MimeType = type, + Extension = extension, + }); + } + } + + /// + /// Parses a recycle time element. + /// + /// Element to parse. + /// Recycle time value. + private string ParseRecycleTimeElement(Intermediate intermediate, IntermediateSection section, XElement element) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + string value = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Value": + value = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == value) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + return value; + } + + /// + /// Parses a web address element. + /// + /// Element to parse. + /// Identifier of parent web site. + /// Identifier for web address. + private string ParseWebAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, string parentWeb) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string header = null; + string ip = null; + string port = null; + var secure = false; + + foreach (var attrib in element.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 "Header": + header = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "IP": + ip = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Port": + port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Secure": + secure = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("iwa", parentWeb, ip, port); + } + + if (null == port) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Port")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsWebAddressSymbol(sourceLineNumbers, id) + { + WebRef = parentWeb, + IP = ip, + Port = port, + Header = header, + Secure = secure ? 1 : 0, + }); + } + + return id?.Id; + } + + /// + /// Parses a web application element. + /// + /// Element to parse. + /// Identifier for web application. + private string ParseWebApplicationElement(Intermediate intermediate, IntermediateSection section, XElement element) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + var allowSessions = YesNoDefaultType.Default; + string appPool = null; + var buffer = YesNoDefaultType.Default; + var clientDebugging = YesNoDefaultType.Default; + string defaultScript = null; + int isolation = 0; + string name = null; + var parentPaths = YesNoDefaultType.Default; + var scriptTimeout = CompilerConstants.IntegerNotSet; + var sessionTimeout = CompilerConstants.IntegerNotSet; + var serverDebugging = YesNoDefaultType.Default; + + foreach (var attrib in element.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 "AllowSessions": + allowSessions = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); + break; + case "Buffer": + buffer = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); + break; + case "ClientDebugging": + clientDebugging = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); + break; + case "DefaultScript": + defaultScript = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < defaultScript.Length) + { + switch (defaultScript) + { + case "JScript": + case "VBScript": + // these are valid values + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, defaultScript, "JScript", "VBScript")); + break; + } + } + break; + case "Isolation": + string isolationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < isolationValue.Length) + { + switch (isolationValue) + { + case "low": + isolation = 0; + break; + case "medium": + isolation = 2; + break; + case "high": + isolation = 1; + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, isolationValue, "low", "medium", "high")); + break; + } + } + break; + case "Name": + name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "ParentPaths": + parentPaths = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); + break; + case "ScriptTimeout": + scriptTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "ServerDebugging": + serverDebugging = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); + break; + case "SessionTimeout": + sessionTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "WebAppPool": + appPool = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsAppPool, appPool); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("wap", name, appPool); + } + + if (null == name) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); + } + else if (-1 != name.IndexOf("\\", StringComparison.Ordinal)) + { + this.Messaging.Write(IIsErrors.IllegalCharacterInAttributeValue(sourceLineNumbers, element.Name.LocalName, "Name", name, '\\')); + } + + foreach (var child in element.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + switch (child.Name.LocalName) + { + case "WebApplicationExtension": + this.ParseWebApplicationExtensionElement(intermediate, section, child, id?.Id); + break; + default: + this.ParseHelper.UnexpectedElement(element, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); + } + } + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new IIsWebApplicationSymbol(sourceLineNumbers, id) + { + Name = name, + Isolation = isolation, + DefaultScript = defaultScript, + AppPoolRef = appPool, + }); + + if (YesNoDefaultType.Default != allowSessions) + { + symbol.AllowSessions = YesNoDefaultType.Yes == allowSessions ? 1 : 0; + } + + if (CompilerConstants.IntegerNotSet != sessionTimeout) + { + symbol.SessionTimeout = sessionTimeout; + } + + if (YesNoDefaultType.Default != buffer) + { + symbol.Buffer = YesNoDefaultType.Yes == buffer ? 1 : 0; + } + + if (YesNoDefaultType.Default != parentPaths) + { + symbol.ParentPaths = YesNoDefaultType.Yes == parentPaths ? 1 : 0; + } + + if (CompilerConstants.IntegerNotSet != scriptTimeout) + { + symbol.ScriptTimeout = scriptTimeout; + } + + if (YesNoDefaultType.Default != serverDebugging) + { + symbol.ServerDebugging = YesNoDefaultType.Yes == serverDebugging ? 1 : 0; + } + + if (YesNoDefaultType.Default != clientDebugging) + { + symbol.ClientDebugging = YesNoDefaultType.Yes == clientDebugging ? 1 : 0; + } + } + + return id?.Id; + } + + /// + /// Parses a web application extension element. + /// + /// Element to parse. + /// Identifier for parent web application. + private void ParseWebApplicationExtensionElement(Intermediate intermediate, IntermediateSection section, XElement element, string application) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + int attributes = 0; + string executable = null; + string extension = null; + string verbs = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "CheckPath": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 4; + } + else + { + attributes &= ~4; + } + break; + case "Executable": + executable = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Extension": + extension = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Script": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 1; + } + else + { + attributes &= ~1; + } + break; + case "Verbs": + verbs = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new IIsWebApplicationExtensionSymbol(sourceLineNumbers) + { + ApplicationRef = application, + Extension = extension, + Verbs = verbs, + Executable = executable, + }); + + if (0 < attributes) + { + symbol.Attributes = attributes; + } + } + } + + /// + /// Parses web application pool element. + /// + /// Element to parse. + /// Optional identifier of parent component. + private void ParseWebAppPoolElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int attributes = 0; + var cpuAction = CompilerConstants.IntegerNotSet; + string cpuMon = null; + var idleTimeout = CompilerConstants.IntegerNotSet; + int maxCpuUsage = 0; + var maxWorkerProcs = CompilerConstants.IntegerNotSet; + string managedRuntimeVersion = null; + string managedPipelineMode = null; + string name = null; + var privateMemory = CompilerConstants.IntegerNotSet; + var queueLimit = CompilerConstants.IntegerNotSet; + var recycleMinutes = CompilerConstants.IntegerNotSet; + var recycleRequests = CompilerConstants.IntegerNotSet; + string recycleTimes = null; + var refreshCpu = CompilerConstants.IntegerNotSet; + string user = null; + var virtualMemory = CompilerConstants.IntegerNotSet; + + foreach (var attrib in element.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 "CpuAction": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + var cpuActionValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < cpuActionValue.Length) + { + switch (cpuActionValue) + { + case "shutdown": + cpuAction = 1; + break; + case "none": + cpuAction = 0; + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, cpuActionValue, "shutdown", "none")); + break; + } + } + break; + case "Identity": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + var identityValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < identityValue.Length) + { + switch (identityValue) + { + case "networkService": + attributes |= 1; + break; + case "localService": + attributes |= 2; + break; + case "localSystem": + attributes |= 4; + break; + case "other": + attributes |= 8; + break; + case "applicationPoolIdentity": + attributes |= 0x10; + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, identityValue, "networkService", "localService", "localSystem", "other", "applicationPoolIdentity")); + break; + } + } + break; + case "IdleTimeout": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + idleTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "ManagedPipelineMode": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + managedPipelineMode = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + + + if (!String.IsNullOrEmpty(managedPipelineMode)) + { + switch (managedPipelineMode) + { + // In 3.5 we allowed lower case values (per camel case enum style), we now use formatted fields, + // so the value needs to match exactly what we pass in to IIS which uses pascal case. + case "classic": + managedPipelineMode = "Classic"; + break; + case "integrated": + managedPipelineMode = "Integrated"; + break; + case "Classic": + break; + case "Integrated": + break; + default: + if (!this.ParseHelper.ContainsProperty(managedPipelineMode)) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, managedPipelineMode, "Classic", "Integrated")); + } + break; + } + } + + break; + case "ManagedRuntimeVersion": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + managedRuntimeVersion = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "MaxCpuUsage": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + maxCpuUsage = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100); + break; + case "MaxWorkerProcesses": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + maxWorkerProcs = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "Name": + name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "PrivateMemory": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + privateMemory = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 4294967); + break; + case "QueueLimit": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + queueLimit = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "RecycleMinutes": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + recycleMinutes = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "RecycleRequests": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + recycleRequests = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "RefreshCpu": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + refreshCpu = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); + break; + case "User": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); + break; + case "VirtualMemory": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + virtualMemory = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 4294967); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("iap", name, componentId, user); + } + + if (null == name) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); + } + + if (null == user && 8 == (attributes & 0x1F)) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "User", "Identity", "other")); + } + + if (null != user && 8 != (attributes & 0x1F)) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, element.Name.LocalName, "User", user, "Identity", "other")); + } + + cpuMon = maxCpuUsage.ToString(CultureInfo.InvariantCulture.NumberFormat); + if (CompilerConstants.IntegerNotSet != refreshCpu) + { + cpuMon = String.Concat(cpuMon, ",", refreshCpu.ToString(CultureInfo.InvariantCulture.NumberFormat)); + if (CompilerConstants.IntegerNotSet != cpuAction) + { + cpuMon = String.Concat(cpuMon, ",", cpuAction.ToString(CultureInfo.InvariantCulture.NumberFormat)); + } + } + + foreach (var child in element.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + switch (child.Name.LocalName) + { + case "RecycleTime": + if (null == componentId) + { + var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, element.Name.LocalName)); + } + + if (null == recycleTimes) + { + recycleTimes = this.ParseRecycleTimeElement(intermediate, section, child); + } + else + { + recycleTimes = String.Concat(recycleTimes, ",", this.ParseRecycleTimeElement(intermediate, section, child)); + } + break; + default: + this.ParseHelper.UnexpectedElement(element, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); + } + } + + if (null != componentId) + { + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + } + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new IIsAppPoolSymbol(sourceLineNumbers, id) + { + Name = name, + ComponentRef = componentId, + Attributes = attributes, + UserRef = user, + RecycleTimes = recycleTimes, + CPUMon = cpuMon, + ManagedRuntimeVersion = managedRuntimeVersion, + ManagedPipelineMode = managedPipelineMode, + }); + + if (CompilerConstants.IntegerNotSet != recycleMinutes) + { + symbol.RecycleMinutes = recycleMinutes; + } + + if (CompilerConstants.IntegerNotSet != recycleRequests) + { + symbol.RecycleRequests = recycleRequests; + } + + if (CompilerConstants.IntegerNotSet != idleTimeout) + { + symbol.IdleTimeout = idleTimeout; + } + + if (CompilerConstants.IntegerNotSet != queueLimit) + { + symbol.QueueLimit = queueLimit; + } + + if (CompilerConstants.IntegerNotSet != maxWorkerProcs) + { + symbol.MaxProc = maxWorkerProcs; + } + + if (CompilerConstants.IntegerNotSet != virtualMemory) + { + symbol.VirtualMemory = virtualMemory; + } + + if (CompilerConstants.IntegerNotSet != privateMemory) + { + symbol.PrivateMemory = privateMemory; + } + } + } + + /// + /// Parses a web directory element. + /// + /// Element to parse. + /// Identifier for parent component. + /// Optional identifier for parent web site. + private void ParseWebDirElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string parentWeb) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string dirProperties = null; + string path = null; + string application = null; + + foreach (var attrib in element.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 "DirProperties": + dirProperties = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + break; + case "Path": + path = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "WebApplication": + application = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "WebSite": + if (null != parentWeb) + { + this.Messaging.Write(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, element.Name.LocalName)); + } + + parentWeb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebSite, parentWeb); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("iwd", componentId, parentWeb, dirProperties, application); + } + + if (null == path) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Path")); + } + + if (null == parentWeb) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "WebSite")); + } + + foreach (var child in element.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); + switch (child.Name.LocalName) + { + case "WebApplication": + if (null != application) + { + this.Messaging.Write(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, element.Name.LocalName)); + } + + application = this.ParseWebApplicationElement(intermediate, section, child); + break; + case "WebDirProperties": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + string childWebDirProperties = this.ParseWebDirPropertiesElement(intermediate, section, child, componentId); + if (null == dirProperties) + { + dirProperties = childWebDirProperties; + } + else + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, child.Name.LocalName, "DirProperties", child.Name.LocalName)); + } + break; + default: + this.ParseHelper.UnexpectedElement(element, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); + } + } + + if (null == dirProperties) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "DirProperties")); + } + + if (null != application) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebApplication, application); + } + + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebDirProperties, dirProperties); + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsWebDirSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + WebRef = parentWeb, + Path = path, + DirPropertiesRef = dirProperties, + ApplicationRef = application, + }); + } + } + + /// + /// Parses a web directory properties element. + /// + /// Element to parse. + /// The identifier for this WebDirProperties. + private string ParseWebDirPropertiesElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int access = 0; + var accessSet = false; + int accessSSLFlags = 0; + var accessSSLFlagsSet = false; + string anonymousUser = null; + var aspDetailedError = YesNoType.NotSet; + string authenticationProviders = null; + int authorization = 0; + var authorizationSet = false; + string cacheControlCustom = null; + var cacheControlMaxAge = CompilerConstants.LongNotSet; + string defaultDocuments = null; + string httpExpires = null; + var iisControlledPassword = false; + var index = YesNoType.NotSet; + var logVisits = YesNoType.NotSet; + var notCustomError = YesNoType.NotSet; + + foreach (var attrib in element.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 "AnonymousUser": + anonymousUser = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", anonymousUser); + break; + case "AspDetailedError": + aspDetailedError = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; + case "AuthenticationProviders": + authenticationProviders = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "CacheControlCustom": + cacheControlCustom = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "CacheControlMaxAge": + cacheControlMaxAge = this.ParseHelper.GetAttributeLongValue(sourceLineNumbers, attrib, 0, uint.MaxValue); // 4294967295 (uint.MaxValue) represents unlimited + break; + case "ClearCustomError": + notCustomError = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; + case "DefaultDocuments": + defaultDocuments = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "HttpExpires": + httpExpires = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "IIsControlledPassword": + iisControlledPassword = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; + case "Index": + index = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; + case "LogVisits": + logVisits = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; + + // Access attributes + case "Execute": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + access |= 4; + } + else + { + access &= ~4; + } + accessSet = true; + break; + case "Read": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + access |= 1; + } + else + { + access &= ~1; + } + accessSet = true; + break; + case "Script": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + access |= 512; + } + else + { + access &= ~512; + } + accessSet = true; + break; + case "Write": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + access |= 2; + } + else + { + access &= ~2; + } + accessSet = true; + break; + + // AccessSSL Attributes + case "AccessSSL": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + accessSSLFlags |= 8; + } + else + { + accessSSLFlags &= ~8; + } + accessSSLFlagsSet = true; + break; + case "AccessSSL128": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + accessSSLFlags |= 256; + } + else + { + accessSSLFlags &= ~256; + } + accessSSLFlagsSet = true; + break; + case "AccessSSLMapCert": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + accessSSLFlags |= 128; + } + else + { + accessSSLFlags &= ~128; + } + accessSSLFlagsSet = true; + break; + case "AccessSSLNegotiateCert": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + accessSSLFlags |= 32; + } + else + { + accessSSLFlags &= ~32; + } + accessSSLFlagsSet = true; + break; + case "AccessSSLRequireCert": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + accessSSLFlags |= 64; + } + else + { + accessSSLFlags &= ~64; + } + accessSSLFlagsSet = true; + break; + + // Authorization attributes + case "AnonymousAccess": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + authorization |= 1; + } + else + { + authorization &= ~1; + } + authorizationSet = true; + break; + case "BasicAuthentication": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + authorization |= 2; + } + else + { + authorization &= ~2; + } + authorizationSet = true; + break; + case "DigestAuthentication": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + authorization |= 16; + } + else + { + authorization &= ~16; + } + authorizationSet = true; + break; + case "PassportAuthentication": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + authorization |= 64; + } + else + { + authorization &= ~64; + } + authorizationSet = true; + break; + case "WindowsAuthentication": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + authorization |= 4; + } + else + { + authorization &= ~4; + } + authorizationSet = true; + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + if (null == componentId) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + id = Identifier.Invalid; + } + else + { + id = this.ParseHelper.CreateIdentifier("wdp", componentId); + } + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new IIsWebDirPropertiesSymbol(sourceLineNumbers, id) + { + AnonymousUserRef = anonymousUser, + IIsControlledPassword = iisControlledPassword ? 1 : 0, + DefaultDoc = defaultDocuments, + HttpExpires = httpExpires, + CacheControlCustom = cacheControlCustom, + }); + + if (accessSet) + { + symbol.Access = access; + } + + if (authorizationSet) + { + symbol.Authorization = authorization; + } + + if (YesNoType.NotSet != logVisits) + { + symbol.LogVisits = YesNoType.Yes == logVisits ? 1 : 0; + } + + if (YesNoType.NotSet != index) + { + symbol.Index = YesNoType.Yes == index ? 1 : 0; + } + + if (YesNoType.NotSet != aspDetailedError) + { + symbol.AspDetailedError = YesNoType.Yes == aspDetailedError ? 1 : 0; + } + + if (CompilerConstants.LongNotSet != cacheControlMaxAge) + { + symbol.CacheControlMaxAge = unchecked((int)cacheControlMaxAge); + } + + if (YesNoType.NotSet != notCustomError) + { + symbol.NoCustomError = YesNoType.Yes == notCustomError ? 1 : 0; + } + + if (accessSSLFlagsSet) + { + symbol.AccessSSLFlags = accessSSLFlags; + } + + if (null != authenticationProviders) + { + symbol.AuthenticationProviders = authenticationProviders; + } + } + + return id?.Id; + } + + /// + /// Parses a web error element. + /// + /// Element to parse. + /// Type of the parent. + /// Id of the parent. + private void ParseWebErrorElement(Intermediate intermediate, IntermediateSection section, XElement element, WebErrorParentType parentType, string parent) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var errorCode = CompilerConstants.IntegerNotSet; + string file = null; + string url = null; + var subCode = CompilerConstants.IntegerNotSet; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "ErrorCode": + errorCode = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 400, 599); + break; + case "File": + file = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "SubCode": + subCode = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); + break; + case "URL": + url = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (CompilerConstants.IntegerNotSet == errorCode) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "ErrorCode")); + errorCode = CompilerConstants.IllegalInteger; + } + + if (CompilerConstants.IntegerNotSet == subCode) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SubCode")); + subCode = CompilerConstants.IllegalInteger; + } + + if (String.IsNullOrEmpty(file) && String.IsNullOrEmpty(url)) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "File", "URL")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsWebErrorSymbol(sourceLineNumbers) + { + ErrorCode = errorCode, + SubCode = subCode, + ParentType = (int)parentType, + ParentValue = parent, + File = file, + URL = url, + }); + } + } + + /// + /// Parses a web filter element. + /// + /// Element to parse. + /// Identifier of parent component. + /// Optional identifier of parent web site. + private void ParseWebFilterElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string parentWeb) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string description = null; + int flags = 0; + var loadOrder = CompilerConstants.IntegerNotSet; + string name = null; + string path = null; + + foreach (var attrib in element.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 "Description": + description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Flags": + flags = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); + break; + case "LoadOrder": + string loadOrderValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < loadOrderValue.Length) + { + switch (loadOrderValue) + { + case "first": + loadOrder = 0; + break; + case "last": + loadOrder = -1; + break; + default: + loadOrder = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); + break; + } + } + break; + case "Name": + name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Path": + path = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "WebSite": + if (null != parentWeb) + { + this.Messaging.Write(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, element.Name.LocalName)); + } + + parentWeb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebSite, parentWeb); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("ifl", name, componentId, path, parentWeb); + } + + if (null == name) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); + } + + if (null == path) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Path")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new IIsFilterSymbol(sourceLineNumbers, id) + { + Name = name, + ComponentRef = componentId, + Path = path, + WebRef = parentWeb, + Description = description, + Flags = flags, + }); + + if (CompilerConstants.IntegerNotSet != loadOrder) + { + symbol.LoadOrder = loadOrder; + } + } + } + + /// + /// Parses web log element. + /// + /// Node to be parsed. + private void ParseWebLogElement(Intermediate intermediate, IntermediateSection section, XElement element) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string type = null; + + foreach (var attrib in element.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 "Type": + var typeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (0 < typeValue.Length) + { + switch (typeValue) + { + case "IIS": + type = "Microsoft IIS Log File Format"; + break; + case "NCSA": + type = "NCSA Common Log File Format"; + break; + case "none": + type = "none"; + break; + case "ODBC": + type = "ODBC Logging"; + break; + case "W3C": + type = "W3C Extended Log File Format"; + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Type", typeValue, "IIS", "NCSA", "none", "ODBC", "W3C")); + break; + } + } + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + } + + if (null == type) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Type")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsWebLogSymbol(sourceLineNumbers, id) + { + Format = type, + }); + } + } + + /// + /// Parses a web property element. + /// + /// Element to parse. + /// Identifier for parent component. + private void ParseWebPropertyElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string value = null; + + foreach (var attrib in element.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 "Value": + value = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + switch (id?.Id) + { + case "ETagChangeNumber": + case "MaxGlobalBandwidth": + // Must specify a value for these + if (null == value) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value", "Id", id.Id)); + } + break; + case "IIs5IsolationMode": + case "LogInUTF8": + // Can't specify a value for these + if (null != value) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Value", "Id", id.Id)); + } + break; + default: + this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Id", id?.Id, "ETagChangeNumber", "IIs5IsolationMode", "LogInUTF8", "MaxGlobalBandwidth")); + break; + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsPropertySymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + Attributes = 0, + Value = value, + }); + } + } + + /// + /// Parses a web service extension element. + /// + /// Element to parse. + /// Identifier for parent component. + private void ParseWebServiceExtensionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int attributes = 0; + string description = null; + string file = null; + string group = null; + + foreach (XAttribute attrib in element.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 "Allow": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 1; + } + else + { + attributes &= ~1; + } + break; + case "Description": + description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "File": + file = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Group": + group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "UIDeletable": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= 2; + } + else + { + attributes &= ~2; + } + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("iwe", componentId, file); + } + + if (null == file) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "File")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsWebServiceExtensionSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + File = file, + Description = description, + Group = group, + Attributes = attributes, + }); + } + } + + /// + /// Parses a web site element. + /// + /// Element to parse. + /// Optional identifier of parent component. + private void ParseWebSiteElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string application = null; + int attributes = 0; + var connectionTimeout = CompilerConstants.IntegerNotSet; + string description = null; + string directory = null; + string dirProperties = null; + string keyAddress = null; + string log = null; + string siteId = null; + var sequence = CompilerConstants.IntegerNotSet; + var state = CompilerConstants.IntegerNotSet; + + foreach (var attrib in element.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 "AutoStart": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + state = 2; + } + else if (state != 1) + { + state = 0; + } + break; + case "ConfigureIfExists": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes &= ~2; + } + else + { + attributes |= 2; + } + break; + case "ConnectionTimeout": + connectionTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); + break; + case "Description": + description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Directory": + directory = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, directory); + break; + case "DirProperties": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + dirProperties = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "SiteId": + siteId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if ("*" == siteId) + { + siteId = "-1"; + } + break; + case "Sequence": + sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); + break; + case "StartOnInstall": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + // when state is set to 2 it implies 1, so don't set it to 1 + if (2 != state && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + state = 1; + } + else if (2 != state) + { + state = 0; + } + break; + case "WebApplication": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + application = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "WebLog": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + log = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebLog, log); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("iws", description, componentId, siteId, application); + } + + if (null == description) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Description")); + } + + if (null == directory && null != componentId) + { + this.Messaging.Write(IIsErrors.RequiredAttributeUnderComponent(sourceLineNumbers, element.Name.LocalName, "Directory")); + } + + foreach (var child in element.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); + switch (child.Name.LocalName) + { + case "CertificateRef": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseCertificateRefElement(intermediate, section, child, id?.Id); + break; + case "HttpHeader": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseHttpHeaderElement(intermediate, section, child, HttpHeaderParentType.WebSite, id?.Id); + break; + case "WebAddress": + string address = this.ParseWebAddressElement(intermediate, section, child, id?.Id); + if (null == keyAddress) + { + keyAddress = address; + } + break; + case "WebApplication": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + if (null != application) + { + this.Messaging.Write(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, element.Name.LocalName)); + } + + application = this.ParseWebApplicationElement(intermediate, section, child); + break; + case "WebDir": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseWebDirElement(intermediate, section, child, componentId, id?.Id); + break; + case "WebDirProperties": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + string childWebDirProperties = this.ParseWebDirPropertiesElement(intermediate, section, child, componentId); + if (null == dirProperties) + { + dirProperties = childWebDirProperties; + } + else + { + this.Messaging.Write(ErrorMessages.IllegalParentAttributeWhenNested(sourceLineNumbers, "WebSite", "DirProperties", child.Name.LocalName)); + } + break; + case "WebError": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseWebErrorElement(intermediate, section, child, WebErrorParentType.WebSite, id?.Id); + break; + case "WebFilter": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseWebFilterElement(intermediate, section, child, componentId, id?.Id); + break; + case "WebVirtualDir": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseWebVirtualDirElement(intermediate, section, child, componentId, id?.Id, null); + break; + case "MimeMap": + this.ParseMimeMapElement(intermediate, section, child, id?.Id, MimeMapParentType.WebSite); + break; + default: + this.ParseHelper.UnexpectedElement(element, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); + } + } + + + if (null == keyAddress) + { + this.Messaging.Write(ErrorMessages.ExpectedElement(sourceLineNumbers, element.Name.LocalName, "WebAddress")); + } + + if (null != application) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebApplication, application); + } + + if (null != dirProperties) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebDirProperties, dirProperties); + } + + if (null != componentId) + { + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + } + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new IIsWebSiteSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + Description = description, + DirectoryRef = directory, + KeyAddressRef = keyAddress, + DirPropertiesRef = dirProperties, + ApplicationRef = application, + LogRef = log, + WebsiteId = siteId, + }); + + if (CompilerConstants.IntegerNotSet != connectionTimeout) + { + symbol.ConnectionTimeout = connectionTimeout; + } + + if (CompilerConstants.IntegerNotSet != state) + { + symbol.State = state; + } + + if (0 != attributes) + { + symbol.Attributes = attributes; + } + + if (CompilerConstants.IntegerNotSet != sequence) + { + symbol.Sequence = sequence; + } + } + } + + /// + /// Parses a HTTP Header element. + /// + /// Element to parse. + /// Type of the parent. + /// Id of the parent. + private void ParseHttpHeaderElement(Intermediate intermediate, IntermediateSection section, XElement element, HttpHeaderParentType parentType, string parent) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string headerName = null; + string headerValue = null; + + foreach (var attrib in element.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 "Name": + headerName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Value": + headerValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == headerName) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); + } + else if (null == id) + { + id = this.ParseHelper.CreateIdentifierFromFilename(headerName); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsHttpHeaderSymbol(sourceLineNumbers, id) + { + HttpHeader = id.Id, + ParentType = (int)parentType, + ParentValue = parent, + Name = headerName, + Value = headerValue, + Attributes = 0, + }); + } + } + + /// + /// Parses a virtual directory element. + /// + /// Element to parse. + /// Identifier of parent component. + /// Identifier of parent web site. + /// Alias of the parent web site. + private void ParseWebVirtualDirElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string parentWeb, string parentAlias) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string alias = null; + string application = null; + string directory = null; + string dirProperties = null; + + foreach (var attrib in element.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 "Alias": + alias = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Directory": + directory = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, directory); + break; + case "DirProperties": + dirProperties = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "WebApplication": + application = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "WebSite": + if (null != parentWeb) + { + this.Messaging.Write(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, element.Name.LocalName)); + } + + parentWeb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebSite, parentWeb); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("wvd", alias, directory, dirProperties, application, parentWeb); + } + + if (null == alias) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Alias")); + } + else if (-1 != alias.IndexOf("\\", StringComparison.Ordinal)) + { + this.Messaging.Write(IIsErrors.IllegalCharacterInAttributeValue(sourceLineNumbers, element.Name.LocalName, "Alias", alias, '\\')); + } + + if (null == directory) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Directory")); + } + + if (null == parentWeb) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "WebSite")); + } + + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(sourceLineNumbers, element.Name.LocalName)); + } + + if (null != parentAlias) + { + alias = String.Concat(parentAlias, "/", alias); + } + + foreach (var child in element.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); + switch (child.Name.LocalName) + { + case "WebApplication": + if (null != application) + { + this.Messaging.Write(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, element.Name.LocalName)); + } + + application = this.ParseWebApplicationElement(intermediate, section, child); + break; + case "WebDirProperties": + if (null == componentId) + { + this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + string childWebDirProperties = this.ParseWebDirPropertiesElement(intermediate, section, child, componentId); + if (null == dirProperties) + { + dirProperties = childWebDirProperties; + } + else + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, child.Name.LocalName, "DirProperties", child.Name.LocalName)); + } + break; + + case "WebError": + this.ParseWebErrorElement(intermediate, section, child, WebErrorParentType.WebVirtualDir, id?.Id); + break; + case "WebVirtualDir": + this.ParseWebVirtualDirElement(intermediate, section, child, componentId, parentWeb, alias); + break; + case "HttpHeader": + this.ParseHttpHeaderElement(intermediate, section, child, HttpHeaderParentType.WebVirtualDir, id?.Id); + break; + case "MimeMap": + this.ParseMimeMapElement(intermediate, section, child, id?.Id, MimeMapParentType.WebVirtualDir); + break; + default: + this.ParseHelper.UnexpectedElement(element, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); + } + } + + if (null != dirProperties) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebDirProperties, dirProperties); + } + + if (null != application) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebApplication, application); + } + + // Reference ConfigureIIs since nothing will happen without it + this.AddReferenceToConfigureIIs(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + section.AddSymbol(new IIsWebVirtualDirSymbol(sourceLineNumbers, id) + { + ComponentRef = componentId, + WebRef = parentWeb, + Alias = alias, + DirectoryRef = directory, + DirPropertiesRef = dirProperties, + ApplicationRef = application, + }); + } + } + + private void AddReferenceToConfigureIIs(IntermediateSection section, SourceLineNumber sourceLineNumbers) + { + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4ConfigureIIs", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + } + } +} diff --git a/src/ext/Iis/wixext/IIsDecompiler.cs b/src/ext/Iis/wixext/IIsDecompiler.cs new file mode 100644 index 00000000..17e15348 --- /dev/null +++ b/src/ext/Iis/wixext/IIsDecompiler.cs @@ -0,0 +1,1549 @@ +// 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.Iis +{ +#if TODO_CONSIDER_DECOMPILER + using System; + using System.Collections; + using System.Globalization; + using WixToolset.Data; + using WixToolset.Extensibility; + using IIs = WixToolset.Extensions.Serialize.IIs; + using Wix = WixToolset.Data.Serialize; + + /// + /// The decompiler for the WiX Toolset Internet Information Services Extension. + /// + public sealed class IIsDecompiler : DecompilerExtension + { + /// + /// Creates a decompiler for IIs Extension. + /// + public IIsDecompiler() + { + this.TableDefinitions = IIsExtensionData.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 IIsExtensionData.GetExtensionLibrary(tableDefinitions); + } + + /// + /// Decompiles an extension table. + /// + /// The table to decompile. + public override void DecompileTable(Table table) + { + switch (table.Name) + { + case "Certificate": + this.DecompileCertificateTable(table); + break; + case "CertificateHash": + // There is nothing to do for this table, it contains no authored data + // to be decompiled. + break; + case "IIsAppPool": + this.DecompileIIsAppPoolTable(table); + break; + case "IIsFilter": + this.DecompileIIsFilterTable(table); + break; + case "IIsProperty": + this.DecompileIIsPropertyTable(table); + break; + case "IIsHttpHeader": + this.DecompileIIsHttpHeaderTable(table); + break; + case "IIsMimeMap": + this.DecompileIIsMimeMapTable(table); + break; + case "IIsWebAddress": + this.DecompileIIsWebAddressTable(table); + break; + case "IIsWebApplication": + this.DecompileIIsWebApplicationTable(table); + break; + case "IIsWebDirProperties": + this.DecompileIIsWebDirPropertiesTable(table); + break; + case "IIsWebError": + this.DecompileIIsWebErrorTable(table); + break; + case "IIsWebLog": + this.DecompileIIsWebLogTable(table); + break; + case "IIsWebServiceExtension": + this.DecompileIIsWebServiceExtensionTable(table); + break; + case "IIsWebSite": + this.DecompileIIsWebSiteTable(table); + break; + case "IIsWebVirtualDir": + this.DecompileIIsWebVirtualDirTable(table); + break; + case "IIsWebSiteCertificates": + this.DecompileIIsWebSiteCertificatesTable(table); + break; + default: + base.DecompileTable(table); + break; + } + } + + /// + /// Finalize decompilation. + /// + /// The collection of all tables. + public override void Finish(TableIndexedCollection tables) + { + this.FinalizeIIsMimeMapTable(tables); + this.FinalizeIIsHttpHeaderTable(tables); + this.FinalizeIIsWebApplicationTable(tables); + this.FinalizeIIsWebErrorTable(tables); + this.FinalizeIIsWebVirtualDirTable(tables); + this.FinalizeIIsWebSiteCertificatesTable(tables); + this.FinalizeWebAddressTable(tables); + } + + /// + /// Decompile the Certificate table. + /// + /// The table to decompile. + private void DecompileCertificateTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.Certificate certificate = new IIs.Certificate(); + + certificate.Id = (string)row[0]; + certificate.Name = (string)row[2]; + + switch ((int)row[3]) + { + case 1: + certificate.StoreLocation = IIs.Certificate.StoreLocationType.currentUser; + break; + case 2: + certificate.StoreLocation = IIs.Certificate.StoreLocationType.localMachine; + break; + default: + // TODO: warn + break; + } + + switch ((string)row[4]) + { + case "CA": + certificate.StoreName = IIs.Certificate.StoreNameType.ca; + break; + case "MY": + certificate.StoreName = IIs.Certificate.StoreNameType.my; + break; + case "REQUEST": + certificate.StoreName = IIs.Certificate.StoreNameType.request; + break; + case "Root": + certificate.StoreName = IIs.Certificate.StoreNameType.root; + break; + case "AddressBook": + certificate.StoreName = IIs.Certificate.StoreNameType.otherPeople; + break; + case "TrustedPeople": + certificate.StoreName = IIs.Certificate.StoreNameType.trustedPeople; + break; + case "TrustedPublisher": + certificate.StoreName = IIs.Certificate.StoreNameType.trustedPublisher; + break; + default: + // TODO: warn + break; + } + + int attribute = (int)row[5]; + + if (0x1 == (attribute & 0x1)) + { + certificate.Request = IIs.YesNoType.yes; + } + + if (0x2 == (attribute & 0x2)) + { + if (null != row[6]) + { + certificate.BinaryKey = (string)row[6]; + } + else + { + // TODO: warn about expected value in row 5 + } + } + else if (null != row[7]) + { + certificate.CertificatePath = (string)row[7]; + } + + if (0x4 == (attribute & 0x4)) + { + certificate.Overwrite = IIs.YesNoType.yes; + } + + if (null != row[8]) + { + certificate.PFXPassword = (string)row[8]; + } + + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + if (null != component) + { + component.AddChild(certificate); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + + /// + /// Decompile the IIsAppPool table. + /// + /// The table to decompile. + private void DecompileIIsAppPoolTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebAppPool webAppPool = new IIs.WebAppPool(); + + webAppPool.Id = (string)row[0]; + + webAppPool.Name = (string)row[1]; + + switch ((int)row[3] & 0x1F) + { + case 1: + webAppPool.Identity = IIs.WebAppPool.IdentityType.networkService; + break; + case 2: + webAppPool.Identity = IIs.WebAppPool.IdentityType.localService; + break; + case 4: + webAppPool.Identity = IIs.WebAppPool.IdentityType.localSystem; + break; + case 8: + webAppPool.Identity = IIs.WebAppPool.IdentityType.other; + break; + case 0x10: + webAppPool.Identity = IIs.WebAppPool.IdentityType.applicationPoolIdentity; + break; + default: + // TODO: warn + break; + } + + if (null != row[4]) + { + webAppPool.User = (string)row[4]; + } + + if (null != row[5]) + { + webAppPool.RecycleMinutes = (int)row[5]; + } + + if (null != row[6]) + { + webAppPool.RecycleRequests = (int)row[6]; + } + + if (null != row[7]) + { + string[] recycleTimeValues = ((string)row[7]).Split(','); + + foreach (string recycleTimeValue in recycleTimeValues) + { + IIs.RecycleTime recycleTime = new IIs.RecycleTime(); + + recycleTime.Value = recycleTimeValue; + + webAppPool.AddChild(recycleTime); + } + } + + if (null != row[8]) + { + webAppPool.IdleTimeout = (int)row[8]; + } + + if (null != row[9]) + { + webAppPool.QueueLimit = (int)row[9]; + } + + if (null != row[10]) + { + string[] cpuMon = ((string)row[10]).Split(','); + + if (0 < cpuMon.Length && "0" != cpuMon[0]) + { + webAppPool.MaxCpuUsage = Convert.ToInt32(cpuMon[0], CultureInfo.InvariantCulture); + } + + if (1 < cpuMon.Length) + { + webAppPool.RefreshCpu = Convert.ToInt32(cpuMon[1], CultureInfo.InvariantCulture); + } + + if (2 < cpuMon.Length) + { + switch (Convert.ToInt32(cpuMon[2], CultureInfo.InvariantCulture)) + { + case 0: + webAppPool.CpuAction = IIs.WebAppPool.CpuActionType.none; + break; + case 1: + webAppPool.CpuAction = IIs.WebAppPool.CpuActionType.shutdown; + break; + default: + // TODO: warn + break; + } + } + + if (3 < cpuMon.Length) + { + // TODO: warn + } + } + + if (null != row[11]) + { + webAppPool.MaxWorkerProcesses = (int)row[11]; + } + + if (null != row[12]) + { + webAppPool.VirtualMemory = (int)row[12]; + } + + if (null != row[13]) + { + webAppPool.PrivateMemory = (int)row[13]; + } + + if (null != row[14]) + { + webAppPool.ManagedRuntimeVersion = (string)row[14]; + } + + if (null != row[15]) + { + webAppPool.ManagedPipelineMode = (string)row[15]; + } + + if (null != row[2]) + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); + + if (null != component) + { + component.AddChild(webAppPool); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); + } + } + else + { + this.Core.RootElement.AddChild(webAppPool); + } + } + } + + /// + /// Decompile the IIsProperty table. + /// + /// The table to decompile. + private void DecompileIIsPropertyTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebProperty webProperty = new IIs.WebProperty(); + + switch ((string)row[0]) + { + case "ETagChangeNumber": + webProperty.Id = IIs.WebProperty.IdType.ETagChangeNumber; + break; + case "IIs5IsolationMode": + webProperty.Id = IIs.WebProperty.IdType.IIs5IsolationMode; + break; + case "LogInUTF8": + webProperty.Id = IIs.WebProperty.IdType.LogInUTF8; + break; + case "MaxGlobalBandwidth": + webProperty.Id = IIs.WebProperty.IdType.MaxGlobalBandwidth; + break; + } + + if (0 != (int)row[2]) + { + // TODO: warn about value in unused column + } + + if (null != row[3]) + { + webProperty.Value = (string)row[3]; + } + + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + if (null != component) + { + component.AddChild(webProperty); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + + /// + /// Decompile the IIsHttpHeader table. + /// + /// The table to decompile. + private void DecompileIIsHttpHeaderTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.HttpHeader httpHeader = new IIs.HttpHeader(); + + httpHeader.Name = (string)row[3]; + + // the ParentType and Parent columns are handled in FinalizeIIsHttpHeaderTable + + httpHeader.Value = (string)row[4]; + + this.Core.IndexElement(row, httpHeader); + } + } + + /// + /// Decompile the IIsMimeMap table. + /// + /// The table to decompile. + private void DecompileIIsMimeMapTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.MimeMap mimeMap = new IIs.MimeMap(); + + mimeMap.Id = (string)row[0]; + + // the ParentType and ParentValue columns are handled in FinalizeIIsMimeMapTable + + mimeMap.Type = (string)row[3]; + + mimeMap.Extension = (string)row[4]; + + this.Core.IndexElement(row, mimeMap); + } + } + + /// + /// Decompile the IIsWebAddress table. + /// + /// The table to decompile. + private void DecompileIIsWebAddressTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebAddress webAddress = new IIs.WebAddress(); + + webAddress.Id = (string)row[0]; + + if (null != row[2]) + { + webAddress.IP = (string)row[2]; + } + + webAddress.Port = (string)row[3]; + + if (null != row[4]) + { + webAddress.Header = (string)row[4]; + } + + if (null != row[5] && 1 == (int)row[5]) + { + webAddress.Secure = IIs.YesNoType.yes; + } + + this.Core.IndexElement(row, webAddress); + } + } + + /// + /// Decompile the IIsWebApplication table. + /// + /// The table to decompile. + private void DecompileIIsWebApplicationTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebApplication webApplication = new IIs.WebApplication(); + + webApplication.Id = (string)row[0]; + + webApplication.Name = (string)row[1]; + + // these are not listed incorrectly - the order is low, high, medium + switch ((int)row[2]) + { + case 0: + webApplication.Isolation = IIs.WebApplication.IsolationType.low; + break; + case 1: + webApplication.Isolation = IIs.WebApplication.IsolationType.high; + break; + case 2: + webApplication.Isolation = IIs.WebApplication.IsolationType.medium; + break; + default: + // TODO: warn + break; + } + + if (null != row[3]) + { + switch ((int)row[3]) + { + case 0: + webApplication.AllowSessions = IIs.YesNoDefaultType.no; + break; + case 1: + webApplication.AllowSessions = IIs.YesNoDefaultType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[4]) + { + webApplication.SessionTimeout = (int)row[4]; + } + + if (null != row[5]) + { + switch ((int)row[5]) + { + case 0: + webApplication.Buffer = IIs.YesNoDefaultType.no; + break; + case 1: + webApplication.Buffer = IIs.YesNoDefaultType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[6]) + { + switch ((int)row[6]) + { + case 0: + webApplication.ParentPaths = IIs.YesNoDefaultType.no; + break; + case 1: + webApplication.ParentPaths = IIs.YesNoDefaultType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[7]) + { + switch ((string)row[7]) + { + case "JScript": + webApplication.DefaultScript = IIs.WebApplication.DefaultScriptType.JScript; + break; + case "VBScript": + webApplication.DefaultScript = IIs.WebApplication.DefaultScriptType.VBScript; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[8]) + { + webApplication.ScriptTimeout = (int)row[8]; + } + + if (null != row[9]) + { + switch ((int)row[9]) + { + case 0: + webApplication.ServerDebugging = IIs.YesNoDefaultType.no; + break; + case 1: + webApplication.ServerDebugging = IIs.YesNoDefaultType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[10]) + { + switch ((int)row[10]) + { + case 0: + webApplication.ClientDebugging = IIs.YesNoDefaultType.no; + break; + case 1: + webApplication.ClientDebugging = IIs.YesNoDefaultType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[11]) + { + webApplication.WebAppPool = (string)row[11]; + } + + this.Core.IndexElement(row, webApplication); + } + } + + /// + /// Decompile the IIsWebDirProperties table. + /// + /// The table to decompile. + private void DecompileIIsWebDirPropertiesTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebDirProperties webDirProperties = new IIs.WebDirProperties(); + + webDirProperties.Id = (string)row[0]; + + if (null != row[1]) + { + int access = (int)row[1]; + + if (0x1 == (access & 0x1)) + { + webDirProperties.Read = IIs.YesNoType.yes; + } + + if (0x2 == (access & 0x2)) + { + webDirProperties.Write = IIs.YesNoType.yes; + } + + if (0x4 == (access & 0x4)) + { + webDirProperties.Execute = IIs.YesNoType.yes; + } + + if (0x200 == (access & 0x200)) + { + webDirProperties.Script = IIs.YesNoType.yes; + } + } + + if (null != row[2]) + { + int authorization = (int)row[2]; + + if (0x1 == (authorization & 0x1)) + { + webDirProperties.AnonymousAccess = IIs.YesNoType.yes; + } + else // set one of the properties to 'no' to force the output value to be '0' if not other attributes are set + { + webDirProperties.AnonymousAccess = IIs.YesNoType.no; + } + + if (0x2 == (authorization & 0x2)) + { + webDirProperties.BasicAuthentication = IIs.YesNoType.yes; + } + + if (0x4 == (authorization & 0x4)) + { + webDirProperties.WindowsAuthentication = IIs.YesNoType.yes; + } + + if (0x10 == (authorization & 0x10)) + { + webDirProperties.DigestAuthentication = IIs.YesNoType.yes; + } + + if (0x40 == (authorization & 0x40)) + { + webDirProperties.PassportAuthentication = IIs.YesNoType.yes; + } + } + + if (null != row[3]) + { + webDirProperties.AnonymousUser = (string)row[3]; + } + + if (null != row[4] && 1 == (int)row[4]) + { + webDirProperties.IIsControlledPassword = IIs.YesNoType.yes; + } + + if (null != row[5]) + { + switch ((int)row[5]) + { + case 0: + webDirProperties.LogVisits = IIs.YesNoType.no; + break; + case 1: + webDirProperties.LogVisits = IIs.YesNoType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[6]) + { + switch ((int)row[6]) + { + case 0: + webDirProperties.Index = IIs.YesNoType.no; + break; + case 1: + webDirProperties.Index = IIs.YesNoType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[7]) + { + webDirProperties.DefaultDocuments = (string)row[7]; + } + + if (null != row[8]) + { + switch ((int)row[8]) + { + case 0: + webDirProperties.AspDetailedError = IIs.YesNoType.no; + break; + case 1: + webDirProperties.AspDetailedError = IIs.YesNoType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[9]) + { + webDirProperties.HttpExpires = (string)row[9]; + } + + if (null != row[10]) + { + // force the value to be a positive number + webDirProperties.CacheControlMaxAge = unchecked((uint)(int)row[10]); + } + + if (null != row[11]) + { + webDirProperties.CacheControlCustom = (string)row[11]; + } + + if (null != row[12]) + { + switch ((int)row[8]) + { + case 0: + webDirProperties.ClearCustomError = IIs.YesNoType.no; + break; + case 1: + webDirProperties.ClearCustomError = IIs.YesNoType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[13]) + { + int accessSSLFlags = (int)row[13]; + + if (0x8 == (accessSSLFlags & 0x8)) + { + webDirProperties.AccessSSL = IIs.YesNoType.yes; + } + + if (0x20 == (accessSSLFlags & 0x20)) + { + webDirProperties.AccessSSLNegotiateCert = IIs.YesNoType.yes; + } + + if (0x40 == (accessSSLFlags & 0x40)) + { + webDirProperties.AccessSSLRequireCert = IIs.YesNoType.yes; + } + + if (0x80 == (accessSSLFlags & 0x80)) + { + webDirProperties.AccessSSLMapCert = IIs.YesNoType.yes; + } + + if (0x100 == (accessSSLFlags & 0x100)) + { + webDirProperties.AccessSSL128 = IIs.YesNoType.yes; + } + } + + if (null != row[14]) + { + webDirProperties.AuthenticationProviders = (string)row[14]; + } + + this.Core.RootElement.AddChild(webDirProperties); + } + } + + /// + /// Decompile the IIsWebError table. + /// + /// The table to decompile. + private void DecompileIIsWebErrorTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebError webError = new IIs.WebError(); + + webError.ErrorCode = (int)row[0]; + + webError.SubCode = (int)row[1]; + + // the ParentType and ParentValue columns are handled in FinalizeIIsWebErrorTable + + if (null != row[4]) + { + webError.File = (string)row[4]; + } + + if (null != row[5]) + { + webError.URL = (string)row[5]; + } + + this.Core.IndexElement(row, webError); + } + } + + /// + /// Decompile the IIsFilter table. + /// + /// The table to decompile. + private void DecompileIIsFilterTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebFilter webFilter = new IIs.WebFilter(); + + webFilter.Id = (string)row[0]; + + webFilter.Name = (string)row[1]; + + if (null != row[3]) + { + webFilter.Path = (string)row[3]; + } + + if (null != row[5]) + { + webFilter.Description = (string)row[5]; + } + + webFilter.Flags = (int)row[6]; + + if (null != row[7]) + { + switch ((int)row[7]) + { + case (-1): + webFilter.LoadOrder = "last"; + break; + case 0: + webFilter.LoadOrder = "first"; + break; + default: + webFilter.LoadOrder = Convert.ToString((int)row[7], CultureInfo.InvariantCulture); + break; + } + } + + if (null != row[4]) + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[4]); + + if (null != webSite) + { + webSite.AddChild(webFilter); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[4], "IIsWebSite")); + } + } + else // Component parent + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); + + if (null != component) + { + component.AddChild(webFilter); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); + } + } + } + } + + /// + /// Decompile the IIsWebLog table. + /// + /// The table to decompile. + private void DecompileIIsWebLogTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebLog webLog = new IIs.WebLog(); + + webLog.Id = (string)row[0]; + + switch ((string)row[1]) + { + case "Microsoft IIS Log File Format": + webLog.Type = IIs.WebLog.TypeType.IIS; + break; + case "NCSA Common Log File Format": + webLog.Type = IIs.WebLog.TypeType.NCSA; + break; + case "none": + webLog.Type = IIs.WebLog.TypeType.none; + break; + case "ODBC Logging": + webLog.Type = IIs.WebLog.TypeType.ODBC; + break; + case "W3C Extended Log File Format": + webLog.Type = IIs.WebLog.TypeType.W3C; + break; + default: + // TODO: warn + break; + } + + this.Core.RootElement.AddChild(webLog); + } + } + + /// + /// Decompile the IIsWebServiceExtension table. + /// + /// The table to decompile. + private void DecompileIIsWebServiceExtensionTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebServiceExtension webServiceExtension = new IIs.WebServiceExtension(); + + webServiceExtension.Id = (string)row[0]; + + webServiceExtension.File = (string)row[2]; + + if (null != row[3]) + { + webServiceExtension.Description = (string)row[3]; + } + + if (null != row[4]) + { + webServiceExtension.Group = (string)row[4]; + } + + int attributes = (int)row[5]; + + if (0x1 == (attributes & 0x1)) + { + webServiceExtension.Allow = IIs.YesNoType.yes; + } + else + { + webServiceExtension.Allow = IIs.YesNoType.no; + } + + if (0x2 == (attributes & 0x2)) + { + webServiceExtension.UIDeletable = IIs.YesNoType.yes; + } + + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + if (null != component) + { + component.AddChild(webServiceExtension); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + + /// + /// Decompile the IIsWebSite table. + /// + /// The table to decompile. + private void DecompileIIsWebSiteTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebSite webSite = new IIs.WebSite(); + + webSite.Id = (string)row[0]; + + if (null != row[2]) + { + webSite.Description = (string)row[2]; + } + + if (null != row[3]) + { + webSite.ConnectionTimeout = (int)row[3]; + } + + if (null != row[4]) + { + webSite.Directory = (string)row[4]; + } + + if (null != row[5]) + { + switch ((int)row[5]) + { + case 0: + // this is the default + break; + case 1: + webSite.StartOnInstall = IIs.YesNoType.yes; + break; + case 2: + webSite.AutoStart = IIs.YesNoType.yes; + break; + default: + // TODO: warn + break; + } + } + + if (null != row[6]) + { + int attributes = (int)row[6]; + + if (0x2 == (attributes & 0x2)) + { + webSite.ConfigureIfExists = IIs.YesNoType.no; + } + } + + // the KeyAddress_ column is handled in FinalizeWebAddressTable + + if (null != row[8]) + { + webSite.DirProperties = (string)row[8]; + } + + // the Application_ column is handled in FinalizeIIsWebApplicationTable + + if (null != row[10]) + { + if (-1 != (int)row[10]) + { + webSite.Sequence = (int)row[10]; + } + } + + if (null != row[11]) + { + webSite.WebLog = (string)row[11]; + } + + if (null != row[12]) + { + webSite.SiteId = (string)row[12]; + } + + if (null != row[1]) + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + + if (null != component) + { + component.AddChild(webSite); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + else + { + this.Core.RootElement.AddChild(webSite); + } + this.Core.IndexElement(row, webSite); + } + } + + /// + /// Decompile the IIsWebVirtualDir table. + /// + /// The table to decompile. + private void DecompileIIsWebVirtualDirTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.WebVirtualDir webVirtualDir = new IIs.WebVirtualDir(); + + webVirtualDir.Id = (string)row[0]; + + // the Component_ and Web_ columns are handled in FinalizeIIsWebVirtualDirTable + + webVirtualDir.Alias = (string)row[3]; + + webVirtualDir.Directory = (string)row[4]; + + if (null != row[5]) + { + webVirtualDir.DirProperties = (string)row[5]; + } + + // the Application_ column is handled in FinalizeIIsWebApplicationTable + + this.Core.IndexElement(row, webVirtualDir); + } + } + + /// + /// Decompile the IIsWebSiteCertificates table. + /// + /// The table to decompile. + private void DecompileIIsWebSiteCertificatesTable(Table table) + { + foreach (Row row in table.Rows) + { + IIs.CertificateRef certificateRef = new IIs.CertificateRef(); + + certificateRef.Id = (string)row[1]; + + this.Core.IndexElement(row, certificateRef); + } + } + + /// + /// Finalize the IIsHttpHeader table. + /// + /// The collection of all tables. + /// + /// The IIsHttpHeader table supports multiple parent types so no foreign key + /// is declared and thus nesting must be done late. + /// + private void FinalizeIIsHttpHeaderTable(TableIndexedCollection tables) + { + Table iisHttpHeaderTable = tables["IIsHttpHeader"]; + + if (null != iisHttpHeaderTable) + { + foreach (Row row in iisHttpHeaderTable.Rows) + { + IIs.HttpHeader httpHeader = (IIs.HttpHeader)this.Core.GetIndexedElement(row); + + if (1 == (int)row[1]) + { + IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement("IIsWebVirtualDir", (string)row[2]); + if (null != webVirtualDir) + { + webVirtualDir.AddChild(httpHeader); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisHttpHeaderTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[2], "IIsWebVirtualDir")); + } + } + else if (2 == (int)row[1]) + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[2]); + if (null != webSite) + { + webSite.AddChild(httpHeader); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisHttpHeaderTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[2], "IIsWebSite")); + } + } + } + } + } + + /// + /// Finalize the IIsMimeMap table. + /// + /// The collection of all tables. + /// + /// The IIsMimeMap table supports multiple parent types so no foreign key + /// is declared and thus nesting must be done late. + /// + private void FinalizeIIsMimeMapTable(TableIndexedCollection tables) + { + Table iisMimeMapTable = tables["IIsMimeMap"]; + + if (null != iisMimeMapTable) + { + foreach (Row row in iisMimeMapTable.Rows) + { + IIs.MimeMap mimeMap = (IIs.MimeMap)this.Core.GetIndexedElement(row); + + if (2 < (int)row[1] || 0 >= (int)row[1]) + { + // TODO: warn about unknown parent type + } + + IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement("IIsWebVirtualDir", (string)row[2]); + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[2]); + if (null != webVirtualDir) + { + webVirtualDir.AddChild(mimeMap); + } + else if (null != webSite) + { + webSite.AddChild(mimeMap); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisMimeMapTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[2], "IIsWebVirtualDir")); + } + } + } + } + + /// + /// Finalize the IIsWebApplication table. + /// + /// The collection of all tables. + /// + /// Since WebApplication elements may nest under a specific WebSite or + /// WebVirtualDir (or just the root element), the nesting must be done late. + /// + private void FinalizeIIsWebApplicationTable(TableIndexedCollection tables) + { + Table iisWebApplicationTable = tables["IIsWebApplication"]; + Table iisWebSiteTable = tables["IIsWebSite"]; + Table iisWebVirtualDirTable = tables["IIsWebVirtualDir"]; + + Hashtable addedWebApplications = new Hashtable(); + + if (null != iisWebSiteTable) + { + foreach (Row row in iisWebSiteTable.Rows) + { + if (null != row[9]) + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement(row); + + IIs.WebApplication webApplication = (IIs.WebApplication)this.Core.GetIndexedElement("IIsWebApplication", (string)row[9]); + if (null != webApplication) + { + webSite.AddChild(webApplication); + addedWebApplications[webApplication] = null; + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebSiteTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Application_", (string)row[9], "IIsWebApplication")); + } + } + } + } + + if (null != iisWebVirtualDirTable) + { + foreach (Row row in iisWebVirtualDirTable.Rows) + { + if (null != row[6]) + { + IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement(row); + + IIs.WebApplication webApplication = (IIs.WebApplication)this.Core.GetIndexedElement("IIsWebApplication", (string)row[6]); + if (null != webApplication) + { + webVirtualDir.AddChild(webApplication); + addedWebApplications[webApplication] = null; + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebVirtualDirTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Application_", (string)row[6], "IIsWebApplication")); + } + } + } + } + + if (null != iisWebApplicationTable) + { + foreach (Row row in iisWebApplicationTable.Rows) + { + IIs.WebApplication webApplication = (IIs.WebApplication)this.Core.GetIndexedElement(row); + + if (!addedWebApplications.Contains(webApplication)) + { + this.Core.RootElement.AddChild(webApplication); + } + } + } + } + + /// + /// Finalize the IIsWebError table. + /// + /// The collection of all tables. + /// + /// Since there is no foreign key relationship declared for this table + /// (because it takes various parent types), it must be nested late. + /// + private void FinalizeIIsWebErrorTable(TableIndexedCollection tables) + { + Table iisWebErrorTable = tables["IIsWebError"]; + + if (null != iisWebErrorTable) + { + foreach (Row row in iisWebErrorTable.Rows) + { + IIs.WebError webError = (IIs.WebError)this.Core.GetIndexedElement(row); + + if (1 == (int)row[2]) // WebVirtualDir parent + { + IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement("IIsWebVirtualDir", (string)row[3]); + + if (null != webVirtualDir) + { + webVirtualDir.AddChild(webError); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebErrorTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[3], "IIsWebVirtualDir")); + } + } + else if (2 == (int)row[2]) // WebSite parent + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[3]); + + if (null != webSite) + { + webSite.AddChild(webError); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebErrorTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[3], "IIsWebSite")); + } + } + else + { + // TODO: warn unknown parent type + } + } + } + } + + /// + /// Finalize the IIsWebVirtualDir table. + /// + /// The collection of all tables. + /// + /// WebVirtualDir elements nest under either a WebSite or component + /// depending upon whether the component in the IIsWebVirtualDir row + /// is the same as the one in the parent IIsWebSite row. + /// + private void FinalizeIIsWebVirtualDirTable(TableIndexedCollection tables) + { + Table iisWebSiteTable = tables["IIsWebSite"]; + Table iisWebVirtualDirTable = tables["IIsWebVirtualDir"]; + + Hashtable iisWebSiteRows = new Hashtable(); + + // index the IIsWebSite rows by their primary keys + if (null != iisWebSiteTable) + { + foreach (Row row in iisWebSiteTable.Rows) + { + iisWebSiteRows.Add(row[0], row); + } + } + + if (null != iisWebVirtualDirTable) + { + foreach (Row row in iisWebVirtualDirTable.Rows) + { + IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement(row); + Row iisWebSiteRow = (Row)iisWebSiteRows[row[2]]; + + if (null != iisWebSiteRow) + { + if ((string)iisWebSiteRow[1] == (string)row[1]) + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement(iisWebSiteRow); + + webSite.AddChild(webVirtualDir); + } + else + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); + + if (null != component) + { + webVirtualDir.WebSite = (string)row[2]; + component.AddChild(webVirtualDir); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebVirtualDirTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); + } + } + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebVirtualDirTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[2], "IIsWebSite")); + } + } + } + } + + /// + /// Finalize the IIsWebSiteCertificates table. + /// + /// The collection of all tables. + /// + /// This table creates CertificateRef elements which nest under WebSite + /// elements. + /// + private void FinalizeIIsWebSiteCertificatesTable(TableIndexedCollection tables) + { + Table IIsWebSiteCertificatesTable = tables["IIsWebSiteCertificates"]; + + if (null != IIsWebSiteCertificatesTable) + { + foreach (Row row in IIsWebSiteCertificatesTable.Rows) + { + IIs.CertificateRef certificateRef = (IIs.CertificateRef)this.Core.GetIndexedElement(row); + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[0]); + + if (null != webSite) + { + webSite.AddChild(certificateRef); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, IIsWebSiteCertificatesTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[0], "IIsWebSite")); + } + } + } + } + + /// + /// Finalize the WebAddress table. + /// + /// The collection of all tables. + /// + /// There is a circular dependency between the WebAddress and WebSite + /// tables, so nesting must be handled here. + /// + private void FinalizeWebAddressTable(TableIndexedCollection tables) + { + Table iisWebAddressTable = tables["IIsWebAddress"]; + Table iisWebSiteTable = tables["IIsWebSite"]; + + Hashtable addedWebAddresses = new Hashtable(); + + if (null != iisWebSiteTable) + { + foreach (Row row in iisWebSiteTable.Rows) + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement(row); + + IIs.WebAddress webAddress = (IIs.WebAddress)this.Core.GetIndexedElement("IIsWebAddress", (string)row[7]); + if (null != webAddress) + { + webSite.AddChild(webAddress); + addedWebAddresses[webAddress] = null; + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebSiteTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "KeyAddress_", (string)row[7], "IIsWebAddress")); + } + } + } + + if (null != iisWebAddressTable) + { + foreach (Row row in iisWebAddressTable.Rows) + { + IIs.WebAddress webAddress = (IIs.WebAddress)this.Core.GetIndexedElement(row); + + if (!addedWebAddresses.Contains(webAddress)) + { + IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[1]); + + if (null != webSite) + { + webSite.AddChild(webAddress); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebAddressTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[1], "IIsWebSite")); + } + } + } + } + } + } +#endif +} diff --git a/src/ext/Iis/wixext/IIsExtensionData.cs b/src/ext/Iis/wixext/IIsExtensionData.cs new file mode 100644 index 00000000..6a0e1f09 --- /dev/null +++ b/src/ext/Iis/wixext/IIsExtensionData.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.Iis +{ + using WixToolset.Data; + using WixToolset.Extensibility; + + /// + /// The WiX Toolset Internet Information Services Extension. + /// + public sealed class IIsExtensionData : BaseExtensionData + { + /// + /// Gets the default culture. + /// + /// The default culture. + public override string DefaultCulture => "en-US"; + + public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) + { + symbolDefinition = IisSymbolDefinitions.ByName(name); + return symbolDefinition != null; + } + + public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) + { + return Intermediate.Load(typeof(IIsExtensionData).Assembly, "WixToolset.Iis.iis.wixlib", symbolDefinitions); + } + } +} diff --git a/src/ext/Iis/wixext/IisErrors.cs b/src/ext/Iis/wixext/IisErrors.cs new file mode 100644 index 00000000..2f226217 --- /dev/null +++ b/src/ext/Iis/wixext/IisErrors.cs @@ -0,0 +1,78 @@ +// 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 IIsErrors + { + public static Message DeprecatedBinaryChildElement(SourceLineNumber sourceLineNumbers, string elementName) + { + return Message(sourceLineNumbers, Ids.DeprecatedBinaryChildElement, "The {0} element contains a deprecated child Binary element. Please move the Binary element under a Fragment, Module, or Product element and set the {0}/@BinaryKey attribute to the value of the Binary/@Id attribute.", elementName); + } + + 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 IllegalCharacterInAttributeValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value, Char illegalCharacter) + { + return Message(sourceLineNumbers, Ids.IllegalCharacterInAttributeValue, "The {0}/@{1} attribute's value, '{2}', is invalid. It cannot contain the character '{3}'.", elementName, attributeName, value, illegalCharacter); + } + + 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 MimeMapExtensionMissingPeriod(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string attributeValue) + { + return Message(sourceLineNumbers, Ids.MimeMapExtensionMissingPeriod, "The {0}/@{1} attribute's value, '{2}', is not a valid mime map extension. It must begin with a period.", elementName, attributeName, attributeValue); + } + + public static Message OneOfAttributesRequiredUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2, string attributeName3, string attributeName4) + { + return Message(sourceLineNumbers, Ids.OneOfAttributesRequiredUnderComponent, "When nested under a Component, the {0} element must have one of the following attributes specified: {1}, {2}, {3} or {4}.", elementName, attributeName1, attributeName2, attributeName3, attributeName4); + } + + public static Message RequiredAttributeUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) + { + return Message(sourceLineNumbers, Ids.RequiredAttributeUnderComponent, "The {0}/@{1} attribute must be specified when the element has a Component as an ancestor.", elementName, attributeName); + } + + public static Message WebApplicationAlreadySpecified(SourceLineNumber sourceLineNumbers, string elementName) + { + return Message(sourceLineNumbers, Ids.WebApplicationAlreadySpecified, "The {0} element can have at most a single WebApplication specified. This can be either through the WebApplication attribute, or through a nested WebApplication element, but not both.", elementName); + } + + public static Message WebSiteAttributeUnderWebSite(SourceLineNumber sourceLineNumbers, string elementName) + { + return Message(sourceLineNumbers, Ids.WebSiteAttributeUnderWebSite, "The {0}/@WebSite attribute cannot be specified when the {0} element is nested under a WebSite element.", elementName); + } + + 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 + { + MimeMapExtensionMissingPeriod = 5150, + IllegalAttributeWithoutComponent = 5151, + IllegalElementWithoutComponent = 5152, + OneOfAttributesRequiredUnderComponent = 5153, + WebSiteAttributeUnderWebSite = 5154, + WebApplicationAlreadySpecified = 5155, + IllegalCharacterInAttributeValue = 5156, + DeprecatedBinaryChildElement = 5157, + RequiredAttributeUnderComponent = 5161, + } + } +} diff --git a/src/ext/Iis/wixext/IisExtensionFactory.cs b/src/ext/Iis/wixext/IisExtensionFactory.cs new file mode 100644 index 00000000..2fb7e682 --- /dev/null +++ b/src/ext/Iis/wixext/IisExtensionFactory.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.Iis +{ + using System; + using System.Collections.Generic; + using WixToolset.Extensibility; + + public class IisExtensionFactory : BaseExtensionFactory + { + protected override IReadOnlyCollection ExtensionTypes => new[] + { + typeof(IIsCompiler), + typeof(IIsExtensionData), + typeof(IisWindowsInstallerBackendBinderExtension), + }; + } +} diff --git a/src/ext/Iis/wixext/IisTableDefinitions.cs b/src/ext/Iis/wixext/IisTableDefinitions.cs new file mode 100644 index 00000000..f513152e --- /dev/null +++ b/src/ext/Iis/wixext/IisTableDefinitions.cs @@ -0,0 +1,324 @@ +// 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.Iis +{ + using WixToolset.Data.WindowsInstaller; + + public static class IisTableDefinitions + { + public static readonly TableDefinition Certificate = new TableDefinition( + "Certificate", + IisSymbolDefinitions.Certificate, + new[] + { + new ColumnDefinition("Certificate", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyColumn: 1, description: "Identifier for the certificate in the package.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, description: "Foreign key into the Component table used to determine install state", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name to be used for the Certificate."), + new ColumnDefinition("StoreLocation", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 1, maxValue: 2, description: "Location of the target certificate store (CurrentUser == 1, LocalMachine == 2)"), + new ColumnDefinition("StoreName", ColumnType.String, 64, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of the target certificate store"), + new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2147483647, description: "Attributes of the certificate"), + new ColumnDefinition("Binary_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Binary", keyColumn: 1, description: "Identifier to Binary table containing certificate.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("CertificatePath", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Property to path of certificate.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("PFXPassword", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Hidden property to a pfx password", modularizeType: ColumnModularizeType.Property), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition CertificateHash = new TableDefinition( + "CertificateHash", + IisSymbolDefinitions.CertificateHash, + new[] + { + new ColumnDefinition("Certificate_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyColumn: 1, description: "Foreign key to certificate in Certificate table.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Hash", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Base64 encoded SHA1 hash of certificate populated at run-time."), + }, + symbolIdIsPrimaryKey: false + ); + + public static readonly TableDefinition IIsWebSiteCertificates = new TableDefinition( + "IIsWebSiteCertificates", + IisSymbolDefinitions.IIsWebSiteCertificates, + new[] + { + new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "The index into the IIsWebSite table.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Certificate_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Text, keyTable: "Certificate", keyColumn: 1, description: "The index into the Certificate table.", modularizeType: ColumnModularizeType.Column), + }, + symbolIdIsPrimaryKey: false + ); + + public static readonly TableDefinition IIsAppPool = new TableDefinition( + "IIsAppPool", + IisSymbolDefinitions.IIsAppPool, + new[] + { + new ColumnDefinition("AppPool", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for apppool", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name to be used for the IIs AppPool.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the app pool", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Attributes of the AppPool"), + new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "User account to run the app pool as", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("RecycleMinutes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Number of minutes between recycling app pool"), + new ColumnDefinition("RecycleRequests", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Number of requests between recycling app pool"), + new ColumnDefinition("RecycleTimes", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Times to recycle app pool (comma delimited - i.e. 1:45,13:30)"), + new ColumnDefinition("IdleTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Amount of idle time before shutting down"), + new ColumnDefinition("QueueLimit", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Reject requests after queue gets how large"), + new ColumnDefinition("CPUMon", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "CPUMon is a comma delimeted list of the following format: ,,. The values for Action are 1 (Shutdown) and 0 (No Action)."), + new ColumnDefinition("MaxProc", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Maximum number of processes to use"), + new ColumnDefinition("VirtualMemory", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Amount of virtual memory (in KB) that a worker process can use before the worker process recycles. The maximum value supported for this field is 4,294,967 KB."), + new ColumnDefinition("PrivateMemory", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Amount of private memory (in KB) that a worker process can use before the worker process recycles. The maximum value supported for this field is 4,294,967 KB."), + new ColumnDefinition("ManagedRuntimeVersion", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Specifies the .NET Framework version to be used by the application pool."), + new ColumnDefinition("ManagedPipelineMode", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Specifies the request-processing mode that is used to process requests for managed content."), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsMimeMap = new TableDefinition( + "IIsMimeMap", + IisSymbolDefinitions.IIsMimeMap, + new[] + { + new ColumnDefinition("MimeMap", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for Mime Map definitions", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("ParentType", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "1;2", description: "Type of parent: 1=vdir 2=website"), + new ColumnDefinition("ParentValue", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, description: "Name of the parent value.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("MimeType", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Mime-type covered by the MimeMap."), + new ColumnDefinition("Extension", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Extension covered by the MimeMap."), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsProperty = new TableDefinition( + "IIsProperty", + IisSymbolDefinitions.IIsProperty, + new[] + { + new ColumnDefinition("Property", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Unique name of the IIsProperty"), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Component that the property is linked to", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Attributes of the IIsProperty (unused)"), + new ColumnDefinition("Value", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Value of the IIsProperty"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebDirProperties = new TableDefinition( + "IIsWebDirProperties", + IisSymbolDefinitions.IIsWebDirProperties, + new[] + { + new ColumnDefinition("DirProperties", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for Web Properties", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Access", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Access rights to the web server"), + new ColumnDefinition("Authorization", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Authorization policy to web server (anonymous access, NTLM, etc)"), + new ColumnDefinition("AnonymousUser_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("IIsControlledPassword", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs is allowed to set the AnonymousUser_ password"), + new ColumnDefinition("LogVisits", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs tracks all access to the directory"), + new ColumnDefinition("Index", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs searches the directory"), + new ColumnDefinition("DefaultDoc", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Comma delimited list of file names to act as a default document"), + new ColumnDefinition("AspDetailedError", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether detailed ASP errors are sent to browser"), + new ColumnDefinition("HttpExpires", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Value to set the HttpExpires attribute to for a Web Dir in the metabase"), + new ColumnDefinition("CacheControlMaxAge", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Integer value specifying the cache control maximum age value."), + new ColumnDefinition("CacheControlCustom", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Custom HTTP 1.1 cache control directives."), + new ColumnDefinition("NoCustomError", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs will return custom errors for this directory."), + new ColumnDefinition("AccessSSLFlags", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Specifies AccessSSLFlags IIS metabase property."), + new ColumnDefinition("AuthenticationProviders", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Comma delimited list, in order of precedence, of Windows authentication providers that IIS will attempt to use: NTLM, Kerberos, Negotiate, and others."), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebAddress = new TableDefinition( + "IIsWebAddress", + IisSymbolDefinitions.IIsWebAddress, + new[] + { + new ColumnDefinition("Address", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing Web that uses the address.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("IP", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "String representing IP address (#.#.#.#) or NT machine name (fooserver)", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Port", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Port web site listens on", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Header", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Special header information for the web site"), + new ColumnDefinition("Secure", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether SSL is used to communicate with web site"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebSite = new TableDefinition( + "IIsWebSite", + IisSymbolDefinitions.IIsWebSite, + new[] + { + new ColumnDefinition("Web", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the web site", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in IIS MMC applet"), + new ColumnDefinition("ConnectionTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Time connection is maintained without activity (in seconds)"), + new ColumnDefinition("Directory_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Directory", keyColumn: 1, description: "Foreign key referencing directory that the web site points at", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("State", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1;2", description: "Sets intial state of web site"), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "2", description: "Control the install behavior of web site"), + new ColumnDefinition("KeyAddress_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebAddress", keyColumn: 1, description: "Foreign key referencing primary address for the web site", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("DirProperties_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebDirProperties", keyColumn: 1, description: "Foreign key referencing possible security information for the web site", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the web site.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Allows ordering of web site install"), + new ColumnDefinition("Log_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, keyTable: "IIsWebLog", keyColumn: 1, description: "Foreign key reference to IIsWebLog data", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Id", ColumnType.String, 74, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional number or formatted value that resolves to number that acts as the WebSite Id."), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebApplication = new TableDefinition( + "IIsWebApplication", + IisSymbolDefinitions.IIsWebApplication, + new[] + { + new ColumnDefinition("Application", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for ASP Application", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of application in IIS MMC applet", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Isolation", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "0;1;2", description: "Isolation level for ASP Application: 0 == Low, 2 == Medium, 1 == High"), + new ColumnDefinition("AllowSessions", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether application may maintain session state"), + new ColumnDefinition("SessionTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Time session state is maintained without user interaction"), + new ColumnDefinition("Buffer", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether application buffers its output"), + new ColumnDefinition("ParentPaths", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "What is this for anyway?"), + new ColumnDefinition("DefaultScript", ColumnType.String, 26, primaryKey: false, nullable: true, ColumnCategory.Text, possibilities: "VBScript;JScript", description: "Default scripting language for ASP applications"), + new ColumnDefinition("ScriptTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Time ASP application page is permitted to process"), + new ColumnDefinition("ServerDebugging", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether to allow ASP server-side script debugging"), + new ColumnDefinition("ClientDebugging", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether to allow ASP client-side script debugging"), + new ColumnDefinition("AppPool_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsAppPool", keyColumn: 1, description: "App Pool this application should run under", modularizeType: ColumnModularizeType.Column), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebApplicationExtension = new TableDefinition( + "IIsWebApplicationExtension", + IisSymbolDefinitions.IIsWebApplicationExtension, + new[] + { + new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the web site", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Extension", ColumnType.String, 255, primaryKey: true, nullable: true, ColumnCategory.Text, description: "Primary key, Extension that should be registered for this ASP application"), + new ColumnDefinition("Verbs", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Comma delimited list of HTTP verbs the extension should be registered with"), + new ColumnDefinition("Executable", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Path to extension (usually file property: [#file])", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "1;4;5", description: "Attributes for extension: 1 == Script, 4 == Check Path Info"), + }, + symbolIdIsPrimaryKey: false + ); + + public static readonly TableDefinition IIsFilter = new TableDefinition( + "IIsFilter", + IisSymbolDefinitions.IIsFilter, + new[] + { + new ColumnDefinition("Filter", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Name of the ISAPI Filter in IIS"), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the filter", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Path", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Path to filter (usually file property: [#file])", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing web site that loads the filter (NULL == global filter", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in IIS MMC applet"), + new ColumnDefinition("Flags", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2147483647, description: "What do all these numbers mean?"), + new ColumnDefinition("LoadOrder", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "-1 == last in order, 0 == first in order, # == place in order"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebDir = new TableDefinition( + "IIsWebDir", + IisSymbolDefinitions.IIsWebDir, + new[] + { + new ColumnDefinition("WebDir", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the virtual directory", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing web site that controls the virtual directory", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Path", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of web directory displayed in IIS MMC applet", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("DirProperties_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebDirProperties", keyColumn: 1, description: "Foreign key referencing possible security information for the virtual directory", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the virtual directory. This column is currently unused, but maintained for compatibility reasons.", modularizeType: ColumnModularizeType.Column), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebError = new TableDefinition( + "IIsWebError", + IisSymbolDefinitions.IIsWebError, + new[] + { + new ColumnDefinition("ErrorCode", ColumnType.Number, 2, primaryKey: true, nullable: false, ColumnCategory.Unknown, minValue: 400, maxValue: 599, description: "HTTP status code indicating error."), + new ColumnDefinition("SubCode", ColumnType.Number, 4, primaryKey: true, nullable: false, ColumnCategory.Unknown, description: "HTTP sub-status code indicating error."), + new ColumnDefinition("ParentType", ColumnType.Number, 2, primaryKey: true, nullable: false, ColumnCategory.Unknown, possibilities: "1;2", description: "Type of parent: 1=vdir, 2=web"), + new ColumnDefinition("ParentValue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Name of the parent value.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Path to file for this custom error (usually file property: [#file]). Must be null if URL is not null."), + new ColumnDefinition("URL", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "URL for this custom error. Must be null if File is not null."), + }, + symbolIdIsPrimaryKey: false + ); + + public static readonly TableDefinition IIsHttpHeader = new TableDefinition( + "IIsHttpHeader", + IisSymbolDefinitions.IIsHttpHeader, + new[] + { + new ColumnDefinition("HttpHeader", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("ParentType", ColumnType.Number, 2, primaryKey: true, nullable: false, ColumnCategory.Unknown, possibilities: "1;2", description: "Type of parent: 1=vdir, 2=web"), + new ColumnDefinition("ParentValue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Name of the parent value.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Name of the HTTP Header"), + new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "URL for this custom error. Must be null if File is not null."), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 0, description: "Attributes for HTTP Header: none"), + new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Order to add the HTTP Headers."), + }, + symbolIdIsPrimaryKey: false + ); + + public static readonly TableDefinition IIsWebServiceExtension = new TableDefinition( + "IIsWebServiceExtension", + IisSymbolDefinitions.IIsWebServiceExtension, + new[] + { + new ColumnDefinition("WebServiceExtension", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the WebServiceExtension handler", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Path to handler (usually file property: [#file])", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Description", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in WebServiceExtension Wizard", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Group", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "String used to identify groups of extensions.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Attributes", ColumnType.Number, 1, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 3, description: "Attributes for WebServiceExtension: 1 = Allow, 2 = UIDeletable"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebVirtualDir = new TableDefinition( + "IIsWebVirtualDir", + IisSymbolDefinitions.IIsWebVirtualDir, + new[] + { + new ColumnDefinition("VirtualDir", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the virtual directory", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing web site that controls the virtual directory", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Alias", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of virtual directory displayed in IIS MMC applet", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Directory_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Directory", keyColumn: 1, description: "Foreign key referencing directory that the virtual directory points at", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("DirProperties_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebDirProperties", keyColumn: 1, description: "Foreign key referencing possible security information for the virtual directory", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the virtual directory", modularizeType: ColumnModularizeType.Column), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition IIsWebLog = new TableDefinition( + "IIsWebLog", + IisSymbolDefinitions.IIsWebLog, + new[] + { + new ColumnDefinition("Log", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Format", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Type of log format"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition[] All = new[] + { + Certificate, + CertificateHash, + IIsWebSiteCertificates, + IIsAppPool, + IIsMimeMap, + IIsProperty, + IIsWebDirProperties, + IIsWebAddress, + IIsWebSite, + IIsWebApplication, + IIsWebApplicationExtension, + IIsFilter, + IIsWebDir, + IIsWebError, + IIsHttpHeader, + IIsWebServiceExtension, + IIsWebVirtualDir, + IIsWebLog, + }; + } +} diff --git a/src/ext/Iis/wixext/IisWindowsInstallerBackendBinderExtension.cs b/src/ext/Iis/wixext/IisWindowsInstallerBackendBinderExtension.cs new file mode 100644 index 00000000..a61cbad6 --- /dev/null +++ b/src/ext/Iis/wixext/IisWindowsInstallerBackendBinderExtension.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.Iis +{ + using System.Collections.Generic; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility; + + public class IisWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension + { + public override IReadOnlyCollection TableDefinitions => IisTableDefinitions.All; + } +} diff --git a/src/ext/Iis/wixext/Symbols/CertificateHashSymbol.cs b/src/ext/Iis/wixext/Symbols/CertificateHashSymbol.cs new file mode 100644 index 00000000..866d474c --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/CertificateHashSymbol.cs @@ -0,0 +1,55 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition CertificateHash = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.CertificateHash.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(CertificateHashSymbolFields.CertificateRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(CertificateHashSymbolFields.Hash), IntermediateFieldType.String), + }, + typeof(CertificateHashSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum CertificateHashSymbolFields + { + CertificateRef, + Hash, + } + + public class CertificateHashSymbol : IntermediateSymbol + { + public CertificateHashSymbol() : base(IisSymbolDefinitions.CertificateHash, null, null) + { + } + + public CertificateHashSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.CertificateHash, sourceLineNumber, id) + { + } + + public IntermediateField this[CertificateHashSymbolFields index] => this.Fields[(int)index]; + + public string CertificateRef + { + get => this.Fields[(int)CertificateHashSymbolFields.CertificateRef].AsString(); + set => this.Set((int)CertificateHashSymbolFields.CertificateRef, value); + } + + public string Hash + { + get => this.Fields[(int)CertificateHashSymbolFields.Hash].AsString(); + set => this.Set((int)CertificateHashSymbolFields.Hash, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/CertificateSymbol.cs b/src/ext/Iis/wixext/Symbols/CertificateSymbol.cs new file mode 100644 index 00000000..b80b6ba4 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/CertificateSymbol.cs @@ -0,0 +1,103 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition Certificate = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.Certificate.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.StoreLocation), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.StoreName), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.BinaryRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.CertificatePath), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(CertificateSymbolFields.PFXPassword), IntermediateFieldType.String), + }, + typeof(CertificateSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum CertificateSymbolFields + { + ComponentRef, + Name, + StoreLocation, + StoreName, + Attributes, + BinaryRef, + CertificatePath, + PFXPassword, + } + + public class CertificateSymbol : IntermediateSymbol + { + public CertificateSymbol() : base(IisSymbolDefinitions.Certificate, null, null) + { + } + + public CertificateSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.Certificate, sourceLineNumber, id) + { + } + + public IntermediateField this[CertificateSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)CertificateSymbolFields.ComponentRef].AsString(); + set => this.Set((int)CertificateSymbolFields.ComponentRef, value); + } + + public string Name + { + get => this.Fields[(int)CertificateSymbolFields.Name].AsString(); + set => this.Set((int)CertificateSymbolFields.Name, value); + } + + public int StoreLocation + { + get => this.Fields[(int)CertificateSymbolFields.StoreLocation].AsNumber(); + set => this.Set((int)CertificateSymbolFields.StoreLocation, value); + } + + public string StoreName + { + get => this.Fields[(int)CertificateSymbolFields.StoreName].AsString(); + set => this.Set((int)CertificateSymbolFields.StoreName, value); + } + + public int Attributes + { + get => this.Fields[(int)CertificateSymbolFields.Attributes].AsNumber(); + set => this.Set((int)CertificateSymbolFields.Attributes, value); + } + + public string BinaryRef + { + get => this.Fields[(int)CertificateSymbolFields.BinaryRef].AsString(); + set => this.Set((int)CertificateSymbolFields.BinaryRef, value); + } + + public string CertificatePath + { + get => this.Fields[(int)CertificateSymbolFields.CertificatePath].AsString(); + set => this.Set((int)CertificateSymbolFields.CertificatePath, value); + } + + public string PFXPassword + { + get => this.Fields[(int)CertificateSymbolFields.PFXPassword].AsString(); + set => this.Set((int)CertificateSymbolFields.PFXPassword, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsAppPoolSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsAppPoolSymbol.cs new file mode 100644 index 00000000..a6fab136 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsAppPoolSymbol.cs @@ -0,0 +1,159 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsAppPool = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsAppPool.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.UserRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.RecycleMinutes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.RecycleRequests), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.RecycleTimes), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.IdleTimeout), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.QueueLimit), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.CPUMon), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.MaxProc), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.VirtualMemory), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.PrivateMemory), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.ManagedRuntimeVersion), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.ManagedPipelineMode), IntermediateFieldType.String), + }, + typeof(IIsAppPoolSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsAppPoolSymbolFields + { + Name, + ComponentRef, + Attributes, + UserRef, + RecycleMinutes, + RecycleRequests, + RecycleTimes, + IdleTimeout, + QueueLimit, + CPUMon, + MaxProc, + VirtualMemory, + PrivateMemory, + ManagedRuntimeVersion, + ManagedPipelineMode, + } + + public class IIsAppPoolSymbol : IntermediateSymbol + { + public IIsAppPoolSymbol() : base(IisSymbolDefinitions.IIsAppPool, null, null) + { + } + + public IIsAppPoolSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsAppPool, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsAppPoolSymbolFields index] => this.Fields[(int)index]; + + public string Name + { + get => this.Fields[(int)IIsAppPoolSymbolFields.Name].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.Name, value); + } + + public string ComponentRef + { + get => this.Fields[(int)IIsAppPoolSymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.ComponentRef, value); + } + + public int Attributes + { + get => this.Fields[(int)IIsAppPoolSymbolFields.Attributes].AsNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.Attributes, value); + } + + public string UserRef + { + get => this.Fields[(int)IIsAppPoolSymbolFields.UserRef].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.UserRef, value); + } + + public int? RecycleMinutes + { + get => this.Fields[(int)IIsAppPoolSymbolFields.RecycleMinutes].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.RecycleMinutes, value); + } + + public int? RecycleRequests + { + get => this.Fields[(int)IIsAppPoolSymbolFields.RecycleRequests].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.RecycleRequests, value); + } + + public string RecycleTimes + { + get => this.Fields[(int)IIsAppPoolSymbolFields.RecycleTimes].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.RecycleTimes, value); + } + + public int? IdleTimeout + { + get => this.Fields[(int)IIsAppPoolSymbolFields.IdleTimeout].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.IdleTimeout, value); + } + + public int? QueueLimit + { + get => this.Fields[(int)IIsAppPoolSymbolFields.QueueLimit].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.QueueLimit, value); + } + + public string CPUMon + { + get => this.Fields[(int)IIsAppPoolSymbolFields.CPUMon].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.CPUMon, value); + } + + public int? MaxProc + { + get => this.Fields[(int)IIsAppPoolSymbolFields.MaxProc].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.MaxProc, value); + } + + public int? VirtualMemory + { + get => this.Fields[(int)IIsAppPoolSymbolFields.VirtualMemory].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.VirtualMemory, value); + } + + public int? PrivateMemory + { + get => this.Fields[(int)IIsAppPoolSymbolFields.PrivateMemory].AsNullableNumber(); + set => this.Set((int)IIsAppPoolSymbolFields.PrivateMemory, value); + } + + public string ManagedRuntimeVersion + { + get => this.Fields[(int)IIsAppPoolSymbolFields.ManagedRuntimeVersion].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.ManagedRuntimeVersion, value); + } + + public string ManagedPipelineMode + { + get => this.Fields[(int)IIsAppPoolSymbolFields.ManagedPipelineMode].AsString(); + set => this.Set((int)IIsAppPoolSymbolFields.ManagedPipelineMode, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsFilterSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsFilterSymbol.cs new file mode 100644 index 00000000..618730bf --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsFilterSymbol.cs @@ -0,0 +1,95 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsFilter = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsFilter.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Path), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.WebRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Description), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Flags), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.LoadOrder), IntermediateFieldType.Number), + }, + typeof(IIsFilterSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsFilterSymbolFields + { + Name, + ComponentRef, + Path, + WebRef, + Description, + Flags, + LoadOrder, + } + + public class IIsFilterSymbol : IntermediateSymbol + { + public IIsFilterSymbol() : base(IisSymbolDefinitions.IIsFilter, null, null) + { + } + + public IIsFilterSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsFilter, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsFilterSymbolFields index] => this.Fields[(int)index]; + + public string Name + { + get => this.Fields[(int)IIsFilterSymbolFields.Name].AsString(); + set => this.Set((int)IIsFilterSymbolFields.Name, value); + } + + public string ComponentRef + { + get => this.Fields[(int)IIsFilterSymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsFilterSymbolFields.ComponentRef, value); + } + + public string Path + { + get => this.Fields[(int)IIsFilterSymbolFields.Path].AsString(); + set => this.Set((int)IIsFilterSymbolFields.Path, value); + } + + public string WebRef + { + get => this.Fields[(int)IIsFilterSymbolFields.WebRef].AsString(); + set => this.Set((int)IIsFilterSymbolFields.WebRef, value); + } + + public string Description + { + get => this.Fields[(int)IIsFilterSymbolFields.Description].AsString(); + set => this.Set((int)IIsFilterSymbolFields.Description, value); + } + + public int Flags + { + get => this.Fields[(int)IIsFilterSymbolFields.Flags].AsNumber(); + set => this.Set((int)IIsFilterSymbolFields.Flags, value); + } + + public int? LoadOrder + { + get => this.Fields[(int)IIsFilterSymbolFields.LoadOrder].AsNullableNumber(); + set => this.Set((int)IIsFilterSymbolFields.LoadOrder, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsHttpHeaderSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsHttpHeaderSymbol.cs new file mode 100644 index 00000000..3ab2bf59 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsHttpHeaderSymbol.cs @@ -0,0 +1,95 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsHttpHeader = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsHttpHeader.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.HttpHeader), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.ParentType), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.ParentValue), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Value), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Sequence), IntermediateFieldType.Number), + }, + typeof(IIsHttpHeaderSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsHttpHeaderSymbolFields + { + HttpHeader, + ParentType, + ParentValue, + Name, + Value, + Attributes, + Sequence, + } + + public class IIsHttpHeaderSymbol : IntermediateSymbol + { + public IIsHttpHeaderSymbol() : base(IisSymbolDefinitions.IIsHttpHeader, null, null) + { + } + + public IIsHttpHeaderSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsHttpHeader, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsHttpHeaderSymbolFields index] => this.Fields[(int)index]; + + public string HttpHeader + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.HttpHeader].AsString(); + set => this.Set((int)IIsHttpHeaderSymbolFields.HttpHeader, value); + } + + public int ParentType + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.ParentType].AsNumber(); + set => this.Set((int)IIsHttpHeaderSymbolFields.ParentType, value); + } + + public string ParentValue + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.ParentValue].AsString(); + set => this.Set((int)IIsHttpHeaderSymbolFields.ParentValue, value); + } + + public string Name + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.Name].AsString(); + set => this.Set((int)IIsHttpHeaderSymbolFields.Name, value); + } + + public string Value + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.Value].AsString(); + set => this.Set((int)IIsHttpHeaderSymbolFields.Value, value); + } + + public int Attributes + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.Attributes].AsNumber(); + set => this.Set((int)IIsHttpHeaderSymbolFields.Attributes, value); + } + + public int? Sequence + { + get => this.Fields[(int)IIsHttpHeaderSymbolFields.Sequence].AsNullableNumber(); + set => this.Set((int)IIsHttpHeaderSymbolFields.Sequence, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsMimeMapSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsMimeMapSymbol.cs new file mode 100644 index 00000000..4af6f81c --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsMimeMapSymbol.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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsMimeMap = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsMimeMap.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.ParentType), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.ParentValue), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.MimeType), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.Extension), IntermediateFieldType.String), + }, + typeof(IIsMimeMapSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsMimeMapSymbolFields + { + ParentType, + ParentValue, + MimeType, + Extension, + } + + public class IIsMimeMapSymbol : IntermediateSymbol + { + public IIsMimeMapSymbol() : base(IisSymbolDefinitions.IIsMimeMap, null, null) + { + } + + public IIsMimeMapSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsMimeMap, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsMimeMapSymbolFields index] => this.Fields[(int)index]; + + public int ParentType + { + get => this.Fields[(int)IIsMimeMapSymbolFields.ParentType].AsNumber(); + set => this.Set((int)IIsMimeMapSymbolFields.ParentType, value); + } + + public string ParentValue + { + get => this.Fields[(int)IIsMimeMapSymbolFields.ParentValue].AsString(); + set => this.Set((int)IIsMimeMapSymbolFields.ParentValue, value); + } + + public string MimeType + { + get => this.Fields[(int)IIsMimeMapSymbolFields.MimeType].AsString(); + set => this.Set((int)IIsMimeMapSymbolFields.MimeType, value); + } + + public string Extension + { + get => this.Fields[(int)IIsMimeMapSymbolFields.Extension].AsString(); + set => this.Set((int)IIsMimeMapSymbolFields.Extension, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsPropertySymbol.cs b/src/ext/Iis/wixext/Symbols/IIsPropertySymbol.cs new file mode 100644 index 00000000..9cf67014 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsPropertySymbol.cs @@ -0,0 +1,63 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsProperty = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsProperty.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsPropertySymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsPropertySymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsPropertySymbolFields.Value), IntermediateFieldType.String), + }, + typeof(IIsPropertySymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsPropertySymbolFields + { + ComponentRef, + Attributes, + Value, + } + + public class IIsPropertySymbol : IntermediateSymbol + { + public IIsPropertySymbol() : base(IisSymbolDefinitions.IIsProperty, null, null) + { + } + + public IIsPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsProperty, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsPropertySymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)IIsPropertySymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsPropertySymbolFields.ComponentRef, value); + } + + public int Attributes + { + get => this.Fields[(int)IIsPropertySymbolFields.Attributes].AsNumber(); + set => this.Set((int)IIsPropertySymbolFields.Attributes, value); + } + + public string Value + { + get => this.Fields[(int)IIsPropertySymbolFields.Value].AsString(); + set => this.Set((int)IIsPropertySymbolFields.Value, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebAddressSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebAddressSymbol.cs new file mode 100644 index 00000000..7111718a --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebAddressSymbol.cs @@ -0,0 +1,79 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebAddress = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebAddress.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.WebRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.IP), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.Port), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.Header), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.Secure), IntermediateFieldType.Number), + }, + typeof(IIsWebAddressSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebAddressSymbolFields + { + WebRef, + IP, + Port, + Header, + Secure, + } + + public class IIsWebAddressSymbol : IntermediateSymbol + { + public IIsWebAddressSymbol() : base(IisSymbolDefinitions.IIsWebAddress, null, null) + { + } + + public IIsWebAddressSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebAddress, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebAddressSymbolFields index] => this.Fields[(int)index]; + + public string WebRef + { + get => this.Fields[(int)IIsWebAddressSymbolFields.WebRef].AsString(); + set => this.Set((int)IIsWebAddressSymbolFields.WebRef, value); + } + + public string IP + { + get => this.Fields[(int)IIsWebAddressSymbolFields.IP].AsString(); + set => this.Set((int)IIsWebAddressSymbolFields.IP, value); + } + + public string Port + { + get => this.Fields[(int)IIsWebAddressSymbolFields.Port].AsString(); + set => this.Set((int)IIsWebAddressSymbolFields.Port, value); + } + + public string Header + { + get => this.Fields[(int)IIsWebAddressSymbolFields.Header].AsString(); + set => this.Set((int)IIsWebAddressSymbolFields.Header, value); + } + + public int? Secure + { + get => this.Fields[(int)IIsWebAddressSymbolFields.Secure].AsNullableNumber(); + set => this.Set((int)IIsWebAddressSymbolFields.Secure, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs new file mode 100644 index 00000000..4283d702 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs @@ -0,0 +1,79 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebApplicationExtension = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebApplicationExtension.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.ApplicationRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Extension), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Verbs), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Executable), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Attributes), IntermediateFieldType.Number), + }, + typeof(IIsWebApplicationExtensionSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebApplicationExtensionSymbolFields + { + ApplicationRef, + Extension, + Verbs, + Executable, + Attributes, + } + + public class IIsWebApplicationExtensionSymbol : IntermediateSymbol + { + public IIsWebApplicationExtensionSymbol() : base(IisSymbolDefinitions.IIsWebApplicationExtension, null, null) + { + } + + public IIsWebApplicationExtensionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebApplicationExtension, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebApplicationExtensionSymbolFields index] => this.Fields[(int)index]; + + public string ApplicationRef + { + get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.ApplicationRef].AsString(); + set => this.Set((int)IIsWebApplicationExtensionSymbolFields.ApplicationRef, value); + } + + public string Extension + { + get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Extension].AsString(); + set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Extension, value); + } + + public string Verbs + { + get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Verbs].AsString(); + set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Verbs, value); + } + + public string Executable + { + get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Executable].AsString(); + set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Executable, value); + } + + public int Attributes + { + get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Attributes].AsNumber(); + set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Attributes, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebApplicationSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebApplicationSymbol.cs new file mode 100644 index 00000000..2f6f87de --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebApplicationSymbol.cs @@ -0,0 +1,127 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebApplication = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebApplication.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.Isolation), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.AllowSessions), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.SessionTimeout), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.Buffer), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ParentPaths), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.DefaultScript), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ScriptTimeout), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ServerDebugging), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ClientDebugging), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.AppPoolRef), IntermediateFieldType.String), + }, + typeof(IIsWebApplicationSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebApplicationSymbolFields + { + Name, + Isolation, + AllowSessions, + SessionTimeout, + Buffer, + ParentPaths, + DefaultScript, + ScriptTimeout, + ServerDebugging, + ClientDebugging, + AppPoolRef, + } + + public class IIsWebApplicationSymbol : IntermediateSymbol + { + public IIsWebApplicationSymbol() : base(IisSymbolDefinitions.IIsWebApplication, null, null) + { + } + + public IIsWebApplicationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebApplication, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebApplicationSymbolFields index] => this.Fields[(int)index]; + + public string Name + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.Name].AsString(); + set => this.Set((int)IIsWebApplicationSymbolFields.Name, value); + } + + public int Isolation + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.Isolation].AsNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.Isolation, value); + } + + public int? AllowSessions + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.AllowSessions].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.AllowSessions, value); + } + + public int? SessionTimeout + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.SessionTimeout].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.SessionTimeout, value); + } + + public int? Buffer + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.Buffer].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.Buffer, value); + } + + public int? ParentPaths + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.ParentPaths].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.ParentPaths, value); + } + + public string DefaultScript + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.DefaultScript].AsString(); + set => this.Set((int)IIsWebApplicationSymbolFields.DefaultScript, value); + } + + public int? ScriptTimeout + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.ScriptTimeout].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.ScriptTimeout, value); + } + + public int? ServerDebugging + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.ServerDebugging].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.ServerDebugging, value); + } + + public int? ClientDebugging + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.ClientDebugging].AsNullableNumber(); + set => this.Set((int)IIsWebApplicationSymbolFields.ClientDebugging, value); + } + + public string AppPoolRef + { + get => this.Fields[(int)IIsWebApplicationSymbolFields.AppPoolRef].AsString(); + set => this.Set((int)IIsWebApplicationSymbolFields.AppPoolRef, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebDirPropertiesSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebDirPropertiesSymbol.cs new file mode 100644 index 00000000..42d2dead --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebDirPropertiesSymbol.cs @@ -0,0 +1,151 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebDirProperties = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebDirProperties.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.Access), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.Authorization), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AnonymousUserRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.IIsControlledPassword), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.LogVisits), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.Index), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.DefaultDoc), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AspDetailedError), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.HttpExpires), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.CacheControlMaxAge), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.CacheControlCustom), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.NoCustomError), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AccessSSLFlags), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AuthenticationProviders), IntermediateFieldType.String), + }, + typeof(IIsWebDirPropertiesSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebDirPropertiesSymbolFields + { + Access, + Authorization, + AnonymousUserRef, + IIsControlledPassword, + LogVisits, + Index, + DefaultDoc, + AspDetailedError, + HttpExpires, + CacheControlMaxAge, + CacheControlCustom, + NoCustomError, + AccessSSLFlags, + AuthenticationProviders, + } + + public class IIsWebDirPropertiesSymbol : IntermediateSymbol + { + public IIsWebDirPropertiesSymbol() : base(IisSymbolDefinitions.IIsWebDirProperties, null, null) + { + } + + public IIsWebDirPropertiesSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebDirProperties, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebDirPropertiesSymbolFields index] => this.Fields[(int)index]; + + public int? Access + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.Access].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.Access, value); + } + + public int? Authorization + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.Authorization].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.Authorization, value); + } + + public string AnonymousUserRef + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AnonymousUserRef].AsString(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.AnonymousUserRef, value); + } + + public int? IIsControlledPassword + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.IIsControlledPassword].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.IIsControlledPassword, value); + } + + public int? LogVisits + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.LogVisits].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.LogVisits, value); + } + + public int? Index + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.Index].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.Index, value); + } + + public string DefaultDoc + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.DefaultDoc].AsString(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.DefaultDoc, value); + } + + public int? AspDetailedError + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AspDetailedError].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.AspDetailedError, value); + } + + public string HttpExpires + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.HttpExpires].AsString(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.HttpExpires, value); + } + + public int? CacheControlMaxAge + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.CacheControlMaxAge].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.CacheControlMaxAge, value); + } + + public string CacheControlCustom + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.CacheControlCustom].AsString(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.CacheControlCustom, value); + } + + public int? NoCustomError + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.NoCustomError].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.NoCustomError, value); + } + + public int? AccessSSLFlags + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AccessSSLFlags].AsNullableNumber(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.AccessSSLFlags, value); + } + + public string AuthenticationProviders + { + get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AuthenticationProviders].AsString(); + set => this.Set((int)IIsWebDirPropertiesSymbolFields.AuthenticationProviders, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebDirSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebDirSymbol.cs new file mode 100644 index 00000000..7f257f14 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebDirSymbol.cs @@ -0,0 +1,79 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebDir = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebDir.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.WebRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.Path), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.DirPropertiesRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.ApplicationRef), IntermediateFieldType.String), + }, + typeof(IIsWebDirSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebDirSymbolFields + { + ComponentRef, + WebRef, + Path, + DirPropertiesRef, + ApplicationRef, + } + + public class IIsWebDirSymbol : IntermediateSymbol + { + public IIsWebDirSymbol() : base(IisSymbolDefinitions.IIsWebDir, null, null) + { + } + + public IIsWebDirSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebDir, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebDirSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)IIsWebDirSymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsWebDirSymbolFields.ComponentRef, value); + } + + public string WebRef + { + get => this.Fields[(int)IIsWebDirSymbolFields.WebRef].AsString(); + set => this.Set((int)IIsWebDirSymbolFields.WebRef, value); + } + + public string Path + { + get => this.Fields[(int)IIsWebDirSymbolFields.Path].AsString(); + set => this.Set((int)IIsWebDirSymbolFields.Path, value); + } + + public string DirPropertiesRef + { + get => this.Fields[(int)IIsWebDirSymbolFields.DirPropertiesRef].AsString(); + set => this.Set((int)IIsWebDirSymbolFields.DirPropertiesRef, value); + } + + public string ApplicationRef + { + get => this.Fields[(int)IIsWebDirSymbolFields.ApplicationRef].AsString(); + set => this.Set((int)IIsWebDirSymbolFields.ApplicationRef, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebErrorSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebErrorSymbol.cs new file mode 100644 index 00000000..f8488fed --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebErrorSymbol.cs @@ -0,0 +1,87 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebError = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebError.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.ErrorCode), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.SubCode), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.ParentType), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.ParentValue), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.File), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.URL), IntermediateFieldType.String), + }, + typeof(IIsWebErrorSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebErrorSymbolFields + { + ErrorCode, + SubCode, + ParentType, + ParentValue, + File, + URL, + } + + public class IIsWebErrorSymbol : IntermediateSymbol + { + public IIsWebErrorSymbol() : base(IisSymbolDefinitions.IIsWebError, null, null) + { + } + + public IIsWebErrorSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebError, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebErrorSymbolFields index] => this.Fields[(int)index]; + + public int ErrorCode + { + get => this.Fields[(int)IIsWebErrorSymbolFields.ErrorCode].AsNumber(); + set => this.Set((int)IIsWebErrorSymbolFields.ErrorCode, value); + } + + public int SubCode + { + get => this.Fields[(int)IIsWebErrorSymbolFields.SubCode].AsNumber(); + set => this.Set((int)IIsWebErrorSymbolFields.SubCode, value); + } + + public int ParentType + { + get => this.Fields[(int)IIsWebErrorSymbolFields.ParentType].AsNumber(); + set => this.Set((int)IIsWebErrorSymbolFields.ParentType, value); + } + + public string ParentValue + { + get => this.Fields[(int)IIsWebErrorSymbolFields.ParentValue].AsString(); + set => this.Set((int)IIsWebErrorSymbolFields.ParentValue, value); + } + + public string File + { + get => this.Fields[(int)IIsWebErrorSymbolFields.File].AsString(); + set => this.Set((int)IIsWebErrorSymbolFields.File, value); + } + + public string URL + { + get => this.Fields[(int)IIsWebErrorSymbolFields.URL].AsString(); + set => this.Set((int)IIsWebErrorSymbolFields.URL, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebLogSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebLogSymbol.cs new file mode 100644 index 00000000..409dc673 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebLogSymbol.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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebLog = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebLog.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebLogSymbolFields.Format), IntermediateFieldType.String), + }, + typeof(IIsWebLogSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebLogSymbolFields + { + Format, + } + + public class IIsWebLogSymbol : IntermediateSymbol + { + public IIsWebLogSymbol() : base(IisSymbolDefinitions.IIsWebLog, null, null) + { + } + + public IIsWebLogSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebLog, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebLogSymbolFields index] => this.Fields[(int)index]; + + public string Format + { + get => this.Fields[(int)IIsWebLogSymbolFields.Format].AsString(); + set => this.Set((int)IIsWebLogSymbolFields.Format, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebServiceExtensionSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebServiceExtensionSymbol.cs new file mode 100644 index 00000000..44922357 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebServiceExtensionSymbol.cs @@ -0,0 +1,79 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebServiceExtension = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebServiceExtension.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.File), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.Description), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.Group), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.Attributes), IntermediateFieldType.Number), + }, + typeof(IIsWebServiceExtensionSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebServiceExtensionSymbolFields + { + ComponentRef, + File, + Description, + Group, + Attributes, + } + + public class IIsWebServiceExtensionSymbol : IntermediateSymbol + { + public IIsWebServiceExtensionSymbol() : base(IisSymbolDefinitions.IIsWebServiceExtension, null, null) + { + } + + public IIsWebServiceExtensionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebServiceExtension, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebServiceExtensionSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsWebServiceExtensionSymbolFields.ComponentRef, value); + } + + public string File + { + get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.File].AsString(); + set => this.Set((int)IIsWebServiceExtensionSymbolFields.File, value); + } + + public string Description + { + get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.Description].AsString(); + set => this.Set((int)IIsWebServiceExtensionSymbolFields.Description, value); + } + + public string Group + { + get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.Group].AsString(); + set => this.Set((int)IIsWebServiceExtensionSymbolFields.Group, value); + } + + public int Attributes + { + get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.Attributes].AsNumber(); + set => this.Set((int)IIsWebServiceExtensionSymbolFields.Attributes, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs new file mode 100644 index 00000000..851ce556 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs @@ -0,0 +1,55 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebSiteCertificates = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebSiteCertificates.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebSiteCertificatesSymbolFields.WebRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteCertificatesSymbolFields.CertificateRef), IntermediateFieldType.String), + }, + typeof(IIsWebSiteCertificatesSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebSiteCertificatesSymbolFields + { + WebRef, + CertificateRef, + } + + public class IIsWebSiteCertificatesSymbol : IntermediateSymbol + { + public IIsWebSiteCertificatesSymbol() : base(IisSymbolDefinitions.IIsWebSiteCertificates, null, null) + { + } + + public IIsWebSiteCertificatesSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebSiteCertificates, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebSiteCertificatesSymbolFields index] => this.Fields[(int)index]; + + public string WebRef + { + get => this.Fields[(int)IIsWebSiteCertificatesSymbolFields.WebRef].AsString(); + set => this.Set((int)IIsWebSiteCertificatesSymbolFields.WebRef, value); + } + + public string CertificateRef + { + get => this.Fields[(int)IIsWebSiteCertificatesSymbolFields.CertificateRef].AsString(); + set => this.Set((int)IIsWebSiteCertificatesSymbolFields.CertificateRef, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebSiteSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebSiteSymbol.cs new file mode 100644 index 00000000..ceba2ea0 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebSiteSymbol.cs @@ -0,0 +1,135 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebSite = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebSite.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.Description), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.ConnectionTimeout), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.DirectoryRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.State), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.KeyAddressRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.DirPropertiesRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.ApplicationRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.Sequence), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.LogRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.WebsiteId), IntermediateFieldType.String), + }, + typeof(IIsWebSiteSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebSiteSymbolFields + { + ComponentRef, + Description, + ConnectionTimeout, + DirectoryRef, + State, + Attributes, + KeyAddressRef, + DirPropertiesRef, + ApplicationRef, + Sequence, + LogRef, + WebsiteId, + } + + public class IIsWebSiteSymbol : IntermediateSymbol + { + public IIsWebSiteSymbol() : base(IisSymbolDefinitions.IIsWebSite, null, null) + { + } + + public IIsWebSiteSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebSite, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebSiteSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)IIsWebSiteSymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.ComponentRef, value); + } + + public string Description + { + get => this.Fields[(int)IIsWebSiteSymbolFields.Description].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.Description, value); + } + + public int? ConnectionTimeout + { + get => this.Fields[(int)IIsWebSiteSymbolFields.ConnectionTimeout].AsNullableNumber(); + set => this.Set((int)IIsWebSiteSymbolFields.ConnectionTimeout, value); + } + + public string DirectoryRef + { + get => this.Fields[(int)IIsWebSiteSymbolFields.DirectoryRef].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.DirectoryRef, value); + } + + public int? State + { + get => this.Fields[(int)IIsWebSiteSymbolFields.State].AsNullableNumber(); + set => this.Set((int)IIsWebSiteSymbolFields.State, value); + } + + public int Attributes + { + get => this.Fields[(int)IIsWebSiteSymbolFields.Attributes].AsNumber(); + set => this.Set((int)IIsWebSiteSymbolFields.Attributes, value); + } + + public string KeyAddressRef + { + get => this.Fields[(int)IIsWebSiteSymbolFields.KeyAddressRef].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.KeyAddressRef, value); + } + + public string DirPropertiesRef + { + get => this.Fields[(int)IIsWebSiteSymbolFields.DirPropertiesRef].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.DirPropertiesRef, value); + } + + public string ApplicationRef + { + get => this.Fields[(int)IIsWebSiteSymbolFields.ApplicationRef].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.ApplicationRef, value); + } + + public int? Sequence + { + get => this.Fields[(int)IIsWebSiteSymbolFields.Sequence].AsNullableNumber(); + set => this.Set((int)IIsWebSiteSymbolFields.Sequence, value); + } + + public string LogRef + { + get => this.Fields[(int)IIsWebSiteSymbolFields.LogRef].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.LogRef, value); + } + + public string WebsiteId + { + get => this.Fields[(int)IIsWebSiteSymbolFields.WebsiteId].AsString(); + set => this.Set((int)IIsWebSiteSymbolFields.WebsiteId, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IIsWebVirtualDirSymbol.cs b/src/ext/Iis/wixext/Symbols/IIsWebVirtualDirSymbol.cs new file mode 100644 index 00000000..bfc29e84 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IIsWebVirtualDirSymbol.cs @@ -0,0 +1,87 @@ +// 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.Iis +{ + using WixToolset.Data; + using WixToolset.Iis.Symbols; + + public static partial class IisSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition IIsWebVirtualDir = new IntermediateSymbolDefinition( + IisSymbolDefinitionType.IIsWebVirtualDir.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.WebRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.Alias), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.DirectoryRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.DirPropertiesRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.ApplicationRef), IntermediateFieldType.String), + }, + typeof(IIsWebVirtualDirSymbol)); + } +} + +namespace WixToolset.Iis.Symbols +{ + using WixToolset.Data; + + public enum IIsWebVirtualDirSymbolFields + { + ComponentRef, + WebRef, + Alias, + DirectoryRef, + DirPropertiesRef, + ApplicationRef, + } + + public class IIsWebVirtualDirSymbol : IntermediateSymbol + { + public IIsWebVirtualDirSymbol() : base(IisSymbolDefinitions.IIsWebVirtualDir, null, null) + { + } + + public IIsWebVirtualDirSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebVirtualDir, sourceLineNumber, id) + { + } + + public IntermediateField this[IIsWebVirtualDirSymbolFields index] => this.Fields[(int)index]; + + public string ComponentRef + { + get => this.Fields[(int)IIsWebVirtualDirSymbolFields.ComponentRef].AsString(); + set => this.Set((int)IIsWebVirtualDirSymbolFields.ComponentRef, value); + } + + public string WebRef + { + get => this.Fields[(int)IIsWebVirtualDirSymbolFields.WebRef].AsString(); + set => this.Set((int)IIsWebVirtualDirSymbolFields.WebRef, value); + } + + public string Alias + { + get => this.Fields[(int)IIsWebVirtualDirSymbolFields.Alias].AsString(); + set => this.Set((int)IIsWebVirtualDirSymbolFields.Alias, value); + } + + public string DirectoryRef + { + get => this.Fields[(int)IIsWebVirtualDirSymbolFields.DirectoryRef].AsString(); + set => this.Set((int)IIsWebVirtualDirSymbolFields.DirectoryRef, value); + } + + public string DirPropertiesRef + { + get => this.Fields[(int)IIsWebVirtualDirSymbolFields.DirPropertiesRef].AsString(); + set => this.Set((int)IIsWebVirtualDirSymbolFields.DirPropertiesRef, value); + } + + public string ApplicationRef + { + get => this.Fields[(int)IIsWebVirtualDirSymbolFields.ApplicationRef].AsString(); + set => this.Set((int)IIsWebVirtualDirSymbolFields.ApplicationRef, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Iis/wixext/Symbols/IisSymbolDefinitions.cs b/src/ext/Iis/wixext/Symbols/IisSymbolDefinitions.cs new file mode 100644 index 00000000..d6ed80a2 --- /dev/null +++ b/src/ext/Iis/wixext/Symbols/IisSymbolDefinitions.cs @@ -0,0 +1,107 @@ +// 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.Iis +{ + using System; + using WixToolset.Data; + + public enum IisSymbolDefinitionType + { + Certificate, + CertificateHash, + IIsAppPool, + IIsFilter, + IIsHttpHeader, + IIsMimeMap, + IIsProperty, + IIsWebAddress, + IIsWebApplication, + IIsWebApplicationExtension, + IIsWebDir, + IIsWebDirProperties, + IIsWebError, + IIsWebLog, + IIsWebServiceExtension, + IIsWebSite, + IIsWebSiteCertificates, + IIsWebVirtualDir, + } + + public static partial class IisSymbolDefinitions + { + public static readonly Version Version = new Version("4.0.0"); + + public static IntermediateSymbolDefinition ByName(string name) + { + if (!Enum.TryParse(name, out IisSymbolDefinitionType type)) + { + return null; + } + + return ByType(type); + } + + public static IntermediateSymbolDefinition ByType(IisSymbolDefinitionType type) + { + switch (type) + { + case IisSymbolDefinitionType.Certificate: + return IisSymbolDefinitions.Certificate; + + case IisSymbolDefinitionType.CertificateHash: + return IisSymbolDefinitions.CertificateHash; + + case IisSymbolDefinitionType.IIsAppPool: + return IisSymbolDefinitions.IIsAppPool; + + case IisSymbolDefinitionType.IIsFilter: + return IisSymbolDefinitions.IIsFilter; + + case IisSymbolDefinitionType.IIsHttpHeader: + return IisSymbolDefinitions.IIsHttpHeader; + + case IisSymbolDefinitionType.IIsMimeMap: + return IisSymbolDefinitions.IIsMimeMap; + + case IisSymbolDefinitionType.IIsProperty: + return IisSymbolDefinitions.IIsProperty; + + case IisSymbolDefinitionType.IIsWebAddress: + return IisSymbolDefinitions.IIsWebAddress; + + case IisSymbolDefinitionType.IIsWebApplication: + return IisSymbolDefinitions.IIsWebApplication; + + case IisSymbolDefinitionType.IIsWebApplicationExtension: + return IisSymbolDefinitions.IIsWebApplicationExtension; + + case IisSymbolDefinitionType.IIsWebDir: + return IisSymbolDefinitions.IIsWebDir; + + case IisSymbolDefinitionType.IIsWebDirProperties: + return IisSymbolDefinitions.IIsWebDirProperties; + + case IisSymbolDefinitionType.IIsWebError: + return IisSymbolDefinitions.IIsWebError; + + case IisSymbolDefinitionType.IIsWebLog: + return IisSymbolDefinitions.IIsWebLog; + + case IisSymbolDefinitionType.IIsWebServiceExtension: + return IisSymbolDefinitions.IIsWebServiceExtension; + + case IisSymbolDefinitionType.IIsWebSite: + return IisSymbolDefinitions.IIsWebSite; + + case IisSymbolDefinitionType.IIsWebSiteCertificates: + return IisSymbolDefinitions.IIsWebSiteCertificates; + + case IisSymbolDefinitionType.IIsWebVirtualDir: + return IisSymbolDefinitions.IIsWebVirtualDir; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + } +} diff --git a/src/ext/Iis/wixext/WixToolset.Iis.wixext.csproj b/src/ext/Iis/wixext/WixToolset.Iis.wixext.csproj new file mode 100644 index 00000000..81d41e77 --- /dev/null +++ b/src/ext/Iis/wixext/WixToolset.Iis.wixext.csproj @@ -0,0 +1,31 @@ + + + + + + netstandard2.0 + WixToolset.Iis + WiX Toolset Iis Extension + WiX Toolset Iis Extension + true + build + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/wixext/WixToolset.Iis.wixext.targets b/src/ext/Iis/wixext/WixToolset.Iis.wixext.targets new file mode 100644 index 00000000..6398fce1 --- /dev/null +++ b/src/ext/Iis/wixext/WixToolset.Iis.wixext.targets @@ -0,0 +1,11 @@ + + + + + + $(MSBuildThisFileDirectory)..\tools\WixToolset.Iis.wixext.dll + + + + + diff --git a/src/ext/Iis/wixlib/IIsExtension.wxs b/src/ext/Iis/wixlib/IIsExtension.wxs new file mode 100644 index 00000000..18fc34ff --- /dev/null +++ b/src/ext/Iis/wixlib/IIsExtension.wxs @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/wixlib/IIsExtension_Platform.wxi b/src/ext/Iis/wixlib/IIsExtension_Platform.wxi new file mode 100644 index 00000000..09562a69 --- /dev/null +++ b/src/ext/Iis/wixlib/IIsExtension_Platform.wxi @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/wixlib/IIsExtension_arm64.wxs b/src/ext/Iis/wixlib/IIsExtension_arm64.wxs new file mode 100644 index 00000000..39ac048f --- /dev/null +++ b/src/ext/Iis/wixlib/IIsExtension_arm64.wxs @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ext/Iis/wixlib/IIsExtension_x64.wxs b/src/ext/Iis/wixlib/IIsExtension_x64.wxs new file mode 100644 index 00000000..553953b3 --- /dev/null +++ b/src/ext/Iis/wixlib/IIsExtension_x64.wxs @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ext/Iis/wixlib/IIsExtension_x86.wxs b/src/ext/Iis/wixlib/IIsExtension_x86.wxs new file mode 100644 index 00000000..c99a243b --- /dev/null +++ b/src/ext/Iis/wixlib/IIsExtension_x86.wxs @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ext/Iis/wixlib/caDecor.wxi b/src/ext/Iis/wixlib/caDecor.wxi new file mode 100644 index 00000000..b1711518 --- /dev/null +++ b/src/ext/Iis/wixlib/caDecor.wxi @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/wixlib/caerr.wxi b/src/ext/Iis/wixlib/caerr.wxi new file mode 100644 index 00000000..ff7ec121 --- /dev/null +++ b/src/ext/Iis/wixlib/caerr.wxi @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/Iis/wixlib/de-de.wxl b/src/ext/Iis/wixlib/de-de.wxl new file mode 100644 index 00000000..5929f258 --- /dev/null +++ b/src/ext/Iis/wixlib/de-de.wxl @@ -0,0 +1,55 @@ + + + + + Konnte keine Verbindung mit dem Internet Information Server herstellen. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebSites. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebDirs. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebVirtualDirs. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebFilters. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der MimeMaps. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebAppPools. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebProperties. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebServiceExtensions. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der WebErrors. ([2] [3] [4] [5]) + Fehler bei der Verarbeitung der HttpHeader. ([2] [3] [4] [5]) + + Die Transaktion für Änderungen am IIS konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS-Websites konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS Web Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS Virtual Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS Filters konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS AppPools konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS Properties konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Installation von IIS Web Service Extensions konnte nicht geschedulded werden. ([2] [3] [4] [5]) + + Die Deinstallation von IIS Web Sites konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Deinstallation von IIS Web Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Deinstallation von IIS Virtual Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Deinstallation von IIS Filters konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Deinstallation von IIS AppPools konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Deinstallation der IIS Properties konnte nicht geschedulded werden. ([2] [3] [4] [5]) + Die Deinstallation von IIS Web Service Extensions konnte nicht geschedulded werden. ([2] [3] [4] [5]) + + Die IIS-Transaktion konnte nicht gestartet werden. ([2] [3] [4] [5]) + Der Metabase Key konnte nicht geöffnet werden. ([2] [3] [4] [5]) + Der Metabase Key konnte nicht erstellt werden. ([2] [3] [4] [5]) + Daten konnten nicht in den Metabase Key geschrieben werden. ([2] [3] [4] [5]) + Webanwendung konnte nicht erstellt werden. ([2] [3] [4] [5]) + Der Metabase Key konnte nicht gelöscht werden. ([2] [3] [4] [5]) + Der Metabase Value konnte nicht gelöscht werden. ([2] [3] [4] [5]) + Die IIS Transaktion konnte aufgrund einer Freigabeverletzung nicht committed werden. Möglicherweise konfiguriert eine andere Anwendung derzeit IIS. + + Konfiguriere IIS + Führe IIS Konfiguration aus + Starte IIS Metabase Transaktion + Mache IIS Metabase Transaktion rückgängig + Committe IIS Metabase Transaktion + Installiere Metabase Keys und Values + + Konfiguriere IIS + Starte IIS Konfigurationstransaktion + Mache IIS Konfigurationstransaktion rückgängig + Committe IIS Konfigurationstransaktion + Installiere Konfigurationskeys and -values + diff --git a/src/ext/Iis/wixlib/en-us.wxl b/src/ext/Iis/wixlib/en-us.wxl new file mode 100644 index 00000000..44949095 --- /dev/null +++ b/src/ext/Iis/wixlib/en-us.wxl @@ -0,0 +1,55 @@ + + + + + Cannot connect to Internet Information Server. ([2] [3] [4] [5]) + Failed while processing WebSites. ([2] [3] [4] [5]) + Failed while processing WebDirs. ([2] [3] [4] [5]) + Failed while processing WebVirtualDirs. ([2] [3] [4] [5]) + Failed while processing WebFilters. ([2] [3] [4] [5]) + Failed while processing MimeMaps. ([2] [3] [4] [5]) + Failed while processing WebAppPools. ([2] [3] [4] [5]) + Failed while processing WebProperties. ([2] [3] [4] [5]) + Failed while processing WebServiceExtensions. ([2] [3] [4] [5]) + Failed while processing WebErrors. ([2] [3] [4] [5]) + Failed while processing HttpHeaders. ([2] [3] [4] [5]) + + Failed to schedule transaction for changes to IIS. ([2] [3] [4] [5]) + Failed to schedule install of IIS Web Sites. ([2] [3] [4] [5]) + Failed to schedule install of IIS Web Directories. ([2] [3] [4] [5]) + Failed to schedule install of IIS Virtual Directories. ([2] [3] [4] [5]) + Failed to schedule install of IIS Filters. ([2] [3] [4] [5]) + Failed to schedule install of IIS AppPools. ([2] [3] [4] [5]) + Failed to schedule install of IIS Properties. ([2] [3] [4] [5]) + Failed to schedule install of IIS Web Service Extensions. ([2] [3] [4] [5]) + + Failed to schedule uninstall of IIS Web Sites. ([2] [3] [4] [5]) + Failed to schedule uninstall of IIS Web Directories. ([2] [3] [4] [5]) + Failed to schedule uninstall of IIS Virtual Directories. ([2] [3] [4] [5]) + Failed to schedule uninstall of IIS Filters. ([2] [3] [4] [5]) + Failed to schedule uninstall of IIS AppPools. ([2] [3] [4] [5]) + Failed to schedule uninstall of IIS Properties. ([2] [3] [4] [5]) + Failed to schedule uninstall of IIS Web Service Extensions. ([2] [3] [4] [5]) + + Failed to start IIS transaction. ([2] [3] [4] [5]) + Failed to open metabase key. ([2] [3] [4] [5]) + Failed to create metabase key. ([2] [3] [4] [5]) + Failed to write data to metabase key. ([2] [3] [4] [5]) + Failed to create web application. ([2] [3] [4] [5]) + Failed to delete metabase key. ([2] [3] [4] [5]) + Failed to delete metabase value. ([2] [3] [4] [5]) + Failed to commit IIS transaction due to a sharing violation. Some other application may be configuring IIS. + + Configuring IIS + Executing IIS Configuration + Starting IIS Metabase Transaction + Rolling back IIS Metabase Transaction + Committing IIS Metabase Transaction + Installing Metabase Keys and Values + + Configuring IIS + Starting IIS Config Transaction + Rolling back IIS Config Transaction + Committing IIS Config Transaction + Installing Config Keys and Values + diff --git a/src/ext/Iis/wixlib/iis.v3.ncrunchproject b/src/ext/Iis/wixlib/iis.v3.ncrunchproject new file mode 100644 index 00000000..319cd523 --- /dev/null +++ b/src/ext/Iis/wixlib/iis.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/src/ext/Iis/wixlib/iis.wixproj b/src/ext/Iis/wixlib/iis.wixproj new file mode 100644 index 00000000..89f9608f --- /dev/null +++ b/src/ext/Iis/wixlib/iis.wixproj @@ -0,0 +1,26 @@ + + + + + Library + true + en-us + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Iis/wixlib/ja-jp.wxl b/src/ext/Iis/wixlib/ja-jp.wxl new file mode 100644 index 00000000..7fd6978a --- /dev/null +++ b/src/ext/Iis/wixlib/ja-jp.wxl @@ -0,0 +1,47 @@ + + + + + IISへ接続できません。 ([2] [3] [4] [5]) + ウェブ サイト処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ ディレクトリ処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ仮想ディレクトリ処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ フィルタ処理中に失敗しました。 ([2] [3] [4] [5]) + MIME マップ処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ アプリケーション プール処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ プロパティ処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ サービス拡張処理中に失敗しました。 ([2] [3] [4] [5]) + ウェブ エラー処理中に失敗しました。 ([2] [3] [4] [5]) + HTTP ヘッダ処理中に失敗しました。 ([2] [3] [4] [5]) + + IIS 変更トランザクションのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS ウェブ サイト インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS ウェブ ディレクトリ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS 仮想ディレクトリ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS フィルタ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS アプリケーション プール インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS プロパティ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS ウェブ サービス拡張インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + + IISウェブ サイト アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS ウェブ ディレクトリ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS 仮想ディレクトリ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS フィルタ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS アプリケーション プール アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS プロパティ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + IIS ウェブ サービス拡張アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) + + IIS トランザクション開始に失敗しました。 ([2] [3] [4] [5]) + メタベース キーのオープンに失敗しました。 ([2] [3] [4] [5]) + メタベース キーの作成に失敗しました。 ([2] [3] [4] [5]) + メタベース キーの書き込みに失敗しました。 ([2] [3] [4] [5]) + ウェブ アプリケーションの作成に失敗しました。 ([2] [3] [4] [5]) + メタベース キーの削除に失敗しました。 ([2] [3] [4] [5]) + メタベース値の削除に失敗しました。 ([2] [3] [4] [5]) + + IIS を構成しています + IIS メタベース トランザクションを開始しています + IIS メタベース トランザクションをロールバックしています + IIS メタベース トランザクションを確定しています + IIS メタベース キーと値をインストールしています + diff --git a/src/ext/Iis/wixlib/pt-br.wxl b/src/ext/Iis/wixlib/pt-br.wxl new file mode 100644 index 00000000..1fc0d768 --- /dev/null +++ b/src/ext/Iis/wixlib/pt-br.wxl @@ -0,0 +1,50 @@ + + + + + Não foi possível conectar no Internet Information Server. ([2] [3] [4] [5]) + Erro ao processar WebSites. ([2] [3] [4] [5]) + Erro ao processar WebDirs. ([2] [3] [4] [5]) + Erro ao processar WebVirtualDirs. ([2] [3] [4] [5]) + Erro ao processar WebFilters. ([2] [3] [4] [5]) + Erro ao processar MimeMaps. ([2] [3] [4] [5]) + Erro ao processar WebAppPools. ([2] [3] [4] [5]) + Erro ao processar WebProperties. ([2] [3] [4] [5]) + Erro ao processar WebServiceExtensions. ([2] [3] [4] [5]) + Erro ao processar WebErrors. ([2] [3] [4] [5]) + Erro ao processar HttpHeaders. ([2] [3] [4] [5]) + Erro ao agendar transação para alterações no IIS. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS Web Sites. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS Web Directories. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS Virtual Directories. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS Filters. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS AppPools. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS Properties. ([2] [3] [4] [5]) + Erro ao agendar instalação de IIS Web Service Extensions. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS Web Sites. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS Web Directories. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS Virtual Directories. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS Filters. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS AppPools. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS Properties. ([2] [3] [4] [5]) + Erro ao agendar desinstalação de IIS Web Service Extensions. ([2] [3] [4] [5]) + Erro ao iniciar transação do IIS . ([2] [3] [4] [5]) + Erro ao abrir metabase key. ([2] [3] [4] [5]) + Erro ao criar metabase key. ([2] [3] [4] [5]) + Erro ao escrever dados na metabase key. ([2] [3] [4] [5]) + Erro ao criar aplicação Web. ([2] [3] [4] [5]) + Erro ao excluir metabase key. ([2] [3] [4] [5]) + Erro ao excluir valor da metabase. ([2] [3] [4] [5]) + Erro ao fazer commit de transação IIS por violação de compartilhamento. Alguma outra aplicação pode estar tentando configurar o ISS ao mesmo tempo. + Configurando IIS + Executando Configurações do IIS + Iniciando Transação de Metabase do IIS + Cancelando Transação de Metabase do IIS + Efetivando Transação de Metabase do IIS + Instalando Chaves e Valores de Metabase do IIS + Configurando IIS + Iniciando Transação de Configuração do IIS + Cancelando Transação de Configuração do IIS + Efetivando Transação de Configuração do IIS + Instalando Chaves e Valores de Configurações do IIS + 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.Iis/IisExtensionFixture.cs b/src/test/WixToolsetTest.Iis/IisExtensionFixture.cs deleted file mode 100644 index 685e7126..00000000 --- a/src/test/WixToolsetTest.Iis/IisExtensionFixture.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.Iis -{ - using System.Linq; - using WixBuildTools.TestSupport; - using WixToolset.Core.TestPackage; - using WixToolset.Iis; - using Xunit; - - public class IisExtensionFixture - { - [Fact] - public void CanBuildUsingIIsWebAddress() - { - var folder = TestData.Get(@"TestData\UsingIis"); - var build = new Builder(folder, typeof(IisExtensionFactory), new[] { folder }); - - var results = build.BuildAndQuery(Build, "IIsWebAddress"); - Assert.Equal(new[] - { - "IIsWebAddress:TestAddress\tTest\t\t[PORT]\t\t0", - }, results); - } - - private static void Build(string[] args) - { - var result = WixRunner.Execute(args) - .AssertSuccess(); - } - } -} diff --git a/src/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl b/src/test/WixToolsetTest.Iis/TestData/UsingIis/Package.en-us.wxl deleted file mode 100644 index 38c12ac1..00000000 --- a/src/test/WixToolsetTest.Iis/TestData/UsingIis/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.Iis/TestData/UsingIis/Package.wxs b/src/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs deleted file mode 100644 index f36aafef..00000000 --- a/src/test/WixToolsetTest.Iis/TestData/UsingIis/Package.wxs +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs b/src/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs deleted file mode 100644 index 03203b50..00000000 --- a/src/test/WixToolsetTest.Iis/TestData/UsingIis/PackageComponents.wxs +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt b/src/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt deleted file mode 100644 index 1b4ffe8a..00000000 --- a/src/test/WixToolsetTest.Iis/TestData/UsingIis/example.txt +++ /dev/null @@ -1 +0,0 @@ -This is example.txt. \ No newline at end of file diff --git a/src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj b/src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj deleted file mode 100644 index 49ed89bc..00000000 --- a/src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - netcoreapp3.1 - false - - - - NU1701 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject b/src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject deleted file mode 100644 index 7b5b2139..00000000 --- a/src/test/WixToolsetTest.Iis/WixToolsetTest.Iis.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file 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/IIsCompiler.cs b/src/wixext/IIsCompiler.cs deleted file mode 100644 index cb573ad1..00000000 --- a/src/wixext/IIsCompiler.cs +++ /dev/null @@ -1,2620 +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.Iis -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Xml.Linq; - using WixToolset.Data; - using WixToolset.Extensibility; - using WixToolset.Extensibility.Data; - using WixToolset.Iis.Symbols; - - /// - /// The compiler for the WiX Toolset Internet Information Services Extension. - /// - public sealed class IIsCompiler : BaseCompilerExtension - { - public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/iis"; - - /// - /// Types of objects that custom HTTP Headers can be applied to. - /// - /// Note that this must be kept in sync with the eHttpHeaderParentType in scahttpheader.h. - private enum HttpHeaderParentType - { - /// Custom HTTP Header is to be applied to a Web Virtual Directory. - WebVirtualDir = 1, - /// Custom HTTP Header is to be applied to a Web Site. - WebSite = 2, - } - - /// - /// Types of objects that MimeMaps can be applied to. - /// - /// Note that this must be kept in sync with the eMimeMapParentType in scamimemap.h. - private enum MimeMapParentType - { - /// MimeMap is to be applied to a Web Virtual Directory. - WebVirtualDir = 1, - WebSite = 2, - } - - /// - /// Types of objects that custom WebErrors can be applied to. - /// - /// Note that this must be kept in sync with the eWebErrorParentType in scaweberror.h. - private enum WebErrorParentType - { - /// Custom WebError is to be applied to a Web Virtual Directory. - WebVirtualDir = 1, - - /// Custom WebError is to be applied to a Web Site. - WebSite = 2, - } - - /// - /// Processes an element for the Compiler. - /// - /// Source line number for the parent element. - /// 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 "Certificate": - this.ParseCertificateElement(intermediate, section, element, componentId); - break; - case "WebAppPool": - this.ParseWebAppPoolElement(intermediate, section, element, componentId); - break; - case "WebDir": - this.ParseWebDirElement(intermediate, section, element, componentId, null); - break; - case "WebFilter": - this.ParseWebFilterElement(intermediate, section, element, componentId, null); - break; - case "WebProperty": - this.ParseWebPropertyElement(intermediate, section, element, componentId); - break; - case "WebServiceExtension": - this.ParseWebServiceExtensionElement(intermediate, section, element, componentId); - break; - case "WebSite": - this.ParseWebSiteElement(intermediate, section, element, componentId); - break; - case "WebVirtualDir": - this.ParseWebVirtualDirElement(intermediate, section, element, componentId, null, null); - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - break; - case "Fragment": - case "Module": - case "Package": - switch (element.Name.LocalName) - { - case "WebApplication": - this.ParseWebApplicationElement(intermediate, section, element); - break; - case "WebAppPool": - this.ParseWebAppPoolElement(intermediate, section, element, null); - break; - case "WebDirProperties": - this.ParseWebDirPropertiesElement(intermediate, section, element, null); - break; - case "WebLog": - this.ParseWebLogElement(intermediate, section, element); - break; - case "WebSite": - this.ParseWebSiteElement(intermediate, section, element, null); - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - } - - /// - /// Parses a certificate element. - /// - /// Element to parse. - /// Identifier for parent component. - private void ParseCertificateElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int attributes = 8; // SCA_CERT_ATTRIBUTE_VITAL - string binaryRef = null; - string certificatePath = null; - string name = null; - string pfxPassword = null; - int storeLocation = 0; - string storeName = null; - - foreach (var attrib in element.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 "BinaryRef": - attributes |= 2; // SCA_CERT_ATTRIBUTE_BINARYDATA - binaryRef = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Binary, binaryRef); - break; - case "CertificatePath": - certificatePath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Name": - name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Overwrite": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 4; // SCA_CERT_ATTRIBUTE_OVERWRITE - } - else - { - attributes &= ~4; // SCA_CERT_ATTRIBUTE_OVERWRITE - } - break; - case "PFXPassword": - pfxPassword = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Request": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 1; // SCA_CERT_ATTRIBUTE_REQUEST - } - else - { - attributes &= ~1; // SCA_CERT_ATTRIBUTE_REQUEST - } - break; - case "StoreLocation": - var storeLocationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < storeLocationValue.Length) - { - switch (storeLocationValue) - { - case "currentUser": - storeLocation = 1; // SCA_CERTSYSTEMSTORE_CURRENTUSER - break; - case "localMachine": - storeLocation = 2; // SCA_CERTSYSTEMSTORE_LOCALMACHINE - break; - default: - storeLocation = -1; - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "StoreLocation", storeLocationValue, "currentUser", "localMachine")); - break; - } - } - break; - case "StoreName": - var storeNameValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < storeNameValue.Length) - { - switch (storeNameValue) - { - case "ca": - storeName = "CA"; - break; - case "my": - case "personal": - storeName = "MY"; - break; - case "request": - storeName = "REQUEST"; - break; - case "root": - storeName = "Root"; - break; - case "otherPeople": - storeName = "AddressBook"; - break; - case "trustedPeople": - storeName = "TrustedPeople"; - break; - case "trustedPublisher": - storeName = "TrustedPublisher"; - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "StoreName", storeNameValue, "ca", "my", "request", "root", "otherPeople", "trustedPeople", "trustedPublisher")); - break; - } - } - break; - case "Vital": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 8; // SCA_CERT_ATTRIBUTE_VITAL - } - else - { - attributes &= ~8; // SCA_CERT_ATTRIBUTE_VITAL - } - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("crt", componentId, binaryRef, certificatePath); - } - - if (null == name) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); - } - - if (0 == storeLocation) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "StoreLocation")); - } - - if (null == storeName) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "StoreName")); - } - - if (null != binaryRef && null != certificatePath) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "BinaryRef", "CertificatePath", certificatePath)); - } - else if (null == binaryRef && null == certificatePath) - { - this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, element.Name.LocalName, "BinaryRef", "CertificatePath")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference InstallCertificates and UninstallCertificates since nothing will happen without them - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4InstallCertificates", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4UninstallCertificates", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); - this.ParseHelper.EnsureTable(section, sourceLineNumbers, IisTableDefinitions.CertificateHash); // Certificate CustomActions require the CertificateHash table - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new CertificateSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - Name = name, - StoreLocation = storeLocation, - StoreName = storeName, - Attributes = attributes, - BinaryRef = binaryRef, - CertificatePath = certificatePath, - PFXPassword = pfxPassword, - }); - } - } - - /// - /// Parses a CertificateRef extension element. - /// - /// Element to parse. - /// Identifier for parent web site. - private void ParseCertificateRefElement(Intermediate intermediate, IntermediateSection section, XElement element, string webId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.Certificate, id.Id); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("wsc", webId); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.Certificate, id.Id); - - section.AddSymbol(new IIsWebSiteCertificatesSymbol(sourceLineNumbers) - { - WebRef = webId, - CertificateRef = id.Id, - }); - } - } - - /// - /// Parses a mime map element. - /// - /// Element to parse. - /// Identifier for parent symbol. - /// Type that parentId refers to. - private void ParseMimeMapElement(Intermediate intermediate, IntermediateSection section, XElement element, string parentId, MimeMapParentType parentType) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string extension = null; - string type = null; - - foreach (var attrib in element.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 "Extension": - extension = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Type": - type = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("imm", parentId, type, extension); - } - - if (null == extension) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Extension")); - } - else if (0 < extension.Length) - { - if (!extension.StartsWith(".", StringComparison.Ordinal)) - { - this.Messaging.Write(IIsErrors.MimeMapExtensionMissingPeriod(sourceLineNumbers, element.Name.LocalName, "Extension", extension)); - } - } - - if (null == type) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Type")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsMimeMapSymbol(sourceLineNumbers, id) - { - ParentType = (int)parentType, - ParentValue = parentId, - MimeType = type, - Extension = extension, - }); - } - } - - /// - /// Parses a recycle time element. - /// - /// Element to parse. - /// Recycle time value. - private string ParseRecycleTimeElement(Intermediate intermediate, IntermediateSection section, XElement element) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - string value = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Value": - value = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == value) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - return value; - } - - /// - /// Parses a web address element. - /// - /// Element to parse. - /// Identifier of parent web site. - /// Identifier for web address. - private string ParseWebAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, string parentWeb) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string header = null; - string ip = null; - string port = null; - var secure = false; - - foreach (var attrib in element.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 "Header": - header = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "IP": - ip = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Port": - port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Secure": - secure = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("iwa", parentWeb, ip, port); - } - - if (null == port) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Port")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsWebAddressSymbol(sourceLineNumbers, id) - { - WebRef = parentWeb, - IP = ip, - Port = port, - Header = header, - Secure = secure ? 1 : 0, - }); - } - - return id?.Id; - } - - /// - /// Parses a web application element. - /// - /// Element to parse. - /// Identifier for web application. - private string ParseWebApplicationElement(Intermediate intermediate, IntermediateSection section, XElement element) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - var allowSessions = YesNoDefaultType.Default; - string appPool = null; - var buffer = YesNoDefaultType.Default; - var clientDebugging = YesNoDefaultType.Default; - string defaultScript = null; - int isolation = 0; - string name = null; - var parentPaths = YesNoDefaultType.Default; - var scriptTimeout = CompilerConstants.IntegerNotSet; - var sessionTimeout = CompilerConstants.IntegerNotSet; - var serverDebugging = YesNoDefaultType.Default; - - foreach (var attrib in element.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 "AllowSessions": - allowSessions = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); - break; - case "Buffer": - buffer = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); - break; - case "ClientDebugging": - clientDebugging = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); - break; - case "DefaultScript": - defaultScript = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < defaultScript.Length) - { - switch (defaultScript) - { - case "JScript": - case "VBScript": - // these are valid values - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, defaultScript, "JScript", "VBScript")); - break; - } - } - break; - case "Isolation": - string isolationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < isolationValue.Length) - { - switch (isolationValue) - { - case "low": - isolation = 0; - break; - case "medium": - isolation = 2; - break; - case "high": - isolation = 1; - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, isolationValue, "low", "medium", "high")); - break; - } - } - break; - case "Name": - name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "ParentPaths": - parentPaths = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); - break; - case "ScriptTimeout": - scriptTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "ServerDebugging": - serverDebugging = this.ParseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); - break; - case "SessionTimeout": - sessionTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "WebAppPool": - appPool = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsAppPool, appPool); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("wap", name, appPool); - } - - if (null == name) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); - } - else if (-1 != name.IndexOf("\\", StringComparison.Ordinal)) - { - this.Messaging.Write(IIsErrors.IllegalCharacterInAttributeValue(sourceLineNumbers, element.Name.LocalName, "Name", name, '\\')); - } - - foreach (var child in element.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - switch (child.Name.LocalName) - { - case "WebApplicationExtension": - this.ParseWebApplicationExtensionElement(intermediate, section, child, id?.Id); - break; - default: - this.ParseHelper.UnexpectedElement(element, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); - } - } - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new IIsWebApplicationSymbol(sourceLineNumbers, id) - { - Name = name, - Isolation = isolation, - DefaultScript = defaultScript, - AppPoolRef = appPool, - }); - - if (YesNoDefaultType.Default != allowSessions) - { - symbol.AllowSessions = YesNoDefaultType.Yes == allowSessions ? 1 : 0; - } - - if (CompilerConstants.IntegerNotSet != sessionTimeout) - { - symbol.SessionTimeout = sessionTimeout; - } - - if (YesNoDefaultType.Default != buffer) - { - symbol.Buffer = YesNoDefaultType.Yes == buffer ? 1 : 0; - } - - if (YesNoDefaultType.Default != parentPaths) - { - symbol.ParentPaths = YesNoDefaultType.Yes == parentPaths ? 1 : 0; - } - - if (CompilerConstants.IntegerNotSet != scriptTimeout) - { - symbol.ScriptTimeout = scriptTimeout; - } - - if (YesNoDefaultType.Default != serverDebugging) - { - symbol.ServerDebugging = YesNoDefaultType.Yes == serverDebugging ? 1 : 0; - } - - if (YesNoDefaultType.Default != clientDebugging) - { - symbol.ClientDebugging = YesNoDefaultType.Yes == clientDebugging ? 1 : 0; - } - } - - return id?.Id; - } - - /// - /// Parses a web application extension element. - /// - /// Element to parse. - /// Identifier for parent web application. - private void ParseWebApplicationExtensionElement(Intermediate intermediate, IntermediateSection section, XElement element, string application) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - int attributes = 0; - string executable = null; - string extension = null; - string verbs = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "CheckPath": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 4; - } - else - { - attributes &= ~4; - } - break; - case "Executable": - executable = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Extension": - extension = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Script": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 1; - } - else - { - attributes &= ~1; - } - break; - case "Verbs": - verbs = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new IIsWebApplicationExtensionSymbol(sourceLineNumbers) - { - ApplicationRef = application, - Extension = extension, - Verbs = verbs, - Executable = executable, - }); - - if (0 < attributes) - { - symbol.Attributes = attributes; - } - } - } - - /// - /// Parses web application pool element. - /// - /// Element to parse. - /// Optional identifier of parent component. - private void ParseWebAppPoolElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int attributes = 0; - var cpuAction = CompilerConstants.IntegerNotSet; - string cpuMon = null; - var idleTimeout = CompilerConstants.IntegerNotSet; - int maxCpuUsage = 0; - var maxWorkerProcs = CompilerConstants.IntegerNotSet; - string managedRuntimeVersion = null; - string managedPipelineMode = null; - string name = null; - var privateMemory = CompilerConstants.IntegerNotSet; - var queueLimit = CompilerConstants.IntegerNotSet; - var recycleMinutes = CompilerConstants.IntegerNotSet; - var recycleRequests = CompilerConstants.IntegerNotSet; - string recycleTimes = null; - var refreshCpu = CompilerConstants.IntegerNotSet; - string user = null; - var virtualMemory = CompilerConstants.IntegerNotSet; - - foreach (var attrib in element.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 "CpuAction": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - var cpuActionValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < cpuActionValue.Length) - { - switch (cpuActionValue) - { - case "shutdown": - cpuAction = 1; - break; - case "none": - cpuAction = 0; - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, cpuActionValue, "shutdown", "none")); - break; - } - } - break; - case "Identity": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - var identityValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < identityValue.Length) - { - switch (identityValue) - { - case "networkService": - attributes |= 1; - break; - case "localService": - attributes |= 2; - break; - case "localSystem": - attributes |= 4; - break; - case "other": - attributes |= 8; - break; - case "applicationPoolIdentity": - attributes |= 0x10; - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, identityValue, "networkService", "localService", "localSystem", "other", "applicationPoolIdentity")); - break; - } - } - break; - case "IdleTimeout": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - idleTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "ManagedPipelineMode": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - managedPipelineMode = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - - - if (!String.IsNullOrEmpty(managedPipelineMode)) - { - switch (managedPipelineMode) - { - // In 3.5 we allowed lower case values (per camel case enum style), we now use formatted fields, - // so the value needs to match exactly what we pass in to IIS which uses pascal case. - case "classic": - managedPipelineMode = "Classic"; - break; - case "integrated": - managedPipelineMode = "Integrated"; - break; - case "Classic": - break; - case "Integrated": - break; - default: - if (!this.ParseHelper.ContainsProperty(managedPipelineMode)) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, managedPipelineMode, "Classic", "Integrated")); - } - break; - } - } - - break; - case "ManagedRuntimeVersion": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - managedRuntimeVersion = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "MaxCpuUsage": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - maxCpuUsage = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100); - break; - case "MaxWorkerProcesses": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - maxWorkerProcs = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "Name": - name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "PrivateMemory": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - privateMemory = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 4294967); - break; - case "QueueLimit": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - queueLimit = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "RecycleMinutes": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - recycleMinutes = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "RecycleRequests": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - recycleRequests = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "RefreshCpu": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - refreshCpu = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); - break; - case "User": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); - break; - case "VirtualMemory": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - virtualMemory = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 4294967); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("iap", name, componentId, user); - } - - if (null == name) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); - } - - if (null == user && 8 == (attributes & 0x1F)) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "User", "Identity", "other")); - } - - if (null != user && 8 != (attributes & 0x1F)) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, element.Name.LocalName, "User", user, "Identity", "other")); - } - - cpuMon = maxCpuUsage.ToString(CultureInfo.InvariantCulture.NumberFormat); - if (CompilerConstants.IntegerNotSet != refreshCpu) - { - cpuMon = String.Concat(cpuMon, ",", refreshCpu.ToString(CultureInfo.InvariantCulture.NumberFormat)); - if (CompilerConstants.IntegerNotSet != cpuAction) - { - cpuMon = String.Concat(cpuMon, ",", cpuAction.ToString(CultureInfo.InvariantCulture.NumberFormat)); - } - } - - foreach (var child in element.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - switch (child.Name.LocalName) - { - case "RecycleTime": - if (null == componentId) - { - var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, element.Name.LocalName)); - } - - if (null == recycleTimes) - { - recycleTimes = this.ParseRecycleTimeElement(intermediate, section, child); - } - else - { - recycleTimes = String.Concat(recycleTimes, ",", this.ParseRecycleTimeElement(intermediate, section, child)); - } - break; - default: - this.ParseHelper.UnexpectedElement(element, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); - } - } - - if (null != componentId) - { - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - } - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new IIsAppPoolSymbol(sourceLineNumbers, id) - { - Name = name, - ComponentRef = componentId, - Attributes = attributes, - UserRef = user, - RecycleTimes = recycleTimes, - CPUMon = cpuMon, - ManagedRuntimeVersion = managedRuntimeVersion, - ManagedPipelineMode = managedPipelineMode, - }); - - if (CompilerConstants.IntegerNotSet != recycleMinutes) - { - symbol.RecycleMinutes = recycleMinutes; - } - - if (CompilerConstants.IntegerNotSet != recycleRequests) - { - symbol.RecycleRequests = recycleRequests; - } - - if (CompilerConstants.IntegerNotSet != idleTimeout) - { - symbol.IdleTimeout = idleTimeout; - } - - if (CompilerConstants.IntegerNotSet != queueLimit) - { - symbol.QueueLimit = queueLimit; - } - - if (CompilerConstants.IntegerNotSet != maxWorkerProcs) - { - symbol.MaxProc = maxWorkerProcs; - } - - if (CompilerConstants.IntegerNotSet != virtualMemory) - { - symbol.VirtualMemory = virtualMemory; - } - - if (CompilerConstants.IntegerNotSet != privateMemory) - { - symbol.PrivateMemory = privateMemory; - } - } - } - - /// - /// Parses a web directory element. - /// - /// Element to parse. - /// Identifier for parent component. - /// Optional identifier for parent web site. - private void ParseWebDirElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string parentWeb) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string dirProperties = null; - string path = null; - string application = null; - - foreach (var attrib in element.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 "DirProperties": - dirProperties = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - break; - case "Path": - path = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "WebApplication": - application = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "WebSite": - if (null != parentWeb) - { - this.Messaging.Write(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, element.Name.LocalName)); - } - - parentWeb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebSite, parentWeb); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("iwd", componentId, parentWeb, dirProperties, application); - } - - if (null == path) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Path")); - } - - if (null == parentWeb) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "WebSite")); - } - - foreach (var child in element.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); - switch (child.Name.LocalName) - { - case "WebApplication": - if (null != application) - { - this.Messaging.Write(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, element.Name.LocalName)); - } - - application = this.ParseWebApplicationElement(intermediate, section, child); - break; - case "WebDirProperties": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - string childWebDirProperties = this.ParseWebDirPropertiesElement(intermediate, section, child, componentId); - if (null == dirProperties) - { - dirProperties = childWebDirProperties; - } - else - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, child.Name.LocalName, "DirProperties", child.Name.LocalName)); - } - break; - default: - this.ParseHelper.UnexpectedElement(element, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); - } - } - - if (null == dirProperties) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "DirProperties")); - } - - if (null != application) - { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebApplication, application); - } - - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebDirProperties, dirProperties); - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsWebDirSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - WebRef = parentWeb, - Path = path, - DirPropertiesRef = dirProperties, - ApplicationRef = application, - }); - } - } - - /// - /// Parses a web directory properties element. - /// - /// Element to parse. - /// The identifier for this WebDirProperties. - private string ParseWebDirPropertiesElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int access = 0; - var accessSet = false; - int accessSSLFlags = 0; - var accessSSLFlagsSet = false; - string anonymousUser = null; - var aspDetailedError = YesNoType.NotSet; - string authenticationProviders = null; - int authorization = 0; - var authorizationSet = false; - string cacheControlCustom = null; - var cacheControlMaxAge = CompilerConstants.LongNotSet; - string defaultDocuments = null; - string httpExpires = null; - var iisControlledPassword = false; - var index = YesNoType.NotSet; - var logVisits = YesNoType.NotSet; - var notCustomError = YesNoType.NotSet; - - foreach (var attrib in element.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 "AnonymousUser": - anonymousUser = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", anonymousUser); - break; - case "AspDetailedError": - aspDetailedError = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - case "AuthenticationProviders": - authenticationProviders = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "CacheControlCustom": - cacheControlCustom = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "CacheControlMaxAge": - cacheControlMaxAge = this.ParseHelper.GetAttributeLongValue(sourceLineNumbers, attrib, 0, uint.MaxValue); // 4294967295 (uint.MaxValue) represents unlimited - break; - case "ClearCustomError": - notCustomError = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - case "DefaultDocuments": - defaultDocuments = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "HttpExpires": - httpExpires = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "IIsControlledPassword": - iisControlledPassword = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - case "Index": - index = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - case "LogVisits": - logVisits = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - - // Access attributes - case "Execute": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - access |= 4; - } - else - { - access &= ~4; - } - accessSet = true; - break; - case "Read": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - access |= 1; - } - else - { - access &= ~1; - } - accessSet = true; - break; - case "Script": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - access |= 512; - } - else - { - access &= ~512; - } - accessSet = true; - break; - case "Write": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - access |= 2; - } - else - { - access &= ~2; - } - accessSet = true; - break; - - // AccessSSL Attributes - case "AccessSSL": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - accessSSLFlags |= 8; - } - else - { - accessSSLFlags &= ~8; - } - accessSSLFlagsSet = true; - break; - case "AccessSSL128": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - accessSSLFlags |= 256; - } - else - { - accessSSLFlags &= ~256; - } - accessSSLFlagsSet = true; - break; - case "AccessSSLMapCert": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - accessSSLFlags |= 128; - } - else - { - accessSSLFlags &= ~128; - } - accessSSLFlagsSet = true; - break; - case "AccessSSLNegotiateCert": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - accessSSLFlags |= 32; - } - else - { - accessSSLFlags &= ~32; - } - accessSSLFlagsSet = true; - break; - case "AccessSSLRequireCert": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - accessSSLFlags |= 64; - } - else - { - accessSSLFlags &= ~64; - } - accessSSLFlagsSet = true; - break; - - // Authorization attributes - case "AnonymousAccess": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - authorization |= 1; - } - else - { - authorization &= ~1; - } - authorizationSet = true; - break; - case "BasicAuthentication": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - authorization |= 2; - } - else - { - authorization &= ~2; - } - authorizationSet = true; - break; - case "DigestAuthentication": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - authorization |= 16; - } - else - { - authorization &= ~16; - } - authorizationSet = true; - break; - case "PassportAuthentication": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - authorization |= 64; - } - else - { - authorization &= ~64; - } - authorizationSet = true; - break; - case "WindowsAuthentication": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - authorization |= 4; - } - else - { - authorization &= ~4; - } - authorizationSet = true; - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - if (null == componentId) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); - id = Identifier.Invalid; - } - else - { - id = this.ParseHelper.CreateIdentifier("wdp", componentId); - } - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new IIsWebDirPropertiesSymbol(sourceLineNumbers, id) - { - AnonymousUserRef = anonymousUser, - IIsControlledPassword = iisControlledPassword ? 1 : 0, - DefaultDoc = defaultDocuments, - HttpExpires = httpExpires, - CacheControlCustom = cacheControlCustom, - }); - - if (accessSet) - { - symbol.Access = access; - } - - if (authorizationSet) - { - symbol.Authorization = authorization; - } - - if (YesNoType.NotSet != logVisits) - { - symbol.LogVisits = YesNoType.Yes == logVisits ? 1 : 0; - } - - if (YesNoType.NotSet != index) - { - symbol.Index = YesNoType.Yes == index ? 1 : 0; - } - - if (YesNoType.NotSet != aspDetailedError) - { - symbol.AspDetailedError = YesNoType.Yes == aspDetailedError ? 1 : 0; - } - - if (CompilerConstants.LongNotSet != cacheControlMaxAge) - { - symbol.CacheControlMaxAge = unchecked((int)cacheControlMaxAge); - } - - if (YesNoType.NotSet != notCustomError) - { - symbol.NoCustomError = YesNoType.Yes == notCustomError ? 1 : 0; - } - - if (accessSSLFlagsSet) - { - symbol.AccessSSLFlags = accessSSLFlags; - } - - if (null != authenticationProviders) - { - symbol.AuthenticationProviders = authenticationProviders; - } - } - - return id?.Id; - } - - /// - /// Parses a web error element. - /// - /// Element to parse. - /// Type of the parent. - /// Id of the parent. - private void ParseWebErrorElement(Intermediate intermediate, IntermediateSection section, XElement element, WebErrorParentType parentType, string parent) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - var errorCode = CompilerConstants.IntegerNotSet; - string file = null; - string url = null; - var subCode = CompilerConstants.IntegerNotSet; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "ErrorCode": - errorCode = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 400, 599); - break; - case "File": - file = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "SubCode": - subCode = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); - break; - case "URL": - url = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (CompilerConstants.IntegerNotSet == errorCode) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "ErrorCode")); - errorCode = CompilerConstants.IllegalInteger; - } - - if (CompilerConstants.IntegerNotSet == subCode) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SubCode")); - subCode = CompilerConstants.IllegalInteger; - } - - if (String.IsNullOrEmpty(file) && String.IsNullOrEmpty(url)) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "File", "URL")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsWebErrorSymbol(sourceLineNumbers) - { - ErrorCode = errorCode, - SubCode = subCode, - ParentType = (int)parentType, - ParentValue = parent, - File = file, - URL = url, - }); - } - } - - /// - /// Parses a web filter element. - /// - /// Element to parse. - /// Identifier of parent component. - /// Optional identifier of parent web site. - private void ParseWebFilterElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string parentWeb) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string description = null; - int flags = 0; - var loadOrder = CompilerConstants.IntegerNotSet; - string name = null; - string path = null; - - foreach (var attrib in element.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 "Description": - description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Flags": - flags = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); - break; - case "LoadOrder": - string loadOrderValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < loadOrderValue.Length) - { - switch (loadOrderValue) - { - case "first": - loadOrder = 0; - break; - case "last": - loadOrder = -1; - break; - default: - loadOrder = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); - break; - } - } - break; - case "Name": - name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Path": - path = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "WebSite": - if (null != parentWeb) - { - this.Messaging.Write(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, element.Name.LocalName)); - } - - parentWeb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebSite, parentWeb); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("ifl", name, componentId, path, parentWeb); - } - - if (null == name) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); - } - - if (null == path) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Path")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new IIsFilterSymbol(sourceLineNumbers, id) - { - Name = name, - ComponentRef = componentId, - Path = path, - WebRef = parentWeb, - Description = description, - Flags = flags, - }); - - if (CompilerConstants.IntegerNotSet != loadOrder) - { - symbol.LoadOrder = loadOrder; - } - } - } - - /// - /// Parses web log element. - /// - /// Node to be parsed. - private void ParseWebLogElement(Intermediate intermediate, IntermediateSection section, XElement element) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string type = null; - - foreach (var attrib in element.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 "Type": - var typeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (0 < typeValue.Length) - { - switch (typeValue) - { - case "IIS": - type = "Microsoft IIS Log File Format"; - break; - case "NCSA": - type = "NCSA Common Log File Format"; - break; - case "none": - type = "none"; - break; - case "ODBC": - type = "ODBC Logging"; - break; - case "W3C": - type = "W3C Extended Log File Format"; - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Type", typeValue, "IIS", "NCSA", "none", "ODBC", "W3C")); - break; - } - } - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); - } - - if (null == type) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Type")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsWebLogSymbol(sourceLineNumbers, id) - { - Format = type, - }); - } - } - - /// - /// Parses a web property element. - /// - /// Element to parse. - /// Identifier for parent component. - private void ParseWebPropertyElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string value = null; - - foreach (var attrib in element.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 "Value": - value = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - switch (id?.Id) - { - case "ETagChangeNumber": - case "MaxGlobalBandwidth": - // Must specify a value for these - if (null == value) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value", "Id", id.Id)); - } - break; - case "IIs5IsolationMode": - case "LogInUTF8": - // Can't specify a value for these - if (null != value) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Value", "Id", id.Id)); - } - break; - default: - this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Id", id?.Id, "ETagChangeNumber", "IIs5IsolationMode", "LogInUTF8", "MaxGlobalBandwidth")); - break; - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsPropertySymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - Attributes = 0, - Value = value, - }); - } - } - - /// - /// Parses a web service extension element. - /// - /// Element to parse. - /// Identifier for parent component. - private void ParseWebServiceExtensionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int attributes = 0; - string description = null; - string file = null; - string group = null; - - foreach (XAttribute attrib in element.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 "Allow": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 1; - } - else - { - attributes &= ~1; - } - break; - case "Description": - description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "File": - file = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Group": - group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "UIDeletable": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= 2; - } - else - { - attributes &= ~2; - } - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("iwe", componentId, file); - } - - if (null == file) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "File")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsWebServiceExtensionSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - File = file, - Description = description, - Group = group, - Attributes = attributes, - }); - } - } - - /// - /// Parses a web site element. - /// - /// Element to parse. - /// Optional identifier of parent component. - private void ParseWebSiteElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string application = null; - int attributes = 0; - var connectionTimeout = CompilerConstants.IntegerNotSet; - string description = null; - string directory = null; - string dirProperties = null; - string keyAddress = null; - string log = null; - string siteId = null; - var sequence = CompilerConstants.IntegerNotSet; - var state = CompilerConstants.IntegerNotSet; - - foreach (var attrib in element.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 "AutoStart": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - state = 2; - } - else if (state != 1) - { - state = 0; - } - break; - case "ConfigureIfExists": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes &= ~2; - } - else - { - attributes |= 2; - } - break; - case "ConnectionTimeout": - connectionTimeout = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); - break; - case "Description": - description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Directory": - directory = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, directory); - break; - case "DirProperties": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - dirProperties = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "SiteId": - siteId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if ("*" == siteId) - { - siteId = "-1"; - } - break; - case "Sequence": - sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); - break; - case "StartOnInstall": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - // when state is set to 2 it implies 1, so don't set it to 1 - if (2 != state && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - state = 1; - } - else if (2 != state) - { - state = 0; - } - break; - case "WebApplication": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - application = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "WebLog": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - log = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebLog, log); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("iws", description, componentId, siteId, application); - } - - if (null == description) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Description")); - } - - if (null == directory && null != componentId) - { - this.Messaging.Write(IIsErrors.RequiredAttributeUnderComponent(sourceLineNumbers, element.Name.LocalName, "Directory")); - } - - foreach (var child in element.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); - switch (child.Name.LocalName) - { - case "CertificateRef": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseCertificateRefElement(intermediate, section, child, id?.Id); - break; - case "HttpHeader": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseHttpHeaderElement(intermediate, section, child, HttpHeaderParentType.WebSite, id?.Id); - break; - case "WebAddress": - string address = this.ParseWebAddressElement(intermediate, section, child, id?.Id); - if (null == keyAddress) - { - keyAddress = address; - } - break; - case "WebApplication": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - if (null != application) - { - this.Messaging.Write(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, element.Name.LocalName)); - } - - application = this.ParseWebApplicationElement(intermediate, section, child); - break; - case "WebDir": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseWebDirElement(intermediate, section, child, componentId, id?.Id); - break; - case "WebDirProperties": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - string childWebDirProperties = this.ParseWebDirPropertiesElement(intermediate, section, child, componentId); - if (null == dirProperties) - { - dirProperties = childWebDirProperties; - } - else - { - this.Messaging.Write(ErrorMessages.IllegalParentAttributeWhenNested(sourceLineNumbers, "WebSite", "DirProperties", child.Name.LocalName)); - } - break; - case "WebError": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseWebErrorElement(intermediate, section, child, WebErrorParentType.WebSite, id?.Id); - break; - case "WebFilter": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseWebFilterElement(intermediate, section, child, componentId, id?.Id); - break; - case "WebVirtualDir": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseWebVirtualDirElement(intermediate, section, child, componentId, id?.Id, null); - break; - case "MimeMap": - this.ParseMimeMapElement(intermediate, section, child, id?.Id, MimeMapParentType.WebSite); - break; - default: - this.ParseHelper.UnexpectedElement(element, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); - } - } - - - if (null == keyAddress) - { - this.Messaging.Write(ErrorMessages.ExpectedElement(sourceLineNumbers, element.Name.LocalName, "WebAddress")); - } - - if (null != application) - { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebApplication, application); - } - - if (null != dirProperties) - { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebDirProperties, dirProperties); - } - - if (null != componentId) - { - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - } - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new IIsWebSiteSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - Description = description, - DirectoryRef = directory, - KeyAddressRef = keyAddress, - DirPropertiesRef = dirProperties, - ApplicationRef = application, - LogRef = log, - WebsiteId = siteId, - }); - - if (CompilerConstants.IntegerNotSet != connectionTimeout) - { - symbol.ConnectionTimeout = connectionTimeout; - } - - if (CompilerConstants.IntegerNotSet != state) - { - symbol.State = state; - } - - if (0 != attributes) - { - symbol.Attributes = attributes; - } - - if (CompilerConstants.IntegerNotSet != sequence) - { - symbol.Sequence = sequence; - } - } - } - - /// - /// Parses a HTTP Header element. - /// - /// Element to parse. - /// Type of the parent. - /// Id of the parent. - private void ParseHttpHeaderElement(Intermediate intermediate, IntermediateSection section, XElement element, HttpHeaderParentType parentType, string parent) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string headerName = null; - string headerValue = null; - - foreach (var attrib in element.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 "Name": - headerName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Value": - headerValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == headerName) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); - } - else if (null == id) - { - id = this.ParseHelper.CreateIdentifierFromFilename(headerName); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsHttpHeaderSymbol(sourceLineNumbers, id) - { - HttpHeader = id.Id, - ParentType = (int)parentType, - ParentValue = parent, - Name = headerName, - Value = headerValue, - Attributes = 0, - }); - } - } - - /// - /// Parses a virtual directory element. - /// - /// Element to parse. - /// Identifier of parent component. - /// Identifier of parent web site. - /// Alias of the parent web site. - private void ParseWebVirtualDirElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string parentWeb, string parentAlias) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string alias = null; - string application = null; - string directory = null; - string dirProperties = null; - - foreach (var attrib in element.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 "Alias": - alias = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Directory": - directory = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, directory); - break; - case "DirProperties": - dirProperties = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "WebApplication": - application = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "WebSite": - if (null != parentWeb) - { - this.Messaging.Write(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, element.Name.LocalName)); - } - - parentWeb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebSite, parentWeb); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("wvd", alias, directory, dirProperties, application, parentWeb); - } - - if (null == alias) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Alias")); - } - else if (-1 != alias.IndexOf("\\", StringComparison.Ordinal)) - { - this.Messaging.Write(IIsErrors.IllegalCharacterInAttributeValue(sourceLineNumbers, element.Name.LocalName, "Alias", alias, '\\')); - } - - if (null == directory) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Directory")); - } - - if (null == parentWeb) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "WebSite")); - } - - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(sourceLineNumbers, element.Name.LocalName)); - } - - if (null != parentAlias) - { - alias = String.Concat(parentAlias, "/", alias); - } - - foreach (var child in element.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); - switch (child.Name.LocalName) - { - case "WebApplication": - if (null != application) - { - this.Messaging.Write(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, element.Name.LocalName)); - } - - application = this.ParseWebApplicationElement(intermediate, section, child); - break; - case "WebDirProperties": - if (null == componentId) - { - this.Messaging.Write(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - string childWebDirProperties = this.ParseWebDirPropertiesElement(intermediate, section, child, componentId); - if (null == dirProperties) - { - dirProperties = childWebDirProperties; - } - else - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, child.Name.LocalName, "DirProperties", child.Name.LocalName)); - } - break; - - case "WebError": - this.ParseWebErrorElement(intermediate, section, child, WebErrorParentType.WebVirtualDir, id?.Id); - break; - case "WebVirtualDir": - this.ParseWebVirtualDirElement(intermediate, section, child, componentId, parentWeb, alias); - break; - case "HttpHeader": - this.ParseHttpHeaderElement(intermediate, section, child, HttpHeaderParentType.WebVirtualDir, id?.Id); - break; - case "MimeMap": - this.ParseMimeMapElement(intermediate, section, child, id?.Id, MimeMapParentType.WebVirtualDir); - break; - default: - this.ParseHelper.UnexpectedElement(element, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); - } - } - - if (null != dirProperties) - { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebDirProperties, dirProperties); - } - - if (null != application) - { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, IisSymbolDefinitions.IIsWebApplication, application); - } - - // Reference ConfigureIIs since nothing will happen without it - this.AddReferenceToConfigureIIs(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - section.AddSymbol(new IIsWebVirtualDirSymbol(sourceLineNumbers, id) - { - ComponentRef = componentId, - WebRef = parentWeb, - Alias = alias, - DirectoryRef = directory, - DirPropertiesRef = dirProperties, - ApplicationRef = application, - }); - } - } - - private void AddReferenceToConfigureIIs(IntermediateSection section, SourceLineNumber sourceLineNumbers) - { - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4ConfigureIIs", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); - } - } -} diff --git a/src/wixext/IIsDecompiler.cs b/src/wixext/IIsDecompiler.cs deleted file mode 100644 index 17e15348..00000000 --- a/src/wixext/IIsDecompiler.cs +++ /dev/null @@ -1,1549 +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.Iis -{ -#if TODO_CONSIDER_DECOMPILER - using System; - using System.Collections; - using System.Globalization; - using WixToolset.Data; - using WixToolset.Extensibility; - using IIs = WixToolset.Extensions.Serialize.IIs; - using Wix = WixToolset.Data.Serialize; - - /// - /// The decompiler for the WiX Toolset Internet Information Services Extension. - /// - public sealed class IIsDecompiler : DecompilerExtension - { - /// - /// Creates a decompiler for IIs Extension. - /// - public IIsDecompiler() - { - this.TableDefinitions = IIsExtensionData.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 IIsExtensionData.GetExtensionLibrary(tableDefinitions); - } - - /// - /// Decompiles an extension table. - /// - /// The table to decompile. - public override void DecompileTable(Table table) - { - switch (table.Name) - { - case "Certificate": - this.DecompileCertificateTable(table); - break; - case "CertificateHash": - // There is nothing to do for this table, it contains no authored data - // to be decompiled. - break; - case "IIsAppPool": - this.DecompileIIsAppPoolTable(table); - break; - case "IIsFilter": - this.DecompileIIsFilterTable(table); - break; - case "IIsProperty": - this.DecompileIIsPropertyTable(table); - break; - case "IIsHttpHeader": - this.DecompileIIsHttpHeaderTable(table); - break; - case "IIsMimeMap": - this.DecompileIIsMimeMapTable(table); - break; - case "IIsWebAddress": - this.DecompileIIsWebAddressTable(table); - break; - case "IIsWebApplication": - this.DecompileIIsWebApplicationTable(table); - break; - case "IIsWebDirProperties": - this.DecompileIIsWebDirPropertiesTable(table); - break; - case "IIsWebError": - this.DecompileIIsWebErrorTable(table); - break; - case "IIsWebLog": - this.DecompileIIsWebLogTable(table); - break; - case "IIsWebServiceExtension": - this.DecompileIIsWebServiceExtensionTable(table); - break; - case "IIsWebSite": - this.DecompileIIsWebSiteTable(table); - break; - case "IIsWebVirtualDir": - this.DecompileIIsWebVirtualDirTable(table); - break; - case "IIsWebSiteCertificates": - this.DecompileIIsWebSiteCertificatesTable(table); - break; - default: - base.DecompileTable(table); - break; - } - } - - /// - /// Finalize decompilation. - /// - /// The collection of all tables. - public override void Finish(TableIndexedCollection tables) - { - this.FinalizeIIsMimeMapTable(tables); - this.FinalizeIIsHttpHeaderTable(tables); - this.FinalizeIIsWebApplicationTable(tables); - this.FinalizeIIsWebErrorTable(tables); - this.FinalizeIIsWebVirtualDirTable(tables); - this.FinalizeIIsWebSiteCertificatesTable(tables); - this.FinalizeWebAddressTable(tables); - } - - /// - /// Decompile the Certificate table. - /// - /// The table to decompile. - private void DecompileCertificateTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.Certificate certificate = new IIs.Certificate(); - - certificate.Id = (string)row[0]; - certificate.Name = (string)row[2]; - - switch ((int)row[3]) - { - case 1: - certificate.StoreLocation = IIs.Certificate.StoreLocationType.currentUser; - break; - case 2: - certificate.StoreLocation = IIs.Certificate.StoreLocationType.localMachine; - break; - default: - // TODO: warn - break; - } - - switch ((string)row[4]) - { - case "CA": - certificate.StoreName = IIs.Certificate.StoreNameType.ca; - break; - case "MY": - certificate.StoreName = IIs.Certificate.StoreNameType.my; - break; - case "REQUEST": - certificate.StoreName = IIs.Certificate.StoreNameType.request; - break; - case "Root": - certificate.StoreName = IIs.Certificate.StoreNameType.root; - break; - case "AddressBook": - certificate.StoreName = IIs.Certificate.StoreNameType.otherPeople; - break; - case "TrustedPeople": - certificate.StoreName = IIs.Certificate.StoreNameType.trustedPeople; - break; - case "TrustedPublisher": - certificate.StoreName = IIs.Certificate.StoreNameType.trustedPublisher; - break; - default: - // TODO: warn - break; - } - - int attribute = (int)row[5]; - - if (0x1 == (attribute & 0x1)) - { - certificate.Request = IIs.YesNoType.yes; - } - - if (0x2 == (attribute & 0x2)) - { - if (null != row[6]) - { - certificate.BinaryKey = (string)row[6]; - } - else - { - // TODO: warn about expected value in row 5 - } - } - else if (null != row[7]) - { - certificate.CertificatePath = (string)row[7]; - } - - if (0x4 == (attribute & 0x4)) - { - certificate.Overwrite = IIs.YesNoType.yes; - } - - if (null != row[8]) - { - certificate.PFXPassword = (string)row[8]; - } - - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - if (null != component) - { - component.AddChild(certificate); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - - /// - /// Decompile the IIsAppPool table. - /// - /// The table to decompile. - private void DecompileIIsAppPoolTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebAppPool webAppPool = new IIs.WebAppPool(); - - webAppPool.Id = (string)row[0]; - - webAppPool.Name = (string)row[1]; - - switch ((int)row[3] & 0x1F) - { - case 1: - webAppPool.Identity = IIs.WebAppPool.IdentityType.networkService; - break; - case 2: - webAppPool.Identity = IIs.WebAppPool.IdentityType.localService; - break; - case 4: - webAppPool.Identity = IIs.WebAppPool.IdentityType.localSystem; - break; - case 8: - webAppPool.Identity = IIs.WebAppPool.IdentityType.other; - break; - case 0x10: - webAppPool.Identity = IIs.WebAppPool.IdentityType.applicationPoolIdentity; - break; - default: - // TODO: warn - break; - } - - if (null != row[4]) - { - webAppPool.User = (string)row[4]; - } - - if (null != row[5]) - { - webAppPool.RecycleMinutes = (int)row[5]; - } - - if (null != row[6]) - { - webAppPool.RecycleRequests = (int)row[6]; - } - - if (null != row[7]) - { - string[] recycleTimeValues = ((string)row[7]).Split(','); - - foreach (string recycleTimeValue in recycleTimeValues) - { - IIs.RecycleTime recycleTime = new IIs.RecycleTime(); - - recycleTime.Value = recycleTimeValue; - - webAppPool.AddChild(recycleTime); - } - } - - if (null != row[8]) - { - webAppPool.IdleTimeout = (int)row[8]; - } - - if (null != row[9]) - { - webAppPool.QueueLimit = (int)row[9]; - } - - if (null != row[10]) - { - string[] cpuMon = ((string)row[10]).Split(','); - - if (0 < cpuMon.Length && "0" != cpuMon[0]) - { - webAppPool.MaxCpuUsage = Convert.ToInt32(cpuMon[0], CultureInfo.InvariantCulture); - } - - if (1 < cpuMon.Length) - { - webAppPool.RefreshCpu = Convert.ToInt32(cpuMon[1], CultureInfo.InvariantCulture); - } - - if (2 < cpuMon.Length) - { - switch (Convert.ToInt32(cpuMon[2], CultureInfo.InvariantCulture)) - { - case 0: - webAppPool.CpuAction = IIs.WebAppPool.CpuActionType.none; - break; - case 1: - webAppPool.CpuAction = IIs.WebAppPool.CpuActionType.shutdown; - break; - default: - // TODO: warn - break; - } - } - - if (3 < cpuMon.Length) - { - // TODO: warn - } - } - - if (null != row[11]) - { - webAppPool.MaxWorkerProcesses = (int)row[11]; - } - - if (null != row[12]) - { - webAppPool.VirtualMemory = (int)row[12]; - } - - if (null != row[13]) - { - webAppPool.PrivateMemory = (int)row[13]; - } - - if (null != row[14]) - { - webAppPool.ManagedRuntimeVersion = (string)row[14]; - } - - if (null != row[15]) - { - webAppPool.ManagedPipelineMode = (string)row[15]; - } - - if (null != row[2]) - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); - - if (null != component) - { - component.AddChild(webAppPool); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); - } - } - else - { - this.Core.RootElement.AddChild(webAppPool); - } - } - } - - /// - /// Decompile the IIsProperty table. - /// - /// The table to decompile. - private void DecompileIIsPropertyTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebProperty webProperty = new IIs.WebProperty(); - - switch ((string)row[0]) - { - case "ETagChangeNumber": - webProperty.Id = IIs.WebProperty.IdType.ETagChangeNumber; - break; - case "IIs5IsolationMode": - webProperty.Id = IIs.WebProperty.IdType.IIs5IsolationMode; - break; - case "LogInUTF8": - webProperty.Id = IIs.WebProperty.IdType.LogInUTF8; - break; - case "MaxGlobalBandwidth": - webProperty.Id = IIs.WebProperty.IdType.MaxGlobalBandwidth; - break; - } - - if (0 != (int)row[2]) - { - // TODO: warn about value in unused column - } - - if (null != row[3]) - { - webProperty.Value = (string)row[3]; - } - - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - if (null != component) - { - component.AddChild(webProperty); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - - /// - /// Decompile the IIsHttpHeader table. - /// - /// The table to decompile. - private void DecompileIIsHttpHeaderTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.HttpHeader httpHeader = new IIs.HttpHeader(); - - httpHeader.Name = (string)row[3]; - - // the ParentType and Parent columns are handled in FinalizeIIsHttpHeaderTable - - httpHeader.Value = (string)row[4]; - - this.Core.IndexElement(row, httpHeader); - } - } - - /// - /// Decompile the IIsMimeMap table. - /// - /// The table to decompile. - private void DecompileIIsMimeMapTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.MimeMap mimeMap = new IIs.MimeMap(); - - mimeMap.Id = (string)row[0]; - - // the ParentType and ParentValue columns are handled in FinalizeIIsMimeMapTable - - mimeMap.Type = (string)row[3]; - - mimeMap.Extension = (string)row[4]; - - this.Core.IndexElement(row, mimeMap); - } - } - - /// - /// Decompile the IIsWebAddress table. - /// - /// The table to decompile. - private void DecompileIIsWebAddressTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebAddress webAddress = new IIs.WebAddress(); - - webAddress.Id = (string)row[0]; - - if (null != row[2]) - { - webAddress.IP = (string)row[2]; - } - - webAddress.Port = (string)row[3]; - - if (null != row[4]) - { - webAddress.Header = (string)row[4]; - } - - if (null != row[5] && 1 == (int)row[5]) - { - webAddress.Secure = IIs.YesNoType.yes; - } - - this.Core.IndexElement(row, webAddress); - } - } - - /// - /// Decompile the IIsWebApplication table. - /// - /// The table to decompile. - private void DecompileIIsWebApplicationTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebApplication webApplication = new IIs.WebApplication(); - - webApplication.Id = (string)row[0]; - - webApplication.Name = (string)row[1]; - - // these are not listed incorrectly - the order is low, high, medium - switch ((int)row[2]) - { - case 0: - webApplication.Isolation = IIs.WebApplication.IsolationType.low; - break; - case 1: - webApplication.Isolation = IIs.WebApplication.IsolationType.high; - break; - case 2: - webApplication.Isolation = IIs.WebApplication.IsolationType.medium; - break; - default: - // TODO: warn - break; - } - - if (null != row[3]) - { - switch ((int)row[3]) - { - case 0: - webApplication.AllowSessions = IIs.YesNoDefaultType.no; - break; - case 1: - webApplication.AllowSessions = IIs.YesNoDefaultType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[4]) - { - webApplication.SessionTimeout = (int)row[4]; - } - - if (null != row[5]) - { - switch ((int)row[5]) - { - case 0: - webApplication.Buffer = IIs.YesNoDefaultType.no; - break; - case 1: - webApplication.Buffer = IIs.YesNoDefaultType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[6]) - { - switch ((int)row[6]) - { - case 0: - webApplication.ParentPaths = IIs.YesNoDefaultType.no; - break; - case 1: - webApplication.ParentPaths = IIs.YesNoDefaultType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[7]) - { - switch ((string)row[7]) - { - case "JScript": - webApplication.DefaultScript = IIs.WebApplication.DefaultScriptType.JScript; - break; - case "VBScript": - webApplication.DefaultScript = IIs.WebApplication.DefaultScriptType.VBScript; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[8]) - { - webApplication.ScriptTimeout = (int)row[8]; - } - - if (null != row[9]) - { - switch ((int)row[9]) - { - case 0: - webApplication.ServerDebugging = IIs.YesNoDefaultType.no; - break; - case 1: - webApplication.ServerDebugging = IIs.YesNoDefaultType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[10]) - { - switch ((int)row[10]) - { - case 0: - webApplication.ClientDebugging = IIs.YesNoDefaultType.no; - break; - case 1: - webApplication.ClientDebugging = IIs.YesNoDefaultType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[11]) - { - webApplication.WebAppPool = (string)row[11]; - } - - this.Core.IndexElement(row, webApplication); - } - } - - /// - /// Decompile the IIsWebDirProperties table. - /// - /// The table to decompile. - private void DecompileIIsWebDirPropertiesTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebDirProperties webDirProperties = new IIs.WebDirProperties(); - - webDirProperties.Id = (string)row[0]; - - if (null != row[1]) - { - int access = (int)row[1]; - - if (0x1 == (access & 0x1)) - { - webDirProperties.Read = IIs.YesNoType.yes; - } - - if (0x2 == (access & 0x2)) - { - webDirProperties.Write = IIs.YesNoType.yes; - } - - if (0x4 == (access & 0x4)) - { - webDirProperties.Execute = IIs.YesNoType.yes; - } - - if (0x200 == (access & 0x200)) - { - webDirProperties.Script = IIs.YesNoType.yes; - } - } - - if (null != row[2]) - { - int authorization = (int)row[2]; - - if (0x1 == (authorization & 0x1)) - { - webDirProperties.AnonymousAccess = IIs.YesNoType.yes; - } - else // set one of the properties to 'no' to force the output value to be '0' if not other attributes are set - { - webDirProperties.AnonymousAccess = IIs.YesNoType.no; - } - - if (0x2 == (authorization & 0x2)) - { - webDirProperties.BasicAuthentication = IIs.YesNoType.yes; - } - - if (0x4 == (authorization & 0x4)) - { - webDirProperties.WindowsAuthentication = IIs.YesNoType.yes; - } - - if (0x10 == (authorization & 0x10)) - { - webDirProperties.DigestAuthentication = IIs.YesNoType.yes; - } - - if (0x40 == (authorization & 0x40)) - { - webDirProperties.PassportAuthentication = IIs.YesNoType.yes; - } - } - - if (null != row[3]) - { - webDirProperties.AnonymousUser = (string)row[3]; - } - - if (null != row[4] && 1 == (int)row[4]) - { - webDirProperties.IIsControlledPassword = IIs.YesNoType.yes; - } - - if (null != row[5]) - { - switch ((int)row[5]) - { - case 0: - webDirProperties.LogVisits = IIs.YesNoType.no; - break; - case 1: - webDirProperties.LogVisits = IIs.YesNoType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[6]) - { - switch ((int)row[6]) - { - case 0: - webDirProperties.Index = IIs.YesNoType.no; - break; - case 1: - webDirProperties.Index = IIs.YesNoType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[7]) - { - webDirProperties.DefaultDocuments = (string)row[7]; - } - - if (null != row[8]) - { - switch ((int)row[8]) - { - case 0: - webDirProperties.AspDetailedError = IIs.YesNoType.no; - break; - case 1: - webDirProperties.AspDetailedError = IIs.YesNoType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[9]) - { - webDirProperties.HttpExpires = (string)row[9]; - } - - if (null != row[10]) - { - // force the value to be a positive number - webDirProperties.CacheControlMaxAge = unchecked((uint)(int)row[10]); - } - - if (null != row[11]) - { - webDirProperties.CacheControlCustom = (string)row[11]; - } - - if (null != row[12]) - { - switch ((int)row[8]) - { - case 0: - webDirProperties.ClearCustomError = IIs.YesNoType.no; - break; - case 1: - webDirProperties.ClearCustomError = IIs.YesNoType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[13]) - { - int accessSSLFlags = (int)row[13]; - - if (0x8 == (accessSSLFlags & 0x8)) - { - webDirProperties.AccessSSL = IIs.YesNoType.yes; - } - - if (0x20 == (accessSSLFlags & 0x20)) - { - webDirProperties.AccessSSLNegotiateCert = IIs.YesNoType.yes; - } - - if (0x40 == (accessSSLFlags & 0x40)) - { - webDirProperties.AccessSSLRequireCert = IIs.YesNoType.yes; - } - - if (0x80 == (accessSSLFlags & 0x80)) - { - webDirProperties.AccessSSLMapCert = IIs.YesNoType.yes; - } - - if (0x100 == (accessSSLFlags & 0x100)) - { - webDirProperties.AccessSSL128 = IIs.YesNoType.yes; - } - } - - if (null != row[14]) - { - webDirProperties.AuthenticationProviders = (string)row[14]; - } - - this.Core.RootElement.AddChild(webDirProperties); - } - } - - /// - /// Decompile the IIsWebError table. - /// - /// The table to decompile. - private void DecompileIIsWebErrorTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebError webError = new IIs.WebError(); - - webError.ErrorCode = (int)row[0]; - - webError.SubCode = (int)row[1]; - - // the ParentType and ParentValue columns are handled in FinalizeIIsWebErrorTable - - if (null != row[4]) - { - webError.File = (string)row[4]; - } - - if (null != row[5]) - { - webError.URL = (string)row[5]; - } - - this.Core.IndexElement(row, webError); - } - } - - /// - /// Decompile the IIsFilter table. - /// - /// The table to decompile. - private void DecompileIIsFilterTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebFilter webFilter = new IIs.WebFilter(); - - webFilter.Id = (string)row[0]; - - webFilter.Name = (string)row[1]; - - if (null != row[3]) - { - webFilter.Path = (string)row[3]; - } - - if (null != row[5]) - { - webFilter.Description = (string)row[5]; - } - - webFilter.Flags = (int)row[6]; - - if (null != row[7]) - { - switch ((int)row[7]) - { - case (-1): - webFilter.LoadOrder = "last"; - break; - case 0: - webFilter.LoadOrder = "first"; - break; - default: - webFilter.LoadOrder = Convert.ToString((int)row[7], CultureInfo.InvariantCulture); - break; - } - } - - if (null != row[4]) - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[4]); - - if (null != webSite) - { - webSite.AddChild(webFilter); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[4], "IIsWebSite")); - } - } - else // Component parent - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); - - if (null != component) - { - component.AddChild(webFilter); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); - } - } - } - } - - /// - /// Decompile the IIsWebLog table. - /// - /// The table to decompile. - private void DecompileIIsWebLogTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebLog webLog = new IIs.WebLog(); - - webLog.Id = (string)row[0]; - - switch ((string)row[1]) - { - case "Microsoft IIS Log File Format": - webLog.Type = IIs.WebLog.TypeType.IIS; - break; - case "NCSA Common Log File Format": - webLog.Type = IIs.WebLog.TypeType.NCSA; - break; - case "none": - webLog.Type = IIs.WebLog.TypeType.none; - break; - case "ODBC Logging": - webLog.Type = IIs.WebLog.TypeType.ODBC; - break; - case "W3C Extended Log File Format": - webLog.Type = IIs.WebLog.TypeType.W3C; - break; - default: - // TODO: warn - break; - } - - this.Core.RootElement.AddChild(webLog); - } - } - - /// - /// Decompile the IIsWebServiceExtension table. - /// - /// The table to decompile. - private void DecompileIIsWebServiceExtensionTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebServiceExtension webServiceExtension = new IIs.WebServiceExtension(); - - webServiceExtension.Id = (string)row[0]; - - webServiceExtension.File = (string)row[2]; - - if (null != row[3]) - { - webServiceExtension.Description = (string)row[3]; - } - - if (null != row[4]) - { - webServiceExtension.Group = (string)row[4]; - } - - int attributes = (int)row[5]; - - if (0x1 == (attributes & 0x1)) - { - webServiceExtension.Allow = IIs.YesNoType.yes; - } - else - { - webServiceExtension.Allow = IIs.YesNoType.no; - } - - if (0x2 == (attributes & 0x2)) - { - webServiceExtension.UIDeletable = IIs.YesNoType.yes; - } - - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - if (null != component) - { - component.AddChild(webServiceExtension); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - - /// - /// Decompile the IIsWebSite table. - /// - /// The table to decompile. - private void DecompileIIsWebSiteTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebSite webSite = new IIs.WebSite(); - - webSite.Id = (string)row[0]; - - if (null != row[2]) - { - webSite.Description = (string)row[2]; - } - - if (null != row[3]) - { - webSite.ConnectionTimeout = (int)row[3]; - } - - if (null != row[4]) - { - webSite.Directory = (string)row[4]; - } - - if (null != row[5]) - { - switch ((int)row[5]) - { - case 0: - // this is the default - break; - case 1: - webSite.StartOnInstall = IIs.YesNoType.yes; - break; - case 2: - webSite.AutoStart = IIs.YesNoType.yes; - break; - default: - // TODO: warn - break; - } - } - - if (null != row[6]) - { - int attributes = (int)row[6]; - - if (0x2 == (attributes & 0x2)) - { - webSite.ConfigureIfExists = IIs.YesNoType.no; - } - } - - // the KeyAddress_ column is handled in FinalizeWebAddressTable - - if (null != row[8]) - { - webSite.DirProperties = (string)row[8]; - } - - // the Application_ column is handled in FinalizeIIsWebApplicationTable - - if (null != row[10]) - { - if (-1 != (int)row[10]) - { - webSite.Sequence = (int)row[10]; - } - } - - if (null != row[11]) - { - webSite.WebLog = (string)row[11]; - } - - if (null != row[12]) - { - webSite.SiteId = (string)row[12]; - } - - if (null != row[1]) - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - - if (null != component) - { - component.AddChild(webSite); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - else - { - this.Core.RootElement.AddChild(webSite); - } - this.Core.IndexElement(row, webSite); - } - } - - /// - /// Decompile the IIsWebVirtualDir table. - /// - /// The table to decompile. - private void DecompileIIsWebVirtualDirTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.WebVirtualDir webVirtualDir = new IIs.WebVirtualDir(); - - webVirtualDir.Id = (string)row[0]; - - // the Component_ and Web_ columns are handled in FinalizeIIsWebVirtualDirTable - - webVirtualDir.Alias = (string)row[3]; - - webVirtualDir.Directory = (string)row[4]; - - if (null != row[5]) - { - webVirtualDir.DirProperties = (string)row[5]; - } - - // the Application_ column is handled in FinalizeIIsWebApplicationTable - - this.Core.IndexElement(row, webVirtualDir); - } - } - - /// - /// Decompile the IIsWebSiteCertificates table. - /// - /// The table to decompile. - private void DecompileIIsWebSiteCertificatesTable(Table table) - { - foreach (Row row in table.Rows) - { - IIs.CertificateRef certificateRef = new IIs.CertificateRef(); - - certificateRef.Id = (string)row[1]; - - this.Core.IndexElement(row, certificateRef); - } - } - - /// - /// Finalize the IIsHttpHeader table. - /// - /// The collection of all tables. - /// - /// The IIsHttpHeader table supports multiple parent types so no foreign key - /// is declared and thus nesting must be done late. - /// - private void FinalizeIIsHttpHeaderTable(TableIndexedCollection tables) - { - Table iisHttpHeaderTable = tables["IIsHttpHeader"]; - - if (null != iisHttpHeaderTable) - { - foreach (Row row in iisHttpHeaderTable.Rows) - { - IIs.HttpHeader httpHeader = (IIs.HttpHeader)this.Core.GetIndexedElement(row); - - if (1 == (int)row[1]) - { - IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement("IIsWebVirtualDir", (string)row[2]); - if (null != webVirtualDir) - { - webVirtualDir.AddChild(httpHeader); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisHttpHeaderTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[2], "IIsWebVirtualDir")); - } - } - else if (2 == (int)row[1]) - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[2]); - if (null != webSite) - { - webSite.AddChild(httpHeader); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisHttpHeaderTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[2], "IIsWebSite")); - } - } - } - } - } - - /// - /// Finalize the IIsMimeMap table. - /// - /// The collection of all tables. - /// - /// The IIsMimeMap table supports multiple parent types so no foreign key - /// is declared and thus nesting must be done late. - /// - private void FinalizeIIsMimeMapTable(TableIndexedCollection tables) - { - Table iisMimeMapTable = tables["IIsMimeMap"]; - - if (null != iisMimeMapTable) - { - foreach (Row row in iisMimeMapTable.Rows) - { - IIs.MimeMap mimeMap = (IIs.MimeMap)this.Core.GetIndexedElement(row); - - if (2 < (int)row[1] || 0 >= (int)row[1]) - { - // TODO: warn about unknown parent type - } - - IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement("IIsWebVirtualDir", (string)row[2]); - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[2]); - if (null != webVirtualDir) - { - webVirtualDir.AddChild(mimeMap); - } - else if (null != webSite) - { - webSite.AddChild(mimeMap); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisMimeMapTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[2], "IIsWebVirtualDir")); - } - } - } - } - - /// - /// Finalize the IIsWebApplication table. - /// - /// The collection of all tables. - /// - /// Since WebApplication elements may nest under a specific WebSite or - /// WebVirtualDir (or just the root element), the nesting must be done late. - /// - private void FinalizeIIsWebApplicationTable(TableIndexedCollection tables) - { - Table iisWebApplicationTable = tables["IIsWebApplication"]; - Table iisWebSiteTable = tables["IIsWebSite"]; - Table iisWebVirtualDirTable = tables["IIsWebVirtualDir"]; - - Hashtable addedWebApplications = new Hashtable(); - - if (null != iisWebSiteTable) - { - foreach (Row row in iisWebSiteTable.Rows) - { - if (null != row[9]) - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement(row); - - IIs.WebApplication webApplication = (IIs.WebApplication)this.Core.GetIndexedElement("IIsWebApplication", (string)row[9]); - if (null != webApplication) - { - webSite.AddChild(webApplication); - addedWebApplications[webApplication] = null; - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebSiteTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Application_", (string)row[9], "IIsWebApplication")); - } - } - } - } - - if (null != iisWebVirtualDirTable) - { - foreach (Row row in iisWebVirtualDirTable.Rows) - { - if (null != row[6]) - { - IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement(row); - - IIs.WebApplication webApplication = (IIs.WebApplication)this.Core.GetIndexedElement("IIsWebApplication", (string)row[6]); - if (null != webApplication) - { - webVirtualDir.AddChild(webApplication); - addedWebApplications[webApplication] = null; - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebVirtualDirTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Application_", (string)row[6], "IIsWebApplication")); - } - } - } - } - - if (null != iisWebApplicationTable) - { - foreach (Row row in iisWebApplicationTable.Rows) - { - IIs.WebApplication webApplication = (IIs.WebApplication)this.Core.GetIndexedElement(row); - - if (!addedWebApplications.Contains(webApplication)) - { - this.Core.RootElement.AddChild(webApplication); - } - } - } - } - - /// - /// Finalize the IIsWebError table. - /// - /// The collection of all tables. - /// - /// Since there is no foreign key relationship declared for this table - /// (because it takes various parent types), it must be nested late. - /// - private void FinalizeIIsWebErrorTable(TableIndexedCollection tables) - { - Table iisWebErrorTable = tables["IIsWebError"]; - - if (null != iisWebErrorTable) - { - foreach (Row row in iisWebErrorTable.Rows) - { - IIs.WebError webError = (IIs.WebError)this.Core.GetIndexedElement(row); - - if (1 == (int)row[2]) // WebVirtualDir parent - { - IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement("IIsWebVirtualDir", (string)row[3]); - - if (null != webVirtualDir) - { - webVirtualDir.AddChild(webError); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebErrorTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[3], "IIsWebVirtualDir")); - } - } - else if (2 == (int)row[2]) // WebSite parent - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[3]); - - if (null != webSite) - { - webSite.AddChild(webError); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebErrorTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ParentValue", (string)row[3], "IIsWebSite")); - } - } - else - { - // TODO: warn unknown parent type - } - } - } - } - - /// - /// Finalize the IIsWebVirtualDir table. - /// - /// The collection of all tables. - /// - /// WebVirtualDir elements nest under either a WebSite or component - /// depending upon whether the component in the IIsWebVirtualDir row - /// is the same as the one in the parent IIsWebSite row. - /// - private void FinalizeIIsWebVirtualDirTable(TableIndexedCollection tables) - { - Table iisWebSiteTable = tables["IIsWebSite"]; - Table iisWebVirtualDirTable = tables["IIsWebVirtualDir"]; - - Hashtable iisWebSiteRows = new Hashtable(); - - // index the IIsWebSite rows by their primary keys - if (null != iisWebSiteTable) - { - foreach (Row row in iisWebSiteTable.Rows) - { - iisWebSiteRows.Add(row[0], row); - } - } - - if (null != iisWebVirtualDirTable) - { - foreach (Row row in iisWebVirtualDirTable.Rows) - { - IIs.WebVirtualDir webVirtualDir = (IIs.WebVirtualDir)this.Core.GetIndexedElement(row); - Row iisWebSiteRow = (Row)iisWebSiteRows[row[2]]; - - if (null != iisWebSiteRow) - { - if ((string)iisWebSiteRow[1] == (string)row[1]) - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement(iisWebSiteRow); - - webSite.AddChild(webVirtualDir); - } - else - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); - - if (null != component) - { - webVirtualDir.WebSite = (string)row[2]; - component.AddChild(webVirtualDir); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebVirtualDirTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); - } - } - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebVirtualDirTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[2], "IIsWebSite")); - } - } - } - } - - /// - /// Finalize the IIsWebSiteCertificates table. - /// - /// The collection of all tables. - /// - /// This table creates CertificateRef elements which nest under WebSite - /// elements. - /// - private void FinalizeIIsWebSiteCertificatesTable(TableIndexedCollection tables) - { - Table IIsWebSiteCertificatesTable = tables["IIsWebSiteCertificates"]; - - if (null != IIsWebSiteCertificatesTable) - { - foreach (Row row in IIsWebSiteCertificatesTable.Rows) - { - IIs.CertificateRef certificateRef = (IIs.CertificateRef)this.Core.GetIndexedElement(row); - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[0]); - - if (null != webSite) - { - webSite.AddChild(certificateRef); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, IIsWebSiteCertificatesTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[0], "IIsWebSite")); - } - } - } - } - - /// - /// Finalize the WebAddress table. - /// - /// The collection of all tables. - /// - /// There is a circular dependency between the WebAddress and WebSite - /// tables, so nesting must be handled here. - /// - private void FinalizeWebAddressTable(TableIndexedCollection tables) - { - Table iisWebAddressTable = tables["IIsWebAddress"]; - Table iisWebSiteTable = tables["IIsWebSite"]; - - Hashtable addedWebAddresses = new Hashtable(); - - if (null != iisWebSiteTable) - { - foreach (Row row in iisWebSiteTable.Rows) - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement(row); - - IIs.WebAddress webAddress = (IIs.WebAddress)this.Core.GetIndexedElement("IIsWebAddress", (string)row[7]); - if (null != webAddress) - { - webSite.AddChild(webAddress); - addedWebAddresses[webAddress] = null; - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebSiteTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "KeyAddress_", (string)row[7], "IIsWebAddress")); - } - } - } - - if (null != iisWebAddressTable) - { - foreach (Row row in iisWebAddressTable.Rows) - { - IIs.WebAddress webAddress = (IIs.WebAddress)this.Core.GetIndexedElement(row); - - if (!addedWebAddresses.Contains(webAddress)) - { - IIs.WebSite webSite = (IIs.WebSite)this.Core.GetIndexedElement("IIsWebSite", (string)row[1]); - - if (null != webSite) - { - webSite.AddChild(webAddress); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, iisWebAddressTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Web_", (string)row[1], "IIsWebSite")); - } - } - } - } - } - } -#endif -} diff --git a/src/wixext/IIsExtensionData.cs b/src/wixext/IIsExtensionData.cs deleted file mode 100644 index 6a0e1f09..00000000 --- a/src/wixext/IIsExtensionData.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.Iis -{ - using WixToolset.Data; - using WixToolset.Extensibility; - - /// - /// The WiX Toolset Internet Information Services Extension. - /// - public sealed class IIsExtensionData : BaseExtensionData - { - /// - /// Gets the default culture. - /// - /// The default culture. - public override string DefaultCulture => "en-US"; - - public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) - { - symbolDefinition = IisSymbolDefinitions.ByName(name); - return symbolDefinition != null; - } - - public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) - { - return Intermediate.Load(typeof(IIsExtensionData).Assembly, "WixToolset.Iis.iis.wixlib", symbolDefinitions); - } - } -} diff --git a/src/wixext/IisErrors.cs b/src/wixext/IisErrors.cs deleted file mode 100644 index 2f226217..00000000 --- a/src/wixext/IisErrors.cs +++ /dev/null @@ -1,78 +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 IIsErrors - { - public static Message DeprecatedBinaryChildElement(SourceLineNumber sourceLineNumbers, string elementName) - { - return Message(sourceLineNumbers, Ids.DeprecatedBinaryChildElement, "The {0} element contains a deprecated child Binary element. Please move the Binary element under a Fragment, Module, or Product element and set the {0}/@BinaryKey attribute to the value of the Binary/@Id attribute.", elementName); - } - - 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 IllegalCharacterInAttributeValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value, Char illegalCharacter) - { - return Message(sourceLineNumbers, Ids.IllegalCharacterInAttributeValue, "The {0}/@{1} attribute's value, '{2}', is invalid. It cannot contain the character '{3}'.", elementName, attributeName, value, illegalCharacter); - } - - 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 MimeMapExtensionMissingPeriod(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string attributeValue) - { - return Message(sourceLineNumbers, Ids.MimeMapExtensionMissingPeriod, "The {0}/@{1} attribute's value, '{2}', is not a valid mime map extension. It must begin with a period.", elementName, attributeName, attributeValue); - } - - public static Message OneOfAttributesRequiredUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2, string attributeName3, string attributeName4) - { - return Message(sourceLineNumbers, Ids.OneOfAttributesRequiredUnderComponent, "When nested under a Component, the {0} element must have one of the following attributes specified: {1}, {2}, {3} or {4}.", elementName, attributeName1, attributeName2, attributeName3, attributeName4); - } - - public static Message RequiredAttributeUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) - { - return Message(sourceLineNumbers, Ids.RequiredAttributeUnderComponent, "The {0}/@{1} attribute must be specified when the element has a Component as an ancestor.", elementName, attributeName); - } - - public static Message WebApplicationAlreadySpecified(SourceLineNumber sourceLineNumbers, string elementName) - { - return Message(sourceLineNumbers, Ids.WebApplicationAlreadySpecified, "The {0} element can have at most a single WebApplication specified. This can be either through the WebApplication attribute, or through a nested WebApplication element, but not both.", elementName); - } - - public static Message WebSiteAttributeUnderWebSite(SourceLineNumber sourceLineNumbers, string elementName) - { - return Message(sourceLineNumbers, Ids.WebSiteAttributeUnderWebSite, "The {0}/@WebSite attribute cannot be specified when the {0} element is nested under a WebSite element.", elementName); - } - - 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 - { - MimeMapExtensionMissingPeriod = 5150, - IllegalAttributeWithoutComponent = 5151, - IllegalElementWithoutComponent = 5152, - OneOfAttributesRequiredUnderComponent = 5153, - WebSiteAttributeUnderWebSite = 5154, - WebApplicationAlreadySpecified = 5155, - IllegalCharacterInAttributeValue = 5156, - DeprecatedBinaryChildElement = 5157, - RequiredAttributeUnderComponent = 5161, - } - } -} diff --git a/src/wixext/IisExtensionFactory.cs b/src/wixext/IisExtensionFactory.cs deleted file mode 100644 index 2fb7e682..00000000 --- a/src/wixext/IisExtensionFactory.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.Iis -{ - using System; - using System.Collections.Generic; - using WixToolset.Extensibility; - - public class IisExtensionFactory : BaseExtensionFactory - { - protected override IReadOnlyCollection ExtensionTypes => new[] - { - typeof(IIsCompiler), - typeof(IIsExtensionData), - typeof(IisWindowsInstallerBackendBinderExtension), - }; - } -} diff --git a/src/wixext/IisTableDefinitions.cs b/src/wixext/IisTableDefinitions.cs deleted file mode 100644 index f513152e..00000000 --- a/src/wixext/IisTableDefinitions.cs +++ /dev/null @@ -1,324 +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.Iis -{ - using WixToolset.Data.WindowsInstaller; - - public static class IisTableDefinitions - { - public static readonly TableDefinition Certificate = new TableDefinition( - "Certificate", - IisSymbolDefinitions.Certificate, - new[] - { - new ColumnDefinition("Certificate", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyColumn: 1, description: "Identifier for the certificate in the package.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, description: "Foreign key into the Component table used to determine install state", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name to be used for the Certificate."), - new ColumnDefinition("StoreLocation", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 1, maxValue: 2, description: "Location of the target certificate store (CurrentUser == 1, LocalMachine == 2)"), - new ColumnDefinition("StoreName", ColumnType.String, 64, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of the target certificate store"), - new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2147483647, description: "Attributes of the certificate"), - new ColumnDefinition("Binary_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Binary", keyColumn: 1, description: "Identifier to Binary table containing certificate.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("CertificatePath", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Property to path of certificate.", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("PFXPassword", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Hidden property to a pfx password", modularizeType: ColumnModularizeType.Property), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition CertificateHash = new TableDefinition( - "CertificateHash", - IisSymbolDefinitions.CertificateHash, - new[] - { - new ColumnDefinition("Certificate_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyColumn: 1, description: "Foreign key to certificate in Certificate table.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Hash", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Base64 encoded SHA1 hash of certificate populated at run-time."), - }, - symbolIdIsPrimaryKey: false - ); - - public static readonly TableDefinition IIsWebSiteCertificates = new TableDefinition( - "IIsWebSiteCertificates", - IisSymbolDefinitions.IIsWebSiteCertificates, - new[] - { - new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "The index into the IIsWebSite table.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Certificate_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Text, keyTable: "Certificate", keyColumn: 1, description: "The index into the Certificate table.", modularizeType: ColumnModularizeType.Column), - }, - symbolIdIsPrimaryKey: false - ); - - public static readonly TableDefinition IIsAppPool = new TableDefinition( - "IIsAppPool", - IisSymbolDefinitions.IIsAppPool, - new[] - { - new ColumnDefinition("AppPool", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for apppool", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name to be used for the IIs AppPool.", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the app pool", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Attributes of the AppPool"), - new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "User account to run the app pool as", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("RecycleMinutes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Number of minutes between recycling app pool"), - new ColumnDefinition("RecycleRequests", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Number of requests between recycling app pool"), - new ColumnDefinition("RecycleTimes", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Times to recycle app pool (comma delimited - i.e. 1:45,13:30)"), - new ColumnDefinition("IdleTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Amount of idle time before shutting down"), - new ColumnDefinition("QueueLimit", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Reject requests after queue gets how large"), - new ColumnDefinition("CPUMon", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "CPUMon is a comma delimeted list of the following format: ,,. The values for Action are 1 (Shutdown) and 0 (No Action)."), - new ColumnDefinition("MaxProc", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Maximum number of processes to use"), - new ColumnDefinition("VirtualMemory", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Amount of virtual memory (in KB) that a worker process can use before the worker process recycles. The maximum value supported for this field is 4,294,967 KB."), - new ColumnDefinition("PrivateMemory", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Amount of private memory (in KB) that a worker process can use before the worker process recycles. The maximum value supported for this field is 4,294,967 KB."), - new ColumnDefinition("ManagedRuntimeVersion", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Specifies the .NET Framework version to be used by the application pool."), - new ColumnDefinition("ManagedPipelineMode", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Specifies the request-processing mode that is used to process requests for managed content."), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsMimeMap = new TableDefinition( - "IIsMimeMap", - IisSymbolDefinitions.IIsMimeMap, - new[] - { - new ColumnDefinition("MimeMap", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for Mime Map definitions", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("ParentType", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "1;2", description: "Type of parent: 1=vdir 2=website"), - new ColumnDefinition("ParentValue", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, description: "Name of the parent value.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("MimeType", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Mime-type covered by the MimeMap."), - new ColumnDefinition("Extension", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Extension covered by the MimeMap."), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsProperty = new TableDefinition( - "IIsProperty", - IisSymbolDefinitions.IIsProperty, - new[] - { - new ColumnDefinition("Property", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Unique name of the IIsProperty"), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Component that the property is linked to", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Attributes of the IIsProperty (unused)"), - new ColumnDefinition("Value", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Value of the IIsProperty"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebDirProperties = new TableDefinition( - "IIsWebDirProperties", - IisSymbolDefinitions.IIsWebDirProperties, - new[] - { - new ColumnDefinition("DirProperties", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for Web Properties", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Access", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Access rights to the web server"), - new ColumnDefinition("Authorization", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Authorization policy to web server (anonymous access, NTLM, etc)"), - new ColumnDefinition("AnonymousUser_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("IIsControlledPassword", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs is allowed to set the AnonymousUser_ password"), - new ColumnDefinition("LogVisits", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs tracks all access to the directory"), - new ColumnDefinition("Index", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs searches the directory"), - new ColumnDefinition("DefaultDoc", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Comma delimited list of file names to act as a default document"), - new ColumnDefinition("AspDetailedError", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether detailed ASP errors are sent to browser"), - new ColumnDefinition("HttpExpires", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Value to set the HttpExpires attribute to for a Web Dir in the metabase"), - new ColumnDefinition("CacheControlMaxAge", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Integer value specifying the cache control maximum age value."), - new ColumnDefinition("CacheControlCustom", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Custom HTTP 1.1 cache control directives."), - new ColumnDefinition("NoCustomError", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether IIs will return custom errors for this directory."), - new ColumnDefinition("AccessSSLFlags", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Specifies AccessSSLFlags IIS metabase property."), - new ColumnDefinition("AuthenticationProviders", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Comma delimited list, in order of precedence, of Windows authentication providers that IIS will attempt to use: NTLM, Kerberos, Negotiate, and others."), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebAddress = new TableDefinition( - "IIsWebAddress", - IisSymbolDefinitions.IIsWebAddress, - new[] - { - new ColumnDefinition("Address", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing Web that uses the address.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("IP", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "String representing IP address (#.#.#.#) or NT machine name (fooserver)", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Port", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Port web site listens on", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Header", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Special header information for the web site"), - new ColumnDefinition("Secure", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether SSL is used to communicate with web site"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebSite = new TableDefinition( - "IIsWebSite", - IisSymbolDefinitions.IIsWebSite, - new[] - { - new ColumnDefinition("Web", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the web site", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in IIS MMC applet"), - new ColumnDefinition("ConnectionTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Time connection is maintained without activity (in seconds)"), - new ColumnDefinition("Directory_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Directory", keyColumn: 1, description: "Foreign key referencing directory that the web site points at", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("State", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1;2", description: "Sets intial state of web site"), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "2", description: "Control the install behavior of web site"), - new ColumnDefinition("KeyAddress_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebAddress", keyColumn: 1, description: "Foreign key referencing primary address for the web site", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("DirProperties_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebDirProperties", keyColumn: 1, description: "Foreign key referencing possible security information for the web site", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the web site.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Allows ordering of web site install"), - new ColumnDefinition("Log_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Unknown, keyTable: "IIsWebLog", keyColumn: 1, description: "Foreign key reference to IIsWebLog data", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Id", ColumnType.String, 74, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional number or formatted value that resolves to number that acts as the WebSite Id."), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebApplication = new TableDefinition( - "IIsWebApplication", - IisSymbolDefinitions.IIsWebApplication, - new[] - { - new ColumnDefinition("Application", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token for ASP Application", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of application in IIS MMC applet", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Isolation", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "0;1;2", description: "Isolation level for ASP Application: 0 == Low, 2 == Medium, 1 == High"), - new ColumnDefinition("AllowSessions", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether application may maintain session state"), - new ColumnDefinition("SessionTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Time session state is maintained without user interaction"), - new ColumnDefinition("Buffer", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether application buffers its output"), - new ColumnDefinition("ParentPaths", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "What is this for anyway?"), - new ColumnDefinition("DefaultScript", ColumnType.String, 26, primaryKey: false, nullable: true, ColumnCategory.Text, possibilities: "VBScript;JScript", description: "Default scripting language for ASP applications"), - new ColumnDefinition("ScriptTimeout", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Time ASP application page is permitted to process"), - new ColumnDefinition("ServerDebugging", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether to allow ASP server-side script debugging"), - new ColumnDefinition("ClientDebugging", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "0;1", description: "Specifies whether to allow ASP client-side script debugging"), - new ColumnDefinition("AppPool_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsAppPool", keyColumn: 1, description: "App Pool this application should run under", modularizeType: ColumnModularizeType.Column), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebApplicationExtension = new TableDefinition( - "IIsWebApplicationExtension", - IisSymbolDefinitions.IIsWebApplicationExtension, - new[] - { - new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the web site", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Extension", ColumnType.String, 255, primaryKey: true, nullable: true, ColumnCategory.Text, description: "Primary key, Extension that should be registered for this ASP application"), - new ColumnDefinition("Verbs", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Comma delimited list of HTTP verbs the extension should be registered with"), - new ColumnDefinition("Executable", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Path to extension (usually file property: [#file])", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, possibilities: "1;4;5", description: "Attributes for extension: 1 == Script, 4 == Check Path Info"), - }, - symbolIdIsPrimaryKey: false - ); - - public static readonly TableDefinition IIsFilter = new TableDefinition( - "IIsFilter", - IisSymbolDefinitions.IIsFilter, - new[] - { - new ColumnDefinition("Filter", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Name", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Name of the ISAPI Filter in IIS"), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the filter", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Path", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Path to filter (usually file property: [#file])", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing web site that loads the filter (NULL == global filter", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in IIS MMC applet"), - new ColumnDefinition("Flags", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2147483647, description: "What do all these numbers mean?"), - new ColumnDefinition("LoadOrder", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "-1 == last in order, 0 == first in order, # == place in order"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebDir = new TableDefinition( - "IIsWebDir", - IisSymbolDefinitions.IIsWebDir, - new[] - { - new ColumnDefinition("WebDir", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the virtual directory", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing web site that controls the virtual directory", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Path", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of web directory displayed in IIS MMC applet", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("DirProperties_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebDirProperties", keyColumn: 1, description: "Foreign key referencing possible security information for the virtual directory", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the virtual directory. This column is currently unused, but maintained for compatibility reasons.", modularizeType: ColumnModularizeType.Column), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebError = new TableDefinition( - "IIsWebError", - IisSymbolDefinitions.IIsWebError, - new[] - { - new ColumnDefinition("ErrorCode", ColumnType.Number, 2, primaryKey: true, nullable: false, ColumnCategory.Unknown, minValue: 400, maxValue: 599, description: "HTTP status code indicating error."), - new ColumnDefinition("SubCode", ColumnType.Number, 4, primaryKey: true, nullable: false, ColumnCategory.Unknown, description: "HTTP sub-status code indicating error."), - new ColumnDefinition("ParentType", ColumnType.Number, 2, primaryKey: true, nullable: false, ColumnCategory.Unknown, possibilities: "1;2", description: "Type of parent: 1=vdir, 2=web"), - new ColumnDefinition("ParentValue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Name of the parent value.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("File", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Path to file for this custom error (usually file property: [#file]). Must be null if URL is not null."), - new ColumnDefinition("URL", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "URL for this custom error. Must be null if File is not null."), - }, - symbolIdIsPrimaryKey: false - ); - - public static readonly TableDefinition IIsHttpHeader = new TableDefinition( - "IIsHttpHeader", - IisSymbolDefinitions.IIsHttpHeader, - new[] - { - new ColumnDefinition("HttpHeader", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("ParentType", ColumnType.Number, 2, primaryKey: true, nullable: false, ColumnCategory.Unknown, possibilities: "1;2", description: "Type of parent: 1=vdir, 2=web"), - new ColumnDefinition("ParentValue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Name of the parent value.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Name of the HTTP Header"), - new ColumnDefinition("Value", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "URL for this custom error. Must be null if File is not null."), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 0, description: "Attributes for HTTP Header: none"), - new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Order to add the HTTP Headers."), - }, - symbolIdIsPrimaryKey: false - ); - - public static readonly TableDefinition IIsWebServiceExtension = new TableDefinition( - "IIsWebServiceExtension", - IisSymbolDefinitions.IIsWebServiceExtension, - new[] - { - new ColumnDefinition("WebServiceExtension", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the WebServiceExtension handler", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("File", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Path to handler (usually file property: [#file])", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Description", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in WebServiceExtension Wizard", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Group", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "String used to identify groups of extensions.", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Attributes", ColumnType.Number, 1, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 3, description: "Attributes for WebServiceExtension: 1 = Allow, 2 = UIDeletable"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebVirtualDir = new TableDefinition( - "IIsWebVirtualDir", - IisSymbolDefinitions.IIsWebVirtualDir, - new[] - { - new ColumnDefinition("VirtualDir", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key referencing Component that controls the virtual directory", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Web_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "IIsWebSite", keyColumn: 1, description: "Foreign key referencing web site that controls the virtual directory", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Alias", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Name of virtual directory displayed in IIS MMC applet", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Directory_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Directory", keyColumn: 1, description: "Foreign key referencing directory that the virtual directory points at", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("DirProperties_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebDirProperties", keyColumn: 1, description: "Foreign key referencing possible security information for the virtual directory", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Application_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "IIsWebApplication", keyColumn: 1, description: "Foreign key referencing possible ASP application for the virtual directory", modularizeType: ColumnModularizeType.Column), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition IIsWebLog = new TableDefinition( - "IIsWebLog", - IisSymbolDefinitions.IIsWebLog, - new[] - { - new ColumnDefinition("Log", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Format", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Type of log format"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition[] All = new[] - { - Certificate, - CertificateHash, - IIsWebSiteCertificates, - IIsAppPool, - IIsMimeMap, - IIsProperty, - IIsWebDirProperties, - IIsWebAddress, - IIsWebSite, - IIsWebApplication, - IIsWebApplicationExtension, - IIsFilter, - IIsWebDir, - IIsWebError, - IIsHttpHeader, - IIsWebServiceExtension, - IIsWebVirtualDir, - IIsWebLog, - }; - } -} diff --git a/src/wixext/IisWindowsInstallerBackendBinderExtension.cs b/src/wixext/IisWindowsInstallerBackendBinderExtension.cs deleted file mode 100644 index a61cbad6..00000000 --- a/src/wixext/IisWindowsInstallerBackendBinderExtension.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.Iis -{ - using System.Collections.Generic; - using WixToolset.Data.WindowsInstaller; - using WixToolset.Extensibility; - - public class IisWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension - { - public override IReadOnlyCollection TableDefinitions => IisTableDefinitions.All; - } -} diff --git a/src/wixext/Symbols/CertificateHashSymbol.cs b/src/wixext/Symbols/CertificateHashSymbol.cs deleted file mode 100644 index 866d474c..00000000 --- a/src/wixext/Symbols/CertificateHashSymbol.cs +++ /dev/null @@ -1,55 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition CertificateHash = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.CertificateHash.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(CertificateHashSymbolFields.CertificateRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(CertificateHashSymbolFields.Hash), IntermediateFieldType.String), - }, - typeof(CertificateHashSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum CertificateHashSymbolFields - { - CertificateRef, - Hash, - } - - public class CertificateHashSymbol : IntermediateSymbol - { - public CertificateHashSymbol() : base(IisSymbolDefinitions.CertificateHash, null, null) - { - } - - public CertificateHashSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.CertificateHash, sourceLineNumber, id) - { - } - - public IntermediateField this[CertificateHashSymbolFields index] => this.Fields[(int)index]; - - public string CertificateRef - { - get => this.Fields[(int)CertificateHashSymbolFields.CertificateRef].AsString(); - set => this.Set((int)CertificateHashSymbolFields.CertificateRef, value); - } - - public string Hash - { - get => this.Fields[(int)CertificateHashSymbolFields.Hash].AsString(); - set => this.Set((int)CertificateHashSymbolFields.Hash, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/CertificateSymbol.cs b/src/wixext/Symbols/CertificateSymbol.cs deleted file mode 100644 index b80b6ba4..00000000 --- a/src/wixext/Symbols/CertificateSymbol.cs +++ /dev/null @@ -1,103 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition Certificate = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.Certificate.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.StoreLocation), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.StoreName), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.BinaryRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.CertificatePath), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(CertificateSymbolFields.PFXPassword), IntermediateFieldType.String), - }, - typeof(CertificateSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum CertificateSymbolFields - { - ComponentRef, - Name, - StoreLocation, - StoreName, - Attributes, - BinaryRef, - CertificatePath, - PFXPassword, - } - - public class CertificateSymbol : IntermediateSymbol - { - public CertificateSymbol() : base(IisSymbolDefinitions.Certificate, null, null) - { - } - - public CertificateSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.Certificate, sourceLineNumber, id) - { - } - - public IntermediateField this[CertificateSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)CertificateSymbolFields.ComponentRef].AsString(); - set => this.Set((int)CertificateSymbolFields.ComponentRef, value); - } - - public string Name - { - get => this.Fields[(int)CertificateSymbolFields.Name].AsString(); - set => this.Set((int)CertificateSymbolFields.Name, value); - } - - public int StoreLocation - { - get => this.Fields[(int)CertificateSymbolFields.StoreLocation].AsNumber(); - set => this.Set((int)CertificateSymbolFields.StoreLocation, value); - } - - public string StoreName - { - get => this.Fields[(int)CertificateSymbolFields.StoreName].AsString(); - set => this.Set((int)CertificateSymbolFields.StoreName, value); - } - - public int Attributes - { - get => this.Fields[(int)CertificateSymbolFields.Attributes].AsNumber(); - set => this.Set((int)CertificateSymbolFields.Attributes, value); - } - - public string BinaryRef - { - get => this.Fields[(int)CertificateSymbolFields.BinaryRef].AsString(); - set => this.Set((int)CertificateSymbolFields.BinaryRef, value); - } - - public string CertificatePath - { - get => this.Fields[(int)CertificateSymbolFields.CertificatePath].AsString(); - set => this.Set((int)CertificateSymbolFields.CertificatePath, value); - } - - public string PFXPassword - { - get => this.Fields[(int)CertificateSymbolFields.PFXPassword].AsString(); - set => this.Set((int)CertificateSymbolFields.PFXPassword, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsAppPoolSymbol.cs b/src/wixext/Symbols/IIsAppPoolSymbol.cs deleted file mode 100644 index a6fab136..00000000 --- a/src/wixext/Symbols/IIsAppPoolSymbol.cs +++ /dev/null @@ -1,159 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsAppPool = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsAppPool.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.UserRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.RecycleMinutes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.RecycleRequests), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.RecycleTimes), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.IdleTimeout), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.QueueLimit), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.CPUMon), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.MaxProc), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.VirtualMemory), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.PrivateMemory), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.ManagedRuntimeVersion), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsAppPoolSymbolFields.ManagedPipelineMode), IntermediateFieldType.String), - }, - typeof(IIsAppPoolSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsAppPoolSymbolFields - { - Name, - ComponentRef, - Attributes, - UserRef, - RecycleMinutes, - RecycleRequests, - RecycleTimes, - IdleTimeout, - QueueLimit, - CPUMon, - MaxProc, - VirtualMemory, - PrivateMemory, - ManagedRuntimeVersion, - ManagedPipelineMode, - } - - public class IIsAppPoolSymbol : IntermediateSymbol - { - public IIsAppPoolSymbol() : base(IisSymbolDefinitions.IIsAppPool, null, null) - { - } - - public IIsAppPoolSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsAppPool, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsAppPoolSymbolFields index] => this.Fields[(int)index]; - - public string Name - { - get => this.Fields[(int)IIsAppPoolSymbolFields.Name].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.Name, value); - } - - public string ComponentRef - { - get => this.Fields[(int)IIsAppPoolSymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.ComponentRef, value); - } - - public int Attributes - { - get => this.Fields[(int)IIsAppPoolSymbolFields.Attributes].AsNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.Attributes, value); - } - - public string UserRef - { - get => this.Fields[(int)IIsAppPoolSymbolFields.UserRef].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.UserRef, value); - } - - public int? RecycleMinutes - { - get => this.Fields[(int)IIsAppPoolSymbolFields.RecycleMinutes].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.RecycleMinutes, value); - } - - public int? RecycleRequests - { - get => this.Fields[(int)IIsAppPoolSymbolFields.RecycleRequests].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.RecycleRequests, value); - } - - public string RecycleTimes - { - get => this.Fields[(int)IIsAppPoolSymbolFields.RecycleTimes].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.RecycleTimes, value); - } - - public int? IdleTimeout - { - get => this.Fields[(int)IIsAppPoolSymbolFields.IdleTimeout].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.IdleTimeout, value); - } - - public int? QueueLimit - { - get => this.Fields[(int)IIsAppPoolSymbolFields.QueueLimit].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.QueueLimit, value); - } - - public string CPUMon - { - get => this.Fields[(int)IIsAppPoolSymbolFields.CPUMon].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.CPUMon, value); - } - - public int? MaxProc - { - get => this.Fields[(int)IIsAppPoolSymbolFields.MaxProc].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.MaxProc, value); - } - - public int? VirtualMemory - { - get => this.Fields[(int)IIsAppPoolSymbolFields.VirtualMemory].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.VirtualMemory, value); - } - - public int? PrivateMemory - { - get => this.Fields[(int)IIsAppPoolSymbolFields.PrivateMemory].AsNullableNumber(); - set => this.Set((int)IIsAppPoolSymbolFields.PrivateMemory, value); - } - - public string ManagedRuntimeVersion - { - get => this.Fields[(int)IIsAppPoolSymbolFields.ManagedRuntimeVersion].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.ManagedRuntimeVersion, value); - } - - public string ManagedPipelineMode - { - get => this.Fields[(int)IIsAppPoolSymbolFields.ManagedPipelineMode].AsString(); - set => this.Set((int)IIsAppPoolSymbolFields.ManagedPipelineMode, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsFilterSymbol.cs b/src/wixext/Symbols/IIsFilterSymbol.cs deleted file mode 100644 index 618730bf..00000000 --- a/src/wixext/Symbols/IIsFilterSymbol.cs +++ /dev/null @@ -1,95 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsFilter = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsFilter.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Path), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.WebRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Description), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.Flags), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsFilterSymbolFields.LoadOrder), IntermediateFieldType.Number), - }, - typeof(IIsFilterSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsFilterSymbolFields - { - Name, - ComponentRef, - Path, - WebRef, - Description, - Flags, - LoadOrder, - } - - public class IIsFilterSymbol : IntermediateSymbol - { - public IIsFilterSymbol() : base(IisSymbolDefinitions.IIsFilter, null, null) - { - } - - public IIsFilterSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsFilter, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsFilterSymbolFields index] => this.Fields[(int)index]; - - public string Name - { - get => this.Fields[(int)IIsFilterSymbolFields.Name].AsString(); - set => this.Set((int)IIsFilterSymbolFields.Name, value); - } - - public string ComponentRef - { - get => this.Fields[(int)IIsFilterSymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsFilterSymbolFields.ComponentRef, value); - } - - public string Path - { - get => this.Fields[(int)IIsFilterSymbolFields.Path].AsString(); - set => this.Set((int)IIsFilterSymbolFields.Path, value); - } - - public string WebRef - { - get => this.Fields[(int)IIsFilterSymbolFields.WebRef].AsString(); - set => this.Set((int)IIsFilterSymbolFields.WebRef, value); - } - - public string Description - { - get => this.Fields[(int)IIsFilterSymbolFields.Description].AsString(); - set => this.Set((int)IIsFilterSymbolFields.Description, value); - } - - public int Flags - { - get => this.Fields[(int)IIsFilterSymbolFields.Flags].AsNumber(); - set => this.Set((int)IIsFilterSymbolFields.Flags, value); - } - - public int? LoadOrder - { - get => this.Fields[(int)IIsFilterSymbolFields.LoadOrder].AsNullableNumber(); - set => this.Set((int)IIsFilterSymbolFields.LoadOrder, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsHttpHeaderSymbol.cs b/src/wixext/Symbols/IIsHttpHeaderSymbol.cs deleted file mode 100644 index 3ab2bf59..00000000 --- a/src/wixext/Symbols/IIsHttpHeaderSymbol.cs +++ /dev/null @@ -1,95 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsHttpHeader = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsHttpHeader.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.HttpHeader), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.ParentType), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.ParentValue), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Value), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsHttpHeaderSymbolFields.Sequence), IntermediateFieldType.Number), - }, - typeof(IIsHttpHeaderSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsHttpHeaderSymbolFields - { - HttpHeader, - ParentType, - ParentValue, - Name, - Value, - Attributes, - Sequence, - } - - public class IIsHttpHeaderSymbol : IntermediateSymbol - { - public IIsHttpHeaderSymbol() : base(IisSymbolDefinitions.IIsHttpHeader, null, null) - { - } - - public IIsHttpHeaderSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsHttpHeader, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsHttpHeaderSymbolFields index] => this.Fields[(int)index]; - - public string HttpHeader - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.HttpHeader].AsString(); - set => this.Set((int)IIsHttpHeaderSymbolFields.HttpHeader, value); - } - - public int ParentType - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.ParentType].AsNumber(); - set => this.Set((int)IIsHttpHeaderSymbolFields.ParentType, value); - } - - public string ParentValue - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.ParentValue].AsString(); - set => this.Set((int)IIsHttpHeaderSymbolFields.ParentValue, value); - } - - public string Name - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.Name].AsString(); - set => this.Set((int)IIsHttpHeaderSymbolFields.Name, value); - } - - public string Value - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.Value].AsString(); - set => this.Set((int)IIsHttpHeaderSymbolFields.Value, value); - } - - public int Attributes - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.Attributes].AsNumber(); - set => this.Set((int)IIsHttpHeaderSymbolFields.Attributes, value); - } - - public int? Sequence - { - get => this.Fields[(int)IIsHttpHeaderSymbolFields.Sequence].AsNullableNumber(); - set => this.Set((int)IIsHttpHeaderSymbolFields.Sequence, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsMimeMapSymbol.cs b/src/wixext/Symbols/IIsMimeMapSymbol.cs deleted file mode 100644 index 4af6f81c..00000000 --- a/src/wixext/Symbols/IIsMimeMapSymbol.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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsMimeMap = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsMimeMap.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.ParentType), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.ParentValue), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.MimeType), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsMimeMapSymbolFields.Extension), IntermediateFieldType.String), - }, - typeof(IIsMimeMapSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsMimeMapSymbolFields - { - ParentType, - ParentValue, - MimeType, - Extension, - } - - public class IIsMimeMapSymbol : IntermediateSymbol - { - public IIsMimeMapSymbol() : base(IisSymbolDefinitions.IIsMimeMap, null, null) - { - } - - public IIsMimeMapSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsMimeMap, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsMimeMapSymbolFields index] => this.Fields[(int)index]; - - public int ParentType - { - get => this.Fields[(int)IIsMimeMapSymbolFields.ParentType].AsNumber(); - set => this.Set((int)IIsMimeMapSymbolFields.ParentType, value); - } - - public string ParentValue - { - get => this.Fields[(int)IIsMimeMapSymbolFields.ParentValue].AsString(); - set => this.Set((int)IIsMimeMapSymbolFields.ParentValue, value); - } - - public string MimeType - { - get => this.Fields[(int)IIsMimeMapSymbolFields.MimeType].AsString(); - set => this.Set((int)IIsMimeMapSymbolFields.MimeType, value); - } - - public string Extension - { - get => this.Fields[(int)IIsMimeMapSymbolFields.Extension].AsString(); - set => this.Set((int)IIsMimeMapSymbolFields.Extension, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsPropertySymbol.cs b/src/wixext/Symbols/IIsPropertySymbol.cs deleted file mode 100644 index 9cf67014..00000000 --- a/src/wixext/Symbols/IIsPropertySymbol.cs +++ /dev/null @@ -1,63 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsProperty = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsProperty.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsPropertySymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsPropertySymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsPropertySymbolFields.Value), IntermediateFieldType.String), - }, - typeof(IIsPropertySymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsPropertySymbolFields - { - ComponentRef, - Attributes, - Value, - } - - public class IIsPropertySymbol : IntermediateSymbol - { - public IIsPropertySymbol() : base(IisSymbolDefinitions.IIsProperty, null, null) - { - } - - public IIsPropertySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsProperty, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsPropertySymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)IIsPropertySymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsPropertySymbolFields.ComponentRef, value); - } - - public int Attributes - { - get => this.Fields[(int)IIsPropertySymbolFields.Attributes].AsNumber(); - set => this.Set((int)IIsPropertySymbolFields.Attributes, value); - } - - public string Value - { - get => this.Fields[(int)IIsPropertySymbolFields.Value].AsString(); - set => this.Set((int)IIsPropertySymbolFields.Value, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebAddressSymbol.cs b/src/wixext/Symbols/IIsWebAddressSymbol.cs deleted file mode 100644 index 7111718a..00000000 --- a/src/wixext/Symbols/IIsWebAddressSymbol.cs +++ /dev/null @@ -1,79 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebAddress = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebAddress.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.WebRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.IP), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.Port), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.Header), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebAddressSymbolFields.Secure), IntermediateFieldType.Number), - }, - typeof(IIsWebAddressSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebAddressSymbolFields - { - WebRef, - IP, - Port, - Header, - Secure, - } - - public class IIsWebAddressSymbol : IntermediateSymbol - { - public IIsWebAddressSymbol() : base(IisSymbolDefinitions.IIsWebAddress, null, null) - { - } - - public IIsWebAddressSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebAddress, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebAddressSymbolFields index] => this.Fields[(int)index]; - - public string WebRef - { - get => this.Fields[(int)IIsWebAddressSymbolFields.WebRef].AsString(); - set => this.Set((int)IIsWebAddressSymbolFields.WebRef, value); - } - - public string IP - { - get => this.Fields[(int)IIsWebAddressSymbolFields.IP].AsString(); - set => this.Set((int)IIsWebAddressSymbolFields.IP, value); - } - - public string Port - { - get => this.Fields[(int)IIsWebAddressSymbolFields.Port].AsString(); - set => this.Set((int)IIsWebAddressSymbolFields.Port, value); - } - - public string Header - { - get => this.Fields[(int)IIsWebAddressSymbolFields.Header].AsString(); - set => this.Set((int)IIsWebAddressSymbolFields.Header, value); - } - - public int? Secure - { - get => this.Fields[(int)IIsWebAddressSymbolFields.Secure].AsNullableNumber(); - set => this.Set((int)IIsWebAddressSymbolFields.Secure, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs b/src/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs deleted file mode 100644 index 4283d702..00000000 --- a/src/wixext/Symbols/IIsWebApplicationExtensionSymbol.cs +++ /dev/null @@ -1,79 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebApplicationExtension = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebApplicationExtension.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.ApplicationRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Extension), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Verbs), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Executable), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebApplicationExtensionSymbolFields.Attributes), IntermediateFieldType.Number), - }, - typeof(IIsWebApplicationExtensionSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebApplicationExtensionSymbolFields - { - ApplicationRef, - Extension, - Verbs, - Executable, - Attributes, - } - - public class IIsWebApplicationExtensionSymbol : IntermediateSymbol - { - public IIsWebApplicationExtensionSymbol() : base(IisSymbolDefinitions.IIsWebApplicationExtension, null, null) - { - } - - public IIsWebApplicationExtensionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebApplicationExtension, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebApplicationExtensionSymbolFields index] => this.Fields[(int)index]; - - public string ApplicationRef - { - get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.ApplicationRef].AsString(); - set => this.Set((int)IIsWebApplicationExtensionSymbolFields.ApplicationRef, value); - } - - public string Extension - { - get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Extension].AsString(); - set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Extension, value); - } - - public string Verbs - { - get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Verbs].AsString(); - set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Verbs, value); - } - - public string Executable - { - get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Executable].AsString(); - set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Executable, value); - } - - public int Attributes - { - get => this.Fields[(int)IIsWebApplicationExtensionSymbolFields.Attributes].AsNumber(); - set => this.Set((int)IIsWebApplicationExtensionSymbolFields.Attributes, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebApplicationSymbol.cs b/src/wixext/Symbols/IIsWebApplicationSymbol.cs deleted file mode 100644 index 2f6f87de..00000000 --- a/src/wixext/Symbols/IIsWebApplicationSymbol.cs +++ /dev/null @@ -1,127 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebApplication = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebApplication.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.Isolation), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.AllowSessions), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.SessionTimeout), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.Buffer), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ParentPaths), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.DefaultScript), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ScriptTimeout), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ServerDebugging), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.ClientDebugging), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebApplicationSymbolFields.AppPoolRef), IntermediateFieldType.String), - }, - typeof(IIsWebApplicationSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebApplicationSymbolFields - { - Name, - Isolation, - AllowSessions, - SessionTimeout, - Buffer, - ParentPaths, - DefaultScript, - ScriptTimeout, - ServerDebugging, - ClientDebugging, - AppPoolRef, - } - - public class IIsWebApplicationSymbol : IntermediateSymbol - { - public IIsWebApplicationSymbol() : base(IisSymbolDefinitions.IIsWebApplication, null, null) - { - } - - public IIsWebApplicationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebApplication, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebApplicationSymbolFields index] => this.Fields[(int)index]; - - public string Name - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.Name].AsString(); - set => this.Set((int)IIsWebApplicationSymbolFields.Name, value); - } - - public int Isolation - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.Isolation].AsNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.Isolation, value); - } - - public int? AllowSessions - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.AllowSessions].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.AllowSessions, value); - } - - public int? SessionTimeout - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.SessionTimeout].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.SessionTimeout, value); - } - - public int? Buffer - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.Buffer].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.Buffer, value); - } - - public int? ParentPaths - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.ParentPaths].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.ParentPaths, value); - } - - public string DefaultScript - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.DefaultScript].AsString(); - set => this.Set((int)IIsWebApplicationSymbolFields.DefaultScript, value); - } - - public int? ScriptTimeout - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.ScriptTimeout].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.ScriptTimeout, value); - } - - public int? ServerDebugging - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.ServerDebugging].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.ServerDebugging, value); - } - - public int? ClientDebugging - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.ClientDebugging].AsNullableNumber(); - set => this.Set((int)IIsWebApplicationSymbolFields.ClientDebugging, value); - } - - public string AppPoolRef - { - get => this.Fields[(int)IIsWebApplicationSymbolFields.AppPoolRef].AsString(); - set => this.Set((int)IIsWebApplicationSymbolFields.AppPoolRef, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebDirPropertiesSymbol.cs b/src/wixext/Symbols/IIsWebDirPropertiesSymbol.cs deleted file mode 100644 index 42d2dead..00000000 --- a/src/wixext/Symbols/IIsWebDirPropertiesSymbol.cs +++ /dev/null @@ -1,151 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebDirProperties = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebDirProperties.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.Access), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.Authorization), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AnonymousUserRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.IIsControlledPassword), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.LogVisits), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.Index), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.DefaultDoc), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AspDetailedError), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.HttpExpires), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.CacheControlMaxAge), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.CacheControlCustom), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.NoCustomError), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AccessSSLFlags), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebDirPropertiesSymbolFields.AuthenticationProviders), IntermediateFieldType.String), - }, - typeof(IIsWebDirPropertiesSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebDirPropertiesSymbolFields - { - Access, - Authorization, - AnonymousUserRef, - IIsControlledPassword, - LogVisits, - Index, - DefaultDoc, - AspDetailedError, - HttpExpires, - CacheControlMaxAge, - CacheControlCustom, - NoCustomError, - AccessSSLFlags, - AuthenticationProviders, - } - - public class IIsWebDirPropertiesSymbol : IntermediateSymbol - { - public IIsWebDirPropertiesSymbol() : base(IisSymbolDefinitions.IIsWebDirProperties, null, null) - { - } - - public IIsWebDirPropertiesSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebDirProperties, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebDirPropertiesSymbolFields index] => this.Fields[(int)index]; - - public int? Access - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.Access].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.Access, value); - } - - public int? Authorization - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.Authorization].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.Authorization, value); - } - - public string AnonymousUserRef - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AnonymousUserRef].AsString(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.AnonymousUserRef, value); - } - - public int? IIsControlledPassword - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.IIsControlledPassword].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.IIsControlledPassword, value); - } - - public int? LogVisits - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.LogVisits].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.LogVisits, value); - } - - public int? Index - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.Index].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.Index, value); - } - - public string DefaultDoc - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.DefaultDoc].AsString(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.DefaultDoc, value); - } - - public int? AspDetailedError - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AspDetailedError].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.AspDetailedError, value); - } - - public string HttpExpires - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.HttpExpires].AsString(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.HttpExpires, value); - } - - public int? CacheControlMaxAge - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.CacheControlMaxAge].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.CacheControlMaxAge, value); - } - - public string CacheControlCustom - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.CacheControlCustom].AsString(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.CacheControlCustom, value); - } - - public int? NoCustomError - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.NoCustomError].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.NoCustomError, value); - } - - public int? AccessSSLFlags - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AccessSSLFlags].AsNullableNumber(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.AccessSSLFlags, value); - } - - public string AuthenticationProviders - { - get => this.Fields[(int)IIsWebDirPropertiesSymbolFields.AuthenticationProviders].AsString(); - set => this.Set((int)IIsWebDirPropertiesSymbolFields.AuthenticationProviders, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebDirSymbol.cs b/src/wixext/Symbols/IIsWebDirSymbol.cs deleted file mode 100644 index 7f257f14..00000000 --- a/src/wixext/Symbols/IIsWebDirSymbol.cs +++ /dev/null @@ -1,79 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebDir = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebDir.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.WebRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.Path), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.DirPropertiesRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebDirSymbolFields.ApplicationRef), IntermediateFieldType.String), - }, - typeof(IIsWebDirSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebDirSymbolFields - { - ComponentRef, - WebRef, - Path, - DirPropertiesRef, - ApplicationRef, - } - - public class IIsWebDirSymbol : IntermediateSymbol - { - public IIsWebDirSymbol() : base(IisSymbolDefinitions.IIsWebDir, null, null) - { - } - - public IIsWebDirSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebDir, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebDirSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)IIsWebDirSymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsWebDirSymbolFields.ComponentRef, value); - } - - public string WebRef - { - get => this.Fields[(int)IIsWebDirSymbolFields.WebRef].AsString(); - set => this.Set((int)IIsWebDirSymbolFields.WebRef, value); - } - - public string Path - { - get => this.Fields[(int)IIsWebDirSymbolFields.Path].AsString(); - set => this.Set((int)IIsWebDirSymbolFields.Path, value); - } - - public string DirPropertiesRef - { - get => this.Fields[(int)IIsWebDirSymbolFields.DirPropertiesRef].AsString(); - set => this.Set((int)IIsWebDirSymbolFields.DirPropertiesRef, value); - } - - public string ApplicationRef - { - get => this.Fields[(int)IIsWebDirSymbolFields.ApplicationRef].AsString(); - set => this.Set((int)IIsWebDirSymbolFields.ApplicationRef, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebErrorSymbol.cs b/src/wixext/Symbols/IIsWebErrorSymbol.cs deleted file mode 100644 index f8488fed..00000000 --- a/src/wixext/Symbols/IIsWebErrorSymbol.cs +++ /dev/null @@ -1,87 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebError = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebError.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.ErrorCode), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.SubCode), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.ParentType), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.ParentValue), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.File), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebErrorSymbolFields.URL), IntermediateFieldType.String), - }, - typeof(IIsWebErrorSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebErrorSymbolFields - { - ErrorCode, - SubCode, - ParentType, - ParentValue, - File, - URL, - } - - public class IIsWebErrorSymbol : IntermediateSymbol - { - public IIsWebErrorSymbol() : base(IisSymbolDefinitions.IIsWebError, null, null) - { - } - - public IIsWebErrorSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebError, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebErrorSymbolFields index] => this.Fields[(int)index]; - - public int ErrorCode - { - get => this.Fields[(int)IIsWebErrorSymbolFields.ErrorCode].AsNumber(); - set => this.Set((int)IIsWebErrorSymbolFields.ErrorCode, value); - } - - public int SubCode - { - get => this.Fields[(int)IIsWebErrorSymbolFields.SubCode].AsNumber(); - set => this.Set((int)IIsWebErrorSymbolFields.SubCode, value); - } - - public int ParentType - { - get => this.Fields[(int)IIsWebErrorSymbolFields.ParentType].AsNumber(); - set => this.Set((int)IIsWebErrorSymbolFields.ParentType, value); - } - - public string ParentValue - { - get => this.Fields[(int)IIsWebErrorSymbolFields.ParentValue].AsString(); - set => this.Set((int)IIsWebErrorSymbolFields.ParentValue, value); - } - - public string File - { - get => this.Fields[(int)IIsWebErrorSymbolFields.File].AsString(); - set => this.Set((int)IIsWebErrorSymbolFields.File, value); - } - - public string URL - { - get => this.Fields[(int)IIsWebErrorSymbolFields.URL].AsString(); - set => this.Set((int)IIsWebErrorSymbolFields.URL, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebLogSymbol.cs b/src/wixext/Symbols/IIsWebLogSymbol.cs deleted file mode 100644 index 409dc673..00000000 --- a/src/wixext/Symbols/IIsWebLogSymbol.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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebLog = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebLog.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebLogSymbolFields.Format), IntermediateFieldType.String), - }, - typeof(IIsWebLogSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebLogSymbolFields - { - Format, - } - - public class IIsWebLogSymbol : IntermediateSymbol - { - public IIsWebLogSymbol() : base(IisSymbolDefinitions.IIsWebLog, null, null) - { - } - - public IIsWebLogSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebLog, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebLogSymbolFields index] => this.Fields[(int)index]; - - public string Format - { - get => this.Fields[(int)IIsWebLogSymbolFields.Format].AsString(); - set => this.Set((int)IIsWebLogSymbolFields.Format, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebServiceExtensionSymbol.cs b/src/wixext/Symbols/IIsWebServiceExtensionSymbol.cs deleted file mode 100644 index 44922357..00000000 --- a/src/wixext/Symbols/IIsWebServiceExtensionSymbol.cs +++ /dev/null @@ -1,79 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebServiceExtension = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebServiceExtension.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.File), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.Description), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.Group), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebServiceExtensionSymbolFields.Attributes), IntermediateFieldType.Number), - }, - typeof(IIsWebServiceExtensionSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebServiceExtensionSymbolFields - { - ComponentRef, - File, - Description, - Group, - Attributes, - } - - public class IIsWebServiceExtensionSymbol : IntermediateSymbol - { - public IIsWebServiceExtensionSymbol() : base(IisSymbolDefinitions.IIsWebServiceExtension, null, null) - { - } - - public IIsWebServiceExtensionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebServiceExtension, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebServiceExtensionSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsWebServiceExtensionSymbolFields.ComponentRef, value); - } - - public string File - { - get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.File].AsString(); - set => this.Set((int)IIsWebServiceExtensionSymbolFields.File, value); - } - - public string Description - { - get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.Description].AsString(); - set => this.Set((int)IIsWebServiceExtensionSymbolFields.Description, value); - } - - public string Group - { - get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.Group].AsString(); - set => this.Set((int)IIsWebServiceExtensionSymbolFields.Group, value); - } - - public int Attributes - { - get => this.Fields[(int)IIsWebServiceExtensionSymbolFields.Attributes].AsNumber(); - set => this.Set((int)IIsWebServiceExtensionSymbolFields.Attributes, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs b/src/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs deleted file mode 100644 index 851ce556..00000000 --- a/src/wixext/Symbols/IIsWebSiteCertificatesSymbol.cs +++ /dev/null @@ -1,55 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebSiteCertificates = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebSiteCertificates.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebSiteCertificatesSymbolFields.WebRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteCertificatesSymbolFields.CertificateRef), IntermediateFieldType.String), - }, - typeof(IIsWebSiteCertificatesSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebSiteCertificatesSymbolFields - { - WebRef, - CertificateRef, - } - - public class IIsWebSiteCertificatesSymbol : IntermediateSymbol - { - public IIsWebSiteCertificatesSymbol() : base(IisSymbolDefinitions.IIsWebSiteCertificates, null, null) - { - } - - public IIsWebSiteCertificatesSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebSiteCertificates, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebSiteCertificatesSymbolFields index] => this.Fields[(int)index]; - - public string WebRef - { - get => this.Fields[(int)IIsWebSiteCertificatesSymbolFields.WebRef].AsString(); - set => this.Set((int)IIsWebSiteCertificatesSymbolFields.WebRef, value); - } - - public string CertificateRef - { - get => this.Fields[(int)IIsWebSiteCertificatesSymbolFields.CertificateRef].AsString(); - set => this.Set((int)IIsWebSiteCertificatesSymbolFields.CertificateRef, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebSiteSymbol.cs b/src/wixext/Symbols/IIsWebSiteSymbol.cs deleted file mode 100644 index ceba2ea0..00000000 --- a/src/wixext/Symbols/IIsWebSiteSymbol.cs +++ /dev/null @@ -1,135 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebSite = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebSite.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.Description), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.ConnectionTimeout), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.DirectoryRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.State), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.KeyAddressRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.DirPropertiesRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.ApplicationRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.Sequence), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.LogRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebSiteSymbolFields.WebsiteId), IntermediateFieldType.String), - }, - typeof(IIsWebSiteSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebSiteSymbolFields - { - ComponentRef, - Description, - ConnectionTimeout, - DirectoryRef, - State, - Attributes, - KeyAddressRef, - DirPropertiesRef, - ApplicationRef, - Sequence, - LogRef, - WebsiteId, - } - - public class IIsWebSiteSymbol : IntermediateSymbol - { - public IIsWebSiteSymbol() : base(IisSymbolDefinitions.IIsWebSite, null, null) - { - } - - public IIsWebSiteSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebSite, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebSiteSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)IIsWebSiteSymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.ComponentRef, value); - } - - public string Description - { - get => this.Fields[(int)IIsWebSiteSymbolFields.Description].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.Description, value); - } - - public int? ConnectionTimeout - { - get => this.Fields[(int)IIsWebSiteSymbolFields.ConnectionTimeout].AsNullableNumber(); - set => this.Set((int)IIsWebSiteSymbolFields.ConnectionTimeout, value); - } - - public string DirectoryRef - { - get => this.Fields[(int)IIsWebSiteSymbolFields.DirectoryRef].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.DirectoryRef, value); - } - - public int? State - { - get => this.Fields[(int)IIsWebSiteSymbolFields.State].AsNullableNumber(); - set => this.Set((int)IIsWebSiteSymbolFields.State, value); - } - - public int Attributes - { - get => this.Fields[(int)IIsWebSiteSymbolFields.Attributes].AsNumber(); - set => this.Set((int)IIsWebSiteSymbolFields.Attributes, value); - } - - public string KeyAddressRef - { - get => this.Fields[(int)IIsWebSiteSymbolFields.KeyAddressRef].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.KeyAddressRef, value); - } - - public string DirPropertiesRef - { - get => this.Fields[(int)IIsWebSiteSymbolFields.DirPropertiesRef].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.DirPropertiesRef, value); - } - - public string ApplicationRef - { - get => this.Fields[(int)IIsWebSiteSymbolFields.ApplicationRef].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.ApplicationRef, value); - } - - public int? Sequence - { - get => this.Fields[(int)IIsWebSiteSymbolFields.Sequence].AsNullableNumber(); - set => this.Set((int)IIsWebSiteSymbolFields.Sequence, value); - } - - public string LogRef - { - get => this.Fields[(int)IIsWebSiteSymbolFields.LogRef].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.LogRef, value); - } - - public string WebsiteId - { - get => this.Fields[(int)IIsWebSiteSymbolFields.WebsiteId].AsString(); - set => this.Set((int)IIsWebSiteSymbolFields.WebsiteId, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IIsWebVirtualDirSymbol.cs b/src/wixext/Symbols/IIsWebVirtualDirSymbol.cs deleted file mode 100644 index bfc29e84..00000000 --- a/src/wixext/Symbols/IIsWebVirtualDirSymbol.cs +++ /dev/null @@ -1,87 +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.Iis -{ - using WixToolset.Data; - using WixToolset.Iis.Symbols; - - public static partial class IisSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition IIsWebVirtualDir = new IntermediateSymbolDefinition( - IisSymbolDefinitionType.IIsWebVirtualDir.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.WebRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.Alias), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.DirectoryRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.DirPropertiesRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(IIsWebVirtualDirSymbolFields.ApplicationRef), IntermediateFieldType.String), - }, - typeof(IIsWebVirtualDirSymbol)); - } -} - -namespace WixToolset.Iis.Symbols -{ - using WixToolset.Data; - - public enum IIsWebVirtualDirSymbolFields - { - ComponentRef, - WebRef, - Alias, - DirectoryRef, - DirPropertiesRef, - ApplicationRef, - } - - public class IIsWebVirtualDirSymbol : IntermediateSymbol - { - public IIsWebVirtualDirSymbol() : base(IisSymbolDefinitions.IIsWebVirtualDir, null, null) - { - } - - public IIsWebVirtualDirSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(IisSymbolDefinitions.IIsWebVirtualDir, sourceLineNumber, id) - { - } - - public IntermediateField this[IIsWebVirtualDirSymbolFields index] => this.Fields[(int)index]; - - public string ComponentRef - { - get => this.Fields[(int)IIsWebVirtualDirSymbolFields.ComponentRef].AsString(); - set => this.Set((int)IIsWebVirtualDirSymbolFields.ComponentRef, value); - } - - public string WebRef - { - get => this.Fields[(int)IIsWebVirtualDirSymbolFields.WebRef].AsString(); - set => this.Set((int)IIsWebVirtualDirSymbolFields.WebRef, value); - } - - public string Alias - { - get => this.Fields[(int)IIsWebVirtualDirSymbolFields.Alias].AsString(); - set => this.Set((int)IIsWebVirtualDirSymbolFields.Alias, value); - } - - public string DirectoryRef - { - get => this.Fields[(int)IIsWebVirtualDirSymbolFields.DirectoryRef].AsString(); - set => this.Set((int)IIsWebVirtualDirSymbolFields.DirectoryRef, value); - } - - public string DirPropertiesRef - { - get => this.Fields[(int)IIsWebVirtualDirSymbolFields.DirPropertiesRef].AsString(); - set => this.Set((int)IIsWebVirtualDirSymbolFields.DirPropertiesRef, value); - } - - public string ApplicationRef - { - get => this.Fields[(int)IIsWebVirtualDirSymbolFields.ApplicationRef].AsString(); - set => this.Set((int)IIsWebVirtualDirSymbolFields.ApplicationRef, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/IisSymbolDefinitions.cs b/src/wixext/Symbols/IisSymbolDefinitions.cs deleted file mode 100644 index d6ed80a2..00000000 --- a/src/wixext/Symbols/IisSymbolDefinitions.cs +++ /dev/null @@ -1,107 +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.Iis -{ - using System; - using WixToolset.Data; - - public enum IisSymbolDefinitionType - { - Certificate, - CertificateHash, - IIsAppPool, - IIsFilter, - IIsHttpHeader, - IIsMimeMap, - IIsProperty, - IIsWebAddress, - IIsWebApplication, - IIsWebApplicationExtension, - IIsWebDir, - IIsWebDirProperties, - IIsWebError, - IIsWebLog, - IIsWebServiceExtension, - IIsWebSite, - IIsWebSiteCertificates, - IIsWebVirtualDir, - } - - public static partial class IisSymbolDefinitions - { - public static readonly Version Version = new Version("4.0.0"); - - public static IntermediateSymbolDefinition ByName(string name) - { - if (!Enum.TryParse(name, out IisSymbolDefinitionType type)) - { - return null; - } - - return ByType(type); - } - - public static IntermediateSymbolDefinition ByType(IisSymbolDefinitionType type) - { - switch (type) - { - case IisSymbolDefinitionType.Certificate: - return IisSymbolDefinitions.Certificate; - - case IisSymbolDefinitionType.CertificateHash: - return IisSymbolDefinitions.CertificateHash; - - case IisSymbolDefinitionType.IIsAppPool: - return IisSymbolDefinitions.IIsAppPool; - - case IisSymbolDefinitionType.IIsFilter: - return IisSymbolDefinitions.IIsFilter; - - case IisSymbolDefinitionType.IIsHttpHeader: - return IisSymbolDefinitions.IIsHttpHeader; - - case IisSymbolDefinitionType.IIsMimeMap: - return IisSymbolDefinitions.IIsMimeMap; - - case IisSymbolDefinitionType.IIsProperty: - return IisSymbolDefinitions.IIsProperty; - - case IisSymbolDefinitionType.IIsWebAddress: - return IisSymbolDefinitions.IIsWebAddress; - - case IisSymbolDefinitionType.IIsWebApplication: - return IisSymbolDefinitions.IIsWebApplication; - - case IisSymbolDefinitionType.IIsWebApplicationExtension: - return IisSymbolDefinitions.IIsWebApplicationExtension; - - case IisSymbolDefinitionType.IIsWebDir: - return IisSymbolDefinitions.IIsWebDir; - - case IisSymbolDefinitionType.IIsWebDirProperties: - return IisSymbolDefinitions.IIsWebDirProperties; - - case IisSymbolDefinitionType.IIsWebError: - return IisSymbolDefinitions.IIsWebError; - - case IisSymbolDefinitionType.IIsWebLog: - return IisSymbolDefinitions.IIsWebLog; - - case IisSymbolDefinitionType.IIsWebServiceExtension: - return IisSymbolDefinitions.IIsWebServiceExtension; - - case IisSymbolDefinitionType.IIsWebSite: - return IisSymbolDefinitions.IIsWebSite; - - case IisSymbolDefinitionType.IIsWebSiteCertificates: - return IisSymbolDefinitions.IIsWebSiteCertificates; - - case IisSymbolDefinitionType.IIsWebVirtualDir: - return IisSymbolDefinitions.IIsWebVirtualDir; - - default: - throw new ArgumentOutOfRangeException(nameof(type)); - } - } - } -} diff --git a/src/wixext/WixToolset.Iis.wixext.csproj b/src/wixext/WixToolset.Iis.wixext.csproj deleted file mode 100644 index 81d41e77..00000000 --- a/src/wixext/WixToolset.Iis.wixext.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - netstandard2.0 - WixToolset.Iis - WiX Toolset Iis Extension - WiX Toolset Iis Extension - true - build - - - - - - - - - - - - - - - - - - - - diff --git a/src/wixext/WixToolset.Iis.wixext.targets b/src/wixext/WixToolset.Iis.wixext.targets deleted file mode 100644 index 6398fce1..00000000 --- a/src/wixext/WixToolset.Iis.wixext.targets +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - $(MSBuildThisFileDirectory)..\tools\WixToolset.Iis.wixext.dll - - - - - diff --git a/src/wixlib/IIsExtension.wxs b/src/wixlib/IIsExtension.wxs deleted file mode 100644 index 18fc34ff..00000000 --- a/src/wixlib/IIsExtension.wxs +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/wixlib/IIsExtension_Platform.wxi b/src/wixlib/IIsExtension_Platform.wxi deleted file mode 100644 index 09562a69..00000000 --- a/src/wixlib/IIsExtension_Platform.wxi +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/wixlib/IIsExtension_arm64.wxs b/src/wixlib/IIsExtension_arm64.wxs deleted file mode 100644 index 39ac048f..00000000 --- a/src/wixlib/IIsExtension_arm64.wxs +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/wixlib/IIsExtension_x64.wxs b/src/wixlib/IIsExtension_x64.wxs deleted file mode 100644 index 553953b3..00000000 --- a/src/wixlib/IIsExtension_x64.wxs +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/wixlib/IIsExtension_x86.wxs b/src/wixlib/IIsExtension_x86.wxs deleted file mode 100644 index c99a243b..00000000 --- a/src/wixlib/IIsExtension_x86.wxs +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/wixlib/caDecor.wxi b/src/wixlib/caDecor.wxi deleted file mode 100644 index b1711518..00000000 --- a/src/wixlib/caDecor.wxi +++ /dev/null @@ -1,39 +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/de-de.wxl b/src/wixlib/de-de.wxl deleted file mode 100644 index 5929f258..00000000 --- a/src/wixlib/de-de.wxl +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Konnte keine Verbindung mit dem Internet Information Server herstellen. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebSites. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebDirs. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebVirtualDirs. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebFilters. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der MimeMaps. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebAppPools. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebProperties. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebServiceExtensions. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der WebErrors. ([2] [3] [4] [5]) - Fehler bei der Verarbeitung der HttpHeader. ([2] [3] [4] [5]) - - Die Transaktion für Änderungen am IIS konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS-Websites konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS Web Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS Virtual Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS Filters konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS AppPools konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS Properties konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Installation von IIS Web Service Extensions konnte nicht geschedulded werden. ([2] [3] [4] [5]) - - Die Deinstallation von IIS Web Sites konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Deinstallation von IIS Web Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Deinstallation von IIS Virtual Directories konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Deinstallation von IIS Filters konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Deinstallation von IIS AppPools konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Deinstallation der IIS Properties konnte nicht geschedulded werden. ([2] [3] [4] [5]) - Die Deinstallation von IIS Web Service Extensions konnte nicht geschedulded werden. ([2] [3] [4] [5]) - - Die IIS-Transaktion konnte nicht gestartet werden. ([2] [3] [4] [5]) - Der Metabase Key konnte nicht geöffnet werden. ([2] [3] [4] [5]) - Der Metabase Key konnte nicht erstellt werden. ([2] [3] [4] [5]) - Daten konnten nicht in den Metabase Key geschrieben werden. ([2] [3] [4] [5]) - Webanwendung konnte nicht erstellt werden. ([2] [3] [4] [5]) - Der Metabase Key konnte nicht gelöscht werden. ([2] [3] [4] [5]) - Der Metabase Value konnte nicht gelöscht werden. ([2] [3] [4] [5]) - Die IIS Transaktion konnte aufgrund einer Freigabeverletzung nicht committed werden. Möglicherweise konfiguriert eine andere Anwendung derzeit IIS. - - Konfiguriere IIS - Führe IIS Konfiguration aus - Starte IIS Metabase Transaktion - Mache IIS Metabase Transaktion rückgängig - Committe IIS Metabase Transaktion - Installiere Metabase Keys und Values - - Konfiguriere IIS - Starte IIS Konfigurationstransaktion - Mache IIS Konfigurationstransaktion rückgängig - Committe IIS Konfigurationstransaktion - Installiere Konfigurationskeys and -values - diff --git a/src/wixlib/en-us.wxl b/src/wixlib/en-us.wxl deleted file mode 100644 index 44949095..00000000 --- a/src/wixlib/en-us.wxl +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Cannot connect to Internet Information Server. ([2] [3] [4] [5]) - Failed while processing WebSites. ([2] [3] [4] [5]) - Failed while processing WebDirs. ([2] [3] [4] [5]) - Failed while processing WebVirtualDirs. ([2] [3] [4] [5]) - Failed while processing WebFilters. ([2] [3] [4] [5]) - Failed while processing MimeMaps. ([2] [3] [4] [5]) - Failed while processing WebAppPools. ([2] [3] [4] [5]) - Failed while processing WebProperties. ([2] [3] [4] [5]) - Failed while processing WebServiceExtensions. ([2] [3] [4] [5]) - Failed while processing WebErrors. ([2] [3] [4] [5]) - Failed while processing HttpHeaders. ([2] [3] [4] [5]) - - Failed to schedule transaction for changes to IIS. ([2] [3] [4] [5]) - Failed to schedule install of IIS Web Sites. ([2] [3] [4] [5]) - Failed to schedule install of IIS Web Directories. ([2] [3] [4] [5]) - Failed to schedule install of IIS Virtual Directories. ([2] [3] [4] [5]) - Failed to schedule install of IIS Filters. ([2] [3] [4] [5]) - Failed to schedule install of IIS AppPools. ([2] [3] [4] [5]) - Failed to schedule install of IIS Properties. ([2] [3] [4] [5]) - Failed to schedule install of IIS Web Service Extensions. ([2] [3] [4] [5]) - - Failed to schedule uninstall of IIS Web Sites. ([2] [3] [4] [5]) - Failed to schedule uninstall of IIS Web Directories. ([2] [3] [4] [5]) - Failed to schedule uninstall of IIS Virtual Directories. ([2] [3] [4] [5]) - Failed to schedule uninstall of IIS Filters. ([2] [3] [4] [5]) - Failed to schedule uninstall of IIS AppPools. ([2] [3] [4] [5]) - Failed to schedule uninstall of IIS Properties. ([2] [3] [4] [5]) - Failed to schedule uninstall of IIS Web Service Extensions. ([2] [3] [4] [5]) - - Failed to start IIS transaction. ([2] [3] [4] [5]) - Failed to open metabase key. ([2] [3] [4] [5]) - Failed to create metabase key. ([2] [3] [4] [5]) - Failed to write data to metabase key. ([2] [3] [4] [5]) - Failed to create web application. ([2] [3] [4] [5]) - Failed to delete metabase key. ([2] [3] [4] [5]) - Failed to delete metabase value. ([2] [3] [4] [5]) - Failed to commit IIS transaction due to a sharing violation. Some other application may be configuring IIS. - - Configuring IIS - Executing IIS Configuration - Starting IIS Metabase Transaction - Rolling back IIS Metabase Transaction - Committing IIS Metabase Transaction - Installing Metabase Keys and Values - - Configuring IIS - Starting IIS Config Transaction - Rolling back IIS Config Transaction - Committing IIS Config Transaction - Installing Config Keys and Values - diff --git a/src/wixlib/iis.v3.ncrunchproject b/src/wixlib/iis.v3.ncrunchproject deleted file mode 100644 index 319cd523..00000000 --- a/src/wixlib/iis.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/src/wixlib/iis.wixproj b/src/wixlib/iis.wixproj deleted file mode 100644 index 89f9608f..00000000 --- a/src/wixlib/iis.wixproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - - Library - true - en-us - - - - - - - - - - - - - - - - - - - diff --git a/src/wixlib/ja-jp.wxl b/src/wixlib/ja-jp.wxl deleted file mode 100644 index 7fd6978a..00000000 --- a/src/wixlib/ja-jp.wxl +++ /dev/null @@ -1,47 +0,0 @@ - - - - - IISへ接続できません。 ([2] [3] [4] [5]) - ウェブ サイト処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ ディレクトリ処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ仮想ディレクトリ処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ フィルタ処理中に失敗しました。 ([2] [3] [4] [5]) - MIME マップ処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ アプリケーション プール処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ プロパティ処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ サービス拡張処理中に失敗しました。 ([2] [3] [4] [5]) - ウェブ エラー処理中に失敗しました。 ([2] [3] [4] [5]) - HTTP ヘッダ処理中に失敗しました。 ([2] [3] [4] [5]) - - IIS 変更トランザクションのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS ウェブ サイト インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS ウェブ ディレクトリ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS 仮想ディレクトリ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS フィルタ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS アプリケーション プール インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS プロパティ インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS ウェブ サービス拡張インストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - - IISウェブ サイト アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS ウェブ ディレクトリ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS 仮想ディレクトリ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS フィルタ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS アプリケーション プール アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS プロパティ アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - IIS ウェブ サービス拡張アンインストールのスケジューリングに失敗しました。 ([2] [3] [4] [5]) - - IIS トランザクション開始に失敗しました。 ([2] [3] [4] [5]) - メタベース キーのオープンに失敗しました。 ([2] [3] [4] [5]) - メタベース キーの作成に失敗しました。 ([2] [3] [4] [5]) - メタベース キーの書き込みに失敗しました。 ([2] [3] [4] [5]) - ウェブ アプリケーションの作成に失敗しました。 ([2] [3] [4] [5]) - メタベース キーの削除に失敗しました。 ([2] [3] [4] [5]) - メタベース値の削除に失敗しました。 ([2] [3] [4] [5]) - - IIS を構成しています - IIS メタベース トランザクションを開始しています - IIS メタベース トランザクションをロールバックしています - IIS メタベース トランザクションを確定しています - IIS メタベース キーと値をインストールしています - diff --git a/src/wixlib/pt-br.wxl b/src/wixlib/pt-br.wxl deleted file mode 100644 index 1fc0d768..00000000 --- a/src/wixlib/pt-br.wxl +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Não foi possível conectar no Internet Information Server. ([2] [3] [4] [5]) - Erro ao processar WebSites. ([2] [3] [4] [5]) - Erro ao processar WebDirs. ([2] [3] [4] [5]) - Erro ao processar WebVirtualDirs. ([2] [3] [4] [5]) - Erro ao processar WebFilters. ([2] [3] [4] [5]) - Erro ao processar MimeMaps. ([2] [3] [4] [5]) - Erro ao processar WebAppPools. ([2] [3] [4] [5]) - Erro ao processar WebProperties. ([2] [3] [4] [5]) - Erro ao processar WebServiceExtensions. ([2] [3] [4] [5]) - Erro ao processar WebErrors. ([2] [3] [4] [5]) - Erro ao processar HttpHeaders. ([2] [3] [4] [5]) - Erro ao agendar transação para alterações no IIS. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS Web Sites. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS Web Directories. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS Virtual Directories. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS Filters. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS AppPools. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS Properties. ([2] [3] [4] [5]) - Erro ao agendar instalação de IIS Web Service Extensions. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS Web Sites. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS Web Directories. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS Virtual Directories. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS Filters. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS AppPools. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS Properties. ([2] [3] [4] [5]) - Erro ao agendar desinstalação de IIS Web Service Extensions. ([2] [3] [4] [5]) - Erro ao iniciar transação do IIS . ([2] [3] [4] [5]) - Erro ao abrir metabase key. ([2] [3] [4] [5]) - Erro ao criar metabase key. ([2] [3] [4] [5]) - Erro ao escrever dados na metabase key. ([2] [3] [4] [5]) - Erro ao criar aplicação Web. ([2] [3] [4] [5]) - Erro ao excluir metabase key. ([2] [3] [4] [5]) - Erro ao excluir valor da metabase. ([2] [3] [4] [5]) - Erro ao fazer commit de transação IIS por violação de compartilhamento. Alguma outra aplicação pode estar tentando configurar o ISS ao mesmo tempo. - Configurando IIS - Executando Configurações do IIS - Iniciando Transação de Metabase do IIS - Cancelando Transação de Metabase do IIS - Efetivando Transação de Metabase do IIS - Instalando Chaves e Valores de Metabase do IIS - Configurando IIS - Iniciando Transação de Configuração do IIS - Cancelando Transação de Configuração do IIS - Efetivando Transação de Configuração do IIS - Instalando Chaves e Valores de Configurações do IIS - 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