Merge pull request #3786 from aspnet/jkotalik/21Merge
This commit is contained in:
commit
6d2e8a5c92
|
|
@ -0,0 +1,67 @@
|
||||||
|
[Oo]bj/
|
||||||
|
[Bb]in/
|
||||||
|
TestResults/
|
||||||
|
.nuget/
|
||||||
|
*.sln.ide/
|
||||||
|
_ReSharper.*/
|
||||||
|
packages/
|
||||||
|
artifacts/
|
||||||
|
PublishProfiles/
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
*.cache
|
||||||
|
*.docstates
|
||||||
|
_ReSharper.*
|
||||||
|
nuget.exe
|
||||||
|
project.lock.json
|
||||||
|
*net45.csproj
|
||||||
|
*net451.csproj
|
||||||
|
*k10.csproj
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.pidb
|
||||||
|
*.userprefs
|
||||||
|
*DS_Store
|
||||||
|
*.ncrunchsolution
|
||||||
|
*.*sdf
|
||||||
|
*.ipch
|
||||||
|
.vscode/
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
*.bin
|
||||||
|
*.vs/
|
||||||
|
.testPublish/
|
||||||
|
|
||||||
|
*.obj
|
||||||
|
*.tlog
|
||||||
|
*.CppClean.log
|
||||||
|
*msbuild.log
|
||||||
|
|
||||||
|
src/*/*/Debug/
|
||||||
|
src/*/*/x64/Debug/
|
||||||
|
src/*/*/Release/
|
||||||
|
src/*/*/x64/Release/
|
||||||
|
x64/
|
||||||
|
|
||||||
|
*vcxproj.filters
|
||||||
|
*.aps
|
||||||
|
*.pdb
|
||||||
|
*.lib
|
||||||
|
*.idb
|
||||||
|
|
||||||
|
src/*/AspNetCore/aspnetcoremodule.h
|
||||||
|
src/*/AspNetCore/aspnetcore_msg.h
|
||||||
|
src/*/AspNetCore/aspnetcore_msg.rc
|
||||||
|
src/*/*/version.h
|
||||||
|
src/*/RequestHandler/version.h
|
||||||
|
src/*/CommonLib/aspnetcore_msg.h
|
||||||
|
src/*/CommonLib/aspnetcore_msg.rc
|
||||||
|
test/*/Debug
|
||||||
|
test/*/Release
|
||||||
|
test/gtest-1.8.0/msvc/Debug
|
||||||
|
test/gtest-1.8.0/msvc/Release
|
||||||
|
.build
|
||||||
|
|
||||||
|
*.VC.*db
|
||||||
|
global.json
|
||||||
|
msbuild.binlog
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<Project>
|
||||||
|
<Import
|
||||||
|
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
|
||||||
|
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
|
||||||
|
|
||||||
|
<Import Project="version.props" />
|
||||||
|
<Import Project="build\dependencies.props" />
|
||||||
|
<Import Project="build\sources.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<Product>Microsoft ASP.NET Core</Product>
|
||||||
|
<RepositoryUrl>https://github.com/aspnet/IISIntegration</RepositoryUrl>
|
||||||
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
||||||
|
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<!-- https://github.com/aspnet/IISIntegration/issues/617 -->
|
||||||
|
<EnableApiCheck>false</EnableApiCheck>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
|
||||||
|
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
|
||||||
|
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.27130.2036
|
||||||
|
MinimumVisualStudioVersion = 15.0.26730.03
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{04B1EDB6-E967-4D25-89B9-E6F8304038CD}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
src\Directory.Build.props = src\Directory.Build.props
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0EF45656-B25D-40D8-959C-726EAF185E60}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
.editorconfig = .editorconfig
|
||||||
|
Directory.Build.props = Directory.Build.props
|
||||||
|
Directory.Build.targets = Directory.Build.targets
|
||||||
|
NuGet.Config = NuGet.Config
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EF30B533-D715-421A-92B7-92FEF460AC9C}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
test\Directory.Build.props = test\Directory.Build.props
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISSample", "samples\IISSample\IISSample.csproj", "{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{8B3446E8-E6A8-4591-AA63-A95837C6E97C}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration.Tests", "test\Microsoft.AspNetCore.Server.IISIntegration.Tests\Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj", "{4106DB10-E09F-480E-9CE6-B39235512EE6}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OutOfProcessWebSite", "test\WebSites\OutOfProcessWebSite\OutOfProcessWebSite.csproj", "{F54715C3-88D8-49E3-A291-C13570FE81FC}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7E80C58E-9CC8-450C-8A8D-94FC76428150}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
build\applicationhost.config = build\applicationhost.config
|
||||||
|
build\applicationhost.iis.config = build\applicationhost.iis.config
|
||||||
|
build\dependencies.props = build\dependencies.props
|
||||||
|
build\Key.snk = build\Key.snk
|
||||||
|
build\native.targets = build\native.targets
|
||||||
|
build\repo.props = build\repo.props
|
||||||
|
build\testsite.props = build\testsite.props
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.FunctionalTests", "test\IISIntegration.FunctionalTests\IISIntegration.FunctionalTests.csproj", "{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeIISSample", "samples\NativeIISSample\NativeIISSample.csproj", "{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "test\WebSites\InProcessWebSite\InProcessWebSite.csproj", "{679FA2A2-898B-4320-884E-C2D294A97CE1}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IIS", "src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj", "{46A8612B-418B-4D70-B3A7-A21DD0627473}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StressTestWebSite", "test\WebSites\StressTestWebSite\StressTestWebSite.csproj", "{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestTasks", "test\TestTasks\TestTasks.csproj", "{064D860B-4D7C-4B1D-918F-E020F1B99E2A}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OverriddenServerWebSite", "test\WebSites\OverriddenServerWebSite\OverriddenServerWebSite.csproj", "{FC2A97F8-A749-4C04-97D1-97500066A820}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {439824F9-1455-4CC4-BD79-B44FA0A16552}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCoreModuleV1", "AspNetCoreModuleV1", "{16E521CE-77F1-4B1C-A183-520A41C4F372}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCoreModuleV2", "AspNetCoreModuleV2", "{06CA2C2B-83B0-4D83-905A-E0C74790009E}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\AspNetCoreModuleV1\IISLib\IISLib.vcxproj", "{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCoreModuleV1\AspNetCore\AspNetCore.vcxproj", "{439824F9-1455-4CC4-BD79-B44FA0A16552}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCoreModuleV2\AspNetCore\AspNetCore.vcxproj", "{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "src\AspNetCoreModuleV2\CommonLib\CommonLib.vcxproj", "{55494E58-E061-4C4C-A0A8-837008E72F85}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\AspNetCoreModuleV2\IISLib\IISLib.vcxproj", "{09D9D1D6-2951-4E14-BC35-76A23CF9391A}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\AspNetCoreModuleV2\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x64.Build.0 = Release|x64
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC}.Release|x86.Build.0 = Release|x86
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|Any CPU.Build.0 = Release|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x64.Build.0 = Release|x64
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}.Release|x86.Build.0 = Release|x86
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1}.Release|x86.Build.0 = Release|x86
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x64.Build.0 = Release|x64
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}.Release|x86.Build.0 = Release|x86
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x64.Build.0 = Release|x64
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820}.Release|x86.Build.0 = Release|x86
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.Build.0 = Release|x64
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.Build.0 = Release|x64
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x64.Build.0 = Release|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Release|x64.Build.0 = Release|x64
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.Build.0 = Release|x64
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{E4E2BDC4-A9C6-4AE9-B429-032EC83EDE64} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
|
||||||
|
{8B3446E8-E6A8-4591-AA63-A95837C6E97C} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
|
{4106DB10-E09F-480E-9CE6-B39235512EE6} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||||
|
{F54715C3-88D8-49E3-A291-C13570FE81FC} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
|
||||||
|
{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||||
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
|
||||||
|
{679FA2A2-898B-4320-884E-C2D294A97CE1} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
|
||||||
|
{46A8612B-418B-4D70-B3A7-A21DD0627473} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
|
{13FD8F12-FFBE-4D01-B4AC-444F2994B04F} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
|
||||||
|
{064D860B-4D7C-4B1D-918F-E020F1B99E2A} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||||
|
{744ACDC6-F6A0-4FF9-9421-F25C5F2DC520} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||||
|
{FC2A97F8-A749-4C04-97D1-97500066A820} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520}
|
||||||
|
{16E521CE-77F1-4B1C-A183-520A41C4F372} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
|
{06CA2C2B-83B0-4D83-905A-E0C74790009E} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {16E521CE-77F1-4B1C-A183-520A41C4F372}
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {16E521CE-77F1-4B1C-A183-520A41C4F372}
|
||||||
|
{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
|
||||||
|
{09D9D1D6-2951-4E14-BC35-76A23CF9391A} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863} = {06CA2C2B-83B0-4D83-905A-E0C74790009E}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
this file except in compliance with the License. You may obtain a copy of the
|
||||||
|
License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
ASP.NET Core Module
|
||||||
|
|
||||||
|
Copyright (c) .NET Foundation
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the ""Software""), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"adx-nonshipping": {
|
||||||
|
"rules": [],
|
||||||
|
"packages": {
|
||||||
|
"Microsoft.AspNetCore.AspNetCoreModule": {},
|
||||||
|
"Microsoft.AspNetCore.AspNetCoreModuleV1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Default": {
|
||||||
|
"rules": [
|
||||||
|
"DefaultCompositeRule"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"Default": {
|
||||||
|
"rules": [
|
||||||
|
"DefaultCompositeRule"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
This repo hosts the ASP.NET Core middleware for IIS integration and the ASP.NET Core Module.
|
||||||
|
|
||||||
|
This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo.
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@ECHO OFF
|
||||||
|
SET RepoRoot="%~dp0..\.."
|
||||||
|
%RepoRoot%\build.cmd -LockFile %RepoRoot%\korebuild-lock.txt -Path %~dp0 %*
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
repo_root="$DIR/../.."
|
||||||
|
"$repo_root/build.sh" --path "$DIR" --lockfile "$repo_root/korebuild-lock.txt" "$@"
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildThisFileDirectory)..\</SolutionDir>
|
||||||
|
<Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
|
||||||
|
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||||
|
<PlatformToolset Condition=" '$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
|
||||||
|
<PlatformToolset Condition=" '$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
|
||||||
|
<PlatformToolset Condition=" '$(PlatformToolset)' == ''">v120</PlatformToolset>
|
||||||
|
<OutputPath Condition="'$(OutputPath)' == ''">$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutputPath>
|
||||||
|
<OutDir>$(OutputPath)</OutDir>
|
||||||
|
<AspNetCoreModuleTargetName>aspnetcore</AspNetCoreModuleTargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<TreatWarningAsError Condition="'$(TreatWarningsAsErrors)' != ''">true</TreatWarningAsError>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||||
|
<StripPrivateSymbols>$(OutDir)$(TargetName).pub.pdb</StripPrivateSymbols>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<Profile>true</Profile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>_WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>_WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<_TwoDigitYear>$([MSBuild]::Subtract($([System.DateTime]::UtcNow.Year), 2000))</_TwoDigitYear>
|
||||||
|
<_ThreeDigitDayOfYear>$([System.DateTime]::UtcNow.DayOfYear.ToString().PadLeft(3, '0'))</_ThreeDigitDayOfYear>
|
||||||
|
<AssemblyBuild>$(_TwoDigitYear)$(_ThreeDigitDayOfYear)</AssemblyBuild>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,966 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
IIS configuration sections.
|
||||||
|
|
||||||
|
For schema documentation, see
|
||||||
|
%IIS_BIN%\config\schema\IIS_schema.xml.
|
||||||
|
|
||||||
|
Please make a backup of this file before making any changes to it.
|
||||||
|
|
||||||
|
NOTE: The following environment variables are available to be used
|
||||||
|
within this file and are understood by the IIS Express.
|
||||||
|
|
||||||
|
%IIS_USER_HOME% - The IIS Express home directory for the user
|
||||||
|
%IIS_SITES_HOME% - The default home directory for sites
|
||||||
|
%IIS_BIN% - The location of the IIS Express binaries
|
||||||
|
%SYSTEMDRIVE% - The drive letter of %IIS_BIN%
|
||||||
|
|
||||||
|
-->
|
||||||
|
<configuration>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <configSections> section controls the registration of sections.
|
||||||
|
Section is the basic unit of deployment, locking, searching and
|
||||||
|
containment for configuration settings.
|
||||||
|
|
||||||
|
Every section belongs to one section group.
|
||||||
|
A section group is a container of logically-related sections.
|
||||||
|
|
||||||
|
Sections cannot be nested.
|
||||||
|
Section groups may be nested.
|
||||||
|
|
||||||
|
<section
|
||||||
|
name="" [Required, Collection Key] [XML name of the section]
|
||||||
|
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
|
||||||
|
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
|
||||||
|
allowLocation="true" [true|false] [Allowed in location tags]
|
||||||
|
/>
|
||||||
|
|
||||||
|
The recommended way to unlock sections is by using a location tag:
|
||||||
|
<location path="Default Web Site" overrideMode="Allow">
|
||||||
|
<system.webServer>
|
||||||
|
<asp />
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
|
||||||
|
-->
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="system.applicationHost">
|
||||||
|
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<sectionGroup name="system.webServer">
|
||||||
|
<section name="asp" overrideModeDefault="Deny" />
|
||||||
|
<section name="caching" overrideModeDefault="Allow" />
|
||||||
|
<section name="cgi" overrideModeDefault="Deny" />
|
||||||
|
<section name="defaultDocument" overrideModeDefault="Allow" />
|
||||||
|
<section name="directoryBrowse" overrideModeDefault="Allow" />
|
||||||
|
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="globalModules" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="handlers" overrideModeDefault="Deny" />
|
||||||
|
<section name="httpCompression" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpErrors" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpLogging" overrideModeDefault="Deny" />
|
||||||
|
<section name="httpProtocol" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpRedirect" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpTracing" overrideModeDefault="Deny" />
|
||||||
|
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||||
|
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||||
|
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||||
|
<section name="odbcLogging" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="security">
|
||||||
|
<section name="access" overrideModeDefault="Deny" />
|
||||||
|
<section name="applicationDependencies" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="authentication">
|
||||||
|
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="basicAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="digestAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="windowsAuthentication" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="authorization" overrideModeDefault="Allow" />
|
||||||
|
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="requestFiltering" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="serverRuntime" overrideModeDefault="Deny" />
|
||||||
|
<section name="serverSideInclude" overrideModeDefault="Deny" />
|
||||||
|
<section name="staticContent" overrideModeDefault="Allow" />
|
||||||
|
<sectionGroup name="tracing">
|
||||||
|
<section name="traceFailedRequests" overrideModeDefault="Allow" />
|
||||||
|
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="urlCompression" overrideModeDefault="Allow" />
|
||||||
|
<section name="validation" overrideModeDefault="Allow" />
|
||||||
|
<sectionGroup name="webdav">
|
||||||
|
<section name="globalSettings" overrideModeDefault="Deny" />
|
||||||
|
<section name="authoring" overrideModeDefault="Deny" />
|
||||||
|
<section name="authoringRules" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<sectionGroup name="rewrite">
|
||||||
|
<section name="allowedServerVariables" overrideModeDefault="Deny" />
|
||||||
|
<section name="rules" overrideModeDefault="Allow" />
|
||||||
|
<section name="outboundRules" overrideModeDefault="Allow" />
|
||||||
|
<section name="globalRules" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||||
|
<section name="providers" overrideModeDefault="Allow" />
|
||||||
|
<section name="rewriteMaps" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="webSocket" overrideModeDefault="Deny" />
|
||||||
|
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<configProtectedData>
|
||||||
|
<providers>
|
||||||
|
<add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
|
||||||
|
<add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAAKmFQvWHDEETRz8l2bjZlRxIkwcqTFaCUnCLljn3Q1OkesrhEO9YyLyx4bUhsj1/DyShAv7OAFFhXlrlomaornnk5PLeyO4lIXxaiT33yOFUUgxDx4GSaygkqghVV0tO5yQ/XguUBp2juMfZyztnsNa4pLcz7ZNZQ6p4yn9hxwNs=" />
|
||||||
|
<add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAA4WoiRJ8KHwzAG8AgejPxEOO4/2Vhkolbwo/8gZeNdUDSD36m55hWv4uC9tr/MlKdnwRLL0NhT50Gccyftqz5xTZ0dg5FtvQhTw/he1NwexTKbV+I4Zrd+sZUqHZTsr7JiEr6OHGXL70qoISW5G2m9U8wKT3caPiDPNj2aAaYPLo=" />
|
||||||
|
</providers>
|
||||||
|
</configProtectedData>
|
||||||
|
<system.applicationHost>
|
||||||
|
<applicationPools>
|
||||||
|
<add name="Clr4IntegratedAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="Clr4ClassicAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="Clr2IntegratedAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="Clr2ClassicAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" />
|
||||||
|
<applicationPoolDefaults managedRuntimeLoader="v4.0">
|
||||||
|
<processModel />
|
||||||
|
</applicationPoolDefaults>
|
||||||
|
</applicationPools>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <listenerAdapters> section defines the protocols with which the
|
||||||
|
Windows Process Activation Service (WAS) binds.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<listenerAdapters>
|
||||||
|
<add name="http" />
|
||||||
|
</listenerAdapters>
|
||||||
|
<sites>
|
||||||
|
<site name="DefaultSite" id="1">
|
||||||
|
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||||
|
<virtualDirectory path="/" physicalPath="%IIS_SITE_PATH%" />
|
||||||
|
</application>
|
||||||
|
<bindings>
|
||||||
|
<binding protocol="http" bindingInformation="*:50690:localhost" />
|
||||||
|
</bindings>
|
||||||
|
</site>
|
||||||
|
<siteDefaults>
|
||||||
|
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
|
||||||
|
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
|
||||||
|
</siteDefaults>
|
||||||
|
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
|
||||||
|
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||||
|
</sites>
|
||||||
|
<webLimits />
|
||||||
|
</system.applicationHost>
|
||||||
|
<system.webServer>
|
||||||
|
<serverRuntime />
|
||||||
|
<asp scriptErrorSentToBrowser="true">
|
||||||
|
<cache diskTemplateCacheDirectory="%TEMP%\iisexpress\ASP Compiled Templates" />
|
||||||
|
<limits />
|
||||||
|
</asp>
|
||||||
|
<caching enabled="true" enableKernelCache="true"></caching>
|
||||||
|
<cgi />
|
||||||
|
<defaultDocument enabled="true">
|
||||||
|
<files>
|
||||||
|
<add value="Default.htm" />
|
||||||
|
<add value="Default.asp" />
|
||||||
|
<add value="index.htm" />
|
||||||
|
<add value="index.html" />
|
||||||
|
<add value="iisstart.htm" />
|
||||||
|
<add value="default.aspx" />
|
||||||
|
</files>
|
||||||
|
</defaultDocument>
|
||||||
|
<directoryBrowse enabled="false" />
|
||||||
|
<fastCgi />
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <globalModules> section defines all native-code modules.
|
||||||
|
To enable a module, specify it in the <modules> section.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<globalModules>
|
||||||
|
<add name="HttpLoggingModule" image="%IIS_BIN%\loghttp.dll" />
|
||||||
|
<add name="UriCacheModule" image="%IIS_BIN%\cachuri.dll" />
|
||||||
|
<!-- <add name="FileCacheModule" image="%IIS_BIN%\cachfile.dll" /> -->
|
||||||
|
<add name="TokenCacheModule" image="%IIS_BIN%\cachtokn.dll" />
|
||||||
|
<!-- <add name="HttpCacheModule" image="%IIS_BIN%\cachhttp.dll" /> -->
|
||||||
|
<add name="DynamicCompressionModule" image="%IIS_BIN%\compdyn.dll" />
|
||||||
|
<add name="StaticCompressionModule" image="%IIS_BIN%\compstat.dll" />
|
||||||
|
<add name="DefaultDocumentModule" image="%IIS_BIN%\defdoc.dll" />
|
||||||
|
<add name="DirectoryListingModule" image="%IIS_BIN%\dirlist.dll" />
|
||||||
|
<add name="ProtocolSupportModule" image="%IIS_BIN%\protsup.dll" />
|
||||||
|
<add name="HttpRedirectionModule" image="%IIS_BIN%\redirect.dll" />
|
||||||
|
<add name="ServerSideIncludeModule" image="%IIS_BIN%\iis_ssi.dll" />
|
||||||
|
<add name="StaticFileModule" image="%IIS_BIN%\static.dll" />
|
||||||
|
<add name="AnonymousAuthenticationModule" image="%IIS_BIN%\authanon.dll" />
|
||||||
|
<add name="CertificateMappingAuthenticationModule" image="%IIS_BIN%\authcert.dll" />
|
||||||
|
<add name="UrlAuthorizationModule" image="%IIS_BIN%\urlauthz.dll" />
|
||||||
|
<add name="BasicAuthenticationModule" image="%IIS_BIN%\authbas.dll" />
|
||||||
|
<add name="WindowsAuthenticationModule" image="%IIS_BIN%\authsspi.dll" />
|
||||||
|
<!-- <add name="DigestAuthenticationModule" image="%IIS_BIN%\authmd5.dll" /> -->
|
||||||
|
<add name="IISCertificateMappingAuthenticationModule" image="%IIS_BIN%\authmap.dll" />
|
||||||
|
<add name="IpRestrictionModule" image="%IIS_BIN%\iprestr.dll" />
|
||||||
|
<add name="DynamicIpRestrictionModule" image="%IIS_BIN%\diprestr.dll" />
|
||||||
|
<add name="RequestFilteringModule" image="%IIS_BIN%\modrqflt.dll" />
|
||||||
|
<add name="CustomLoggingModule" image="%IIS_BIN%\logcust.dll" />
|
||||||
|
<add name="CustomErrorModule" image="%IIS_BIN%\custerr.dll" />
|
||||||
|
<!-- <add name="TracingModule" image="%IIS_BIN%\iisetw.dll" /> -->
|
||||||
|
<add name="FailedRequestsTracingModule" image="%IIS_BIN%\iisfreb.dll" />
|
||||||
|
<add name="RequestMonitorModule" image="%IIS_BIN%\iisreqs.dll" />
|
||||||
|
<add name="IsapiModule" image="%IIS_BIN%\isapi.dll" />
|
||||||
|
<add name="IsapiFilterModule" image="%IIS_BIN%\filter.dll" />
|
||||||
|
<add name="CgiModule" image="%IIS_BIN%\cgi.dll" />
|
||||||
|
<add name="FastCgiModule" image="%IIS_BIN%\iisfcgi.dll" />
|
||||||
|
<!-- <add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" /> -->
|
||||||
|
<add name="RewriteModule" image="%IIS_BIN%\rewrite.dll" />
|
||||||
|
<add name="ConfigurationValidationModule" image="%IIS_BIN%\validcfg.dll" />
|
||||||
|
<add name="WebSocketModule" image="%IIS_BIN%\iiswsock.dll" />
|
||||||
|
<add name="WebMatrixSupportModule" image="%IIS_BIN%\webmatrixsup.dll" />
|
||||||
|
<add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness32" />
|
||||||
|
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
|
||||||
|
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="ApplicationInitializationModule" image="%IIS_BIN%\warmup.dll" />
|
||||||
|
<add name="AspNetCoreModule" image="%ANCM_PATH%" />
|
||||||
|
</globalModules>
|
||||||
|
<httpCompression directory="%TEMP%\iisexpress\IIS Temporary Compressed Files">
|
||||||
|
<scheme name="gzip" dll="%IIS_BIN%\gzip.dll" />
|
||||||
|
<dynamicTypes>
|
||||||
|
<add mimeType="text/*" enabled="true" />
|
||||||
|
<add mimeType="message/*" enabled="true" />
|
||||||
|
<add mimeType="application/javascript" enabled="true" />
|
||||||
|
<add mimeType="application/atom+xml" enabled="true" />
|
||||||
|
<add mimeType="application/xaml+xml" enabled="true" />
|
||||||
|
<add mimeType="*/*" enabled="false" />
|
||||||
|
</dynamicTypes>
|
||||||
|
<staticTypes>
|
||||||
|
<add mimeType="text/*" enabled="true" />
|
||||||
|
<add mimeType="message/*" enabled="true" />
|
||||||
|
<add mimeType="image/svg+xml" enabled="true" />
|
||||||
|
<add mimeType="application/javascript" enabled="true" />
|
||||||
|
<add mimeType="application/atom+xml" enabled="true" />
|
||||||
|
<add mimeType="application/xaml+xml" enabled="true" />
|
||||||
|
<add mimeType="*/*" enabled="false" />
|
||||||
|
</staticTypes>
|
||||||
|
</httpCompression>
|
||||||
|
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
|
||||||
|
<error statusCode="401" prefixLanguageFilePath="%IIS_BIN%\custerr" path="401.htm" />
|
||||||
|
<error statusCode="403" prefixLanguageFilePath="%IIS_BIN%\custerr" path="403.htm" />
|
||||||
|
<error statusCode="404" prefixLanguageFilePath="%IIS_BIN%\custerr" path="404.htm" />
|
||||||
|
<error statusCode="405" prefixLanguageFilePath="%IIS_BIN%\custerr" path="405.htm" />
|
||||||
|
<error statusCode="406" prefixLanguageFilePath="%IIS_BIN%\custerr" path="406.htm" />
|
||||||
|
<error statusCode="412" prefixLanguageFilePath="%IIS_BIN%\custerr" path="412.htm" />
|
||||||
|
<error statusCode="500" prefixLanguageFilePath="%IIS_BIN%\custerr" path="500.htm" />
|
||||||
|
<error statusCode="501" prefixLanguageFilePath="%IIS_BIN%\custerr" path="501.htm" />
|
||||||
|
<error statusCode="502" prefixLanguageFilePath="%IIS_BIN%\custerr" path="502.htm" />
|
||||||
|
</httpErrors>
|
||||||
|
<httpLogging dontLog="false" />
|
||||||
|
<httpProtocol>
|
||||||
|
<customHeaders>
|
||||||
|
<clear />
|
||||||
|
<add name="X-Powered-By" value="ASP.NET" />
|
||||||
|
</customHeaders>
|
||||||
|
<redirectHeaders>
|
||||||
|
<clear />
|
||||||
|
</redirectHeaders>
|
||||||
|
</httpProtocol>
|
||||||
|
<httpRedirect enabled="false" />
|
||||||
|
<httpTracing></httpTracing>
|
||||||
|
<isapiFilters>
|
||||||
|
<filter name="ASP.Net_2.0.50727-64" path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv2.0" />
|
||||||
|
<filter name="ASP.Net_2.0.50727.0" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv2.0" />
|
||||||
|
<filter name="ASP.Net_2.0_for_v1.1" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="runtimeVersionv1.1" />
|
||||||
|
<filter name="ASP.Net_4.0_32bit" path="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv4.0" />
|
||||||
|
<filter name="ASP.Net_4.0_64bit" path="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv4.0" />
|
||||||
|
</isapiFilters>
|
||||||
|
<odbcLogging />
|
||||||
|
<security>
|
||||||
|
<access sslFlags="None" />
|
||||||
|
<applicationDependencies>
|
||||||
|
<application name="Active Server Pages" groupId="ASP" />
|
||||||
|
</applicationDependencies>
|
||||||
|
<authentication>
|
||||||
|
<anonymousAuthentication enabled="true" userName="" />
|
||||||
|
<basicAuthentication enabled="false" />
|
||||||
|
<clientCertificateMappingAuthentication enabled="false" />
|
||||||
|
<digestAuthentication enabled="false" />
|
||||||
|
<iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
|
||||||
|
<windowsAuthentication enabled="false">
|
||||||
|
<providers>
|
||||||
|
<add value="Negotiate" />
|
||||||
|
<add value="NTLM" />
|
||||||
|
</providers>
|
||||||
|
</windowsAuthentication>
|
||||||
|
</authentication>
|
||||||
|
<authorization>
|
||||||
|
<add accessType="Allow" users="*" />
|
||||||
|
</authorization>
|
||||||
|
<ipSecurity allowUnlisted="true" />
|
||||||
|
<isapiCgiRestriction notListedIsapisAllowed="true" notListedCgisAllowed="true">
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
|
||||||
|
</isapiCgiRestriction>
|
||||||
|
<requestFiltering>
|
||||||
|
<fileExtensions allowUnlisted="true" applyToWebDAV="true">
|
||||||
|
<add fileExtension=".asa" allowed="false" />
|
||||||
|
<add fileExtension=".asax" allowed="false" />
|
||||||
|
<add fileExtension=".ascx" allowed="false" />
|
||||||
|
<add fileExtension=".master" allowed="false" />
|
||||||
|
<add fileExtension=".skin" allowed="false" />
|
||||||
|
<add fileExtension=".browser" allowed="false" />
|
||||||
|
<add fileExtension=".sitemap" allowed="false" />
|
||||||
|
<add fileExtension=".config" allowed="false" />
|
||||||
|
<add fileExtension=".cs" allowed="false" />
|
||||||
|
<add fileExtension=".csproj" allowed="false" />
|
||||||
|
<add fileExtension=".vb" allowed="false" />
|
||||||
|
<add fileExtension=".vbproj" allowed="false" />
|
||||||
|
<add fileExtension=".webinfo" allowed="false" />
|
||||||
|
<add fileExtension=".licx" allowed="false" />
|
||||||
|
<add fileExtension=".resx" allowed="false" />
|
||||||
|
<add fileExtension=".resources" allowed="false" />
|
||||||
|
<add fileExtension=".mdb" allowed="false" />
|
||||||
|
<add fileExtension=".vjsproj" allowed="false" />
|
||||||
|
<add fileExtension=".java" allowed="false" />
|
||||||
|
<add fileExtension=".jsl" allowed="false" />
|
||||||
|
<add fileExtension=".ldb" allowed="false" />
|
||||||
|
<add fileExtension=".dsdgm" allowed="false" />
|
||||||
|
<add fileExtension=".ssdgm" allowed="false" />
|
||||||
|
<add fileExtension=".lsad" allowed="false" />
|
||||||
|
<add fileExtension=".ssmap" allowed="false" />
|
||||||
|
<add fileExtension=".cd" allowed="false" />
|
||||||
|
<add fileExtension=".dsprototype" allowed="false" />
|
||||||
|
<add fileExtension=".lsaprototype" allowed="false" />
|
||||||
|
<add fileExtension=".sdm" allowed="false" />
|
||||||
|
<add fileExtension=".sdmDocument" allowed="false" />
|
||||||
|
<add fileExtension=".mdf" allowed="false" />
|
||||||
|
<add fileExtension=".ldf" allowed="false" />
|
||||||
|
<add fileExtension=".ad" allowed="false" />
|
||||||
|
<add fileExtension=".dd" allowed="false" />
|
||||||
|
<add fileExtension=".ldd" allowed="false" />
|
||||||
|
<add fileExtension=".sd" allowed="false" />
|
||||||
|
<add fileExtension=".adprototype" allowed="false" />
|
||||||
|
<add fileExtension=".lddprototype" allowed="false" />
|
||||||
|
<add fileExtension=".exclude" allowed="false" />
|
||||||
|
<add fileExtension=".refresh" allowed="false" />
|
||||||
|
<add fileExtension=".compiled" allowed="false" />
|
||||||
|
<add fileExtension=".msgx" allowed="false" />
|
||||||
|
<add fileExtension=".vsdisco" allowed="false" />
|
||||||
|
<add fileExtension=".rules" allowed="false" />
|
||||||
|
</fileExtensions>
|
||||||
|
<verbs allowUnlisted="true" applyToWebDAV="true" />
|
||||||
|
<hiddenSegments applyToWebDAV="true">
|
||||||
|
<add segment="web.config" />
|
||||||
|
<add segment="bin" />
|
||||||
|
<add segment="App_code" />
|
||||||
|
<add segment="App_GlobalResources" />
|
||||||
|
<add segment="App_LocalResources" />
|
||||||
|
<add segment="App_WebReferences" />
|
||||||
|
<add segment="App_Data" />
|
||||||
|
<add segment="App_Browsers" />
|
||||||
|
</hiddenSegments>
|
||||||
|
</requestFiltering>
|
||||||
|
</security>
|
||||||
|
<serverSideInclude ssiExecDisable="false" />
|
||||||
|
<staticContent lockAttributes="isDocFooterFileName">
|
||||||
|
<mimeMap fileExtension=".323" mimeType="text/h323" />
|
||||||
|
<mimeMap fileExtension=".3g2" mimeType="video/3gpp2" />
|
||||||
|
<mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" />
|
||||||
|
<mimeMap fileExtension=".3gp" mimeType="video/3gpp" />
|
||||||
|
<mimeMap fileExtension=".3gpp" mimeType="video/3gpp" />
|
||||||
|
<mimeMap fileExtension=".aac" mimeType="audio/aac" />
|
||||||
|
<mimeMap fileExtension=".aaf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".aca" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".accdb" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".accde" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".accdt" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" />
|
||||||
|
<mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" />
|
||||||
|
<mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" />
|
||||||
|
<mimeMap fileExtension=".afm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ai" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".aif" mimeType="audio/x-aiff" />
|
||||||
|
<mimeMap fileExtension=".aifc" mimeType="audio/aiff" />
|
||||||
|
<mimeMap fileExtension=".aiff" mimeType="audio/aiff" />
|
||||||
|
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
|
||||||
|
<mimeMap fileExtension=".application" mimeType="application/x-ms-application" />
|
||||||
|
<mimeMap fileExtension=".art" mimeType="image/x-jg" />
|
||||||
|
<mimeMap fileExtension=".asd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".asi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".asm" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".atom" mimeType="application/atom+xml" />
|
||||||
|
<mimeMap fileExtension=".au" mimeType="audio/basic" />
|
||||||
|
<mimeMap fileExtension=".avi" mimeType="video/msvideo" />
|
||||||
|
<mimeMap fileExtension=".axs" mimeType="application/olescript" />
|
||||||
|
<mimeMap fileExtension=".bas" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" />
|
||||||
|
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".bmp" mimeType="image/bmp" />
|
||||||
|
<mimeMap fileExtension=".c" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" />
|
||||||
|
<mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" />
|
||||||
|
<mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" />
|
||||||
|
<mimeMap fileExtension=".cdf" mimeType="application/x-cdf" />
|
||||||
|
<mimeMap fileExtension=".chm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".class" mimeType="application/x-java-applet" />
|
||||||
|
<mimeMap fileExtension=".clp" mimeType="application/x-msclip" />
|
||||||
|
<mimeMap fileExtension=".cmx" mimeType="image/x-cmx" />
|
||||||
|
<mimeMap fileExtension=".cnf" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".cod" mimeType="image/cis-cod" />
|
||||||
|
<mimeMap fileExtension=".cpio" mimeType="application/x-cpio" />
|
||||||
|
<mimeMap fileExtension=".cpp" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" />
|
||||||
|
<mimeMap fileExtension=".crl" mimeType="application/pkix-crl" />
|
||||||
|
<mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" />
|
||||||
|
<mimeMap fileExtension=".csh" mimeType="application/x-csh" />
|
||||||
|
<mimeMap fileExtension=".css" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".csv" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".cur" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dcr" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" />
|
||||||
|
<mimeMap fileExtension=".dib" mimeType="image/bmp" />
|
||||||
|
<mimeMap fileExtension=".dir" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".disco" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dll" mimeType="application/x-msdownload" />
|
||||||
|
<mimeMap fileExtension=".dll.config" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dlm" mimeType="text/dlm" />
|
||||||
|
<mimeMap fileExtension=".doc" mimeType="application/msword" />
|
||||||
|
<mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
|
||||||
|
<mimeMap fileExtension=".dot" mimeType="application/msword" />
|
||||||
|
<mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
|
||||||
|
<mimeMap fileExtension=".dsp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dtd" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dvi" mimeType="application/x-dvi" />
|
||||||
|
<mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" />
|
||||||
|
<mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" />
|
||||||
|
<mimeMap fileExtension=".dwp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dxr" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".eml" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".emz" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
|
||||||
|
<mimeMap fileExtension=".eps" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".etx" mimeType="text/x-setext" />
|
||||||
|
<mimeMap fileExtension=".evy" mimeType="application/envoy" />
|
||||||
|
<mimeMap fileExtension=".exe" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".exe.config" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" />
|
||||||
|
<mimeMap fileExtension=".fif" mimeType="application/fractals" />
|
||||||
|
<mimeMap fileExtension=".fla" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
|
||||||
|
<mimeMap fileExtension=".gif" mimeType="image/gif" />
|
||||||
|
<mimeMap fileExtension=".gtar" mimeType="application/x-gtar" />
|
||||||
|
<mimeMap fileExtension=".gz" mimeType="application/x-gzip" />
|
||||||
|
<mimeMap fileExtension=".h" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".hdf" mimeType="application/x-hdf" />
|
||||||
|
<mimeMap fileExtension=".hdml" mimeType="text/x-hdml" />
|
||||||
|
<mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" />
|
||||||
|
<mimeMap fileExtension=".hhk" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".hhp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".hlp" mimeType="application/winhlp" />
|
||||||
|
<mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" />
|
||||||
|
<mimeMap fileExtension=".hta" mimeType="application/hta" />
|
||||||
|
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
|
||||||
|
<mimeMap fileExtension=".htm" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".html" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".htt" mimeType="text/webviewhtml" />
|
||||||
|
<mimeMap fileExtension=".hxt" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
|
||||||
|
<mimeMap fileExtension=".ics" mimeType="text/calendar" />
|
||||||
|
<mimeMap fileExtension=".ief" mimeType="image/ief" />
|
||||||
|
<mimeMap fileExtension=".iii" mimeType="application/x-iphone" />
|
||||||
|
<mimeMap fileExtension=".inf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" />
|
||||||
|
<mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" />
|
||||||
|
<mimeMap fileExtension=".IVF" mimeType="video/x-ivf" />
|
||||||
|
<mimeMap fileExtension=".jar" mimeType="application/java-archive" />
|
||||||
|
<mimeMap fileExtension=".java" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".jck" mimeType="application/liquidmotion" />
|
||||||
|
<mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" />
|
||||||
|
<mimeMap fileExtension=".jfif" mimeType="image/pjpeg" />
|
||||||
|
<mimeMap fileExtension=".jpb" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".jpe" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".jpeg" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".js" mimeType="application/javascript" />
|
||||||
|
<mimeMap fileExtension=".json" mimeType="application/json" />
|
||||||
|
<mimeMap fileExtension=".jsonld" mimeType="application/ld+json" />
|
||||||
|
<mimeMap fileExtension=".jsx" mimeType="text/jscript" />
|
||||||
|
<mimeMap fileExtension=".latex" mimeType="application/x-latex" />
|
||||||
|
<mimeMap fileExtension=".less" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" />
|
||||||
|
<mimeMap fileExtension=".lpk" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" />
|
||||||
|
<mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" />
|
||||||
|
<mimeMap fileExtension=".lzh" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".m1v" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" />
|
||||||
|
<mimeMap fileExtension=".m4a" mimeType="audio/mp4" />
|
||||||
|
<mimeMap fileExtension=".m4v" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".man" mimeType="application/x-troff-man" />
|
||||||
|
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" />
|
||||||
|
<mimeMap fileExtension=".map" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" />
|
||||||
|
<mimeMap fileExtension=".mdp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".me" mimeType="application/x-troff-me" />
|
||||||
|
<mimeMap fileExtension=".mht" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".mhtml" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".mid" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".midi" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".mix" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mmf" mimeType="application/x-smaf" />
|
||||||
|
<mimeMap fileExtension=".mno" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".mny" mimeType="application/x-msmoney" />
|
||||||
|
<mimeMap fileExtension=".mov" mimeType="video/quicktime" />
|
||||||
|
<mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" />
|
||||||
|
<mimeMap fileExtension=".mp2" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".mp4v" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".mpa" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpe" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpeg" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" />
|
||||||
|
<mimeMap fileExtension=".mpv2" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" />
|
||||||
|
<mimeMap fileExtension=".msi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mso" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" />
|
||||||
|
<mimeMap fileExtension=".nc" mimeType="application/x-netcdf" />
|
||||||
|
<mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".nws" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".ocx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".oda" mimeType="application/oda" />
|
||||||
|
<mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" />
|
||||||
|
<mimeMap fileExtension=".ods" mimeType="application/oleobject" />
|
||||||
|
<mimeMap fileExtension=".oga" mimeType="audio/ogg" />
|
||||||
|
<mimeMap fileExtension=".ogg" mimeType="video/ogg" />
|
||||||
|
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
|
||||||
|
<mimeMap fileExtension=".one" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onea" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetoc" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetoc2" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetmp" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onepkg" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" />
|
||||||
|
<mimeMap fileExtension=".otf" mimeType="font/otf" />
|
||||||
|
<mimeMap fileExtension=".p10" mimeType="application/pkcs10" />
|
||||||
|
<mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" />
|
||||||
|
<mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" />
|
||||||
|
<mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" />
|
||||||
|
<mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" />
|
||||||
|
<mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" />
|
||||||
|
<mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" />
|
||||||
|
<mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" />
|
||||||
|
<mimeMap fileExtension=".pcx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pcz" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pdf" mimeType="application/pdf" />
|
||||||
|
<mimeMap fileExtension=".pfb" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pfm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" />
|
||||||
|
<mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" />
|
||||||
|
<mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" />
|
||||||
|
<mimeMap fileExtension=".pma" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pml" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".png" mimeType="image/png" />
|
||||||
|
<mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" />
|
||||||
|
<mimeMap fileExtension=".pnz" mimeType="image/png" />
|
||||||
|
<mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
|
||||||
|
<mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" />
|
||||||
|
<mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
|
||||||
|
<mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
|
||||||
|
<mimeMap fileExtension=".prf" mimeType="application/pics-rules" />
|
||||||
|
<mimeMap fileExtension=".prm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".prx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ps" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".psd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".psm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".psp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" />
|
||||||
|
<mimeMap fileExtension=".qt" mimeType="video/quicktime" />
|
||||||
|
<mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" />
|
||||||
|
<mimeMap fileExtension=".qxd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" />
|
||||||
|
<mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" />
|
||||||
|
<mimeMap fileExtension=".rar" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" />
|
||||||
|
<mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" />
|
||||||
|
<mimeMap fileExtension=".rgb" mimeType="image/x-rgb" />
|
||||||
|
<mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" />
|
||||||
|
<mimeMap fileExtension=".rmi" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".roff" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" />
|
||||||
|
<mimeMap fileExtension=".rtf" mimeType="application/rtf" />
|
||||||
|
<mimeMap fileExtension=".rtx" mimeType="text/richtext" />
|
||||||
|
<mimeMap fileExtension=".scd" mimeType="application/x-msschedule" />
|
||||||
|
<mimeMap fileExtension=".sct" mimeType="text/scriptlet" />
|
||||||
|
<mimeMap fileExtension=".sea" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" />
|
||||||
|
<mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" />
|
||||||
|
<mimeMap fileExtension=".sgml" mimeType="text/sgml" />
|
||||||
|
<mimeMap fileExtension=".sh" mimeType="application/x-sh" />
|
||||||
|
<mimeMap fileExtension=".shar" mimeType="application/x-shar" />
|
||||||
|
<mimeMap fileExtension=".sit" mimeType="application/x-stuffit" />
|
||||||
|
<mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" />
|
||||||
|
<mimeMap fileExtension=".smd" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".smi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".smx" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".smz" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".snd" mimeType="audio/basic" />
|
||||||
|
<mimeMap fileExtension=".snp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" />
|
||||||
|
<mimeMap fileExtension=".spl" mimeType="application/futuresplash" />
|
||||||
|
<mimeMap fileExtension=".spx" mimeType="audio/ogg" />
|
||||||
|
<mimeMap fileExtension=".src" mimeType="application/x-wais-source" />
|
||||||
|
<mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" />
|
||||||
|
<mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" />
|
||||||
|
<mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" />
|
||||||
|
<mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" />
|
||||||
|
<mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" />
|
||||||
|
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
|
||||||
|
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
|
||||||
|
<mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" />
|
||||||
|
<mimeMap fileExtension=".t" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".tar" mimeType="application/x-tar" />
|
||||||
|
<mimeMap fileExtension=".tcl" mimeType="application/x-tcl" />
|
||||||
|
<mimeMap fileExtension=".tex" mimeType="application/x-tex" />
|
||||||
|
<mimeMap fileExtension=".texi" mimeType="application/x-texinfo" />
|
||||||
|
<mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" />
|
||||||
|
<mimeMap fileExtension=".tgz" mimeType="application/x-compressed" />
|
||||||
|
<mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" />
|
||||||
|
<mimeMap fileExtension=".thn" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tif" mimeType="image/tiff" />
|
||||||
|
<mimeMap fileExtension=".tiff" mimeType="image/tiff" />
|
||||||
|
<mimeMap fileExtension=".toc" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tr" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".trm" mimeType="application/x-msterminal" />
|
||||||
|
<mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" />
|
||||||
|
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".txt" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".u32" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".uls" mimeType="text/iuls" />
|
||||||
|
<mimeMap fileExtension=".ustar" mimeType="application/x-ustar" />
|
||||||
|
<mimeMap fileExtension=".vbs" mimeType="text/vbscript" />
|
||||||
|
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
|
||||||
|
<mimeMap fileExtension=".vcs" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" />
|
||||||
|
<mimeMap fileExtension=".vml" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vss" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vst" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" />
|
||||||
|
<mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".wav" mimeType="audio/wav" />
|
||||||
|
<mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" />
|
||||||
|
<mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" />
|
||||||
|
<mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".webm" mimeType="video/webm" />
|
||||||
|
<mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" />
|
||||||
|
<mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" />
|
||||||
|
<mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" />
|
||||||
|
<mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" />
|
||||||
|
<mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" />
|
||||||
|
<mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" />
|
||||||
|
<mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" />
|
||||||
|
<mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" />
|
||||||
|
<mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" />
|
||||||
|
<mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" />
|
||||||
|
<mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" />
|
||||||
|
<mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" />
|
||||||
|
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
|
||||||
|
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
|
||||||
|
<mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wri" mimeType="application/x-mswrite" />
|
||||||
|
<mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".wsdl" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" />
|
||||||
|
<mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" />
|
||||||
|
<mimeMap fileExtension=".x" mimeType="application/directx" />
|
||||||
|
<mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" />
|
||||||
|
<mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" />
|
||||||
|
<mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" />
|
||||||
|
<mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" />
|
||||||
|
<mimeMap fileExtension=".xdr" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" />
|
||||||
|
<mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" />
|
||||||
|
<mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
|
||||||
|
<mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
|
||||||
|
<mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xml" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" />
|
||||||
|
<mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" />
|
||||||
|
<mimeMap fileExtension=".xsd" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsf" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsl" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xslt" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsn" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".xtp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" />
|
||||||
|
<mimeMap fileExtension=".z" mimeType="application/x-compress" />
|
||||||
|
<mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" />
|
||||||
|
</staticContent>
|
||||||
|
<tracing>
|
||||||
|
<traceProviderDefinitions>
|
||||||
|
<add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}">
|
||||||
|
<areas>
|
||||||
|
<clear />
|
||||||
|
<add name="Authentication" value="2" />
|
||||||
|
<add name="Security" value="4" />
|
||||||
|
<add name="Filter" value="8" />
|
||||||
|
<add name="StaticFile" value="16" />
|
||||||
|
<add name="CGI" value="32" />
|
||||||
|
<add name="Compression" value="64" />
|
||||||
|
<add name="Cache" value="128" />
|
||||||
|
<add name="RequestNotifications" value="256" />
|
||||||
|
<add name="Module" value="512" />
|
||||||
|
<add name="Rewrite" value="1024" />
|
||||||
|
<add name="FastCGI" value="4096" />
|
||||||
|
<add name="WebSocket" value="16384" />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
<add name="ASP" guid="{06b94d9a-b15e-456e-a4ef-37c984a2cb4b}">
|
||||||
|
<areas>
|
||||||
|
<clear />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
<add name="ISAPI Extension" guid="{a1c2040e-8840-4c31-ba11-9871031a19ea}">
|
||||||
|
<areas>
|
||||||
|
<clear />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
<add name="ASPNET" guid="{AFF081FE-0247-4275-9C4E-021F3DC1DA35}">
|
||||||
|
<areas>
|
||||||
|
<add name="Infrastructure" value="1" />
|
||||||
|
<add name="Module" value="2" />
|
||||||
|
<add name="Page" value="4" />
|
||||||
|
<add name="AppServices" value="8" />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
</traceProviderDefinitions>
|
||||||
|
<traceFailedRequests>
|
||||||
|
<add path="*">
|
||||||
|
<traceAreas>
|
||||||
|
<add provider="ASP" verbosity="Verbose" />
|
||||||
|
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
|
||||||
|
<add provider="ISAPI Extension" verbosity="Verbose" />
|
||||||
|
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,WebSocket" verbosity="Verbose" />
|
||||||
|
</traceAreas>
|
||||||
|
<failureDefinitions statusCodes="200-999" />
|
||||||
|
</add>
|
||||||
|
</traceFailedRequests>
|
||||||
|
</tracing>
|
||||||
|
<urlCompression />
|
||||||
|
<validation />
|
||||||
|
<webdav>
|
||||||
|
<globalSettings>
|
||||||
|
<propertyStores>
|
||||||
|
<add name="webdav_simple_prop" image="%IIS_BIN%\webdav_simple_prop.dll" image32="%IIS_BIN%\webdav_simple_prop.dll" />
|
||||||
|
</propertyStores>
|
||||||
|
<lockStores>
|
||||||
|
<add name="webdav_simple_lock" image="%IIS_BIN%\webdav_simple_lock.dll" image32="%IIS_BIN%\webdav_simple_lock.dll" />
|
||||||
|
</lockStores>
|
||||||
|
</globalSettings>
|
||||||
|
<authoring>
|
||||||
|
<locks enabled="true" lockStore="webdav_simple_lock" />
|
||||||
|
</authoring>
|
||||||
|
<authoringRules />
|
||||||
|
</webdav>
|
||||||
|
<webSocket />
|
||||||
|
<applicationInitialization />
|
||||||
|
</system.webServer>
|
||||||
|
<location path="" overrideMode="Allow">
|
||||||
|
<system.webServer>
|
||||||
|
<modules>
|
||||||
|
<add name="IsapiFilterModule" lockItem="true" />
|
||||||
|
<add name="BasicAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="IsapiModule" lockItem="true" />
|
||||||
|
<add name="HttpLoggingModule" lockItem="true" />
|
||||||
|
<!--
|
||||||
|
<add name="HttpCacheModule" lockItem="true" />
|
||||||
|
-->
|
||||||
|
<add name="DynamicCompressionModule" lockItem="true" />
|
||||||
|
<add name="StaticCompressionModule" lockItem="true" />
|
||||||
|
<add name="DefaultDocumentModule" lockItem="true" />
|
||||||
|
<add name="DirectoryListingModule" lockItem="true" />
|
||||||
|
<add name="ProtocolSupportModule" lockItem="true" />
|
||||||
|
<add name="HttpRedirectionModule" lockItem="true" />
|
||||||
|
<add name="ServerSideIncludeModule" lockItem="true" />
|
||||||
|
<add name="StaticFileModule" lockItem="true" />
|
||||||
|
<add name="AnonymousAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="CertificateMappingAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="UrlAuthorizationModule" lockItem="true" />
|
||||||
|
<add name="WindowsAuthenticationModule" lockItem="true" />
|
||||||
|
<!--
|
||||||
|
<add name="DigestAuthenticationModule" lockItem="true" />
|
||||||
|
-->
|
||||||
|
<add name="IISCertificateMappingAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="WebMatrixSupportModule" lockItem="true" />
|
||||||
|
<add name="IpRestrictionModule" lockItem="true" />
|
||||||
|
<add name="DynamicIpRestrictionModule" lockItem="true" />
|
||||||
|
<add name="RequestFilteringModule" lockItem="true" />
|
||||||
|
<add name="CustomLoggingModule" lockItem="true" />
|
||||||
|
<add name="CustomErrorModule" lockItem="true" />
|
||||||
|
<add name="FailedRequestsTracingModule" lockItem="true" />
|
||||||
|
<add name="CgiModule" lockItem="true" />
|
||||||
|
<add name="FastCgiModule" lockItem="true" />
|
||||||
|
<!-- <add name="WebDAVModule" /> -->
|
||||||
|
<add name="RewriteModule" />
|
||||||
|
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" preCondition="managedHandler" />
|
||||||
|
<add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="managedHandler" />
|
||||||
|
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="managedHandler" />
|
||||||
|
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
|
||||||
|
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" />
|
||||||
|
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" preCondition="managedHandler" />
|
||||||
|
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
|
||||||
|
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" />
|
||||||
|
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" />
|
||||||
|
<add name="Profile" type="System.Web.Profile.ProfileModule" preCondition="managedHandler" />
|
||||||
|
<add name="UrlMappingsModule" type="System.Web.UrlMappingsModule" preCondition="managedHandler" />
|
||||||
|
<add name="ApplicationInitializationModule" lockItem="true" />
|
||||||
|
<add name="WebSocketModule" lockItem="true" />
|
||||||
|
<add name="ServiceModel-4.0" type="System.ServiceModel.Activation.ServiceHttpModule,System.ServiceModel.Activation,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||||
|
<add name="ConfigurationValidationModule" lockItem="true" />
|
||||||
|
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||||
|
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||||
|
<add name="AspNetCoreModule" lockItem="true" />
|
||||||
|
</modules>
|
||||||
|
<handlers accessPolicy="Read, Script">
|
||||||
|
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
|
||||||
|
<add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-4.0_64bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="aspq-ISAPI-4.0_64bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="cshtm-ISAPI-4.0_64bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="cshtml-ISAPI-4.0_64bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtm-ISAPI-4.0_64bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtml-ISAPI-4.0_64bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="AXD-ISAPI-4.0_32bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-4.0_32bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="aspq-ISAPI-4.0_32bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="cshtm-ISAPI-4.0_32bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="cshtml-ISAPI-4.0_32bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtm-ISAPI-4.0_32bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtml-ISAPI-4.0_32bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="TraceHandler-Integrated-4.0" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="WebAdminHandler-Integrated-4.0" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-Integrated-4.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-Integrated-4.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="aspq-Integrated-4.0" path="*.aspq" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="cshtm-Integrated-4.0" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="cshtml-Integrated-4.0" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="vbhtm-Integrated-4.0" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="vbhtml-Integrated-4.0" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="ScriptHandlerFactoryAppServices-Integrated-4.0" path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="ScriptResourceIntegrated-4.0" path="*ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
|
||||||
|
<add name="SecurityCertificate" path="*.cer" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
|
||||||
|
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
|
||||||
|
<add name="TraceHandler-Integrated" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="WebAdminHandler-Integrated" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="AssemblyResourceLoader-Integrated" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory,System.Web.Services,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-Integrated" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-Integrated" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="AXD-ISAPI-2.0" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-2.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-2.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="AXD-ISAPI-2.0-64" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-2.0-64" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-2.0-64" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-2.0-64" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0-64" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0-64" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
|
||||||
|
<add name="SSINC-stm" path="*.stm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||||
|
<add name="SSINC-shtm" path="*.shtm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||||
|
<add name="SSINC-shtml" path="*.shtml" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||||
|
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
|
||||||
|
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
|
||||||
|
<add name="ExtensionlessUrl-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
|
||||||
|
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
|
||||||
|
</handlers>
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
</configuration>
|
||||||
|
|
@ -0,0 +1,730 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
IIS configuration sections.
|
||||||
|
|
||||||
|
For schema documentation, see
|
||||||
|
%windir%\system32\inetsrv\config\schema\IIS_schema.xml.
|
||||||
|
|
||||||
|
Please make a backup of this file before making any changes to it.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <configSections> section controls the registration of sections.
|
||||||
|
Section is the basic unit of deployment, locking, searching and
|
||||||
|
containment for configuration settings.
|
||||||
|
|
||||||
|
Every section belongs to one section group.
|
||||||
|
A section group is a container of logically-related sections.
|
||||||
|
|
||||||
|
Sections cannot be nested.
|
||||||
|
Section groups may be nested.
|
||||||
|
|
||||||
|
<section
|
||||||
|
name="" [Required, Collection Key] [XML name of the section]
|
||||||
|
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
|
||||||
|
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
|
||||||
|
allowLocation="true" [true|false] [Allowed in location tags]
|
||||||
|
/>
|
||||||
|
|
||||||
|
The recommended way to unlock sections is by using a location tag:
|
||||||
|
<location path="Default Web Site" overrideMode="Allow">
|
||||||
|
<system.webServer>
|
||||||
|
<asp />
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
|
||||||
|
-->
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="system.applicationHost">
|
||||||
|
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="sites" overrideModeDefault="Allow" />
|
||||||
|
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
|
||||||
|
<sectionGroup name="system.webServer">
|
||||||
|
<section name="asp" overrideModeDefault="Deny" />
|
||||||
|
<section name="caching" overrideModeDefault="Allow" />
|
||||||
|
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||||
|
<section name="cgi" overrideModeDefault="Deny" />
|
||||||
|
<section name="defaultDocument" overrideModeDefault="Allow" />
|
||||||
|
<section name="directoryBrowse" overrideModeDefault="Allow" />
|
||||||
|
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="globalModules" overrideModeDefault="Allow" />
|
||||||
|
<section name="handlers" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpCompression" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpErrors" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpLogging" overrideModeDefault="Deny" />
|
||||||
|
<section name="httpProtocol" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpRedirect" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpTracing" overrideModeDefault="Deny" />
|
||||||
|
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||||
|
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||||
|
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||||
|
<section name="odbcLogging" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="security">
|
||||||
|
<section name="access" overrideModeDefault="Deny" />
|
||||||
|
<section name="applicationDependencies" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="authentication">
|
||||||
|
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="basicAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="digestAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="windowsAuthentication" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="authorization" overrideModeDefault="Allow" />
|
||||||
|
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="requestFiltering" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="serverRuntime" overrideModeDefault="Deny" />
|
||||||
|
<section name="serverSideInclude" overrideModeDefault="Deny" />
|
||||||
|
<section name="staticContent" overrideModeDefault="Allow" />
|
||||||
|
<sectionGroup name="tracing">
|
||||||
|
<section name="traceFailedRequests" overrideModeDefault="Allow" />
|
||||||
|
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="urlCompression" overrideModeDefault="Allow" />
|
||||||
|
<section name="validation" overrideModeDefault="Allow" />
|
||||||
|
<sectionGroup name="webdav">
|
||||||
|
<section name="globalSettings" overrideModeDefault="Deny" />
|
||||||
|
<section name="authoring" overrideModeDefault="Deny" />
|
||||||
|
<section name="authoringRules" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="webSocket" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<sectionGroup name="system.ftpServer">
|
||||||
|
<section name="log" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||||
|
<section name="firewallSupport" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||||
|
<section name="caching" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||||
|
<section name="providerDefinitions" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="security">
|
||||||
|
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="requestFiltering" overrideModeDefault="Deny" />
|
||||||
|
<section name="authorization" overrideModeDefault="Deny" />
|
||||||
|
<section name="authentication" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="serverRuntime" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
|
||||||
|
<configProtectedData>
|
||||||
|
<providers>
|
||||||
|
<add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
|
||||||
|
<add name="IISCngProvider" type="Microsoft.ApplicationHost.CngProtectedConfigurationProvider" description="Uses Win32 Crypto CNG to encrypt and decrypt" keyContainerName="iisCngConfigurationKey" useMachineContainer="true" />
|
||||||
|
<add name="IISWASOnlyCngProvider" type="Microsoft.ApplicationHost.CngProtectedConfigurationProvider" description="(WAS Only) Uses Win32 Crypto CNG to encrypt and decrypt" keyContainerName="iisCngWasKey" useMachineContainer="true" />
|
||||||
|
<add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAA761WPlg/O0KIRimaL0QzaMUtBeu0wvDNy2z7w2Bt6jKMn2vd1rsTm2CkiLB9XfTVBXkd9QnX0PVkzaubmf2eJ1ZoovreHp367sKvP0ycL3wToFfOkbzmCGcyR5K97x7zqgokJ2nZ4+upP6eB5YGQbVoOvYkO124LwZdPurAepHlBF6BnLw6iOmzqEISQhjb2TnlHuI54wGy7PEqog8Yw5KWAHT1v5llXAIi3BUT4J0ALPGxzZeY6sfuupb5UWjgBmHRGxRC7Q67tY9ZrjSHynIazcroAreBHJHD7V4Ie4I+8y32Vupej3HhN0WPZIVgIERN6XH7/88IQbO7oGdRKMw==" />
|
||||||
|
<add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAAyfG50d0OvPU6AmHdvHBKc9XoUZKF24/cmB4ZU2ol04N+Hj++IytaIbPR6hRXwZGGXqRnFunrCtHbNvjXinU3esyYJ2ij+HZCzAfUspWbfK+tyyGKQ+E2GY65mKqwfXu2BcZBO5At/LxOAwDqVwl9iFsMhtqfAoe/SxQXh1a1T3oSRYUBfsr6jvfWeH0lI8AznEG2KdPS8Smaf8XtF51R3Z0JbbWfIa+WmvmfUkHgcFHHqlDd2LOuB3cWNJhSR9EX2h4t1v3AvGqHmYs5bq63/p5I3aW6jQ4r3HfNWm1TGEvXgeNqOZHZvGSMxKN1TE0AAWd17WTP4tn6icEblR4YGw==" />
|
||||||
|
</providers>
|
||||||
|
</configProtectedData>
|
||||||
|
|
||||||
|
<system.applicationHost>
|
||||||
|
|
||||||
|
<applicationPools>
|
||||||
|
<add name="DefaultAppPool" />
|
||||||
|
<applicationPoolDefaults managedRuntimeVersion="v4.0">
|
||||||
|
<processModel identityType="ApplicationPoolIdentity" />
|
||||||
|
</applicationPoolDefaults>
|
||||||
|
</applicationPools>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <customMetadata> section is used internally by the Admin Base Objects
|
||||||
|
(ABO) Compatibility component. Please do not modify its content.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<customMetadata />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <listenerAdapters> section defines the protocols with which the
|
||||||
|
Windows Process Activation Service (WAS) binds.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<listenerAdapters>
|
||||||
|
<add name="http" />
|
||||||
|
</listenerAdapters>
|
||||||
|
|
||||||
|
<log>
|
||||||
|
<centralBinaryLogFile enabled="true" directory="%SystemDrive%\inetpub\logs\LogFiles" />
|
||||||
|
<centralW3CLogFile enabled="true" directory="%SystemDrive%\inetpub\logs\LogFiles" />
|
||||||
|
</log>
|
||||||
|
|
||||||
|
<sites>
|
||||||
|
<site name="Default Web Site" id="1">
|
||||||
|
<application path="/">
|
||||||
|
<virtualDirectory path="/" physicalPath="%IIS_SITE_PATH%" />
|
||||||
|
</application>
|
||||||
|
<bindings>
|
||||||
|
<binding protocol="http" bindingInformation="*:50690:localhost" />
|
||||||
|
</bindings>
|
||||||
|
</site>
|
||||||
|
<siteDefaults>
|
||||||
|
<logFile logFormat="W3C" directory="%SystemDrive%\inetpub\logs\LogFiles" />
|
||||||
|
<traceFailedRequestsLogging directory="%SystemDrive%\inetpub\logs\FailedReqLogFiles" />
|
||||||
|
</siteDefaults>
|
||||||
|
<applicationDefaults applicationPool="DefaultAppPool" />
|
||||||
|
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||||
|
</sites>
|
||||||
|
|
||||||
|
<webLimits />
|
||||||
|
|
||||||
|
</system.applicationHost>
|
||||||
|
|
||||||
|
<system.webServer>
|
||||||
|
|
||||||
|
<asp />
|
||||||
|
|
||||||
|
<caching enabled="true" enableKernelCache="true">
|
||||||
|
</caching>
|
||||||
|
|
||||||
|
<cgi />
|
||||||
|
|
||||||
|
<defaultDocument enabled="true">
|
||||||
|
<files>
|
||||||
|
<add value="Default.htm" />
|
||||||
|
<add value="Default.asp" />
|
||||||
|
<add value="index.htm" />
|
||||||
|
<add value="index.html" />
|
||||||
|
<add value="iisstart.htm" />
|
||||||
|
</files>
|
||||||
|
</defaultDocument>
|
||||||
|
|
||||||
|
<directoryBrowse enabled="false" />
|
||||||
|
|
||||||
|
<fastCgi />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <globalModules> section defines all native-code modules.
|
||||||
|
To enable a module, specify it in the <modules> section.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<globalModules>
|
||||||
|
<add name="HttpLoggingModule" image="%windir%\System32\inetsrv\loghttp.dll" />
|
||||||
|
<add name="UriCacheModule" image="%windir%\System32\inetsrv\cachuri.dll" />
|
||||||
|
<add name="FileCacheModule" image="%windir%\System32\inetsrv\cachfile.dll" />
|
||||||
|
<add name="TokenCacheModule" image="%windir%\System32\inetsrv\cachtokn.dll" />
|
||||||
|
<add name="HttpCacheModule" image="%windir%\System32\inetsrv\cachhttp.dll" />
|
||||||
|
<add name="StaticCompressionModule" image="%windir%\System32\inetsrv\compstat.dll" />
|
||||||
|
<add name="DefaultDocumentModule" image="%windir%\System32\inetsrv\defdoc.dll" />
|
||||||
|
<add name="DirectoryListingModule" image="%windir%\System32\inetsrv\dirlist.dll" />
|
||||||
|
<add name="ProtocolSupportModule" image="%windir%\System32\inetsrv\protsup.dll" />
|
||||||
|
<add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
|
||||||
|
<add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
|
||||||
|
<add name="RequestFilteringModule" image="%windir%\System32\inetsrv\modrqflt.dll" />
|
||||||
|
<add name="CustomErrorModule" image="%windir%\System32\inetsrv\custerr.dll" />
|
||||||
|
<add name="AspNetCoreModule" image="%ANCM_PATH%" />
|
||||||
|
</globalModules>
|
||||||
|
|
||||||
|
<handlers accessPolicy="Read, Script">
|
||||||
|
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
|
||||||
|
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
|
||||||
|
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
|
||||||
|
</handlers>
|
||||||
|
|
||||||
|
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
|
||||||
|
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
|
||||||
|
<staticTypes>
|
||||||
|
<add mimeType="text/*" enabled="true" />
|
||||||
|
<add mimeType="message/*" enabled="true" />
|
||||||
|
<add mimeType="application/javascript" enabled="true" />
|
||||||
|
<add mimeType="application/atom+xml" enabled="true" />
|
||||||
|
<add mimeType="application/xaml+xml" enabled="true" />
|
||||||
|
<add mimeType="image/svg+xml" enabled="true" />
|
||||||
|
<add mimeType="*/*" enabled="false" />
|
||||||
|
</staticTypes>
|
||||||
|
</httpCompression>
|
||||||
|
|
||||||
|
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
|
||||||
|
<error statusCode="401" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="401.htm" />
|
||||||
|
<error statusCode="403" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="403.htm" />
|
||||||
|
<error statusCode="404" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="404.htm" />
|
||||||
|
<error statusCode="405" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="405.htm" />
|
||||||
|
<error statusCode="406" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="406.htm" />
|
||||||
|
<error statusCode="412" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="412.htm" />
|
||||||
|
<error statusCode="500" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="500.htm" />
|
||||||
|
<error statusCode="501" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="501.htm" />
|
||||||
|
<error statusCode="502" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="502.htm" />
|
||||||
|
</httpErrors>
|
||||||
|
|
||||||
|
<httpLogging dontLog="false" />
|
||||||
|
|
||||||
|
<httpProtocol>
|
||||||
|
<customHeaders>
|
||||||
|
<clear />
|
||||||
|
</customHeaders>
|
||||||
|
<redirectHeaders>
|
||||||
|
<clear />
|
||||||
|
</redirectHeaders>
|
||||||
|
</httpProtocol>
|
||||||
|
|
||||||
|
<httpRedirect />
|
||||||
|
|
||||||
|
<httpTracing />
|
||||||
|
|
||||||
|
<isapiFilters />
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<add name="HttpLoggingModule" lockItem="true" />
|
||||||
|
<add name="HttpCacheModule" lockItem="true" />
|
||||||
|
<add name="StaticCompressionModule" lockItem="true" />
|
||||||
|
<add name="DefaultDocumentModule" lockItem="true" />
|
||||||
|
<add name="DirectoryListingModule" lockItem="true" />
|
||||||
|
<add name="ProtocolSupportModule" lockItem="true" />
|
||||||
|
<add name="StaticFileModule" lockItem="true" />
|
||||||
|
<add name="AnonymousAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="RequestFilteringModule" lockItem="true" />
|
||||||
|
<add name="CustomErrorModule" lockItem="true" />
|
||||||
|
<add name="AspNetCoreModule" lockItem="true" />
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<odbcLogging />
|
||||||
|
|
||||||
|
<security>
|
||||||
|
|
||||||
|
<access sslFlags="None" />
|
||||||
|
|
||||||
|
<applicationDependencies />
|
||||||
|
|
||||||
|
<authentication>
|
||||||
|
|
||||||
|
<anonymousAuthentication enabled="true" userName="IUSR" />
|
||||||
|
|
||||||
|
<basicAuthentication />
|
||||||
|
|
||||||
|
<clientCertificateMappingAuthentication />
|
||||||
|
|
||||||
|
<digestAuthentication />
|
||||||
|
|
||||||
|
<iisClientCertificateMappingAuthentication />
|
||||||
|
|
||||||
|
<windowsAuthentication />
|
||||||
|
|
||||||
|
</authentication>
|
||||||
|
|
||||||
|
<authorization />
|
||||||
|
|
||||||
|
<ipSecurity />
|
||||||
|
|
||||||
|
<isapiCgiRestriction />
|
||||||
|
|
||||||
|
<requestFiltering>
|
||||||
|
<fileExtensions allowUnlisted="true" applyToWebDAV="true" />
|
||||||
|
<verbs allowUnlisted="true" applyToWebDAV="true" />
|
||||||
|
<hiddenSegments applyToWebDAV="true">
|
||||||
|
<add segment="web.config" />
|
||||||
|
</hiddenSegments>
|
||||||
|
</requestFiltering>
|
||||||
|
|
||||||
|
</security>
|
||||||
|
|
||||||
|
<serverRuntime />
|
||||||
|
|
||||||
|
<serverSideInclude />
|
||||||
|
|
||||||
|
<staticContent lockAttributes="isDocFooterFileName">
|
||||||
|
<mimeMap fileExtension=".323" mimeType="text/h323" />
|
||||||
|
<mimeMap fileExtension=".3g2" mimeType="video/3gpp2" />
|
||||||
|
<mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" />
|
||||||
|
<mimeMap fileExtension=".3gp" mimeType="video/3gpp" />
|
||||||
|
<mimeMap fileExtension=".3gpp" mimeType="video/3gpp" />
|
||||||
|
<mimeMap fileExtension=".aaf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".aac" mimeType="audio/aac" />
|
||||||
|
<mimeMap fileExtension=".aca" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".accdb" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".accde" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".accdt" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" />
|
||||||
|
<mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" />
|
||||||
|
<mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" />
|
||||||
|
<mimeMap fileExtension=".afm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ai" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".aif" mimeType="audio/x-aiff" />
|
||||||
|
<mimeMap fileExtension=".aifc" mimeType="audio/aiff" />
|
||||||
|
<mimeMap fileExtension=".aiff" mimeType="audio/aiff" />
|
||||||
|
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
|
||||||
|
<mimeMap fileExtension=".application" mimeType="application/x-ms-application" />
|
||||||
|
<mimeMap fileExtension=".art" mimeType="image/x-jg" />
|
||||||
|
<mimeMap fileExtension=".asd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".asi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".asm" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".atom" mimeType="application/atom+xml" />
|
||||||
|
<mimeMap fileExtension=".au" mimeType="audio/basic" />
|
||||||
|
<mimeMap fileExtension=".avi" mimeType="video/avi" />
|
||||||
|
<mimeMap fileExtension=".axs" mimeType="application/olescript" />
|
||||||
|
<mimeMap fileExtension=".bas" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" />
|
||||||
|
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".bmp" mimeType="image/bmp" />
|
||||||
|
<mimeMap fileExtension=".c" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" />
|
||||||
|
<mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" />
|
||||||
|
<mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" />
|
||||||
|
<mimeMap fileExtension=".cdf" mimeType="application/x-cdf" />
|
||||||
|
<mimeMap fileExtension=".chm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".class" mimeType="application/x-java-applet" />
|
||||||
|
<mimeMap fileExtension=".clp" mimeType="application/x-msclip" />
|
||||||
|
<mimeMap fileExtension=".cmx" mimeType="image/x-cmx" />
|
||||||
|
<mimeMap fileExtension=".cnf" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".cod" mimeType="image/cis-cod" />
|
||||||
|
<mimeMap fileExtension=".cpio" mimeType="application/x-cpio" />
|
||||||
|
<mimeMap fileExtension=".cpp" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" />
|
||||||
|
<mimeMap fileExtension=".crl" mimeType="application/pkix-crl" />
|
||||||
|
<mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" />
|
||||||
|
<mimeMap fileExtension=".csh" mimeType="application/x-csh" />
|
||||||
|
<mimeMap fileExtension=".css" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".csv" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".cur" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dcr" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" />
|
||||||
|
<mimeMap fileExtension=".dib" mimeType="image/bmp" />
|
||||||
|
<mimeMap fileExtension=".dir" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".disco" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dll" mimeType="application/x-msdownload" />
|
||||||
|
<mimeMap fileExtension=".dll.config" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dlm" mimeType="text/dlm" />
|
||||||
|
<mimeMap fileExtension=".doc" mimeType="application/msword" />
|
||||||
|
<mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
|
||||||
|
<mimeMap fileExtension=".dot" mimeType="application/msword" />
|
||||||
|
<mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
|
||||||
|
<mimeMap fileExtension=".dsp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dtd" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dvi" mimeType="application/x-dvi" />
|
||||||
|
<mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" />
|
||||||
|
<mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" />
|
||||||
|
<mimeMap fileExtension=".dwp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dxr" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".eml" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".emz" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
|
||||||
|
<mimeMap fileExtension=".eps" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".esd" mimeType="application/vnd.ms-cab-compressed" />
|
||||||
|
<mimeMap fileExtension=".etx" mimeType="text/x-setext" />
|
||||||
|
<mimeMap fileExtension=".evy" mimeType="application/envoy" />
|
||||||
|
<mimeMap fileExtension=".exe" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".exe.config" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" />
|
||||||
|
<mimeMap fileExtension=".fif" mimeType="application/fractals" />
|
||||||
|
<mimeMap fileExtension=".fla" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
|
||||||
|
<mimeMap fileExtension=".gif" mimeType="image/gif" />
|
||||||
|
<mimeMap fileExtension=".gtar" mimeType="application/x-gtar" />
|
||||||
|
<mimeMap fileExtension=".gz" mimeType="application/x-gzip" />
|
||||||
|
<mimeMap fileExtension=".h" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".hdf" mimeType="application/x-hdf" />
|
||||||
|
<mimeMap fileExtension=".hdml" mimeType="text/x-hdml" />
|
||||||
|
<mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" />
|
||||||
|
<mimeMap fileExtension=".hhk" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".hhp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".hlp" mimeType="application/winhlp" />
|
||||||
|
<mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" />
|
||||||
|
<mimeMap fileExtension=".hta" mimeType="application/hta" />
|
||||||
|
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
|
||||||
|
<mimeMap fileExtension=".htm" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".html" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".htt" mimeType="text/webviewhtml" />
|
||||||
|
<mimeMap fileExtension=".hxt" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
|
||||||
|
<mimeMap fileExtension=".ics" mimeType="text/calendar" />
|
||||||
|
<mimeMap fileExtension=".ief" mimeType="image/ief" />
|
||||||
|
<mimeMap fileExtension=".iii" mimeType="application/x-iphone" />
|
||||||
|
<mimeMap fileExtension=".inf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" />
|
||||||
|
<mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" />
|
||||||
|
<mimeMap fileExtension=".IVF" mimeType="video/x-ivf" />
|
||||||
|
<mimeMap fileExtension=".jar" mimeType="application/java-archive" />
|
||||||
|
<mimeMap fileExtension=".java" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".jck" mimeType="application/liquidmotion" />
|
||||||
|
<mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" />
|
||||||
|
<mimeMap fileExtension=".jfif" mimeType="image/pjpeg" />
|
||||||
|
<mimeMap fileExtension=".jpb" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".jpe" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".jpeg" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".js" mimeType="application/javascript" />
|
||||||
|
<mimeMap fileExtension=".json" mimeType="application/json" />
|
||||||
|
<mimeMap fileExtension=".jsonld" mimeType="application/ld+json" />
|
||||||
|
<mimeMap fileExtension=".jsx" mimeType="text/jscript" />
|
||||||
|
<mimeMap fileExtension=".latex" mimeType="application/x-latex" />
|
||||||
|
<mimeMap fileExtension=".less" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" />
|
||||||
|
<mimeMap fileExtension=".lpk" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" />
|
||||||
|
<mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" />
|
||||||
|
<mimeMap fileExtension=".lzh" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".m1v" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" />
|
||||||
|
<mimeMap fileExtension=".m4a" mimeType="audio/mp4" />
|
||||||
|
<mimeMap fileExtension=".m4v" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".man" mimeType="application/x-troff-man" />
|
||||||
|
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" />
|
||||||
|
<mimeMap fileExtension=".map" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" />
|
||||||
|
<mimeMap fileExtension=".mdp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".me" mimeType="application/x-troff-me" />
|
||||||
|
<mimeMap fileExtension=".mht" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".mhtml" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".mid" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".midi" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".mix" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mmf" mimeType="application/x-smaf" />
|
||||||
|
<mimeMap fileExtension=".mno" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".mny" mimeType="application/x-msmoney" />
|
||||||
|
<mimeMap fileExtension=".mov" mimeType="video/quicktime" />
|
||||||
|
<mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" />
|
||||||
|
<mimeMap fileExtension=".mp2" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".mp4v" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".mpa" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpe" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpeg" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" />
|
||||||
|
<mimeMap fileExtension=".mpv2" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" />
|
||||||
|
<mimeMap fileExtension=".msi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mso" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" />
|
||||||
|
<mimeMap fileExtension=".nc" mimeType="application/x-netcdf" />
|
||||||
|
<mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".nws" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".ocx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".oda" mimeType="application/oda" />
|
||||||
|
<mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" />
|
||||||
|
<mimeMap fileExtension=".ods" mimeType="application/oleobject" />
|
||||||
|
<mimeMap fileExtension=".oga" mimeType="audio/ogg" />
|
||||||
|
<mimeMap fileExtension=".ogg" mimeType="video/ogg" />
|
||||||
|
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
|
||||||
|
<mimeMap fileExtension=".one" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onea" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetoc" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetoc2" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetmp" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onepkg" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" />
|
||||||
|
<mimeMap fileExtension=".otf" mimeType="font/otf" />
|
||||||
|
<mimeMap fileExtension=".p10" mimeType="application/pkcs10" />
|
||||||
|
<mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" />
|
||||||
|
<mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" />
|
||||||
|
<mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" />
|
||||||
|
<mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" />
|
||||||
|
<mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" />
|
||||||
|
<mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" />
|
||||||
|
<mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" />
|
||||||
|
<mimeMap fileExtension=".pcx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pcz" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pdf" mimeType="application/pdf" />
|
||||||
|
<mimeMap fileExtension=".pfb" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pfm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" />
|
||||||
|
<mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" />
|
||||||
|
<mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" />
|
||||||
|
<mimeMap fileExtension=".pma" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pml" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".png" mimeType="image/png" />
|
||||||
|
<mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" />
|
||||||
|
<mimeMap fileExtension=".pnz" mimeType="image/png" />
|
||||||
|
<mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
|
||||||
|
<mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" />
|
||||||
|
<mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
|
||||||
|
<mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
|
||||||
|
<mimeMap fileExtension=".prf" mimeType="application/pics-rules" />
|
||||||
|
<mimeMap fileExtension=".prm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".prx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ps" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".psd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".psm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".psp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" />
|
||||||
|
<mimeMap fileExtension=".qt" mimeType="video/quicktime" />
|
||||||
|
<mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" />
|
||||||
|
<mimeMap fileExtension=".qxd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" />
|
||||||
|
<mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" />
|
||||||
|
<mimeMap fileExtension=".rar" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" />
|
||||||
|
<mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" />
|
||||||
|
<mimeMap fileExtension=".rgb" mimeType="image/x-rgb" />
|
||||||
|
<mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" />
|
||||||
|
<mimeMap fileExtension=".rmi" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".roff" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" />
|
||||||
|
<mimeMap fileExtension=".rtf" mimeType="application/rtf" />
|
||||||
|
<mimeMap fileExtension=".rtx" mimeType="text/richtext" />
|
||||||
|
<mimeMap fileExtension=".scd" mimeType="application/x-msschedule" />
|
||||||
|
<mimeMap fileExtension=".sct" mimeType="text/scriptlet" />
|
||||||
|
<mimeMap fileExtension=".sea" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" />
|
||||||
|
<mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" />
|
||||||
|
<mimeMap fileExtension=".sgml" mimeType="text/sgml" />
|
||||||
|
<mimeMap fileExtension=".sh" mimeType="application/x-sh" />
|
||||||
|
<mimeMap fileExtension=".shar" mimeType="application/x-shar" />
|
||||||
|
<mimeMap fileExtension=".sit" mimeType="application/x-stuffit" />
|
||||||
|
<mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" />
|
||||||
|
<mimeMap fileExtension=".smd" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".smi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".smx" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".smz" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".snd" mimeType="audio/basic" />
|
||||||
|
<mimeMap fileExtension=".snp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" />
|
||||||
|
<mimeMap fileExtension=".spl" mimeType="application/futuresplash" />
|
||||||
|
<mimeMap fileExtension=".spx" mimeType="audio/ogg" />
|
||||||
|
<mimeMap fileExtension=".src" mimeType="application/x-wais-source" />
|
||||||
|
<mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" />
|
||||||
|
<mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" />
|
||||||
|
<mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" />
|
||||||
|
<mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" />
|
||||||
|
<mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" />
|
||||||
|
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
|
||||||
|
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
|
||||||
|
<mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" />
|
||||||
|
<mimeMap fileExtension=".t" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".tar" mimeType="application/x-tar" />
|
||||||
|
<mimeMap fileExtension=".tcl" mimeType="application/x-tcl" />
|
||||||
|
<mimeMap fileExtension=".tex" mimeType="application/x-tex" />
|
||||||
|
<mimeMap fileExtension=".texi" mimeType="application/x-texinfo" />
|
||||||
|
<mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" />
|
||||||
|
<mimeMap fileExtension=".tgz" mimeType="application/x-compressed" />
|
||||||
|
<mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" />
|
||||||
|
<mimeMap fileExtension=".thn" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tif" mimeType="image/tiff" />
|
||||||
|
<mimeMap fileExtension=".tiff" mimeType="image/tiff" />
|
||||||
|
<mimeMap fileExtension=".toc" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tr" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".trm" mimeType="application/x-msterminal" />
|
||||||
|
<mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" />
|
||||||
|
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".txt" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".u32" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".uls" mimeType="text/iuls" />
|
||||||
|
<mimeMap fileExtension=".ustar" mimeType="application/x-ustar" />
|
||||||
|
<mimeMap fileExtension=".vbs" mimeType="text/vbscript" />
|
||||||
|
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
|
||||||
|
<mimeMap fileExtension=".vcs" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" />
|
||||||
|
<mimeMap fileExtension=".vml" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vss" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vst" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" />
|
||||||
|
<mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".wav" mimeType="audio/wav" />
|
||||||
|
<mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" />
|
||||||
|
<mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" />
|
||||||
|
<mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".webm" mimeType="video/webm" />
|
||||||
|
<mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" />
|
||||||
|
<mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" />
|
||||||
|
<mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" />
|
||||||
|
<mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" />
|
||||||
|
<mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" />
|
||||||
|
<mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" />
|
||||||
|
<mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" />
|
||||||
|
<mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" />
|
||||||
|
<mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" />
|
||||||
|
<mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" />
|
||||||
|
<mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" />
|
||||||
|
<mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" />
|
||||||
|
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
|
||||||
|
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
|
||||||
|
<mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wri" mimeType="application/x-mswrite" />
|
||||||
|
<mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".wsdl" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" />
|
||||||
|
<mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" />
|
||||||
|
<mimeMap fileExtension=".x" mimeType="application/directx" />
|
||||||
|
<mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" />
|
||||||
|
<mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" />
|
||||||
|
<mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" />
|
||||||
|
<mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" />
|
||||||
|
<mimeMap fileExtension=".xdr" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" />
|
||||||
|
<mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" />
|
||||||
|
<mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
|
||||||
|
<mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
|
||||||
|
<mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xml" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" />
|
||||||
|
<mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" />
|
||||||
|
<mimeMap fileExtension=".xsd" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsf" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsl" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xslt" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsn" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".xtp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" />
|
||||||
|
<mimeMap fileExtension=".z" mimeType="application/x-compress" />
|
||||||
|
<mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" />
|
||||||
|
</staticContent>
|
||||||
|
|
||||||
|
<tracing>
|
||||||
|
|
||||||
|
<traceFailedRequests />
|
||||||
|
|
||||||
|
<traceProviderDefinitions />
|
||||||
|
|
||||||
|
</tracing>
|
||||||
|
|
||||||
|
<urlCompression />
|
||||||
|
|
||||||
|
<validation />
|
||||||
|
|
||||||
|
</system.webServer>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildThisFileDirectory)\Build.Settings" />
|
||||||
|
<ItemGroup>
|
||||||
|
<Projects Include="$(SolutionDir)\src\AspNetCoreModuleV1\AspNetCore\AspNetCore.vcxproj" />
|
||||||
|
<Projects Include="$(SolutionDir)\src\AspNetCoreModuleV2\AspNetCore\AspNetCore.vcxproj" />
|
||||||
|
<Projects Include="$(SolutionDir)\src\AspNetCoreModuleV2\RequestHandler\RequestHandler.vcxproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="Build">
|
||||||
|
<MSBuild Targets="$(BuildTargets)"
|
||||||
|
Projects="@(Projects)"
|
||||||
|
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="Clean">
|
||||||
|
<MSBuild Targets="Clean"
|
||||||
|
Projects="@(Projects)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="Rebuild">
|
||||||
|
<MSBuild Targets="Clean;Build"
|
||||||
|
Projects="$(MSBuildProjectFile)"
|
||||||
|
Properties="BuildTargets=Rebuild;Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="Test" DependsOnTargets="Build">
|
||||||
|
<!-- once we have test project ready, we should add executions to run the test post build-->
|
||||||
|
</Target>
|
||||||
|
<Import Project="Config.Definitions.Props" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- These package versions may be overridden or updated by automation. -->
|
||||||
|
<PropertyGroup Label="Package Versions: Auto">
|
||||||
|
<InternalAspNetCoreSdkPackageVersion>2.1.3-rtm-15802</InternalAspNetCoreSdkPackageVersion>
|
||||||
|
<MicrosoftBuildFrameworkPackageVersion>15.6.82</MicrosoftBuildFrameworkPackageVersion>
|
||||||
|
<MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion>
|
||||||
|
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
|
||||||
|
<MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion>
|
||||||
|
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
||||||
|
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||||
|
<SystemBuffersPackageVersion>4.5.0</SystemBuffersPackageVersion>
|
||||||
|
<SystemIOPipelinesPackageVersion>4.5.0</SystemIOPipelinesPackageVersion>
|
||||||
|
<SystemMemoryPackageVersion>4.5.1</SystemMemoryPackageVersion>
|
||||||
|
<SystemNetWebSocketsWebSocketProtocolPackageVersion>4.5.1</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||||
|
<SystemNumericsVectorsPackageVersion>4.5.0</SystemNumericsVectorsPackageVersion>
|
||||||
|
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.5.1</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||||
|
<SystemSecurityPrincipalWindowsPackageVersion>4.5.0</SystemSecurityPrincipalWindowsPackageVersion>
|
||||||
|
<Tooling_NewtonsoftJsonPackageVersion>9.0.1</Tooling_NewtonsoftJsonPackageVersion>
|
||||||
|
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||||
|
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- This may import a generated file which may override the variables above. -->
|
||||||
|
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
|
||||||
|
|
||||||
|
<!-- These are package versions that should not be overridden or updated by automation. -->
|
||||||
|
<PropertyGroup Label="Package Versions: Pinned">
|
||||||
|
<MicrosoftAspNetCoreAllPackageVersion>2.1.2</MicrosoftAspNetCoreAllPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreAuthenticationCorePackageVersion>2.1.1</MicrosoftAspNetCoreAuthenticationCorePackageVersion>
|
||||||
|
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.1</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreHostingPackageVersion>2.1.1</MicrosoftAspNetCoreHostingPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.1.1</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreHttpOverridesPackageVersion>2.1.1</MicrosoftAspNetCoreHttpOverridesPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreHttpPackageVersion>2.1.1</MicrosoftAspNetCoreHttpPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreHttpSysSourcesPackageVersion>2.1.1</MicrosoftAspNetCoreHttpSysSourcesPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.5.1</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.2</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreTestHostPackageVersion>2.1.1</MicrosoftAspNetCoreTestHostPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0</MicrosoftAspNetCoreTestingPackageVersion>
|
||||||
|
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.1.1</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
|
||||||
|
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>2.1.1</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||||
|
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.1.1</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.1.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.1</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingDebugPackageVersion>2.1.1</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingPackageVersion>2.1.1</MicrosoftExtensionsLoggingPackageVersion>
|
||||||
|
<MicrosoftExtensionsLoggingTestingPackageVersion>2.1.1</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||||
|
<MicrosoftExtensionsOptionsPackageVersion>2.1.1</MicrosoftExtensionsOptionsPackageVersion>
|
||||||
|
<MicrosoftNetHttpHeadersPackageVersion>2.1.1</MicrosoftNetHttpHeadersPackageVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": true,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:5762/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"ANCM IIS Express": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$(IISExpressPath)",
|
||||||
|
"commandLineArgs": "$(IISExpressArguments)",
|
||||||
|
"nativeDebugging": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
|
||||||
|
"ANCM_PATH": "$(TargetDir)$(AncmPath)",
|
||||||
|
"LAUNCHER_ARGS": "$(TargetPath)",
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"LAUNCHER_PATH": "$(DotNetPath)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ANCM IIS": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$(IISPath)",
|
||||||
|
"commandLineArgs": "$(IISArguments)",
|
||||||
|
"environmentVariables": {
|
||||||
|
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
|
||||||
|
"ANCM_PATH": "$(TargetDir)$(AncmPath)",
|
||||||
|
"LAUNCHER_ARGS": "$(TargetPath)",
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"LAUNCHER_PATH": "$(DotNetPath)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<Project>
|
||||||
|
|
||||||
|
<Target Name="CreateVersionHeader" BeforeTargets="PrepareForBuild">
|
||||||
|
<ItemGroup>
|
||||||
|
<VersionHeaderContents Include="// Copyright (c) .NET Foundation. All rights reserved." />
|
||||||
|
<VersionHeaderContents Include="// Licensed under the MIT License. See LICENSE.txt in the project root for license information." />
|
||||||
|
<VersionHeaderContents Include="%0a" />
|
||||||
|
<VersionHeaderContents Include="// This file is auto-generated" />
|
||||||
|
<VersionHeaderContents Include="%0a" />
|
||||||
|
<VersionHeaderContents Include="#define FileVersion $(AspNetCoreModuleVersionMajor),$(AspNetCoreModuleVersionMinor),$(AssemblyBuild),$(AspNetCoreModuleVersionRevision)" />
|
||||||
|
<VersionHeaderContents Include="#define FileVersionStr "$(AspNetCoreModuleVersionMajor).$(AspNetCoreModuleVersionMinor).$(AssemblyBuild).$(AspNetCoreModuleVersionRevision)\0"" />
|
||||||
|
<VersionHeaderContents Include="#define ProductVersion $(AspNetCoreModuleVersionMajor),$(AspNetCoreModuleVersionMinor),$(AssemblyBuild),$(AspNetCoreModuleVersionRevision)" />
|
||||||
|
<VersionHeaderContents Include="#define ProductVersionStr "$(AspNetCoreModuleVersionMajor).$(AspNetCoreModuleVersionMinor).$(AssemblyBuild).$(AspNetCoreModuleVersionRevision)\0"" />
|
||||||
|
<VersionHeaderContents Include="#define PlatformToolset "$(PlatformToolset)\0"" />
|
||||||
|
<VersionHeaderContents Include="#define CommitHash "$(CommitHash)\0"" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FileWrites Include="version.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<WriteLinesToFile File="version.h" Lines="@(VersionHeaderContents)" OverWrite="true" WriteOnlyWhenDifferent="True" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<Project>
|
||||||
|
<Import Project="dependencies.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblySigningCertName>Microsoft</AssemblySigningCertName>
|
||||||
|
<AncmZipOutputPath>$(BuildDir)AspNetCoreModule.zip</AncmZipOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\TestSites\*.csproj" />
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\IISTestSite\*.csproj" />
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\IISIntegration.FunctionalTests\*.csproj" Condition="'$(OS)' != 'Windows_NT'" />
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\IISIntegration.IISServerFunctionalTests\*.csproj" Condition="'$(OS)' != 'Windows_NT'" />
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\AspNetCoreModule.TestSites.Standard\*.csproj" />
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\WebSocketClientEXE\*.csproj" />
|
||||||
|
<ExcludeFromTest Include="$(RepositoryRoot)test\AspNetCoreModule.Test\*.csproj" Condition="'$(OS)' != 'Windows_NT'" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- These properties are use by the automation that updates dependencies.props -->
|
||||||
|
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
|
||||||
|
<LineupPackageVersion>2.1.0-rc1-*</LineupPackageVersion>
|
||||||
|
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" />
|
||||||
|
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" />
|
||||||
|
<!-- These are for functional test projects that are only runable on windows -->
|
||||||
|
<DotNetCoreRuntime Condition="'$(OS)' == 'Windows_NT'" Include="$(MicrosoftNETCoreApp20PackageVersion)" Arch="x86" />
|
||||||
|
<DotNetCoreRuntime Condition="'$(OS)' == 'Windows_NT'" Include="$(MicrosoftNETCoreApp21PackageVersion)" Arch="x86" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
<Project>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<CompileDependsOn Condition="'$(OS)'=='Windows_NT'">BuildNativeAssets;$(CompileDependsOn)</CompileDependsOn>
|
||||||
|
<PackageDependsOn Condition="'$(OS)'=='Windows_NT'">$(PackageDependsOn);PackageNativeProjects</PackageDependsOn>
|
||||||
|
<NuGetVerifierRuleFile Condition="'$(OS)' != 'Windows_NT'">$(RepositoryRoot)NuGetPackageVerifier.xplat.json</NuGetVerifierRuleFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="BuildNativeAssets" DependsOnTargets="Prepare;GetToolsets" >
|
||||||
|
<PropertyGroup>
|
||||||
|
<BuildArgs>-p:Configuration=$(Configuration) -v:m -nologo -clp:NoSummary -p:CommitHash=$(CommitHash)</BuildArgs>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Platforms Include="Win32;x64" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Error
|
||||||
|
Text="Could not find an installation of Visual Studio with the C++ development tools."
|
||||||
|
Condition="'$(VisualStudioMSBuildx86Path)' == ''" />
|
||||||
|
|
||||||
|
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\AspNetCore.vcxproj" $(BuildArgs) -p:Platform=%(Platforms.Identity) -bl:$(LogOutputDir)native.%(Platforms.Identity).binlog"
|
||||||
|
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||||
|
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\AspNetCore.vcxproj" $(BuildArgs) -p:Platform=%(Platforms.Identity) -bl:$(LogOutputDir)native.%(Platforms.Identity).binlog"
|
||||||
|
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||||
|
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)src\AspNetCoreModuleV2\RequestHandler\RequestHandler.vcxproj" $(BuildArgs) -p:Platform=%(Platforms.Identity) -bl:$(LogOutputDir)native.%(Platforms.Identity).binlog"
|
||||||
|
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(OS)' == 'Windows_NT' ">
|
||||||
|
<ArtifactInfo Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModule.$(PackageVersion).nupkg">
|
||||||
|
<ArtifactType>NuGetPackage</ArtifactType>
|
||||||
|
<PackageId>Microsoft.AspNetCore.AspNetCoreModule</PackageId>
|
||||||
|
<Version>$(PackageVersion)</Version>
|
||||||
|
<RepositoryRoot>$(RepositoryRoot)</RepositoryRoot>
|
||||||
|
</ArtifactInfo>
|
||||||
|
<FilesToExcludeFromSigning Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModule.$(PackageVersion).nupkg" />
|
||||||
|
|
||||||
|
<ArtifactInfo Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModuleV1.$(PackageVersion).nupkg">
|
||||||
|
<ArtifactType>NuGetPackage</ArtifactType>
|
||||||
|
<PackageId>Microsoft.AspNetCore.AspNetCoreModuleV1</PackageId>
|
||||||
|
<Version>$(PackageVersion)</Version>
|
||||||
|
<RepositoryRoot>$(RepositoryRoot)</RepositoryRoot>
|
||||||
|
</ArtifactInfo>
|
||||||
|
<FilesToExcludeFromSigning Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModuleV1.$(PackageVersion).nupkg" />
|
||||||
|
|
||||||
|
<ArtifactInfo Include="$(AncmZipOutputPath)">
|
||||||
|
<ArtifactType>ZipArchive</ArtifactType>
|
||||||
|
<RepositoryRoot>$(RepositoryRoot)</RepositoryRoot>
|
||||||
|
<Category>shipoob</Category>
|
||||||
|
</ArtifactInfo>
|
||||||
|
|
||||||
|
<FilesToSign Include="$(AncmZipOutputPath)" IsContainer="true" />
|
||||||
|
<FilesToSign Include="AspNetCoreModuleV1/x64/aspnetcore.dll" Container="$(AncmZipOutputPath)" Certificate="$(AssemblySigningCertName)" />
|
||||||
|
<FilesToSign Include="AspNetCoreModuleV1/x86/aspnetcore.dll" Container="$(AncmZipOutputPath)" Certificate="$(AssemblySigningCertName)" />
|
||||||
|
<FilesToSign Include="AspNetCoreModuleV2/x64/aspnetcore.dll" Container="$(AncmZipOutputPath)" Certificate="$(AssemblySigningCertName)" />
|
||||||
|
<FilesToSign Include="AspNetCoreModuleV2/x86/aspnetcore.dll" Container="$(AncmZipOutputPath)" Certificate="$(AssemblySigningCertName)" />
|
||||||
|
<FilesToSign Include="AspNetCoreModuleV2/x64/aspnetcorerh.dll" Container="$(AncmZipOutputPath)" Certificate="$(AssemblySigningCertName)" />
|
||||||
|
<FilesToSign Include="AspNetCoreModuleV2/x86/aspnetcorerh.dll" Container="$(AncmZipOutputPath)" Certificate="$(AssemblySigningCertName)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="PackageNativeProjects">
|
||||||
|
<PackNuspec NuspecPath="$(MSBuildThisFileDirectory)..\nuget\AspNetCoreV1.nuspec"
|
||||||
|
DestinationFolder="$(BuildDir)"
|
||||||
|
Properties="version=$(PackageVersion);Configuration=$(Configuration)"
|
||||||
|
Overwrite="true"
|
||||||
|
BasePath="$(RepositoryRoot)" />
|
||||||
|
|
||||||
|
<PackNuspec NuspecPath="$(MSBuildThisFileDirectory)..\nuget\AspNetCoreV2.nuspec"
|
||||||
|
DestinationFolder="$(BuildDir)"
|
||||||
|
Properties="version=$(PackageVersion);Configuration=$(Configuration)"
|
||||||
|
Overwrite="true"
|
||||||
|
BasePath="$(RepositoryRoot)" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- x64 -->
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\x64\aspnetcore.dll" Link="AspNetCoreModuleV1\x64\aspnetcore.dll" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\x64\aspnetcore.pdb" Link="AspNetCoreModuleV1\x64\aspnetcore.pdb" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\x64\aspnetcore.dll" Link="AspNetCoreModuleV2\x64\aspnetcore.dll" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\x64\aspnetcore.pdb" Link="AspNetCoreModuleV2\x64\aspnetcore.pdb" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\RequestHandler\bin\$(Configuration)\x64\aspnetcorerh.dll" Link="AspNetCoreModuleV2\x64\aspnetcorerh.dll" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\RequestHandler\bin\$(Configuration)\x64\aspnetcorerh.pdb" Link="AspNetCoreModuleV2\x64\aspnetcorerh.pdb" />
|
||||||
|
<!-- x86 -->
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\Win32\aspnetcore.dll" Link="AspNetCoreModuleV1\x86\aspnetcore.dll" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\Win32\aspnetcore.pdb" Link="AspNetCoreModuleV1\x86\aspnetcore.pdb" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\Win32\aspnetcore.dll" Link="AspNetCoreModuleV2\x86\aspnetcore.dll" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\Win32\aspnetcore.pdb" Link="AspNetCoreModuleV2\x86\aspnetcore.pdb" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\RequestHandler\bin\$(Configuration)\Win32\aspnetcorerh.dll" Link="AspNetCoreModuleV2\x86\aspnetcorerh.dll" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\RequestHandler\bin\$(Configuration)\Win32\aspnetcorerh.pdb" Link="AspNetCoreModuleV2\x86\aspnetcorerh.pdb" />
|
||||||
|
<!-- Schema-->
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\x64\aspnetcore_schema.xml" Link="AspNetCoreModuleV1\aspnetcore_schema.xml" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\x64\aspnetcore_schema.xml" Link="AspNetCoreModuleV2\aspnetcore_schema.xml" />
|
||||||
|
<AncmFiles Include="$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\x64\ancm.mof" Link="AspNetCoreModuleV2\ancm.mof" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ZipArchive File="$(AncmZipOutputPath)"
|
||||||
|
Overwrite="true"
|
||||||
|
SourceFiles="@(AncmFiles)"
|
||||||
|
WorkingDirectory="$(RepositoryRoot)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<Project>
|
||||||
|
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
||||||
|
|
||||||
|
<PropertyGroup Label="RestoreSources">
|
||||||
|
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
|
||||||
|
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
|
||||||
|
$(RestoreSources);
|
||||||
|
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
|
||||||
|
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
|
||||||
|
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||||
|
</RestoreSources>
|
||||||
|
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
||||||
|
$(RestoreSources);
|
||||||
|
https://api.nuget.org/v3/index.json;
|
||||||
|
</RestoreSources>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
<Project>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<RuntimeIdentifiers>win7-x64;win7-x86</RuntimeIdentifiers>
|
||||||
|
<Platforms>x64;x86</Platforms>
|
||||||
|
<IISExpressAppHostConfig>$(MSBuildThisFileDirectory)applicationhost.config</IISExpressAppHostConfig>
|
||||||
|
<IISAppHostConfig>$(MSBuildThisFileDirectory)applicationhost.iis.config</IISAppHostConfig>
|
||||||
|
<NativePlatform Condition="'$(Platform)' == 'AnyCPU'">x64</NativePlatform>
|
||||||
|
<NativePlatform Condition="'$(NativePlatform)' == ''">$(Platform)</NativePlatform>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(NativePlatform)' == 'x86'">
|
||||||
|
<IISExpressPath>$(MSBuildProgramFiles32)\IIS Express\iisexpress.exe</IISExpressPath>
|
||||||
|
<IISPath>$(SystemRoot)\SysWOW64\inetsrv\w3wp.exe</IISPath>
|
||||||
|
<NativeFolder>Win32</NativeFolder>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(NativePlatform)' == 'x64'">
|
||||||
|
<IISExpressPath>$(ProgramW6432)\IIS Express\iisexpress.exe</IISExpressPath>
|
||||||
|
<IISPath>$(SystemRoot)\System32\inetsrv\w3wp.exe</IISPath>
|
||||||
|
<NativeFolder>x64</NativeFolder>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- For standalone publish, all dlls are flattened to the same folder.
|
||||||
|
Set the base path to the request handler
|
||||||
|
-->
|
||||||
|
<BasePathForRequestHandler Condition="'$(RuntimeIdentifier)' == ''">$(NativePlatform)\</BasePathForRequestHandler>
|
||||||
|
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition="'$(OS)' == 'Windows_NT' AND ('$(ANCMVersion)' == 'V2' Or '$(ANCMVersion)' == '')">
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)..\src\AspNetCoreModuleV2\RequestHandler\bin\$(Configuration)\$(NativeFolder)\aspnetcorerh.dll" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="$(BasePathForRequestHandler)%(FileName)%(Extension)" />
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)..\src\AspNetCoreModuleV2\RequestHandler\bin\$(Configuration)\$(NativeFolder)\aspnetcorerh.pdb" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="$(BasePathForRequestHandler)%(FileName)%(Extension)" />
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)..\src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\$(NativeFolder)\aspnetcore.dll" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="$(NativePlatform)\%(FileName)%(Extension)" />
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)..\src\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\$(NativeFolder)\aspnetcore.pdb" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="$(NativePlatform)\%(FileName)%(Extension)" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(OS)' == 'Windows_NT' AND '$(ANCMVersion)' == 'V1'">
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)..\src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\$(NativeFolder)\aspnetcore.dll" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="$(NativePlatform)\%(FileName)%(Extension)" />
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)..\src\AspNetCoreModuleV1\AspNetCore\bin\$(Configuration)\$(NativeFolder)\aspnetcore.pdb" CopyToOutputDirectory="PreserveNewest" Visible="true" Link="$(NativePlatform)\%(FileName)%(Extension)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<IISExpressArguments>/config:"$(IISExpressAppHostConfig)"</IISExpressArguments>
|
||||||
|
<IISArguments>-h "$(IISAppHostConfig)"</IISArguments>
|
||||||
|
|
||||||
|
<AncmPath>$(NativePlatform)\aspnetcore.dll</AncmPath>
|
||||||
|
<AncmRHPath>$(NativePlatform)\aspnetcorerh.dll</AncmRHPath>
|
||||||
|
<DotNetPath>$(userprofile)\.dotnet\$(NativePlatform)\dotnet.exe</DotNetPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyLaunchSettings" AfterTargets="CoreBuild">
|
||||||
|
<!-- This would always override launch settings files in test projects by the default one -->
|
||||||
|
<Copy SourceFiles="$(MSBuildThisFileDirectory)launchSettings.json" DestinationFolder="$(MSBuildProjectDirectory)\Properties" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- Deps file injection-->
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="$(MSBuildThisFileDirectory)..\test\TestTasks\TestTasks.csproj">
|
||||||
|
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<Target Name="PrepareInjectionApp" Condition="'$(ANCMVersion)' == 'V2' Or '$(ANCMVersion)' == ''">
|
||||||
|
<PropertyGroup>
|
||||||
|
<InjectDepsAssembly>$(MSBuildThisFileDirectory)..\test\TestTasks\bin\$(Configuration)\$(TargetFramework)\TestTasks</InjectDepsAssembly>
|
||||||
|
|
||||||
|
<InjectDepsApp Condition="'$(TargetFramework)' == 'net461'">$(InjectDepsAssembly)</InjectDepsApp>
|
||||||
|
<InjectDepsArguments>"win7-$(NativePlatform)" "$(AncmRHPath)"</InjectDepsArguments>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(TargetFramework)' == 'net461'">
|
||||||
|
<InjectDepsAssembly>$(InjectDepsAssembly).exe</InjectDepsAssembly>
|
||||||
|
<InjectDepsApp>$(InjectDepsAssembly)</InjectDepsApp>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(TargetFramework)' != 'net461'">
|
||||||
|
<InjectDepsAssembly>$(InjectDepsAssembly).dll</InjectDepsAssembly>
|
||||||
|
<InjectDepsApp>dotnet</InjectDepsApp>
|
||||||
|
<InjectDepsArguments>$(InjectDepsAssembly) $(InjectDepsArguments)</InjectDepsArguments>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="InjectRequestHandler" AfterTargets="GenerateBuildDependencyFile" DependsOnTargets="PrepareInjectionApp" Condition="'$(ANCMVersion)' == 'V2' Or '$(ANCMVersion)' == ''">
|
||||||
|
<Exec Command="$(InjectDepsApp) $(InjectDepsArguments) "$(ProjectDepsFilePath)"" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="InjectRequestHandlerOnPublish" AfterTargets="GeneratePublishDependencyFile" DependsOnTargets="PrepareInjectionApp" Condition="'$(ANCMVersion)' == 'V2' Or '$(ANCMVersion)' == ''">
|
||||||
|
<Exec Command="$(InjectDepsApp) $(InjectDepsArguments) "$(PublishDepsFilePath)"" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json",
|
||||||
|
"channel": "release/2.1",
|
||||||
|
"toolsets": {
|
||||||
|
"visualstudio": {
|
||||||
|
"required": ["Windows"],
|
||||||
|
"includePrerelease": true,
|
||||||
|
"minVersion": "15.0.26730.03",
|
||||||
|
"requiredWorkloads": [
|
||||||
|
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
||||||
|
"Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Win81",
|
||||||
|
"Microsoft.VisualStudio.Component.VC.ATL",
|
||||||
|
"Microsoft.VisualStudio.Component.Windows10SDK.15063.Desktop"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Microsoft.AspNetCore.AspNetCoreModuleV1</id>
|
||||||
|
<title>Microsoft ASP.NET Core Module</title>
|
||||||
|
<version>$VERSION$</version>
|
||||||
|
<authors>Microsoft</authors>
|
||||||
|
<owners>Microsoft</owners>
|
||||||
|
<licenseUrl>https://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
||||||
|
<copyright>© .NET Foundation. All rights reserved.</copyright>
|
||||||
|
<projectUrl>https://www.asp.net/</projectUrl>
|
||||||
|
<iconUrl>https://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
|
||||||
|
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||||
|
<description>ASP.NET Core Module</description>
|
||||||
|
<language>en-US</language>
|
||||||
|
<tags>Microsoft.AspNetCore.AspNetCoreModuleV1</tags>
|
||||||
|
<contentFiles>
|
||||||
|
<files include="any/any/*/*.dll" buildAction="None" copyToOutput="true" flatten="false" />
|
||||||
|
</contentFiles>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="src\AspNetCoreModuleV1\AspNetCore\bin\$Configuration$\Win32\aspnetcore.dll" target="contentFiles\any\any\x86\aspnetcore.dll" />
|
||||||
|
<file src="src\AspNetCoreModuleV1\AspNetCore\bin\$Configuration$\x64\aspnetcore.dll" target="contentFiles\any\any\x64\aspnetcore.dll" />
|
||||||
|
<file src="src\AspNetCoreModuleV1\AspNetCore\bin\$Configuration$\x64\*.xml"/>
|
||||||
|
<file src="tools\installancm.ps1"/>
|
||||||
|
<file src="LICENSE.txt"/>
|
||||||
|
<file src="nuget\Microsoft.AspNetCore.AspNetCoreModule.props" target="build\" />
|
||||||
|
</files>
|
||||||
|
</package>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Microsoft.AspNetCore.AspNetCoreModule</id> <!--TODO make this package version V2 when possible -->
|
||||||
|
<title>Microsoft ASP.NET Core Module</title>
|
||||||
|
<version>$VERSION$</version>
|
||||||
|
<authors>Microsoft</authors>
|
||||||
|
<owners>Microsoft</owners>
|
||||||
|
<licenseUrl>https://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
||||||
|
<copyright>© .NET Foundation. All rights reserved.</copyright>
|
||||||
|
<projectUrl>https://www.asp.net/</projectUrl>
|
||||||
|
<iconUrl>https://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
|
||||||
|
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||||
|
<description>ASP.NET Core Module</description>
|
||||||
|
<language>en-US</language>
|
||||||
|
<tags>Microsoft.AspNetCore.AspNetCoreModule</tags>
|
||||||
|
<contentFiles>
|
||||||
|
<files include="any/any/*/*.dll" buildAction="None" copyToOutput="true" flatten="false" />
|
||||||
|
</contentFiles>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="src\AspNetCoreModuleV2\AspNetCore\bin\$Configuration$\Win32\aspnetcore.dll" target="contentFiles\any\any\x86\aspnetcore.dll" />
|
||||||
|
<file src="src\AspNetCoreModuleV2\AspNetCore\bin\$Configuration$\x64\aspnetcore.dll" target="contentFiles\any\any\x64\aspnetcore.dll" />
|
||||||
|
<file src="src\AspNetCoreModuleV2\RequestHandler\bin\$Configuration$\Win32\aspnetcorerh.dll" target="contentFiles\any\any\x86\aspnetcorerh.dll" />
|
||||||
|
<file src="src\AspNetCoreModuleV2\RequestHandler\bin\$Configuration$\x64\aspnetcorerh.dll" target="contentFiles\any\any\x64\aspnetcorerh.dll" />
|
||||||
|
<file src="src\AspNetCoreModuleV2\AspNetCore\bin\$Configuration$\x64\*.xml"/>
|
||||||
|
<file src="tools\installancm.ps1"/>
|
||||||
|
<file src="LICENSE.txt"/>
|
||||||
|
<file src="nuget\Microsoft.AspNetCore.AspNetCoreModule.props" target="build\" />
|
||||||
|
</files>
|
||||||
|
</package>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<Project>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AspNetCoreModuleX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcore.dll</AspNetCoreModuleX64Location>
|
||||||
|
<AspNetCoreModuleX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcore.dll</AspNetCoreModuleX86Location>
|
||||||
|
<RequestHandlerX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcorerh.dll</RequestHandlerX64Location>
|
||||||
|
<RequestHandlerX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcorerh.dll</RequestHandlerX86Location>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:25334/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Server.IISIntegration"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IISSample": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.Server.IISIntegration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace IISSample
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// These two middleware are registered via an IStartupFilter in UseIISIntegration but you can configure them here.
|
||||||
|
services.Configure<IISOptions>(options =>
|
||||||
|
{
|
||||||
|
options.AuthenticationDisplayName = "Windows Auth";
|
||||||
|
});
|
||||||
|
services.Configure<ForwardedHeadersOptions>(options =>
|
||||||
|
{
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory, IAuthenticationSchemeProvider authSchemeProvider)
|
||||||
|
{
|
||||||
|
var logger = loggerfactory.CreateLogger("Requests");
|
||||||
|
|
||||||
|
app.Run(async (context) =>
|
||||||
|
{
|
||||||
|
logger.LogDebug("Received request: " + context.Request.Method + " " + context.Request.Path);
|
||||||
|
|
||||||
|
context.Response.ContentType = "text/plain";
|
||||||
|
await context.Response.WriteAsync("Hello World - " + DateTimeOffset.Now + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Address:" + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Scheme: " + context.Request.Scheme + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Host: " + context.Request.Headers["Host"] + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Path: " + context.Request.Path.Value + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Query: " + context.Request.QueryString.Value + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Connection:" + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine);
|
||||||
|
var scheme = await authSchemeProvider.GetSchemeAsync(IISDefaults.AuthenticationScheme);
|
||||||
|
await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Headers:" + Environment.NewLine);
|
||||||
|
foreach (var header in context.Request.Headers)
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync(header.Key + ": " + header.Value + Environment.NewLine);
|
||||||
|
}
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Environment Variables:" + Environment.NewLine);
|
||||||
|
var vars = Environment.GetEnvironmentVariables();
|
||||||
|
foreach (var key in vars.Keys.Cast<string>().OrderBy(key => key, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var value = vars[key];
|
||||||
|
await context.Response.WriteAsync(key + ": " + value + Environment.NewLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
if (context.Features.Get<IHttpUpgradeFeature>() != null)
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("Websocket feature is enabled.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("Websocket feature is disabled.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var host = new WebHostBuilder()
|
||||||
|
.ConfigureLogging((_, factory) =>
|
||||||
|
{
|
||||||
|
factory.AddConsole();
|
||||||
|
factory.AddFilter("Console", level => level >= LogLevel.Debug);
|
||||||
|
})
|
||||||
|
.UseKestrel()
|
||||||
|
.UseStartup<Startup>()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
host.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<!-- Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380 -->
|
||||||
|
|
||||||
|
<system.webServer>
|
||||||
|
<handlers>
|
||||||
|
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
|
||||||
|
</handlers>
|
||||||
|
<!-- This set of attributes are used for launching the sample using IISExpress via Visual Studio tooling -->
|
||||||
|
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
|
||||||
|
|
||||||
|
<!-- This set of attributes are used for launching the sample for full CLR (net46) without Visual Studio tooling
|
||||||
|
<aspNetCore processPath=".\IISSample.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- This set of attributes are used for launching the sample for Core CLR (netcoreapp2.0) without Visual Studio tooling
|
||||||
|
<aspNetCore processPath="dotnet" arguments=".\IISSample.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
|
||||||
|
-->
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<Import Project="..\..\build\testsite.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AspNetCoreModuleHostingModel>inprocess</AspNetCoreModuleHostingModel>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": true,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:5762/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"ANCM IIS Express": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$(IISExpressPath)",
|
||||||
|
"commandLineArgs": "$(IISExpressArguments)",
|
||||||
|
"nativeDebugging": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
|
||||||
|
"ANCM_PATH": "$(TargetDir)$(AncmPath)",
|
||||||
|
"LAUNCHER_ARGS": "$(TargetPath)",
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"LAUNCHER_PATH": "$(DotNetPath)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ANCM IIS": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$(IISPath)",
|
||||||
|
"commandLineArgs": "$(IISArguments)",
|
||||||
|
"environmentVariables": {
|
||||||
|
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
|
||||||
|
"ANCM_PATH": "$(TargetDir)$(AncmPath)",
|
||||||
|
"LAUNCHER_ARGS": "$(TargetPath)",
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"LAUNCHER_PATH": "$(DotNetPath)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.Server.IISIntegration;
|
||||||
|
|
||||||
|
namespace NativeIISSample
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAuthenticationSchemeProvider authSchemeProvider)
|
||||||
|
{
|
||||||
|
app.Run(async (context) =>
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "text/plain";
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Hello World - " + DateTimeOffset.Now + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Address:" + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Scheme: " + context.Request.Scheme + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Host: " + context.Request.Headers["Host"] + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Path: " + context.Request.Path.Value + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("Query: " + context.Request.QueryString.Value + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Connection:" + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + Environment.NewLine);
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine);
|
||||||
|
var scheme = await authSchemeProvider.GetSchemeAsync(IISDefaults.AuthenticationScheme);
|
||||||
|
await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Headers:" + Environment.NewLine);
|
||||||
|
foreach (var header in context.Request.Headers)
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync(header.Key + ": " + header.Value + Environment.NewLine);
|
||||||
|
}
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync("Environment Variables:" + Environment.NewLine);
|
||||||
|
var vars = Environment.GetEnvironmentVariables();
|
||||||
|
foreach (var key in vars.Keys.Cast<string>().OrderBy(key => key, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var value = vars[key];
|
||||||
|
await context.Response.WriteAsync(key + ": " + value + Environment.NewLine);
|
||||||
|
}
|
||||||
|
await context.Response.WriteAsync(Environment.NewLine);
|
||||||
|
|
||||||
|
// accessing IIS server variables
|
||||||
|
await context.Response.WriteAsync("Server Variables:" + Environment.NewLine);
|
||||||
|
|
||||||
|
if (context.Features.Get<IHttpUpgradeFeature>() != null)
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("Websocket feature is enabled.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("Websocket feature is disabled.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var host = new WebHostBuilder()
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseStartup<Startup>()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
host.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<configuration>
|
||||||
|
<system.webServer>
|
||||||
|
<handlers>
|
||||||
|
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||||
|
</handlers>
|
||||||
|
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="false" hostingModel="inprocess"/>
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\..\..\Build\Build.Settings" />
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{439824F9-1455-4CC4-BD79-B44FA0A16552}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>AspNetCoreModule</RootNamespace>
|
||||||
|
<ProjectName>AspNetCore</ProjectName>
|
||||||
|
<TargetName>aspnetcore</TargetName>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;inc\</AdditionalIncludeDirectories>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||||
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>8Bytes</StructMemberAlignment>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<OmitDefaultLibName>true</OmitDefaultLibName>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ahadmin.lib;rpcrt4.lib;winhttp.lib;pdh.lib;ws2_32.lib;wbemuuid.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
|
<ResourceCompile>
|
||||||
|
<AdditionalIncludeDirectories>..\Commonlib</AdditionalIncludeDirectories>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;inc\</AdditionalIncludeDirectories>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||||
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>8Bytes</StructMemberAlignment>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<OmitDefaultLibName>true</OmitDefaultLibName>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ahadmin.lib;rpcrt4.lib;winhttp.lib;pdh.lib;ws2_32.lib;wbemuuid.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
|
<ResourceCompile>
|
||||||
|
<AdditionalIncludeDirectories>..\Commonlib</AdditionalIncludeDirectories>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;inc\</AdditionalIncludeDirectories>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||||
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>8Bytes</StructMemberAlignment>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<OmitDefaultLibName>true</OmitDefaultLibName>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
|
||||||
|
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;winhttp.lib;odbc32.lib;ws2_32.lib;odbccp32.lib;wbemuuid.lib;iphlpapi.lib;pdh.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<ResourceCompile>
|
||||||
|
<AdditionalIncludeDirectories>..\Commonlib</AdditionalIncludeDirectories>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;inc\</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||||
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
|
<StructMemberAlignment>8Bytes</StructMemberAlignment>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<OmitDefaultLibName>true</OmitDefaultLibName>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
|
||||||
|
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;rpcrt4.lib;winhttp.lib;pdh.lib;ws2_32.lib;wbemuuid.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<ResourceCompile>
|
||||||
|
<AdditionalIncludeDirectories>..\Commonlib</AdditionalIncludeDirectories>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Source.def" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="aspnetcore_schema.xml">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Xml Include="aspnetcore_schema.xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\application.cxx" />
|
||||||
|
<ClCompile Include="src\applicationmanager.cxx" />
|
||||||
|
<ClCompile Include="src\aspnetcoreconfig.cxx" />
|
||||||
|
<ClCompile Include="src\filewatcher.cxx" />
|
||||||
|
<ClCompile Include="src\forwarderconnection.cxx" />
|
||||||
|
<ClCompile Include="src\forwardinghandler.cxx" />
|
||||||
|
<ClCompile Include="src\main.cxx" />
|
||||||
|
<ClCompile Include="src\path.cxx" />
|
||||||
|
<ClCompile Include="src\processmanager.cxx" />
|
||||||
|
<ClCompile Include="src\protocolconfig.cxx" />
|
||||||
|
<ClCompile Include="src\proxymodule.cxx" />
|
||||||
|
<ClCompile Include="src\responseheaderhash.cxx" />
|
||||||
|
<ClCompile Include="src\serverprocess.cxx" />
|
||||||
|
<ClCompile Include="src\websockethandler.cxx" />
|
||||||
|
<ClCompile Include="src\winhttphelper.cxx" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Inc\application.h" />
|
||||||
|
<ClInclude Include="Inc\applicationmanager.h" />
|
||||||
|
<ClInclude Include="Inc\aspnetcoreconfig.h" />
|
||||||
|
<ClInclude Include="Inc\debugutil.h" />
|
||||||
|
<ClInclude Include="Inc\environmentvariablehash.h" />
|
||||||
|
<ClInclude Include="Inc\filewatcher.h" />
|
||||||
|
<ClInclude Include="Inc\forwarderconnection.h" />
|
||||||
|
<ClInclude Include="Inc\forwardinghandler.h" />
|
||||||
|
<ClInclude Include="Inc\path.h" />
|
||||||
|
<ClInclude Include="Inc\processmanager.h" />
|
||||||
|
<ClInclude Include="Inc\protocolconfig.h" />
|
||||||
|
<ClInclude Include="Inc\proxymodule.h" />
|
||||||
|
<ClInclude Include="Inc\resource.h" />
|
||||||
|
<ClInclude Include="Inc\responseheaderhash.h" />
|
||||||
|
<ClInclude Include="Inc\serverprocess.h" />
|
||||||
|
<ClInclude Include="Inc\sttimer.h" />
|
||||||
|
<ClInclude Include="Inc\websockethandler.h" />
|
||||||
|
<ClInclude Include="Inc\winhttphelper.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include="src\precomp.hxx" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="aspnetcoremodule.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
|
||||||
|
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\..\..\build\native.targets" />
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<CustomBuild Include="aspnetcore_msg.mc">
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
<Command>mc %(FullPath)</Command>
|
||||||
|
<Message>Compiling Event Messages ...</Message>
|
||||||
|
<Outputs>%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//
|
||||||
|
// The key used for hash-table lookups, consists of the port on which the http process is created.
|
||||||
|
//
|
||||||
|
class APPLICATION_KEY
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
APPLICATION_KEY(
|
||||||
|
VOID
|
||||||
|
) : INLINE_STRU_INIT(m_struKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
_In_ LPCWSTR pszKey
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_struKey.Copy(pszKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
GetIsEqual(
|
||||||
|
const APPLICATION_KEY * key2
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return m_struKey.Equals(key2->m_struKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CalcKeyHash() const
|
||||||
|
{
|
||||||
|
return Hash(m_struKey.QueryStr());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
INLINE_STRU(m_struKey, 1024);
|
||||||
|
};
|
||||||
|
|
||||||
|
class APP_OFFLINE_HTM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
APP_OFFLINE_HTM(LPCWSTR pszPath) : m_cRefs(1)
|
||||||
|
{
|
||||||
|
m_Path.Copy( pszPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceAppOfflineHtm() const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceAppOfflineHtm() const
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
Load(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL fResult = TRUE;
|
||||||
|
LARGE_INTEGER li = {0};
|
||||||
|
CHAR *pszBuff = NULL;
|
||||||
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
handle = CreateFile( m_Path.QueryStr(),
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if( handle == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
if ( GetLastError() == ERROR_FILE_NOT_FOUND )
|
||||||
|
{
|
||||||
|
fResult = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This Load() member function is supposed be called only when the change notification event of file creation or file modification happens.
|
||||||
|
// If file is currenlty locked exclusively by other processes, we might get INVALID_HANDLE_VALUE even though the file exists. In that case, we should return TRUE here.
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!GetFileSizeEx( handle, &li ))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( li.HighPart != 0 )
|
||||||
|
{
|
||||||
|
// > 4gb file size not supported
|
||||||
|
// todo: log a warning at event log
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
|
||||||
|
if(li.LowPart > 0)
|
||||||
|
{
|
||||||
|
pszBuff = new CHAR[ li.LowPart + 1 ];
|
||||||
|
|
||||||
|
if( ReadFile( handle, pszBuff, li.LowPart, &bytesRead, NULL ) )
|
||||||
|
{
|
||||||
|
m_Contents.Copy( pszBuff, bytesRead );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if( handle != INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
handle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pszBuff != NULL )
|
||||||
|
{
|
||||||
|
delete[] pszBuff;
|
||||||
|
pszBuff = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
STRA m_Contents;
|
||||||
|
STRU m_Path;
|
||||||
|
};
|
||||||
|
|
||||||
|
class APPLICATION_MANAGER;
|
||||||
|
|
||||||
|
class APPLICATION
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
APPLICATION() : m_pProcessManager(NULL), m_pApplicationManager(NULL), m_cRefs(1),
|
||||||
|
m_fAppOfflineFound(FALSE), m_pAppOfflineHtm(NULL), m_pFileWatcherEntry(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
APPLICATION_KEY *
|
||||||
|
QueryApplicationKey()
|
||||||
|
{
|
||||||
|
return &m_applicationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetAppOfflineFound(
|
||||||
|
BOOL found
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_fAppOfflineFound = found;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
AppOfflineFound()
|
||||||
|
{
|
||||||
|
return m_fAppOfflineFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetProcess(
|
||||||
|
_In_ IHttpContext *context,
|
||||||
|
_In_ ASPNETCORE_CONFIG *pConfig,
|
||||||
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pProcessManager->GetProcess( context, pConfig, ppServerProcess );
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Recycle()
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
m_pProcessManager->ShutdownAllProcesses();
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceApplication() const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceApplication() const
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_OFFLINE_HTM* QueryAppOfflineHtm()
|
||||||
|
{
|
||||||
|
return m_pAppOfflineHtm;
|
||||||
|
}
|
||||||
|
|
||||||
|
~APPLICATION();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
_In_ APPLICATION_MANAGER *pApplicationManager,
|
||||||
|
_In_ LPCWSTR pszApplication,
|
||||||
|
_In_ LPCWSTR pszPhysicalPath
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
UpdateAppOfflineFileHandle();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
StartMonitoringAppOffline();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
STRU m_strAppPhysicalPath;
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
APPLICATION_KEY m_applicationKey;
|
||||||
|
PROCESS_MANAGER* m_pProcessManager;
|
||||||
|
APPLICATION_MANAGER *m_pApplicationManager;
|
||||||
|
BOOL m_fAppOfflineFound;
|
||||||
|
APP_OFFLINE_HTM *m_pAppOfflineHtm;
|
||||||
|
FILE_WATCHER_ENTRY *m_pFileWatcherEntry;
|
||||||
|
};
|
||||||
|
|
||||||
|
class APPLICATION_HASH :
|
||||||
|
public HASH_TABLE<APPLICATION, APPLICATION_KEY *>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
APPLICATION_HASH()
|
||||||
|
{}
|
||||||
|
|
||||||
|
APPLICATION_KEY *
|
||||||
|
ExtractKey(
|
||||||
|
APPLICATION *pApplication
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return pApplication->QueryApplicationKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
CalcKeyHash(
|
||||||
|
APPLICATION_KEY *key
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return key->CalcKeyHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
EqualKeys(
|
||||||
|
APPLICATION_KEY *key1,
|
||||||
|
APPLICATION_KEY *key2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return key1->GetIsEqual(key2);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceRecord(
|
||||||
|
APPLICATION *pApplication
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pApplication->ReferenceApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceRecord(
|
||||||
|
APPLICATION *pApplication
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pApplication->DereferenceApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
APPLICATION_HASH(const APPLICATION_HASH &);
|
||||||
|
void operator=(const APPLICATION_HASH &);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define DEFAULT_HASH_BUCKETS 293
|
||||||
|
|
||||||
|
class APPLICATION_MANAGER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static
|
||||||
|
APPLICATION_MANAGER*
|
||||||
|
GetInstance(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if( sm_pApplicationManager == NULL )
|
||||||
|
{
|
||||||
|
sm_pApplicationManager = new APPLICATION_MANAGER();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sm_pApplicationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
Cleanup(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(sm_pApplicationManager != NULL)
|
||||||
|
{
|
||||||
|
delete sm_pApplicationManager;
|
||||||
|
sm_pApplicationManager = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetApplication(
|
||||||
|
_In_ IHttpContext* pContext,
|
||||||
|
_Out_ APPLICATION ** ppApplication
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
RecycleApplication(
|
||||||
|
_In_ LPCWSTR pszApplication
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Get502ErrorPage(
|
||||||
|
_Out_ HTTP_DATA_CHUNK** ppErrorPage
|
||||||
|
);
|
||||||
|
|
||||||
|
~APPLICATION_MANAGER()
|
||||||
|
{
|
||||||
|
if(m_pApplicationHash != NULL)
|
||||||
|
{
|
||||||
|
m_pApplicationHash->Clear();
|
||||||
|
delete m_pApplicationHash;
|
||||||
|
m_pApplicationHash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_pFileWatcher!= NULL )
|
||||||
|
{
|
||||||
|
delete m_pFileWatcher;
|
||||||
|
m_pFileWatcher = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_pHttp502ErrorPage != NULL)
|
||||||
|
{
|
||||||
|
delete m_pHttp502ErrorPage;
|
||||||
|
m_pHttp502ErrorPage = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_WATCHER*
|
||||||
|
GetFileWatcher()
|
||||||
|
{
|
||||||
|
return m_pFileWatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Initialize()
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if(m_pApplicationHash == NULL)
|
||||||
|
{
|
||||||
|
m_pApplicationHash = new APPLICATION_HASH();
|
||||||
|
if(m_pApplicationHash == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_pApplicationHash->Initialize(DEFAULT_HASH_BUCKETS);
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_pFileWatcher == NULL )
|
||||||
|
{
|
||||||
|
m_pFileWatcher = new FILE_WATCHER;
|
||||||
|
if(m_pFileWatcher == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pFileWatcher->Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload
|
||||||
|
//
|
||||||
|
APPLICATION_MANAGER() : m_pApplicationHash(NULL), m_pFileWatcher(NULL), m_pHttp502ErrorPage(NULL), m_pstrErrorInfo(
|
||||||
|
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> \
|
||||||
|
<html xmlns=\"http://www.w3.org/1999/xhtml\"> \
|
||||||
|
<head> \
|
||||||
|
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" /> \
|
||||||
|
<title> IIS 502.5 Error </title><style type=\"text/css\"></style></head> \
|
||||||
|
<body> <div id = \"content\"> \
|
||||||
|
<div class = \"content-container\"><h3> HTTP Error 502.5 - Process Failure </h3></div> \
|
||||||
|
<div class = \"content-container\"> \
|
||||||
|
<fieldset> <h4> Common causes of this issue: </h4> \
|
||||||
|
<ul><li> The application process failed to start </li> \
|
||||||
|
<li> The application process started but then stopped </li> \
|
||||||
|
<li> The application process started but failed to listen on the configured port </li></ul></fieldset> \
|
||||||
|
</div> \
|
||||||
|
<div class = \"content-container\"> \
|
||||||
|
<fieldset><h4> Troubleshooting steps: </h4> \
|
||||||
|
<ul><li> Check the system event log for error messages </li> \
|
||||||
|
<li> Enable logging the application process' stdout messages </li> \
|
||||||
|
<li> Attach a debugger to the application process and inspect </li></ul></fieldset> \
|
||||||
|
<fieldset><h4> For more information visit: \
|
||||||
|
<a href=\"https://go.microsoft.com/fwlink/?linkid=808681\"> <cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite></a></h4> \
|
||||||
|
</fieldset> \
|
||||||
|
</div> \
|
||||||
|
</div></body></html>")
|
||||||
|
{
|
||||||
|
InitializeSRWLock(&m_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_WATCHER *m_pFileWatcher;
|
||||||
|
APPLICATION_HASH *m_pApplicationHash;
|
||||||
|
static APPLICATION_MANAGER *sm_pApplicationManager;
|
||||||
|
SRWLOCK m_srwLock;
|
||||||
|
HTTP_DATA_CHUNK *m_pHttp502ErrorPage;
|
||||||
|
LPSTR m_pstrErrorInfo;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define CS_ROOTWEB_CONFIG L"MACHINE/WEBROOT/APPHOST/"
|
||||||
|
#define CS_ROOTWEB_CONFIG_LEN _countof(CS_ROOTWEB_CONFIG)-1
|
||||||
|
#define CS_ASPNETCORE_SECTION L"system.webServer/aspNetCore"
|
||||||
|
#define CS_WINDOWS_AUTHENTICATION_SECTION L"system.webServer/security/authentication/windowsAuthentication"
|
||||||
|
#define CS_BASIC_AUTHENTICATION_SECTION L"system.webServer/security/authentication/basicAuthentication"
|
||||||
|
#define CS_ANONYMOUS_AUTHENTICATION_SECTION L"system.webServer/security/authentication/anonymousAuthentication"
|
||||||
|
#define CS_AUTHENTICATION_ENABLED L"enabled"
|
||||||
|
#define CS_ASPNETCORE_PROCESS_EXE_PATH L"processPath"
|
||||||
|
#define CS_ASPNETCORE_PROCESS_ARGUMENTS L"arguments"
|
||||||
|
#define CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT L"startupTimeLimit"
|
||||||
|
#define CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT L"shutdownTimeLimit"
|
||||||
|
#define CS_ASPNETCORE_WINHTTP_REQUEST_TIMEOUT L"requestTimeout"
|
||||||
|
#define CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE L"rapidFailsPerMinute"
|
||||||
|
#define CS_ASPNETCORE_STDOUT_LOG_ENABLED L"stdoutLogEnabled"
|
||||||
|
#define CS_ASPNETCORE_STDOUT_LOG_FILE L"stdoutLogFile"
|
||||||
|
#define CS_ASPNETCORE_ENVIRONMENT_VARIABLES L"environmentVariables"
|
||||||
|
#define CS_ASPNETCORE_ENVIRONMENT_VARIABLE L"environmentVariable"
|
||||||
|
#define CS_ASPNETCORE_ENVIRONMENT_VARIABLE_NAME L"name"
|
||||||
|
#define CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE L"value"
|
||||||
|
#define CS_ASPNETCORE_PROCESSES_PER_APPLICATION L"processesPerApplication"
|
||||||
|
#define CS_ASPNETCORE_FORWARD_WINDOWS_AUTH_TOKEN L"forwardWindowsAuthToken"
|
||||||
|
#define CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE L"disableStartUpErrorPage"
|
||||||
|
#define CS_ASPNETCORE_RECYCLE_ON_FILE_CHANGE L"recycleOnFileChange"
|
||||||
|
#define CS_ASPNETCORE_RECYCLE_ON_FILE_CHANGE_FILE L"file"
|
||||||
|
#define CS_ASPNETCORE_RECYCLE_ON_FILE_CHANGE_FILE_PATH L"path"
|
||||||
|
|
||||||
|
#define MAX_RAPID_FAILS_PER_MINUTE 100
|
||||||
|
#define MILLISECONDS_IN_ONE_SECOND 1000
|
||||||
|
#define MIN_PORT 1025
|
||||||
|
#define MAX_PORT 48000
|
||||||
|
|
||||||
|
#define HEX_TO_ASCII(c) ((CHAR)(((c) < 10) ? ((c) + '0') : ((c) + 'a' - 10)))
|
||||||
|
|
||||||
|
extern HTTP_MODULE_ID g_pModuleId;
|
||||||
|
extern IHttpServer * g_pHttpServer;
|
||||||
|
|
||||||
|
class ASPNETCORE_CONFIG : IHttpStoredContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~ASPNETCORE_CONFIG();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanupStoredContext()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
GetConfig(
|
||||||
|
_In_ IHttpContext *pHttpContext,
|
||||||
|
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
ENVIRONMENT_VAR_HASH*
|
||||||
|
QueryEnvironmentVariables(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pEnvironmentVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryRapidFailsPerMinute(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_dwRapidFailsPerMinute;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryStartupTimeLimitInMS(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_dwStartupTimeLimitInMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryShutdownTimeLimitInMS(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_dwShutdownTimeLimitInMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryProcessesPerApplication(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_dwProcessesPerApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryRequestTimeoutInMS(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_dwRequestTimeoutInMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRU*
|
||||||
|
QueryArguments(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return &m_struArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRU*
|
||||||
|
QueryApplicationPath(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return &m_struApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRU*
|
||||||
|
QueryProcessPath(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return &m_struProcessPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryStdoutLogEnabled()
|
||||||
|
{
|
||||||
|
return m_fStdoutLogEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryForwardWindowsAuthToken()
|
||||||
|
{
|
||||||
|
return m_fForwardWindowsAuthToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryWindowsAuthEnabled()
|
||||||
|
{
|
||||||
|
return m_fWindowsAuthEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryBasicAuthEnabled()
|
||||||
|
{
|
||||||
|
return m_fBasicAuthEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryAnonymousAuthEnabled()
|
||||||
|
{
|
||||||
|
return m_fAnonymousAuthEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryDisableStartUpErrorPage()
|
||||||
|
{
|
||||||
|
return m_fDisableStartUpErrorPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRU*
|
||||||
|
QueryStdoutLogFile()
|
||||||
|
{
|
||||||
|
return &m_struStdoutLogFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//
|
||||||
|
// private constructor
|
||||||
|
//
|
||||||
|
ASPNETCORE_CONFIG():
|
||||||
|
m_fStdoutLogEnabled( FALSE ),
|
||||||
|
m_pEnvironmentVariables( NULL )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Populate(
|
||||||
|
IHttpContext *pHttpContext
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD m_dwRequestTimeoutInMS;
|
||||||
|
DWORD m_dwStartupTimeLimitInMS;
|
||||||
|
DWORD m_dwShutdownTimeLimitInMS;
|
||||||
|
DWORD m_dwRapidFailsPerMinute;
|
||||||
|
DWORD m_dwProcessesPerApplication;
|
||||||
|
STRU m_struApplication;
|
||||||
|
STRU m_struArguments;
|
||||||
|
STRU m_struProcessPath;
|
||||||
|
STRU m_struStdoutLogFile;
|
||||||
|
BOOL m_fStdoutLogEnabled;
|
||||||
|
BOOL m_fForwardWindowsAuthToken;
|
||||||
|
BOOL m_fDisableStartUpErrorPage;
|
||||||
|
BOOL m_fWindowsAuthEnabled;
|
||||||
|
BOOL m_fBasicAuthEnabled;
|
||||||
|
BOOL m_fAnonymousAuthEnabled;
|
||||||
|
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ASPNETCORE_DEBUG_FLAG_INFO 0x00000001
|
||||||
|
#define ASPNETCORE_DEBUG_FLAG_WARNING 0x00000002
|
||||||
|
#define ASPNETCORE_DEBUG_FLAG_ERROR 0x00000004
|
||||||
|
|
||||||
|
extern DWORD g_dwAspNetCoreDebugFlags;
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOL
|
||||||
|
IfDebug(
|
||||||
|
DWORD dwFlag
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ( dwFlag & g_dwAspNetCoreDebugFlags );
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
DebugPrint(
|
||||||
|
DWORD dwFlag,
|
||||||
|
LPCSTR szString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
STACK_STRA (strOutput, 256);
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if ( IfDebug( dwFlag ) )
|
||||||
|
{
|
||||||
|
hr = strOutput.SafeSnprintf(
|
||||||
|
"[aspnetcore.dll] %s\r\n",
|
||||||
|
szString );
|
||||||
|
|
||||||
|
if (FAILED (hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputDebugStringA( strOutput.QueryStr() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
DebugPrintf(
|
||||||
|
DWORD dwFlag,
|
||||||
|
LPCSTR szFormat,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
STACK_STRA (strCooked,256);
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if ( IfDebug( dwFlag ) )
|
||||||
|
{
|
||||||
|
va_start( args, szFormat );
|
||||||
|
|
||||||
|
hr = strCooked.SafeVsnprintf(szFormat, args );
|
||||||
|
|
||||||
|
va_end( args );
|
||||||
|
|
||||||
|
if (FAILED (hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugPrint( dwFlag, strCooked.QueryStr() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//
|
||||||
|
// The key used for hash-table lookups, consists of the port on which the http process is created.
|
||||||
|
//
|
||||||
|
|
||||||
|
class ENVIRONMENT_VAR_ENTRY
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ENVIRONMENT_VAR_ENTRY():
|
||||||
|
_cRefs(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
PCWSTR pszName,
|
||||||
|
PCWSTR pszValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
if (FAILED(hr = _strName.Copy(pszName)) ||
|
||||||
|
FAILED(hr = _strValue.Copy(pszValue)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Reference() const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Dereference() const
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement(&_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PWSTR const
|
||||||
|
QueryName()
|
||||||
|
{
|
||||||
|
return _strName.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
PWSTR const
|
||||||
|
QueryValue()
|
||||||
|
{
|
||||||
|
return _strValue.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~ENVIRONMENT_VAR_ENTRY()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
STRU _strName;
|
||||||
|
STRU _strValue;
|
||||||
|
mutable LONG _cRefs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ENVIRONMENT_VAR_HASH : public HASH_TABLE<ENVIRONMENT_VAR_ENTRY, PWSTR>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ENVIRONMENT_VAR_HASH()
|
||||||
|
{}
|
||||||
|
|
||||||
|
PWSTR
|
||||||
|
ExtractKey(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return pEntry->QueryName();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
CalcKeyHash(
|
||||||
|
PWSTR pszName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return HashStringNoCase(pszName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
EqualKeys(
|
||||||
|
PWSTR pszName1,
|
||||||
|
PWSTR pszName2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (_wcsicmp(pszName1, pszName2) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceRecord(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pEntry->Reference();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceRecord(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pEntry->Dereference();
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CopyToMultiSz(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry,
|
||||||
|
PVOID pvData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
STRU strTemp;
|
||||||
|
MULTISZ *pMultiSz = static_cast<MULTISZ *>(pvData);
|
||||||
|
DBG_ASSERT(pMultiSz);
|
||||||
|
DBG_ASSERT(pEntry);
|
||||||
|
strTemp.Copy(pEntry->QueryName());
|
||||||
|
strTemp.Append(pEntry->QueryValue());
|
||||||
|
pMultiSz->Append(strTemp.QueryStr());
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CopyToTable(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry,
|
||||||
|
PVOID pvData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// best effort copy, ignore the failure
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pNewEntry = new ENVIRONMENT_VAR_ENTRY();
|
||||||
|
if (pNewEntry != NULL)
|
||||||
|
{
|
||||||
|
pNewEntry->Initialize(pEntry->QueryName(), pEntry->QueryValue());
|
||||||
|
ENVIRONMENT_VAR_HASH *pHash = static_cast<ENVIRONMENT_VAR_HASH *>(pvData);
|
||||||
|
DBG_ASSERT(pHash);
|
||||||
|
pHash->InsertRecord(pNewEntry);
|
||||||
|
// Need to dereference as InsertRecord references it now
|
||||||
|
pNewEntry->Dereference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ENVIRONMENT_VAR_HASH(const ENVIRONMENT_VAR_HASH &);
|
||||||
|
void operator=(const ENVIRONMENT_VAR_HASH &);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define FILE_WATCHER_SHUTDOWN_KEY (ULONG_PTR)(-1)
|
||||||
|
#define FILE_WATCHER_ENTRY_BUFFER_SIZE 4096
|
||||||
|
#ifndef CONTAINING_RECORD
|
||||||
|
//
|
||||||
|
// Calculate the address of the base of the structure given its type, and an
|
||||||
|
// address of a field within the structure.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CONTAINING_RECORD(address, type, field) \
|
||||||
|
((type *)((PCHAR)(address)-(ULONG_PTR)(&((type *)0)->field)))
|
||||||
|
|
||||||
|
#endif // !CONTAINING_RECORD
|
||||||
|
#define FILE_NOTIFY_VALID_MASK 0x00000fff
|
||||||
|
#define FILE_WATCHER_ENTRY_SIGNATURE ((DWORD) 'FWES')
|
||||||
|
#define FILE_WATCHER_ENTRY_SIGNATURE_FREE ((DWORD) 'sewf')
|
||||||
|
|
||||||
|
class APPLICATION;
|
||||||
|
|
||||||
|
class FILE_WATCHER{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FILE_WATCHER();
|
||||||
|
|
||||||
|
~FILE_WATCHER();
|
||||||
|
|
||||||
|
HRESULT Create();
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
QueryCompletionPort(
|
||||||
|
VOID
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return m_hCompletionPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
DWORD
|
||||||
|
WINAPI ChangeNotificationThread(LPVOID);
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
WINAPI FileWatcherCompletionRoutine
|
||||||
|
(
|
||||||
|
DWORD dwCompletionStatus,
|
||||||
|
DWORD cbCompletion,
|
||||||
|
OVERLAPPED * pOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_hCompletionPort;
|
||||||
|
HANDLE m_hChangeNotificationThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FILE_WATCHER_ENTRY
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FILE_WATCHER_ENTRY(FILE_WATCHER * pFileMonitor);
|
||||||
|
|
||||||
|
OVERLAPPED _overlapped;
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Create(
|
||||||
|
_In_ PCWSTR pszDirectoryToMonitor,
|
||||||
|
_In_ PCWSTR pszFileNameToMonitor,
|
||||||
|
_In_ APPLICATION* pApplication,
|
||||||
|
_In_ HANDLE hImpersonationToken
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceFileWatcherEntry() const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceFileWatcherEntry() const
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement(&_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryIsValid() const
|
||||||
|
{
|
||||||
|
return _fIsValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MarkEntryInValid()
|
||||||
|
{
|
||||||
|
_fIsValid = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Monitor();
|
||||||
|
|
||||||
|
VOID StopMonitor();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
HandleChangeCompletion(
|
||||||
|
_In_ DWORD dwCompletionStatus,
|
||||||
|
_In_ DWORD cbCompletion
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual ~FILE_WATCHER_ENTRY();
|
||||||
|
|
||||||
|
DWORD _dwSignature;
|
||||||
|
BUFFER _buffDirectoryChanges;
|
||||||
|
HANDLE _hImpersonationToken;
|
||||||
|
HANDLE _hDirectory;
|
||||||
|
FILE_WATCHER* _pFileMonitor;
|
||||||
|
APPLICATION* _pApplication;
|
||||||
|
STRU _strFileName;
|
||||||
|
STRU _strDirectoryName;
|
||||||
|
LONG _lStopMonitorCalled;
|
||||||
|
mutable LONG _cRefs;
|
||||||
|
BOOL _fIsValid;
|
||||||
|
SRWLOCK _srwLock;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//
|
||||||
|
// The key used for hash-table lookups, consists of the port on which the http process is created.
|
||||||
|
//
|
||||||
|
class FORWARDER_CONNECTION_KEY
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION_KEY(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
_In_ DWORD dwPort
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_dwPort = dwPort;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
GetIsEqual(
|
||||||
|
const FORWARDER_CONNECTION_KEY * key2
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return m_dwPort == key2->m_dwPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CalcKeyHash() const
|
||||||
|
{
|
||||||
|
// TODO: Review hash distribution.
|
||||||
|
return Hash(m_dwPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DWORD m_dwPort;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FORWARDER_CONNECTION
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
DWORD dwPort
|
||||||
|
);
|
||||||
|
|
||||||
|
HINTERNET
|
||||||
|
QueryHandle() const
|
||||||
|
{
|
||||||
|
return m_hConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceForwarderConnection() const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceForwarderConnection() const
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION_KEY *
|
||||||
|
QueryConnectionKey()
|
||||||
|
{
|
||||||
|
return &m_ConnectionKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
~FORWARDER_CONNECTION()
|
||||||
|
{
|
||||||
|
if (m_hConnection != NULL)
|
||||||
|
{
|
||||||
|
WinHttpCloseHandle(m_hConnection);
|
||||||
|
m_hConnection = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
FORWARDER_CONNECTION_KEY m_ConnectionKey;
|
||||||
|
HINTERNET m_hConnection;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FORWARDER_CONNECTION_HASH :
|
||||||
|
public HASH_TABLE<FORWARDER_CONNECTION, FORWARDER_CONNECTION_KEY *>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION_HASH()
|
||||||
|
{}
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION_KEY *
|
||||||
|
ExtractKey(
|
||||||
|
FORWARDER_CONNECTION *pConnection
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return pConnection->QueryConnectionKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
CalcKeyHash(
|
||||||
|
FORWARDER_CONNECTION_KEY *key
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return key->CalcKeyHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
EqualKeys(
|
||||||
|
FORWARDER_CONNECTION_KEY *key1,
|
||||||
|
FORWARDER_CONNECTION_KEY *key2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return key1->GetIsEqual(key2);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceRecord(
|
||||||
|
FORWARDER_CONNECTION *pConnection
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pConnection->ReferenceForwarderConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceRecord(
|
||||||
|
FORWARDER_CONNECTION *pConnection
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pConnection->DereferenceForwarderConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION_HASH(const FORWARDER_CONNECTION_HASH &);
|
||||||
|
void operator=(const FORWARDER_CONNECTION_HASH &);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,468 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "forwarderconnection.h"
|
||||||
|
#include "protocolconfig.h"
|
||||||
|
#include "serverprocess.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include "tracelog.h"
|
||||||
|
#include "websockethandler.h"
|
||||||
|
|
||||||
|
#define ASPNETCORE_DEBUG_STRU_BUFFER_SIZE 100
|
||||||
|
#define ASPNETCORE_DEBUG_STRU_ARRAY_SIZE 100
|
||||||
|
|
||||||
|
enum FORWARDING_REQUEST_STATUS
|
||||||
|
{
|
||||||
|
FORWARDER_START,
|
||||||
|
FORWARDER_SENDING_REQUEST,
|
||||||
|
FORWARDER_RECEIVING_RESPONSE,
|
||||||
|
FORWARDER_RECEIVED_WEBSOCKET_RESPONSE,
|
||||||
|
FORWARDER_RESET_CONNECTION,
|
||||||
|
FORWARDER_DONE
|
||||||
|
};
|
||||||
|
|
||||||
|
extern HTTP_MODULE_ID g_pModuleId;
|
||||||
|
extern IHttpServer * g_pHttpServer;
|
||||||
|
extern BOOL g_fAsyncDisconnectAvailable;
|
||||||
|
extern PCWSTR g_pszModuleName;
|
||||||
|
extern HMODULE g_hModule;
|
||||||
|
extern HMODULE g_hWinHttpModule;
|
||||||
|
extern DWORD g_dwTlsIndex;
|
||||||
|
extern DWORD g_OptionalWinHttpFlags;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
extern STRA g_strLogs[ASPNETCORE_DEBUG_STRU_ARRAY_SIZE];
|
||||||
|
extern DWORD g_dwLogCounter;
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
enum MULTI_PART_POSITION
|
||||||
|
{
|
||||||
|
MULTI_PART_IN_BOUNDARY,
|
||||||
|
MULTI_PART_IN_HEADER,
|
||||||
|
MULTI_PART_IN_CHUNK,
|
||||||
|
MULTI_PART_IN_CHUNK_END
|
||||||
|
};
|
||||||
|
|
||||||
|
class ASYNC_DISCONNECT_CONTEXT;
|
||||||
|
|
||||||
|
#define FORWARDING_HANDLER_SIGNATURE ((DWORD)'FHLR')
|
||||||
|
#define FORWARDING_HANDLER_SIGNATURE_FREE ((DWORD)'fhlr')
|
||||||
|
|
||||||
|
class FORWARDING_HANDLER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
FORWARDING_HANDLER(
|
||||||
|
__in IHttpContext * pW3Context
|
||||||
|
);
|
||||||
|
|
||||||
|
static void * operator new(size_t size);
|
||||||
|
|
||||||
|
static void operator delete(void * pMemory);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceForwardingHandler(
|
||||||
|
VOID
|
||||||
|
) const;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceForwardingHandler(
|
||||||
|
VOID
|
||||||
|
) const;
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnExecuteRequestHandler();
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnAsyncCompletion(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
IHttpTraceContext *
|
||||||
|
QueryTraceContext()
|
||||||
|
{
|
||||||
|
return m_pW3Context->GetTraceContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
IHttpContext *
|
||||||
|
QueryHttpContext(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pW3Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CALLBACK
|
||||||
|
OnWinHttpCompletion(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD_PTR dwContext,
|
||||||
|
DWORD dwInternetStatus,
|
||||||
|
LPVOID lpvStatusInformation,
|
||||||
|
DWORD dwStatusInformationLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
FORWARDING_HANDLER * pThis = static_cast<FORWARDING_HANDLER *>(reinterpret_cast<PVOID>(dwContext));
|
||||||
|
if (pThis == NULL)
|
||||||
|
{
|
||||||
|
//error happened, nothing can be done here
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DBG_ASSERT(pThis->m_Signature == FORWARDING_HANDLER_SIGNATURE);
|
||||||
|
pThis->OnWinHttpCompletionInternal(hRequest,
|
||||||
|
dwInternetStatus,
|
||||||
|
lpvStatusInformation,
|
||||||
|
dwStatusInformationLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
StaticInitialize(
|
||||||
|
BOOL fEnableReferenceCountTracing
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
StaticTerminate();
|
||||||
|
|
||||||
|
static
|
||||||
|
PCWSTR
|
||||||
|
QueryErrorFormat()
|
||||||
|
{
|
||||||
|
return sm_strErrorFormat.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
HANDLE
|
||||||
|
QueryEventLog()
|
||||||
|
{
|
||||||
|
return sm_hEventLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TerminateRequest(
|
||||||
|
BOOL fClientInitiated
|
||||||
|
);
|
||||||
|
|
||||||
|
static HINTERNET sm_hSession;
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetStatusAndHeaders(
|
||||||
|
PCSTR pszHeaders,
|
||||||
|
DWORD cchHeaders
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnSharedRequestEntity(
|
||||||
|
ULONGLONG ulOffset,
|
||||||
|
LPCBYTE pvBuffer,
|
||||||
|
DWORD cbBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetStatus(
|
||||||
|
FORWARDING_REQUEST_STATUS status
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_RequestStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~FORWARDING_HANDLER(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//
|
||||||
|
// Begin OnMapRequestHandler phases.
|
||||||
|
//
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
CreateWinHttpRequest(
|
||||||
|
__in const IHttpRequest * pRequest,
|
||||||
|
__in const PROTOCOL_CONFIG * pProtocol,
|
||||||
|
__in HINTERNET hConnect,
|
||||||
|
__inout STRU * pstrUrl,
|
||||||
|
ASPNETCORE_CONFIG* pAspNetCoreConfig,
|
||||||
|
SERVER_PROCESS* pServerProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// End OnMapRequestHandler phases.
|
||||||
|
//
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RemoveRequest();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetHeaders(
|
||||||
|
const PROTOCOL_CONFIG * pProtocol,
|
||||||
|
PCWSTR * ppszHeaders,
|
||||||
|
DWORD * pcchHeaders,
|
||||||
|
ASPNETCORE_CONFIG* pAspNetCoreConfig,
|
||||||
|
SERVER_PROCESS* pServerProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoReverseRewrite(
|
||||||
|
__in IHttpResponse *pResponse
|
||||||
|
);
|
||||||
|
|
||||||
|
BYTE *
|
||||||
|
GetNewResponseBuffer(
|
||||||
|
DWORD dwBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FreeResponseBuffers();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
OnWinHttpCompletionInternal(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD dwInternetStatus,
|
||||||
|
LPVOID lpvStatusInformation,
|
||||||
|
DWORD dwStatusInformationLength
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionSendRequestOrWriteComplete(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD dwInternetStatus,
|
||||||
|
__out BOOL * pfClientError,
|
||||||
|
__out BOOL * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionStatusHeadersAvailable(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
__out BOOL * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionStatusDataAvailable(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD dwBytes,
|
||||||
|
__out BOOL * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionStatusReadComplete(
|
||||||
|
__in IHttpResponse * pResponse,
|
||||||
|
DWORD dwStatusInformationLength,
|
||||||
|
__out BOOL * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnSendingRequest(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus,
|
||||||
|
__out BOOL * pfClientError
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnReceivingResponse();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWebSocketWinHttpSendComplete(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
LPVOID pvStatus,
|
||||||
|
DWORD hrCompletion,
|
||||||
|
DWORD cbCompletion,
|
||||||
|
BOOL * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWebSocketWinHttpReceiveComplete(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
LPVOID pvStatus,
|
||||||
|
DWORD hrCompletion,
|
||||||
|
DWORD cbCompletion,
|
||||||
|
BOOL * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWebSocketIisSendComplete(
|
||||||
|
DWORD hrCompletion,
|
||||||
|
DWORD cbCompletion
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWebSocketIisReceiveComplete(
|
||||||
|
DWORD hrCompletion,
|
||||||
|
DWORD cbCompletion
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoIisWebSocketReceive(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TerminateWebsocket(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD m_Signature;
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
|
||||||
|
IHttpContext * m_pW3Context;
|
||||||
|
|
||||||
|
//
|
||||||
|
// WinHTTP request handle is protected using a read-write lock.
|
||||||
|
//
|
||||||
|
SRWLOCK m_RequestLock;
|
||||||
|
HINTERNET m_hRequest;
|
||||||
|
|
||||||
|
APP_OFFLINE_HTM *m_pAppOfflineHtm;
|
||||||
|
APPLICATION *m_pApplication;
|
||||||
|
|
||||||
|
BOOL m_fResponseHeadersReceivedAndSet;
|
||||||
|
volatile BOOL m_fClientDisconnected;
|
||||||
|
//
|
||||||
|
// A safety guard flag indicating no more IIS PostCompletion is allowed
|
||||||
|
//
|
||||||
|
volatile BOOL m_fFinishRequest;
|
||||||
|
//
|
||||||
|
// A safety guard flag to prevent from unexpect callback which may signal IIS pipeline
|
||||||
|
// more than once with non-pending status
|
||||||
|
//
|
||||||
|
volatile BOOL m_fDoneAsyncCompletion;
|
||||||
|
volatile BOOL m_fHasError;
|
||||||
|
//
|
||||||
|
// WinHttp may hit AV under race if handle got closed more than once simultaneously
|
||||||
|
// Use two bool variables to guard
|
||||||
|
//
|
||||||
|
volatile BOOL m_fHttpHandleInClose;
|
||||||
|
volatile BOOL m_fWebSocketHandleInClose;
|
||||||
|
//
|
||||||
|
// Record the number of winhttp handles in use
|
||||||
|
// release IIS pipeline only after all handles got closed
|
||||||
|
//
|
||||||
|
volatile LONG m_dwHandlers;
|
||||||
|
|
||||||
|
BOOL m_fDoReverseRewriteHeaders;
|
||||||
|
BOOL m_fServerResetConn;
|
||||||
|
DWORD m_msStartTime;
|
||||||
|
DWORD m_BytesToReceive;
|
||||||
|
DWORD m_BytesToSend;
|
||||||
|
|
||||||
|
BYTE * m_pEntityBuffer;
|
||||||
|
DWORD m_cchLastSend;
|
||||||
|
|
||||||
|
static const SIZE_T INLINE_ENTITY_BUFFERS = 8;
|
||||||
|
DWORD m_cEntityBuffers;
|
||||||
|
BUFFER_T<BYTE*,INLINE_ENTITY_BUFFERS> m_buffEntityBuffers;
|
||||||
|
|
||||||
|
DWORD m_cBytesBuffered;
|
||||||
|
DWORD m_cMinBufferLimit;
|
||||||
|
|
||||||
|
PCSTR m_pszOriginalHostHeader;
|
||||||
|
|
||||||
|
volatile FORWARDING_REQUEST_STATUS m_RequestStatus;
|
||||||
|
|
||||||
|
ASYNC_DISCONNECT_CONTEXT * m_pDisconnect;
|
||||||
|
|
||||||
|
PCWSTR m_pszHeaders;
|
||||||
|
DWORD m_cchHeaders;
|
||||||
|
|
||||||
|
BOOL m_fWebSocketEnabled;
|
||||||
|
|
||||||
|
STRU m_strFullUri;
|
||||||
|
|
||||||
|
ULONGLONG m_cContentLength;
|
||||||
|
|
||||||
|
WEBSOCKET_HANDLER * m_pWebSocket;
|
||||||
|
|
||||||
|
static PROTOCOL_CONFIG sm_ProtocolConfig;
|
||||||
|
|
||||||
|
static STRU sm_strErrorFormat;
|
||||||
|
|
||||||
|
static HANDLE sm_hEventLog;
|
||||||
|
|
||||||
|
static ALLOC_CACHE_HANDLER * sm_pAlloc;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reference cout tracing for debugging purposes.
|
||||||
|
//
|
||||||
|
static TRACE_LOG * sm_pTraceLog;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ASYNC_DISCONNECT_CONTEXT : public IHttpConnectionStoredContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ASYNC_DISCONNECT_CONTEXT()
|
||||||
|
{
|
||||||
|
m_pHandler = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanupStoredContext()
|
||||||
|
{
|
||||||
|
DBG_ASSERT(m_pHandler == NULL);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NotifyDisconnect()
|
||||||
|
{
|
||||||
|
FORWARDING_HANDLER *pInitialValue = (FORWARDING_HANDLER*)
|
||||||
|
InterlockedExchangePointer((PVOID*) &m_pHandler, NULL);
|
||||||
|
|
||||||
|
if (pInitialValue != NULL)
|
||||||
|
{
|
||||||
|
pInitialValue->TerminateRequest(TRUE);
|
||||||
|
pInitialValue->DereferenceForwardingHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetHandler(
|
||||||
|
FORWARDING_HANDLER *pHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Take a reference on the forwarding handler.
|
||||||
|
// This reference will be released on either of two conditions:
|
||||||
|
//
|
||||||
|
// 1. When the request processing ends, in which case a ResetHandler()
|
||||||
|
// is called.
|
||||||
|
//
|
||||||
|
// 2. When a disconnect notification arrives.
|
||||||
|
//
|
||||||
|
// We need to make sure that only one of them ends up dereferencing
|
||||||
|
// the object.
|
||||||
|
//
|
||||||
|
|
||||||
|
DBG_ASSERT (pHandler != NULL);
|
||||||
|
DBG_ASSERT (m_pHandler == NULL);
|
||||||
|
|
||||||
|
pHandler->ReferenceForwardingHandler();
|
||||||
|
InterlockedExchangePointer((PVOID*)&m_pHandler, pHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ResetHandler(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FORWARDING_HANDLER *pInitialValue = (FORWARDING_HANDLER*)
|
||||||
|
InterlockedExchangePointer( (PVOID*)&m_pHandler, NULL);
|
||||||
|
|
||||||
|
if (pInitialValue != NULL)
|
||||||
|
{
|
||||||
|
pInitialValue->DereferenceForwardingHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~ASYNC_DISCONNECT_CONTEXT()
|
||||||
|
{}
|
||||||
|
|
||||||
|
FORWARDING_HANDLER * m_pHandler;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class PATH
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
SplitUrl(
|
||||||
|
PCWSTR pszDestinationUrl,
|
||||||
|
BOOL *pfSecure,
|
||||||
|
STRU *pstrDestination,
|
||||||
|
STRU *pstrUrl
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
UnEscapeUrl(
|
||||||
|
PCWSTR pszUrl,
|
||||||
|
DWORD cchUrl,
|
||||||
|
bool fCopyQuery,
|
||||||
|
STRA * pstrResult
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
UnEscapeUrl(
|
||||||
|
PCWSTR pszUrl,
|
||||||
|
DWORD cchUrl,
|
||||||
|
STRU * pstrResult
|
||||||
|
);
|
||||||
|
|
||||||
|
static HRESULT
|
||||||
|
EscapeAbsPath(
|
||||||
|
IHttpRequest * pRequest,
|
||||||
|
STRU * strEscapedUrl
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
IsValidAttributeNameChar(
|
||||||
|
WCHAR ch
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
IsValidQueryStringName(
|
||||||
|
PCWSTR pszName
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
IsValidHeaderName(
|
||||||
|
PCWSTR pszName
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
FindInMultiString(
|
||||||
|
PCWSTR pszMultiString,
|
||||||
|
PCWSTR pszStringToFind
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
IsPathUnc(
|
||||||
|
__in LPCWSTR pszPath,
|
||||||
|
__out BOOL * pfIsUnc
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
ConvertPathToFullPath(
|
||||||
|
_In_ LPCWSTR pszPath,
|
||||||
|
_In_ LPCWSTR pszRootPath,
|
||||||
|
_Out_ STRU* pStrFullPath
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
PATH() {}
|
||||||
|
~PATH() {}
|
||||||
|
|
||||||
|
static
|
||||||
|
CHAR
|
||||||
|
ToHexDigit(
|
||||||
|
UINT nDigit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return static_cast<CHAR>(nDigit > 9 ? nDigit - 10 + 'A' : nDigit + '0');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ONE_MINUTE_IN_MILLISECONDS 60000
|
||||||
|
|
||||||
|
class PROCESS_MANAGER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~PROCESS_MANAGER();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceProcessManager() const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceProcessManager() const
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetProcess(
|
||||||
|
_In_ IHttpContext *context,
|
||||||
|
_In_ ASPNETCORE_CONFIG *pConfig,
|
||||||
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
QueryNULHandle()
|
||||||
|
{
|
||||||
|
return m_hNULHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SendShutdownSignal()
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
|
||||||
|
for(DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
|
||||||
|
{
|
||||||
|
if( m_ppServerProcessList != NULL &&
|
||||||
|
m_ppServerProcessList[i] != NULL )
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[i]->SendSignal();
|
||||||
|
m_ppServerProcessList[i]->DereferenceServerProcess();
|
||||||
|
m_ppServerProcessList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ShutdownProcess(
|
||||||
|
SERVER_PROCESS* pServerProcess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
|
||||||
|
ShutdownProcessNoLock( pServerProcess );
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ShutdownAllProcesses(
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
|
||||||
|
ShutdownAllProcessesNoLock();
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IncrementRapidFailCount(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRapidFailCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_MANAGER() :
|
||||||
|
m_ppServerProcessList( NULL ),
|
||||||
|
m_hNULHandle( NULL ),
|
||||||
|
m_cRapidFailCount( 0 ),
|
||||||
|
m_dwProcessesPerApplication( 1 ),
|
||||||
|
m_dwRouteToProcessIndex( 0 ),
|
||||||
|
m_fServerProcessListReady(FALSE),
|
||||||
|
m_cRefs( 1 )
|
||||||
|
{
|
||||||
|
InitializeSRWLock( &m_srwLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
RapidFailsPerMinuteExceeded(
|
||||||
|
LONG dwRapidFailsPerMinute
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DWORD dwCurrentTickCount = GetTickCount();
|
||||||
|
|
||||||
|
if( (dwCurrentTickCount - m_dwRapidFailTickStart)
|
||||||
|
>= ONE_MINUTE_IN_MILLISECONDS )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// reset counters every minute.
|
||||||
|
//
|
||||||
|
|
||||||
|
InterlockedExchange(&m_cRapidFailCount, 0);
|
||||||
|
m_dwRapidFailTickStart = dwCurrentTickCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_cRapidFailCount > dwRapidFailsPerMinute;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ShutdownProcessNoLock(
|
||||||
|
SERVER_PROCESS* pServerProcess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for(DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
|
||||||
|
{
|
||||||
|
if( m_ppServerProcessList != NULL &&
|
||||||
|
m_ppServerProcessList[i] != NULL &&
|
||||||
|
m_ppServerProcessList[i]->GetPort() == pServerProcess->GetPort() )
|
||||||
|
{
|
||||||
|
// shutdown pServerProcess if not already shutdown.
|
||||||
|
m_ppServerProcessList[i]->StopProcess();
|
||||||
|
m_ppServerProcessList[i]->DereferenceServerProcess();
|
||||||
|
m_ppServerProcessList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ShutdownAllProcessesNoLock(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for(DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
|
||||||
|
{
|
||||||
|
if( m_ppServerProcessList != NULL &&
|
||||||
|
m_ppServerProcessList[i] != NULL )
|
||||||
|
{
|
||||||
|
// shutdown pServerProcess if not already shutdown.
|
||||||
|
m_ppServerProcessList[i]->SendSignal();
|
||||||
|
m_ppServerProcessList[i]->DereferenceServerProcess();
|
||||||
|
m_ppServerProcessList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile LONG m_cRapidFailCount;
|
||||||
|
DWORD m_dwRapidFailTickStart;
|
||||||
|
DWORD m_dwProcessesPerApplication;
|
||||||
|
volatile DWORD m_dwRouteToProcessIndex;
|
||||||
|
|
||||||
|
SRWLOCK m_srwLock;
|
||||||
|
SERVER_PROCESS **m_ppServerProcessList;
|
||||||
|
|
||||||
|
//
|
||||||
|
// m_hNULHandle is used to redirect stdout/stderr to NUL.
|
||||||
|
// If Createprocess is called to launch a batch file for example,
|
||||||
|
// it tries to write to the console buffer by default. It fails to
|
||||||
|
// start if the console buffer is owned by the parent process i.e
|
||||||
|
// in our case w3wp.exe. So we have to redirect the stdout/stderr
|
||||||
|
// of the child process to NUL or to a file (anything other than
|
||||||
|
// the console buffer of the parent process).
|
||||||
|
//
|
||||||
|
|
||||||
|
HANDLE m_hNULHandle;
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
|
||||||
|
volatile static BOOL sm_fWSAStartupDone;
|
||||||
|
volatile BOOL m_fServerProcessListReady;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "aspnetcoreconfig.h"
|
||||||
|
|
||||||
|
class PROTOCOL_CONFIG
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PROTOCOL_CONFIG()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
OverrideConfig(
|
||||||
|
ASPNETCORE_CONFIG *pAspNetCoreConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryDoKeepAlive() const
|
||||||
|
{
|
||||||
|
return m_fKeepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryTimeout() const
|
||||||
|
{
|
||||||
|
return m_msTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryPreserveHostHeader() const
|
||||||
|
{
|
||||||
|
return m_fPreserveHostHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryReverseRewriteHeaders() const
|
||||||
|
{
|
||||||
|
return m_fReverseRewriteHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
const STRA *
|
||||||
|
QueryXForwardedForName() const
|
||||||
|
{
|
||||||
|
return &m_strXForwardedForName;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryIncludePortInXForwardedFor() const
|
||||||
|
{
|
||||||
|
return m_fIncludePortInXForwardedFor;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryMinResponseBuffer() const
|
||||||
|
{
|
||||||
|
return m_dwMinResponseBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryResponseBufferLimit() const
|
||||||
|
{
|
||||||
|
return m_dwResponseBufferLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryMaxResponseHeaderSize() const
|
||||||
|
{
|
||||||
|
return m_dwMaxResponseHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const STRA*
|
||||||
|
QuerySslHeaderName() const
|
||||||
|
{
|
||||||
|
return &m_strSslHeaderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const STRA *
|
||||||
|
QueryClientCertName() const
|
||||||
|
{
|
||||||
|
return &m_strClientCertName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
BOOL m_fKeepAlive;
|
||||||
|
BOOL m_fPreserveHostHeader;
|
||||||
|
BOOL m_fReverseRewriteHeaders;
|
||||||
|
BOOL m_fIncludePortInXForwardedFor;
|
||||||
|
|
||||||
|
DWORD m_msTimeout;
|
||||||
|
DWORD m_dwMinResponseBuffer;
|
||||||
|
DWORD m_dwResponseBufferLimit;
|
||||||
|
DWORD m_dwMaxResponseHeaderSize;
|
||||||
|
|
||||||
|
STRA m_strXForwardedForName;
|
||||||
|
STRA m_strSslHeaderName;
|
||||||
|
STRA m_strClientCertName;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "forwardinghandler.h"
|
||||||
|
|
||||||
|
class CProxyModule : public CHttpModule
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CProxyModule();
|
||||||
|
|
||||||
|
~CProxyModule();
|
||||||
|
|
||||||
|
void * operator new(size_t size, IModuleAllocator * pPlacement)
|
||||||
|
{
|
||||||
|
return pPlacement->AllocateMemory(static_cast<DWORD>(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
operator delete(
|
||||||
|
void *
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnExecuteRequestHandler(
|
||||||
|
IHttpContext * pHttpContext,
|
||||||
|
IHttpEventProvider * pProvider
|
||||||
|
);
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnAsyncCompletion(
|
||||||
|
IHttpContext * pHttpContext,
|
||||||
|
DWORD dwNotification,
|
||||||
|
BOOL fPostNotification,
|
||||||
|
IHttpEventProvider * pProvider,
|
||||||
|
IHttpCompletionInfo * pCompletionInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FORWARDING_HANDLER * m_pHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CProxyModuleFactory : public IHttpModuleFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HRESULT
|
||||||
|
GetHttpModule(
|
||||||
|
CHttpModule ** ppModule,
|
||||||
|
IModuleAllocator * pAllocator
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Terminate();
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define IDS_INVALID_PROPERTY 1000
|
||||||
|
#define IDS_SERVER_ERROR 1001
|
||||||
|
|
||||||
|
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'."
|
||||||
|
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_INTERNAL_ERROR_MSG L"Application '%s' failed to parse processPath and arguments due to internal error, ErrorCode = '0x%x'."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_POSTCREATE_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s'but failed to get its status, ErrorCode = '0x%x'."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s', ErrorCode = '0x%x : %x."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_WRONGPORT_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but failed to listen on the given port '%d'"
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_NOTREADY_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but either crashed or did not reponse or did not listen on the given port '%d', ErrorCode = '0x%x'"
|
||||||
|
#define ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG L"Warning: Could not create stdoutLogFile %s, ErrorCode = %d."
|
||||||
|
#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE_MSG L"Failed to gracefully shutdown process '%d'."
|
||||||
|
#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST_MSG L"Sent shutdown HTTP message to process '%d' and received http status '%d'."
|
||||||
|
#define ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG L"App_offline file '%s' was detected."
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//
|
||||||
|
// *_HEADER_HASH maps strings to UlHeader* values
|
||||||
|
//
|
||||||
|
|
||||||
|
#define UNKNOWN_INDEX (0xFFFFFFFF)
|
||||||
|
|
||||||
|
struct HEADER_RECORD
|
||||||
|
{
|
||||||
|
PCSTR _pszName;
|
||||||
|
ULONG _ulHeaderIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RESPONSE_HEADER_HASH: public HASH_TABLE<HEADER_RECORD, PCSTR>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RESPONSE_HEADER_HASH()
|
||||||
|
{}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceRecord(
|
||||||
|
HEADER_RECORD *
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceRecord(
|
||||||
|
HEADER_RECORD *
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PCSTR
|
||||||
|
ExtractKey(
|
||||||
|
HEADER_RECORD * pRecord
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return pRecord->_pszName;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
CalcKeyHash(
|
||||||
|
PCSTR key
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return HashStringNoCase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
EqualKeys(
|
||||||
|
PCSTR key1,
|
||||||
|
PCSTR key2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (_stricmp(key1, key2) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Terminate(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
GetIndex(
|
||||||
|
PCSTR pszName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HEADER_RECORD * pRecord = NULL;
|
||||||
|
|
||||||
|
FindKey(pszName, &pRecord);
|
||||||
|
if (pRecord != NULL)
|
||||||
|
{
|
||||||
|
return pRecord->_ulHeaderIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNKNOWN_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
PCSTR
|
||||||
|
GetString(
|
||||||
|
ULONG ulIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (ulIndex < HttpHeaderResponseMaximum)
|
||||||
|
{
|
||||||
|
DBG_ASSERT(sm_rgHeaders[ulIndex]._ulHeaderIndex == ulIndex);
|
||||||
|
return sm_rgHeaders[ulIndex]._pszName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static HEADER_RECORD sm_rgHeaders[];
|
||||||
|
|
||||||
|
RESPONSE_HEADER_HASH(const RESPONSE_HEADER_HASH &);
|
||||||
|
void operator=(const RESPONSE_HEADER_HASH &);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern RESPONSE_HEADER_HASH * g_pResponseHeaderHash;
|
||||||
|
|
@ -0,0 +1,329 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
#define MIN_PORT 1025
|
||||||
|
#define MAX_PORT 48000
|
||||||
|
#define MAX_RETRY 10
|
||||||
|
#define MAX_ACTIVE_CHILD_PROCESSES 16
|
||||||
|
#define LOCALHOST "127.0.0.1"
|
||||||
|
#define ASPNETCORE_PORT_STR L"ASPNETCORE_PORT"
|
||||||
|
#define ASPNETCORE_PORT_ENV_STR L"ASPNETCORE_PORT="
|
||||||
|
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
||||||
|
#define ASPNETCORE_APP_TOKEN_ENV_STR L"ASPNETCORE_TOKEN="
|
||||||
|
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
||||||
|
#define HOSTING_STARTUP_ASSEMBLIES_ENV_STR L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES"
|
||||||
|
#define HOSTING_STARTUP_ASSEMBLIES_NAME L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES="
|
||||||
|
#define HOSTING_STARTUP_ASSEMBLIES_VALUE L"Microsoft.AspNetCore.Server.IISIntegration"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_ENV_STR L"ASPNETCORE_IIS_HTTPAUTH="
|
||||||
|
#define ASPNETCORE_IIS_AUTH_WINDOWS L"windows;"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_BASIC L"basic;"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_ANONYMOUS L"anonymous;"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_NONE L"none"
|
||||||
|
|
||||||
|
class PROCESS_MANAGER;
|
||||||
|
class FORWARDER_CONNECTION;
|
||||||
|
|
||||||
|
class SERVER_PROCESS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SERVER_PROCESS();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
_In_ PROCESS_MANAGER *pProcessManager,
|
||||||
|
_In_ STRU *pszProcessExePath,
|
||||||
|
_In_ STRU *pszArguments,
|
||||||
|
_In_ DWORD dwStartupTimeLimitInMS,
|
||||||
|
_In_ DWORD dwShtudownTimeLimitInMS,
|
||||||
|
_In_ BOOL fWindowsAuthEnabled,
|
||||||
|
_In_ BOOL fBasicAuthEnabled,
|
||||||
|
_In_ BOOL fAnonymousAuthEnabled,
|
||||||
|
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
|
||||||
|
_In_ BOOL fStdoutLogEnabled,
|
||||||
|
_In_ STRU *pstruStdoutLogFile
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
StartProcess(
|
||||||
|
_In_ IHttpContext *context
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetWindowsAuthToken(
|
||||||
|
_In_ HANDLE hToken,
|
||||||
|
_Out_ LPHANDLE pTargeTokenHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IsReady(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_fReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
StopProcess(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
GetPort()
|
||||||
|
{
|
||||||
|
return m_dwPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceServerProcess(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceServerProcess(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_ASSERT(m_cRefs != 0 );
|
||||||
|
|
||||||
|
if (InterlockedDecrement(&m_cRefs) == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~SERVER_PROCESS();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
HandleProcessExit(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION*
|
||||||
|
QueryWinHttpConnection(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pForwarderConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CALLBACK
|
||||||
|
TimerCallback(
|
||||||
|
_In_ PTP_CALLBACK_INSTANCE Instance,
|
||||||
|
_In_ PVOID Context,
|
||||||
|
_In_ PTP_TIMER Timer
|
||||||
|
);
|
||||||
|
|
||||||
|
LPCWSTR
|
||||||
|
QueryPortStr()
|
||||||
|
{
|
||||||
|
return m_struPort.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
LPCWSTR
|
||||||
|
QueryFullLogPath()
|
||||||
|
{
|
||||||
|
return m_struFullLogFile.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
LPCSTR
|
||||||
|
QueryGuid()
|
||||||
|
{
|
||||||
|
return m_straGuid.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryProcessGroupId()
|
||||||
|
{
|
||||||
|
return m_dwProcessId;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SendSignal(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IsDebuggerIsAttached(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
StopAllProcessesInJobObject(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetupStdHandles(
|
||||||
|
_In_ IHttpContext *context,
|
||||||
|
_In_ LPSTARTUPINFOW pStartupInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
CheckIfServerIsUp(
|
||||||
|
_In_ DWORD dwPort,
|
||||||
|
_Out_ DWORD * pdwProcessId,
|
||||||
|
_Out_ BOOL * pfReady
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
RegisterProcessWait(
|
||||||
|
_In_ PHANDLE phWaitHandle,
|
||||||
|
_In_ HANDLE hProcessToWaitOn
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetChildProcessHandles(
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetupListenPort(
|
||||||
|
ENVIRONMENT_VAR_HASH *pEnvironmentVarTable
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetupAppPath(
|
||||||
|
IHttpContext* pContext,
|
||||||
|
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetupAppToken(
|
||||||
|
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
InitEnvironmentVariablesTable(
|
||||||
|
ENVIRONMENT_VAR_HASH** pEnvironmentVarTable
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OutputEnvironmentVariables(
|
||||||
|
MULTISZ* pmszOutput,
|
||||||
|
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetupCommandLine(
|
||||||
|
STRU* pstrCommandLine
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PostStartCheck(
|
||||||
|
const STRU* const pStruCommandline,
|
||||||
|
STRU* pStruErrorMessage
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetRandomPort(
|
||||||
|
DWORD* pdwPickedPort,
|
||||||
|
DWORD dwExcludedPort
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
GetNumberOfDigits(
|
||||||
|
_In_ DWORD dwNumber
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DWORD digits = 0;
|
||||||
|
|
||||||
|
if( dwNumber == 0 )
|
||||||
|
{
|
||||||
|
digits = 1;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( dwNumber > 0)
|
||||||
|
{
|
||||||
|
dwNumber = dwNumber / 10;
|
||||||
|
digits ++;
|
||||||
|
}
|
||||||
|
Finished:
|
||||||
|
return digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
SendShutDownSignal(
|
||||||
|
LPVOID lpParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SendShutDownSignalInternal(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SendShutdownHttpMessage(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TerminateBackendProcess(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION *m_pForwarderConnection;
|
||||||
|
BOOL m_fStdoutLogEnabled;
|
||||||
|
BOOL m_fWindowsAuthEnabled;
|
||||||
|
BOOL m_fBasicAuthEnabled;
|
||||||
|
BOOL m_fAnonymousAuthEnabled;
|
||||||
|
|
||||||
|
STTIMER m_Timer;
|
||||||
|
SOCKET m_socket;
|
||||||
|
|
||||||
|
STRU m_struLogFile;
|
||||||
|
STRU m_struFullLogFile;
|
||||||
|
STRU m_ProcessPath;
|
||||||
|
STRU m_Arguments;
|
||||||
|
STRU m_struAppPath;
|
||||||
|
STRU m_struAppFullPath;
|
||||||
|
STRU m_struPort;
|
||||||
|
STRU m_pszRootApplicationPath;
|
||||||
|
volatile LONG m_lStopping;
|
||||||
|
volatile BOOL m_fReady;
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
|
||||||
|
std::mt19937 m_randomGenerator;
|
||||||
|
|
||||||
|
DWORD m_dwPort;
|
||||||
|
DWORD m_dwStartupTimeLimitInMS;
|
||||||
|
DWORD m_dwShutdownTimeLimitInMS;
|
||||||
|
DWORD m_cChildProcess;
|
||||||
|
DWORD m_dwChildProcessIds[MAX_ACTIVE_CHILD_PROCESSES];
|
||||||
|
DWORD m_dwProcessId;
|
||||||
|
DWORD m_dwListeningProcessId;
|
||||||
|
|
||||||
|
STRA m_straGuid;
|
||||||
|
|
||||||
|
HANDLE m_hJobObject;
|
||||||
|
HANDLE m_hStdoutHandle;
|
||||||
|
//
|
||||||
|
// m_hProcessHandle is the handle to process this object creates.
|
||||||
|
//
|
||||||
|
HANDLE m_hProcessHandle;
|
||||||
|
HANDLE m_hListeningProcessHandle;
|
||||||
|
HANDLE m_hProcessWaitHandle;
|
||||||
|
HANDLE m_hShutdownHandle;
|
||||||
|
//
|
||||||
|
// m_hChildProcessHandle is the handle to process created by
|
||||||
|
// m_hProcessHandle process if it does.
|
||||||
|
//
|
||||||
|
HANDLE m_hChildProcessHandles[MAX_ACTIVE_CHILD_PROCESSES];
|
||||||
|
HANDLE m_hChildProcessWaitHandles[MAX_ACTIVE_CHILD_PROCESSES];
|
||||||
|
|
||||||
|
PROCESS_MANAGER *m_pProcessManager;
|
||||||
|
ENVIRONMENT_VAR_HASH *m_pEnvironmentVarTable ;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,279 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _STTIMER_H
|
||||||
|
#define _STTIMER_H
|
||||||
|
|
||||||
|
class STTIMER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
STTIMER()
|
||||||
|
: _pTimer( NULL )
|
||||||
|
{
|
||||||
|
fInCanel = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~STTIMER()
|
||||||
|
{
|
||||||
|
if ( _pTimer )
|
||||||
|
{
|
||||||
|
CancelTimer();
|
||||||
|
CloseThreadpoolTimer( _pTimer );
|
||||||
|
_pTimer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
InitializeTimer(
|
||||||
|
PTP_TIMER_CALLBACK pfnCallback,
|
||||||
|
VOID * pContext,
|
||||||
|
DWORD dwInitialWait = 0,
|
||||||
|
DWORD dwPeriod = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_pTimer = CreateThreadpoolTimer( pfnCallback,
|
||||||
|
pContext,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if ( !_pTimer )
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dwInitialWait )
|
||||||
|
{
|
||||||
|
SetTimer( dwInitialWait,
|
||||||
|
dwPeriod );
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetTimer(
|
||||||
|
DWORD dwInitialWait,
|
||||||
|
DWORD dwPeriod = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FILETIME ftInitialWait;
|
||||||
|
|
||||||
|
if ( dwInitialWait == 0 && dwPeriod == 0 )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Special case. We are preventing new callbacks
|
||||||
|
// from being queued. Any existing callbacks in the
|
||||||
|
// queue will still run.
|
||||||
|
//
|
||||||
|
// This effectively disables the timer. It can be
|
||||||
|
// re-enabled by setting non-zero initial wait or
|
||||||
|
// period values.
|
||||||
|
//
|
||||||
|
if (_pTimer != NULL)
|
||||||
|
{
|
||||||
|
SetThreadpoolTimer(_pTimer, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeRelativeFileTime( &ftInitialWait, dwInitialWait );
|
||||||
|
|
||||||
|
SetThreadpoolTimer( _pTimer,
|
||||||
|
&ftInitialWait,
|
||||||
|
dwPeriod,
|
||||||
|
0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CancelTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Disable the timer
|
||||||
|
//
|
||||||
|
if (fInCanel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fInCanel = TRUE;
|
||||||
|
SetTimer( 0 );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wait until any callbacks queued prior to disabling
|
||||||
|
// have completed.
|
||||||
|
//
|
||||||
|
if (_pTimer != NULL)
|
||||||
|
{
|
||||||
|
WaitForThreadpoolTimerCallbacks(_pTimer, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fInCanel = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CALLBACK
|
||||||
|
TimerCallback(
|
||||||
|
_In_ PTP_CALLBACK_INSTANCE Instance,
|
||||||
|
_In_ PVOID Context,
|
||||||
|
_In_ PTP_TIMER Timer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Instance;
|
||||||
|
Timer;
|
||||||
|
STRU* pstruLogFilePath = (STRU*)Context;
|
||||||
|
HANDLE hStdoutHandle = NULL;
|
||||||
|
SECURITY_ATTRIBUTES saAttr = { 0 };
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
hStdoutHandle = CreateFileW(pstruLogFilePath->QueryStr(),
|
||||||
|
FILE_READ_DATA,
|
||||||
|
FILE_SHARE_WRITE,
|
||||||
|
&saAttr,
|
||||||
|
OPEN_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
if (hStdoutHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hStdoutHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InitializeRelativeFileTime(
|
||||||
|
FILETIME * pft,
|
||||||
|
DWORD dwMilliseconds
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER li;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The pftDueTime parameter expects the time to be
|
||||||
|
// expressed as the number of 100 nanosecond intervals
|
||||||
|
// times -1.
|
||||||
|
//
|
||||||
|
// To convert from milliseconds, we'll multiply by
|
||||||
|
// -10000
|
||||||
|
//
|
||||||
|
|
||||||
|
li.QuadPart = (LONGLONG)dwMilliseconds * -10000;
|
||||||
|
|
||||||
|
pft->dwHighDateTime = li.HighPart;
|
||||||
|
pft->dwLowDateTime = li.LowPart;
|
||||||
|
};
|
||||||
|
|
||||||
|
TP_TIMER * _pTimer;
|
||||||
|
BOOL fInCanel;
|
||||||
|
};
|
||||||
|
|
||||||
|
class STELAPSED
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
STELAPSED()
|
||||||
|
: _dwInitTime( 0 ),
|
||||||
|
_dwInitTickCount( 0 ),
|
||||||
|
_dwPerfCountsPerMillisecond( 0 ),
|
||||||
|
_fUsingHighResolution( FALSE )
|
||||||
|
{
|
||||||
|
LARGE_INTEGER li;
|
||||||
|
BOOL fResult;
|
||||||
|
|
||||||
|
_dwInitTickCount = GetTickCount64();
|
||||||
|
|
||||||
|
fResult = QueryPerformanceFrequency( &li );
|
||||||
|
|
||||||
|
if ( !fResult )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dwPerfCountsPerMillisecond = li.QuadPart / 1000;
|
||||||
|
|
||||||
|
fResult = QueryPerformanceCounter( &li );
|
||||||
|
|
||||||
|
if ( !fResult )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dwInitTime = li.QuadPart / _dwPerfCountsPerMillisecond;
|
||||||
|
|
||||||
|
_fUsingHighResolution = TRUE;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~STELAPSED()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LONGLONG
|
||||||
|
QueryElapsedTime()
|
||||||
|
{
|
||||||
|
LARGE_INTEGER li;
|
||||||
|
|
||||||
|
if ( _fUsingHighResolution && QueryPerformanceCounter( &li ) )
|
||||||
|
{
|
||||||
|
DWORD64 dwCurrentTime = li.QuadPart / _dwPerfCountsPerMillisecond;
|
||||||
|
|
||||||
|
if ( dwCurrentTime < _dwInitTime )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// It's theoretically possible that QueryPerformanceCounter
|
||||||
|
// may return slightly different values on different CPUs.
|
||||||
|
// In this case, we don't want to return an unexpected value
|
||||||
|
// so we'll return zero. This is acceptable because
|
||||||
|
// presumably such a case would only happen for a very short
|
||||||
|
// time window.
|
||||||
|
//
|
||||||
|
// It would be possible to prevent this by ensuring processor
|
||||||
|
// affinity for all calls to QueryPerformanceCounter, but that
|
||||||
|
// would be undesirable in the general case because it could
|
||||||
|
// introduce unnecessary context switches and potentially a
|
||||||
|
// CPU bottleneck.
|
||||||
|
//
|
||||||
|
// Note that this issue also applies to callers doing rapid
|
||||||
|
// calls to this function. If a caller wants to mitigate
|
||||||
|
// that, they could enforce the affinitization, or they
|
||||||
|
// could implement a similar sanity check when comparing
|
||||||
|
// returned values from this function.
|
||||||
|
//
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwCurrentTime - _dwInitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetTickCount64() - _dwInitTickCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryUsingHighResolution()
|
||||||
|
{
|
||||||
|
return _fUsingHighResolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DWORD64 _dwInitTime;
|
||||||
|
DWORD64 _dwInitTickCount;
|
||||||
|
DWORD64 _dwPerfCountsPerMillisecond;
|
||||||
|
BOOL _fUsingHighResolution;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _STTIMER_H
|
||||||
|
|
@ -0,0 +1,221 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class FORWARDING_HANDLER;
|
||||||
|
|
||||||
|
class WEBSOCKET_HANDLER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WEBSOCKET_HANDLER();
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~WEBSOCKET_HANDLER();
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
StaticInitialize(
|
||||||
|
BOOL fEnableReferenceTraceLogging
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
StaticTerminate(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Terminate(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TerminateRequest(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Cleanup(ServerStateUnavailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ProcessRequest(
|
||||||
|
FORWARDING_HANDLER *pHandler,
|
||||||
|
IHttpContext * pHttpContext,
|
||||||
|
HINTERNET hRequest,
|
||||||
|
BOOL* fHandleCreated
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnAsyncCompletion(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpSendComplete(
|
||||||
|
WINHTTP_WEB_SOCKET_STATUS * pCompletionStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpShutdownComplete(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpReceiveComplete(
|
||||||
|
WINHTTP_WEB_SOCKET_STATUS * pCompletionStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpIoError(
|
||||||
|
WINHTTP_WEB_SOCKET_ASYNC_RESULT *pCompletionStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum CleanupReason
|
||||||
|
{
|
||||||
|
CleanupReasonUnknown = 0,
|
||||||
|
IdleTimeout = 1,
|
||||||
|
ConnectFailed = 2,
|
||||||
|
ClientDisconnect = 3,
|
||||||
|
ServerDisconnect = 4,
|
||||||
|
ServerStateUnavailable = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
WEBSOCKET_HANDLER(const WEBSOCKET_HANDLER &);
|
||||||
|
void operator=(const WEBSOCKET_HANDLER &);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InsertRequest(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RemoveRequest(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
WINAPI
|
||||||
|
OnReadIoCompletion(
|
||||||
|
HRESULT hrError,
|
||||||
|
VOID * pvCompletionContext,
|
||||||
|
DWORD cbIO,
|
||||||
|
BOOL fUTF8Encoded,
|
||||||
|
BOOL fFinalFragment,
|
||||||
|
BOOL fClose
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
WINAPI
|
||||||
|
OnWriteIoCompletion(
|
||||||
|
HRESULT hrError,
|
||||||
|
VOID * pvCompletionContext,
|
||||||
|
DWORD cbIO,
|
||||||
|
BOOL fUTF8Encoded,
|
||||||
|
BOOL fFinalFragment,
|
||||||
|
BOOL fClose
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Cleanup(
|
||||||
|
CleanupReason reason
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoIisWebSocketReceive(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoWinHttpWebSocketReceive(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoIisWebSocketSend(
|
||||||
|
DWORD cbData,
|
||||||
|
WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoWinHttpWebSocketSend(
|
||||||
|
DWORD cbData,
|
||||||
|
WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnIisSendComplete(
|
||||||
|
HRESULT hrError,
|
||||||
|
DWORD cbIO
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnIisReceiveComplete(
|
||||||
|
HRESULT hrError,
|
||||||
|
DWORD cbIO,
|
||||||
|
BOOL fUTF8Encoded,
|
||||||
|
BOOL fFinalFragment,
|
||||||
|
BOOL fClose
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IncrementOutstandingIo(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DecrementOutstandingIo(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IndicateCompletionToIIS(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const
|
||||||
|
DWORD RECEIVE_BUFFER_SIZE = 4*1024;
|
||||||
|
|
||||||
|
LIST_ENTRY _listEntry;
|
||||||
|
|
||||||
|
IHttpContext3 * _pHttpContext;
|
||||||
|
|
||||||
|
IWebSocketContext * _pWebSocketContext;
|
||||||
|
|
||||||
|
FORWARDING_HANDLER *_pHandler;
|
||||||
|
|
||||||
|
HINTERNET _hWebSocketRequest;
|
||||||
|
|
||||||
|
BYTE _WinHttpReceiveBuffer[RECEIVE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
BYTE _IisReceiveBuffer[RECEIVE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
CRITICAL_SECTION _RequestLock;
|
||||||
|
|
||||||
|
LONG _dwOutstandingIo;
|
||||||
|
|
||||||
|
volatile
|
||||||
|
BOOL _fHandleClosed;
|
||||||
|
|
||||||
|
volatile
|
||||||
|
BOOL _fCleanupInProgress;
|
||||||
|
|
||||||
|
volatile
|
||||||
|
BOOL _fIndicateCompletionToIis;
|
||||||
|
|
||||||
|
volatile
|
||||||
|
BOOL _fReceivedCloseMsg;
|
||||||
|
|
||||||
|
static
|
||||||
|
LIST_ENTRY sm_RequestsListHead;
|
||||||
|
|
||||||
|
static
|
||||||
|
SRWLOCK sm_RequestsListLock;
|
||||||
|
|
||||||
|
static
|
||||||
|
TRACE_LOG * sm_pTraceLog;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef
|
||||||
|
HINTERNET
|
||||||
|
(WINAPI * PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE)(
|
||||||
|
_In_ HINTERNET hRequest,
|
||||||
|
_In_opt_ DWORD_PTR pContext
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
typedef
|
||||||
|
DWORD
|
||||||
|
(WINAPI * PFN_WINHTTP_WEBSOCKET_SEND)(
|
||||||
|
_In_ HINTERNET hWebSocket,
|
||||||
|
_In_ WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType,
|
||||||
|
_In_reads_opt_(dwBufferLength) PVOID pvBuffer,
|
||||||
|
_In_ DWORD dwBufferLength
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
DWORD
|
||||||
|
(WINAPI * PFN_WINHTTP_WEBSOCKET_RECEIVE)(
|
||||||
|
_In_ HINTERNET hWebSocket,
|
||||||
|
_Out_writes_bytes_to_(dwBufferLength, *pdwBytesRead) PVOID pvBuffer,
|
||||||
|
_In_ DWORD dwBufferLength,
|
||||||
|
_Out_range_(0, dwBufferLength) DWORD *pdwBytesRead,
|
||||||
|
_Out_ WINHTTP_WEB_SOCKET_BUFFER_TYPE *peBufferType
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
DWORD
|
||||||
|
(WINAPI * PFN_WINHTTP_WEBSOCKET_SHUTDOWN)(
|
||||||
|
_In_ HINTERNET hWebSocket,
|
||||||
|
_In_ USHORT usStatus,
|
||||||
|
_In_reads_bytes_opt_(dwReasonLength) PVOID pvReason,
|
||||||
|
_In_range_(0, WINHTTP_WEB_SOCKET_MAX_CLOSE_REASON_LENGTH) DWORD dwReasonLength
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
DWORD
|
||||||
|
(WINAPI * PFN_WINHTTP_WEBSOCKET_QUERY_CLOSE_STATUS)(
|
||||||
|
_In_ HINTERNET hWebSocket,
|
||||||
|
_Out_ USHORT *pusStatus,
|
||||||
|
_Out_writes_bytes_to_opt_(dwReasonLength, *pdwReasonLengthConsumed) PVOID pvReason,
|
||||||
|
_In_range_(0, WINHTTP_WEB_SOCKET_MAX_CLOSE_REASON_LENGTH) DWORD dwReasonLength,
|
||||||
|
_Out_range_(0, WINHTTP_WEB_SOCKET_MAX_CLOSE_REASON_LENGTH) DWORD *pdwReasonLengthConsumed
|
||||||
|
);
|
||||||
|
|
||||||
|
class WINHTTP_HELPER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
StaticInitialize();
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
GetFlagsFromBufferType(
|
||||||
|
__in WINHTTP_WEB_SOCKET_BUFFER_TYPE BufferType,
|
||||||
|
__out BOOL * pfUtf8Encoded,
|
||||||
|
__out BOOL * pfFinalFragment,
|
||||||
|
__out BOOL * pfClose
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
GetBufferTypeFromFlags(
|
||||||
|
__in BOOL fUtf8Encoded,
|
||||||
|
__in BOOL fFinalFragment,
|
||||||
|
__in BOOL fClose,
|
||||||
|
__out WINHTTP_WEB_SOCKET_BUFFER_TYPE* pBufferType
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE sm_pfnWinHttpWebSocketCompleteUpgrade;
|
||||||
|
|
||||||
|
static
|
||||||
|
PFN_WINHTTP_WEBSOCKET_SEND sm_pfnWinHttpWebSocketSend;
|
||||||
|
|
||||||
|
static
|
||||||
|
PFN_WINHTTP_WEBSOCKET_RECEIVE sm_pfnWinHttpWebSocketReceive;
|
||||||
|
|
||||||
|
static
|
||||||
|
PFN_WINHTTP_WEBSOCKET_SHUTDOWN sm_pfnWinHttpWebSocketShutdown;
|
||||||
|
|
||||||
|
static
|
||||||
|
PFN_WINHTTP_WEBSOCKET_QUERY_CLOSE_STATUS sm_pfnWinHttpWebSocketQueryCloseStatus;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
LIBRARY aspnetcore
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
RegisterModule
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
;/*++
|
||||||
|
;
|
||||||
|
;Copyright (c) 2014 Microsoft Corporation
|
||||||
|
;
|
||||||
|
;Module Name:
|
||||||
|
;
|
||||||
|
; aspnetcore_msg.mc
|
||||||
|
;
|
||||||
|
;Abstract:
|
||||||
|
;
|
||||||
|
; Asp.Net Core Module localizable messages.
|
||||||
|
;
|
||||||
|
;--*/
|
||||||
|
;
|
||||||
|
;
|
||||||
|
;#ifndef _ASPNETCORE_MSG_H_
|
||||||
|
;#define _ASPNETCORE_MSG_H_
|
||||||
|
;
|
||||||
|
|
||||||
|
SeverityNames=(Success=0x0
|
||||||
|
Informational=0x1
|
||||||
|
Warning=0x2
|
||||||
|
Error=0x3
|
||||||
|
)
|
||||||
|
|
||||||
|
MessageIdTypedef=DWORD
|
||||||
|
|
||||||
|
Messageid=1000
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_PROCESS_START_ERROR
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1001
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_PROCESS_START_SUCCESS
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1002
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_PROCESS_CRASH
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1003
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1004
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_CONFIG_ERROR
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1005
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1006
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
Messageid=1012
|
||||||
|
SymbolicName=ASPNETCORE_EVENT_RECYCLE_APPOFFLINE
|
||||||
|
Language=English
|
||||||
|
%1
|
||||||
|
.
|
||||||
|
|
||||||
|
;
|
||||||
|
;#endif // _ASPNETCORE_MODULE_MSG_H_
|
||||||
|
;
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<!--
|
||||||
|
|
||||||
|
IIS Asp.Net Core Extension Schema
|
||||||
|
|
||||||
|
** Please DO NOT edit this file yourself. **
|
||||||
|
|
||||||
|
If you want to add configuration sections to the schema, you may place
|
||||||
|
them in .xml files similar to this one, in this directory. They will be
|
||||||
|
picked up automatically on startup.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<configSchema>
|
||||||
|
<sectionSchema name="system.webServer/aspNetCore">
|
||||||
|
<attribute name="processPath" type="string" expanded="true"/>
|
||||||
|
<attribute name="arguments" type="string" expanded="true" defaultValue=""/>
|
||||||
|
<attribute name="startupTimeLimit" type="uint" defaultValue="120" validationType="integerRange" validationParameter="0,3600"/>
|
||||||
|
<!-- in seconds -->
|
||||||
|
<attribute name="shutdownTimeLimit" type="uint" defaultValue="10" validationType="integerRange" validationParameter="0,600"/>
|
||||||
|
<!-- in seconds -->
|
||||||
|
<attribute name="rapidFailsPerMinute" type="uint" defaultValue="10" validationType="integerRange" validationParameter="0,100"/>
|
||||||
|
<attribute name="requestTimeout" type="timeSpan" defaultValue="00:02:00" validationType="timeSpanRange" validationParameter="0,1296000,1"/>
|
||||||
|
<attribute name="stdoutLogEnabled" type="bool" defaultValue="false" />
|
||||||
|
<attribute name="stdoutLogFile" type="string" defaultValue=".\aspnetcore-stdout" expanded="true"/>
|
||||||
|
<attribute name="processesPerApplication" type="uint" defaultValue="1" validationType="integerRange" validationParameter="1,100"/>
|
||||||
|
<attribute name="forwardWindowsAuthToken" type="bool" defaultValue="true" />
|
||||||
|
<attribute name="disableStartUpErrorPage" type="bool" defaultValue="false" />
|
||||||
|
<attribute name="hostingModel" type="string" />
|
||||||
|
<element name="recycleOnFileChange">
|
||||||
|
<collection addElement="file" clearElement="clear">
|
||||||
|
<attribute name="path" type="string" required="true" validationType="nonEmptyString" expanded="true"/>
|
||||||
|
</collection>
|
||||||
|
</element>
|
||||||
|
<element name="environmentVariables">
|
||||||
|
<collection addElement="environmentVariable" clearElement="clear" >
|
||||||
|
<attribute name="name" type="string" required="true" validationType="nonEmptyString"/>
|
||||||
|
<attribute name="value" type="string" required="true"/>
|
||||||
|
</collection>
|
||||||
|
</element>
|
||||||
|
<element name="handlerSettings">
|
||||||
|
<collection addElement="handlerSetting" clearElement="clear" >
|
||||||
|
<attribute name="name" type="string" required="true" validationType="nonEmptyString"/>
|
||||||
|
<attribute name="value" type="string" required="true"/>
|
||||||
|
</collection>
|
||||||
|
</element>
|
||||||
|
</sectionSchema>
|
||||||
|
</configSchema>
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
// Microsoft Visual C++ generated resource script.
|
||||||
|
//
|
||||||
|
#include <windows.h>
|
||||||
|
#include "version.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "aspnetcore_msg.rc"
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (United States) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
|
#define FileDescription "IIS AspNetCore Module. Commit: " CommitHash
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 11
|
||||||
|
//
|
||||||
|
|
||||||
|
//1 11
|
||||||
|
//BEGIN
|
||||||
|
// 0x0001, 0x0000, 0x03e8, 0x0000, 0x03ed, 0x0000, 0x0010, 0x0000, 0x0010,
|
||||||
|
// 0x0001, 0x0025, 0x0031, 0x000d, 0x000a, 0x0000, 0x0000, 0x0010, 0x0001,
|
||||||
|
// 0x0025, 0x0031, 0x000d, 0x000a, 0x0000, 0x0000, 0x0010, 0x0001, 0x0025,
|
||||||
|
// 0x0031, 0x000d, 0x000a, 0x0000, 0x0000, 0x0010, 0x0001, 0x0025, 0x0031,
|
||||||
|
// 0x000d, 0x000a, 0x0000, 0x0000, 0x0010, 0x0001, 0x0025, 0x0031, 0x000d,
|
||||||
|
// 0x000a, 0x0000, 0x0000, 0x0010, 0x0001, 0x0025, 0x0031, 0x000d, 0x000a,
|
||||||
|
// 0x0000, 0x0000
|
||||||
|
//END
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TEXTINCLUDE
|
||||||
|
//
|
||||||
|
|
||||||
|
1 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"resource.h\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
2 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
3 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION FileVersion
|
||||||
|
PRODUCTVERSION ProductVersion
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x40004L
|
||||||
|
FILETYPE 0x2L
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "Microsoft"
|
||||||
|
VALUE "FileDescription", FileDescription
|
||||||
|
VALUE "FileVersion", FileVersionStr
|
||||||
|
VALUE "InternalName", "aspnetcore.dll"
|
||||||
|
VALUE "LegalCopyright", "Copyright (C) 2016"
|
||||||
|
VALUE "OriginalFilename", "aspnetcore.dll"
|
||||||
|
VALUE "ProductName", "ASP.NET Core Module"
|
||||||
|
VALUE "ProductVersion", ProductVersionStr
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// String Table
|
||||||
|
//
|
||||||
|
|
||||||
|
STRINGTABLE
|
||||||
|
BEGIN
|
||||||
|
IDS_INVALID_PROPERTY "Property name '%s' in system.webServer/aspNetCore section has invalid value '%s' which does not conform to the prescribed format"
|
||||||
|
IDS_SERVER_ERROR "There was a connection error while trying to route the request."
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // English (United States) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by aspnetcoremodule.rc
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
|
||||||
|
#define IDS_INVALID_PROPERTY 1000
|
||||||
|
#define IDS_SERVER_ERROR 1001
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
APPLICATION::~APPLICATION()
|
||||||
|
{
|
||||||
|
if (m_pAppOfflineHtm != NULL)
|
||||||
|
{
|
||||||
|
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
|
||||||
|
m_pAppOfflineHtm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pFileWatcherEntry != NULL)
|
||||||
|
{
|
||||||
|
// Mark the entry as invalid,
|
||||||
|
// StopMonitor will close the file handle and trigger a FCN
|
||||||
|
// the entry will delete itself when processing this FCN
|
||||||
|
m_pFileWatcherEntry->MarkEntryInValid();
|
||||||
|
m_pFileWatcherEntry->StopMonitor();
|
||||||
|
m_pFileWatcherEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pProcessManager != NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager->ShutdownAllProcesses();
|
||||||
|
m_pProcessManager->DereferenceProcessManager();
|
||||||
|
m_pProcessManager = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION::Initialize(
|
||||||
|
_In_ APPLICATION_MANAGER* pApplicationManager,
|
||||||
|
_In_ LPCWSTR pszApplication,
|
||||||
|
_In_ LPCWSTR pszPhysicalPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
DBG_ASSERT(pszPhysicalPath != NULL);
|
||||||
|
DBG_ASSERT(pApplicationManager != NULL);
|
||||||
|
DBG_ASSERT(pszPhysicalPath != NULL);
|
||||||
|
m_strAppPhysicalPath.Copy(pszPhysicalPath);
|
||||||
|
|
||||||
|
m_pApplicationManager = pApplicationManager;
|
||||||
|
|
||||||
|
hr = m_applicationKey.Initialize(pszApplication);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pProcessManager == NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager = new PROCESS_MANAGER;
|
||||||
|
if (m_pProcessManager == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_pProcessManager->Initialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pFileWatcherEntry == NULL)
|
||||||
|
{
|
||||||
|
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(pApplicationManager->GetFileWatcher());
|
||||||
|
if (m_pFileWatcherEntry == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAppOfflineFileHandle();
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (m_pFileWatcherEntry != NULL)
|
||||||
|
{
|
||||||
|
m_pFileWatcherEntry->DereferenceFileWatcherEntry();
|
||||||
|
m_pFileWatcherEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pProcessManager != NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager->DereferenceProcessManager();
|
||||||
|
m_pProcessManager = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION::StartMonitoringAppOffline()
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
hr = m_pFileWatcherEntry->Create(m_strAppPhysicalPath.QueryStr(), L"app_offline.htm", this, NULL);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
APPLICATION::UpdateAppOfflineFileHandle()
|
||||||
|
{
|
||||||
|
STRU strFilePath;
|
||||||
|
PATH::ConvertPathToFullPath(L".\\app_offline.htm", m_strAppPhysicalPath.QueryStr(), &strFilePath);
|
||||||
|
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
|
||||||
|
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
|
||||||
|
|
||||||
|
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) && GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||||
|
{
|
||||||
|
m_fAppOfflineFound = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_fAppOfflineFound = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// send shutdown signal
|
||||||
|
//
|
||||||
|
|
||||||
|
// The reason why we send the shutdown signal before loading the new app_offline file is because we want to make some delay
|
||||||
|
// before reading the appoffline.htm so that the file change can be done on time.
|
||||||
|
if (m_pProcessManager != NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager->SendShutdownSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
|
||||||
|
|
||||||
|
if ( pNewAppOfflineHtm != NULL )
|
||||||
|
{
|
||||||
|
if (pNewAppOfflineHtm->Load())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// loaded the new app_offline.htm
|
||||||
|
//
|
||||||
|
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
|
||||||
|
|
||||||
|
if (pOldAppOfflineHtm != NULL)
|
||||||
|
{
|
||||||
|
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
|
||||||
|
pOldAppOfflineHtm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ignored the new app_offline file because the file does not exist.
|
||||||
|
pNewAppOfflineHtm->DereferenceAppOfflineHtm();
|
||||||
|
pNewAppOfflineHtm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION_MANAGER::GetApplication(
|
||||||
|
_In_ IHttpContext* pContext,
|
||||||
|
_Out_ APPLICATION ** ppApplication
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
APPLICATION *pApplication = NULL;
|
||||||
|
APPLICATION_KEY key;
|
||||||
|
BOOL fExclusiveLock = FALSE;
|
||||||
|
PCWSTR pszApplicationId = NULL;
|
||||||
|
|
||||||
|
*ppApplication = NULL;
|
||||||
|
|
||||||
|
DBG_ASSERT(pContext != NULL);
|
||||||
|
DBG_ASSERT(pContext->GetApplication() != NULL);
|
||||||
|
pszApplicationId = pContext->GetApplication()->GetApplicationId();
|
||||||
|
|
||||||
|
hr = key.Initialize(pszApplicationId);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pApplicationHash->FindKey(&key, ppApplication);
|
||||||
|
|
||||||
|
if (*ppApplication == NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
pApplication = new APPLICATION();
|
||||||
|
if (pApplication == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = TRUE;
|
||||||
|
m_pApplicationHash->FindKey(&key, ppApplication);
|
||||||
|
|
||||||
|
if (*ppApplication != NULL)
|
||||||
|
{
|
||||||
|
// someone else created the application
|
||||||
|
delete pApplication;
|
||||||
|
pApplication = NULL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pApplication->Initialize(this, pszApplicationId, pContext->GetApplication()->GetApplicationPhysicalPath());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_pApplicationHash->InsertRecord( pApplication );
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = FALSE;
|
||||||
|
|
||||||
|
pApplication->StartMonitoringAppOffline();
|
||||||
|
|
||||||
|
*ppApplication = pApplication;
|
||||||
|
pApplication = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (fExclusiveLock == TRUE)
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (pApplication != NULL)
|
||||||
|
{
|
||||||
|
pApplication->DereferenceApplication();
|
||||||
|
pApplication = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION_MANAGER::RecycleApplication(
|
||||||
|
_In_ LPCWSTR pszApplication
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
APPLICATION_KEY key;
|
||||||
|
|
||||||
|
hr = key.Initialize(pszApplication);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
m_pApplicationHash->DeleteKey(&key);
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION_MANAGER::Get502ErrorPage(
|
||||||
|
_Out_ HTTP_DATA_CHUNK** ppErrorPage
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fExclusiveLock = FALSE;
|
||||||
|
HTTP_DATA_CHUNK *pHttp502ErrorPage = NULL;
|
||||||
|
|
||||||
|
DBG_ASSERT(ppErrorPage != NULL);
|
||||||
|
|
||||||
|
//on-demand create the error page
|
||||||
|
if (m_pHttp502ErrorPage != NULL)
|
||||||
|
{
|
||||||
|
*ppErrorPage = m_pHttp502ErrorPage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = TRUE;
|
||||||
|
if (m_pHttp502ErrorPage != NULL)
|
||||||
|
{
|
||||||
|
*ppErrorPage = m_pHttp502ErrorPage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t maxsize = 5000;
|
||||||
|
pHttp502ErrorPage = new HTTP_DATA_CHUNK();
|
||||||
|
if (pHttp502ErrorPage == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
pHttp502ErrorPage->DataChunkType = HttpDataChunkFromMemory;
|
||||||
|
pHttp502ErrorPage->FromMemory.pBuffer = (PVOID)m_pstrErrorInfo;
|
||||||
|
|
||||||
|
pHttp502ErrorPage->FromMemory.BufferLength = (ULONG)strnlen(m_pstrErrorInfo, maxsize); //(ULONG)(wcslen(m_pstrErrorInfo)); // *sizeof(WCHAR);
|
||||||
|
if(m_pHttp502ErrorPage != NULL)
|
||||||
|
{
|
||||||
|
delete m_pHttp502ErrorPage;
|
||||||
|
}
|
||||||
|
m_pHttp502ErrorPage = pHttp502ErrorPage;
|
||||||
|
*ppErrorPage = m_pHttp502ErrorPage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (fExclusiveLock)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (pHttp502ErrorPage != NULL)
|
||||||
|
{
|
||||||
|
delete pHttp502ErrorPage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,416 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// the destructor will be called once IIS decides to recycle the module context (i.e., application)
|
||||||
|
//
|
||||||
|
if (!m_struApplication.IsEmpty())
|
||||||
|
{
|
||||||
|
APPLICATION_MANAGER::GetInstance()->RecycleApplication(m_struApplication.QueryStr());
|
||||||
|
}
|
||||||
|
if(m_pEnvironmentVariables != NULL)
|
||||||
|
{
|
||||||
|
m_pEnvironmentVariables->Clear();
|
||||||
|
delete m_pEnvironmentVariables;
|
||||||
|
m_pEnvironmentVariables = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ASPNETCORE_CONFIG::GetConfig(
|
||||||
|
_In_ IHttpContext *pHttpContext,
|
||||||
|
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
IHttpApplication *pHttpApplication = pHttpContext->GetApplication();
|
||||||
|
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
|
||||||
|
|
||||||
|
if (ppAspNetCoreConfig == NULL)
|
||||||
|
{
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppAspNetCoreConfig = NULL;
|
||||||
|
|
||||||
|
// potential bug if user sepcific config at virtual dir level
|
||||||
|
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
|
||||||
|
pHttpApplication->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
|
||||||
|
|
||||||
|
if (pAspNetCoreConfig != NULL)
|
||||||
|
{
|
||||||
|
*ppAspNetCoreConfig = pAspNetCoreConfig;
|
||||||
|
pAspNetCoreConfig = NULL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAspNetCoreConfig = new ASPNETCORE_CONFIG;
|
||||||
|
if (pAspNetCoreConfig == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAspNetCoreConfig->Populate(pHttpContext);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pHttpApplication->GetModuleContextContainer()->
|
||||||
|
SetModuleContext(pAspNetCoreConfig, g_pModuleId);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
|
||||||
|
{
|
||||||
|
delete pAspNetCoreConfig;
|
||||||
|
|
||||||
|
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
|
||||||
|
GetModuleContextContainer()->
|
||||||
|
GetModuleContext(g_pModuleId);
|
||||||
|
|
||||||
|
_ASSERT(pAspNetCoreConfig != NULL);
|
||||||
|
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set appliction info here instead of inside Populate()
|
||||||
|
// as the destructor will delete the backend process
|
||||||
|
hr = pAspNetCoreConfig->QueryApplicationPath()->Copy(pHttpApplication->GetApplicationId());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppAspNetCoreConfig = pAspNetCoreConfig;
|
||||||
|
pAspNetCoreConfig = NULL;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (pAspNetCoreConfig != NULL)
|
||||||
|
{
|
||||||
|
delete pAspNetCoreConfig;
|
||||||
|
pAspNetCoreConfig = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ASPNETCORE_CONFIG::Populate(
|
||||||
|
IHttpContext *pHttpContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
STACK_STRU(strSiteConfigPath, 256);
|
||||||
|
STRU strEnvName;
|
||||||
|
STRU strEnvValue;
|
||||||
|
STRU strExpandedEnvValue;
|
||||||
|
IAppHostAdminManager *pAdminManager = NULL;
|
||||||
|
IAppHostElement *pAspNetCoreElement = NULL;
|
||||||
|
IAppHostElement *pWindowsAuthenticationElement = NULL;
|
||||||
|
IAppHostElement *pBasicAuthenticationElement = NULL;
|
||||||
|
IAppHostElement *pAnonymousAuthenticationElement = NULL;
|
||||||
|
IAppHostElement *pEnvVarList = NULL;
|
||||||
|
IAppHostElement *pEnvVar = NULL;
|
||||||
|
IAppHostElementCollection *pEnvVarCollection = NULL;
|
||||||
|
ULONGLONG ullRawTimeSpan = 0;
|
||||||
|
ENUM_INDEX index;
|
||||||
|
ENVIRONMENT_VAR_ENTRY* pEntry = NULL;
|
||||||
|
|
||||||
|
m_pEnvironmentVariables = new ENVIRONMENT_VAR_HASH();
|
||||||
|
if (m_pEnvironmentVariables == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
if (FAILED(hr = m_pEnvironmentVariables->Initialize(37 /*prime*/)))
|
||||||
|
{
|
||||||
|
delete m_pEnvironmentVariables;
|
||||||
|
m_pEnvironmentVariables = NULL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAdminManager = g_pHttpServer->GetAdminManager();
|
||||||
|
|
||||||
|
hr = strSiteConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAdminManager->GetAdminSection(CS_WINDOWS_AUTHENTICATION_SECTION,
|
||||||
|
strSiteConfigPath.QueryStr(),
|
||||||
|
&pWindowsAuthenticationElement);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// assume the corresponding authen was not enabled
|
||||||
|
// as the section may get deleted by user in some HWC case
|
||||||
|
// ToDo: log a warning to event log
|
||||||
|
m_fWindowsAuthEnabled = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = GetElementBoolProperty(pWindowsAuthenticationElement,
|
||||||
|
CS_AUTHENTICATION_ENABLED,
|
||||||
|
&m_fWindowsAuthEnabled);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAdminManager->GetAdminSection(CS_BASIC_AUTHENTICATION_SECTION,
|
||||||
|
strSiteConfigPath.QueryStr(),
|
||||||
|
&pBasicAuthenticationElement);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
m_fBasicAuthEnabled = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = GetElementBoolProperty(pBasicAuthenticationElement,
|
||||||
|
CS_AUTHENTICATION_ENABLED,
|
||||||
|
&m_fBasicAuthEnabled);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAdminManager->GetAdminSection(CS_ANONYMOUS_AUTHENTICATION_SECTION,
|
||||||
|
strSiteConfigPath.QueryStr(),
|
||||||
|
&pAnonymousAuthenticationElement);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
m_fAnonymousAuthEnabled = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = GetElementBoolProperty(pAnonymousAuthenticationElement,
|
||||||
|
CS_AUTHENTICATION_ENABLED,
|
||||||
|
&m_fAnonymousAuthEnabled);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAdminManager->GetAdminSection(CS_ASPNETCORE_SECTION,
|
||||||
|
strSiteConfigPath.QueryStr(),
|
||||||
|
&pAspNetCoreElement);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementStringProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_PROCESS_EXE_PATH,
|
||||||
|
&m_struProcessPath);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementStringProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_PROCESS_ARGUMENTS,
|
||||||
|
&m_struArguments);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementDWORDProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE,
|
||||||
|
&m_dwRapidFailsPerMinute);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// rapidFailsPerMinute cannot be greater than 100.
|
||||||
|
//
|
||||||
|
if (m_dwRapidFailsPerMinute > MAX_RAPID_FAILS_PER_MINUTE)
|
||||||
|
{
|
||||||
|
m_dwRapidFailsPerMinute = MAX_RAPID_FAILS_PER_MINUTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementDWORDProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_PROCESSES_PER_APPLICATION,
|
||||||
|
&m_dwProcessesPerApplication);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementDWORDProperty(
|
||||||
|
pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT,
|
||||||
|
&m_dwStartupTimeLimitInMS
|
||||||
|
);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dwStartupTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND;
|
||||||
|
|
||||||
|
hr = GetElementDWORDProperty(
|
||||||
|
pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT,
|
||||||
|
&m_dwShutdownTimeLimitInMS
|
||||||
|
);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
m_dwShutdownTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND;
|
||||||
|
|
||||||
|
hr = GetElementBoolProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_FORWARD_WINDOWS_AUTH_TOKEN,
|
||||||
|
&m_fForwardWindowsAuthToken);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementBoolProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE,
|
||||||
|
&m_fDisableStartUpErrorPage);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementRawTimeSpanProperty(
|
||||||
|
pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_WINHTTP_REQUEST_TIMEOUT,
|
||||||
|
&ullRawTimeSpan
|
||||||
|
);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dwRequestTimeoutInMS = (DWORD)TIMESPAN_IN_MILLISECONDS(ullRawTimeSpan);
|
||||||
|
|
||||||
|
hr = GetElementBoolProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_STDOUT_LOG_ENABLED,
|
||||||
|
&m_fStdoutLogEnabled);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementStringProperty(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_STDOUT_LOG_FILE,
|
||||||
|
&m_struStdoutLogFile);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetElementChildByName(pAspNetCoreElement,
|
||||||
|
CS_ASPNETCORE_ENVIRONMENT_VARIABLES,
|
||||||
|
&pEnvVarList);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pEnvVarList->get_Collection(&pEnvVarCollection);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hr = FindFirstElement(pEnvVarCollection, &index, &pEnvVar);
|
||||||
|
SUCCEEDED(hr);
|
||||||
|
hr = FindNextElement(pEnvVarCollection, &index, &pEnvVar))
|
||||||
|
{
|
||||||
|
if (hr == S_FALSE)
|
||||||
|
{
|
||||||
|
hr = S_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = GetElementStringProperty(pEnvVar,
|
||||||
|
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_NAME,
|
||||||
|
&strEnvName)) ||
|
||||||
|
FAILED(hr = GetElementStringProperty(pEnvVar,
|
||||||
|
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE,
|
||||||
|
&strEnvValue)) ||
|
||||||
|
FAILED(hr = strEnvName.Append(L"=")) ||
|
||||||
|
FAILED(hr = STRU::ExpandEnvironmentVariables(strEnvValue.QueryStr(), &strExpandedEnvValue)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pEntry = new ENVIRONMENT_VAR_ENTRY();
|
||||||
|
if (pEntry == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = pEntry->Initialize(strEnvName.QueryStr(), strExpandedEnvValue.QueryStr())) ||
|
||||||
|
FAILED(hr = m_pEnvironmentVariables->InsertRecord(pEntry)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
strEnvName.Reset();
|
||||||
|
strEnvValue.Reset();
|
||||||
|
strExpandedEnvValue.Reset();
|
||||||
|
pEnvVar->Release();
|
||||||
|
pEnvVar = NULL;
|
||||||
|
pEntry->Dereference();
|
||||||
|
pEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (pAspNetCoreElement != NULL)
|
||||||
|
{
|
||||||
|
pAspNetCoreElement->Release();
|
||||||
|
pAspNetCoreElement = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEnvVarList != NULL)
|
||||||
|
{
|
||||||
|
pEnvVarList->Release();
|
||||||
|
pEnvVarList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEnvVar != NULL)
|
||||||
|
{
|
||||||
|
pEnvVar->Release();
|
||||||
|
pEnvVar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEnvVarCollection != NULL)
|
||||||
|
{
|
||||||
|
pEnvVarCollection->Release();
|
||||||
|
pEnvVarCollection = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEntry != NULL)
|
||||||
|
{
|
||||||
|
pEntry->Dereference();
|
||||||
|
pEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,481 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
FILE_WATCHER::FILE_WATCHER() :
|
||||||
|
m_hCompletionPort(NULL),
|
||||||
|
m_hChangeNotificationThread(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_WATCHER::~FILE_WATCHER()
|
||||||
|
{
|
||||||
|
if (m_hChangeNotificationThread != NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(m_hChangeNotificationThread);
|
||||||
|
m_hChangeNotificationThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FILE_WATCHER::Create(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
m_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (m_hCompletionPort == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hChangeNotificationThread = CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
ChangeNotificationThread,
|
||||||
|
this,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (m_hChangeNotificationThread == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
|
||||||
|
CloseHandle(m_hCompletionPort);
|
||||||
|
m_hCompletionPort = NULL;
|
||||||
|
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
WINAPI
|
||||||
|
FILE_WATCHER::ChangeNotificationThread(
|
||||||
|
LPVOID pvArg
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
IO completion thread
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
Win32 error
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE_WATCHER * pFileMonitor;
|
||||||
|
BOOL fSuccess = FALSE;
|
||||||
|
DWORD cbCompletion = 0;
|
||||||
|
OVERLAPPED * pOverlapped = NULL;
|
||||||
|
DWORD dwErrorStatus;
|
||||||
|
ULONG_PTR completionKey;
|
||||||
|
|
||||||
|
pFileMonitor = (FILE_WATCHER*)pvArg;
|
||||||
|
DBG_ASSERT(pFileMonitor != NULL);
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
fSuccess = GetQueuedCompletionStatus(
|
||||||
|
pFileMonitor->m_hCompletionPort,
|
||||||
|
&cbCompletion,
|
||||||
|
&completionKey,
|
||||||
|
&pOverlapped,
|
||||||
|
INFINITE);
|
||||||
|
|
||||||
|
DBG_ASSERT(fSuccess);
|
||||||
|
DebugPrint(1, "FILE_WATCHER::ChangeNotificationThread");
|
||||||
|
dwErrorStatus = fSuccess ? ERROR_SUCCESS : GetLastError();
|
||||||
|
|
||||||
|
if (completionKey == FILE_WATCHER_SHUTDOWN_KEY)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_ASSERT(pOverlapped != NULL);
|
||||||
|
if (pOverlapped != NULL)
|
||||||
|
{
|
||||||
|
FileWatcherCompletionRoutine(
|
||||||
|
dwErrorStatus,
|
||||||
|
cbCompletion,
|
||||||
|
pOverlapped);
|
||||||
|
}
|
||||||
|
pOverlapped = NULL;
|
||||||
|
cbCompletion = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
WINAPI
|
||||||
|
FILE_WATCHER::FileWatcherCompletionRoutine(
|
||||||
|
DWORD dwCompletionStatus,
|
||||||
|
DWORD cbCompletion,
|
||||||
|
OVERLAPPED * pOverlapped
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Called when ReadDirectoryChangesW() completes
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
dwCompletionStatus - Error of completion
|
||||||
|
cbCompletion - Bytes of completion
|
||||||
|
pOverlapped - State of completion
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE_WATCHER_ENTRY * pMonitorEntry;
|
||||||
|
pMonitorEntry = CONTAINING_RECORD(pOverlapped, FILE_WATCHER_ENTRY, _overlapped);
|
||||||
|
pMonitorEntry->DereferenceFileWatcherEntry();
|
||||||
|
DBG_ASSERT(pMonitorEntry != NULL);
|
||||||
|
|
||||||
|
pMonitorEntry->HandleChangeCompletion(dwCompletionStatus, cbCompletion);
|
||||||
|
|
||||||
|
if (pMonitorEntry->QueryIsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Continue monitoring
|
||||||
|
//
|
||||||
|
pMonitorEntry->Monitor();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Marked by application distructor
|
||||||
|
// Deference the entry to delete it
|
||||||
|
//
|
||||||
|
pMonitorEntry->DereferenceFileWatcherEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE_WATCHER_ENTRY::FILE_WATCHER_ENTRY(FILE_WATCHER * pFileMonitor) :
|
||||||
|
_pFileMonitor(pFileMonitor),
|
||||||
|
_hDirectory(INVALID_HANDLE_VALUE),
|
||||||
|
_hImpersonationToken(NULL),
|
||||||
|
_pApplication(NULL),
|
||||||
|
_lStopMonitorCalled(0),
|
||||||
|
_cRefs(1),
|
||||||
|
_fIsValid(TRUE)
|
||||||
|
{
|
||||||
|
_dwSignature = FILE_WATCHER_ENTRY_SIGNATURE;
|
||||||
|
InitializeSRWLock(&_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_WATCHER_ENTRY::~FILE_WATCHER_ENTRY()
|
||||||
|
{
|
||||||
|
_dwSignature = FILE_WATCHER_ENTRY_SIGNATURE_FREE;
|
||||||
|
|
||||||
|
if (_hDirectory != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(_hDirectory);
|
||||||
|
_hDirectory = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_hImpersonationToken != NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(_hImpersonationToken);
|
||||||
|
_hImpersonationToken = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(disable:4100)
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FILE_WATCHER_ENTRY::HandleChangeCompletion(
|
||||||
|
_In_ DWORD dwCompletionStatus,
|
||||||
|
_In_ DWORD cbCompletion
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Handle change notification (see if any of associated config files
|
||||||
|
need to be flushed)
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
dwCompletionStatus - Completion status
|
||||||
|
cbCompletion - Bytes of completion
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
FILE_NOTIFY_INFORMATION * pNotificationInfo;
|
||||||
|
BOOL fFileChanged = FALSE;
|
||||||
|
STRU strEventMsg;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&_srwLock);
|
||||||
|
if (!_fIsValid)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When directory handle is closed then HandleChangeCompletion
|
||||||
|
// happens with cbCompletion = 0 and dwCompletionStatus = 0
|
||||||
|
// From documentation it is not clear if that combination
|
||||||
|
// of return values is specific to closing handles or whether
|
||||||
|
// it could also mean an error condition. Hence we will maintain
|
||||||
|
// explicit flag that will help us determine if entry
|
||||||
|
// is being shutdown (StopMonitor() called)
|
||||||
|
//
|
||||||
|
if (_lStopMonitorCalled)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// There could be a FCN overflow
|
||||||
|
// Let assume the file got changed instead of checking files
|
||||||
|
// Othersie we have to cache the file info
|
||||||
|
//
|
||||||
|
if (cbCompletion == 0)
|
||||||
|
{
|
||||||
|
fFileChanged = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNotificationInfo = (FILE_NOTIFY_INFORMATION*)_buffDirectoryChanges.QueryPtr();
|
||||||
|
DBG_ASSERT(pNotificationInfo != NULL);
|
||||||
|
|
||||||
|
while (pNotificationInfo != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// check whether the monitored file got changed
|
||||||
|
//
|
||||||
|
if (_wcsnicmp(pNotificationInfo->FileName,
|
||||||
|
_strFileName.QueryStr(),
|
||||||
|
pNotificationInfo->FileNameLength/sizeof(WCHAR)) == 0)
|
||||||
|
{
|
||||||
|
fFileChanged = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Advance to next notification
|
||||||
|
//
|
||||||
|
if (pNotificationInfo->NextEntryOffset == 0)
|
||||||
|
{
|
||||||
|
pNotificationInfo = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNotificationInfo = (FILE_NOTIFY_INFORMATION*)
|
||||||
|
((PBYTE)pNotificationInfo +
|
||||||
|
pNotificationInfo->NextEntryOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fFileChanged)
|
||||||
|
{
|
||||||
|
LPCWSTR apsz[1];
|
||||||
|
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
|
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG,
|
||||||
|
_strFileName.QueryStr())))
|
||||||
|
{
|
||||||
|
apsz[0] = strEventMsg.QueryStr();
|
||||||
|
|
||||||
|
//
|
||||||
|
// not checking return code because if ReportEvent
|
||||||
|
// fails, we cannot do anything.
|
||||||
|
//
|
||||||
|
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
|
{
|
||||||
|
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
EVENTLOG_INFORMATION_TYPE,
|
||||||
|
0,
|
||||||
|
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE,
|
||||||
|
NULL,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
apsz,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// so far we only monitoring app_offline
|
||||||
|
//
|
||||||
|
_pApplication->UpdateAppOfflineFileHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
ReleaseSRWLockExclusive(&_srwLock);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning( error : 4100 )
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FILE_WATCHER_ENTRY::Monitor(VOID)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD cbRead;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&_srwLock);
|
||||||
|
ReferenceFileWatcherEntry();
|
||||||
|
ZeroMemory(&_overlapped, sizeof(_overlapped));
|
||||||
|
|
||||||
|
if(!ReadDirectoryChangesW(_hDirectory,
|
||||||
|
_buffDirectoryChanges.QueryPtr(),
|
||||||
|
_buffDirectoryChanges.QuerySize(),
|
||||||
|
FALSE, // Watching sub dirs. Set to False now as only monitoring app_offline
|
||||||
|
FILE_NOTIFY_VALID_MASK & ~FILE_NOTIFY_CHANGE_LAST_ACCESS,
|
||||||
|
&cbRead,
|
||||||
|
&_overlapped,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&_srwLock);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FILE_WATCHER_ENTRY::StopMonitor(VOID)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Flag that monitoring is being stopped so that
|
||||||
|
// we know that HandleChangeCompletion() call
|
||||||
|
// can be ignored
|
||||||
|
//
|
||||||
|
InterlockedExchange(&_lStopMonitorCalled, 1);
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&_srwLock);
|
||||||
|
|
||||||
|
if (_hDirectory != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(_hDirectory);
|
||||||
|
_hDirectory = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FILE_WATCHER_ENTRY::Create(
|
||||||
|
_In_ PCWSTR pszDirectoryToMonitor,
|
||||||
|
_In_ PCWSTR pszFileNameToMonitor,
|
||||||
|
_In_ APPLICATION* pApplication,
|
||||||
|
_In_ HANDLE hImpersonationToken
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fRet = FALSE;
|
||||||
|
|
||||||
|
if (pszDirectoryToMonitor == NULL ||
|
||||||
|
pszFileNameToMonitor == NULL ||
|
||||||
|
pApplication == NULL)
|
||||||
|
{
|
||||||
|
DBG_ASSERT(FALSE);
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//remember the application
|
||||||
|
//
|
||||||
|
_pApplication = pApplication;
|
||||||
|
|
||||||
|
if (FAILED(hr = _strFileName.Copy(pszFileNameToMonitor)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = _strDirectoryName.Copy(pszDirectoryToMonitor)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resize change buffer to something "reasonable"
|
||||||
|
//
|
||||||
|
if (!_buffDirectoryChanges.Resize(FILE_WATCHER_ENTRY_BUFFER_SIZE))
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hImpersonationToken != NULL)
|
||||||
|
{
|
||||||
|
fRet = DuplicateHandle(GetCurrentProcess(),
|
||||||
|
hImpersonationToken,
|
||||||
|
GetCurrentProcess(),
|
||||||
|
&_hImpersonationToken,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
|
||||||
|
if (!fRet)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_hImpersonationToken != NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(_hImpersonationToken);
|
||||||
|
_hImpersonationToken = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_hDirectory = CreateFileW(
|
||||||
|
_strDirectoryName.QueryStr(),
|
||||||
|
FILE_LIST_DIRECTORY,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (_hDirectory == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CreateIoCompletionPort(
|
||||||
|
_hDirectory,
|
||||||
|
_pFileMonitor->QueryCompletionPort(),
|
||||||
|
NULL,
|
||||||
|
0) == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start monitoring
|
||||||
|
//
|
||||||
|
hr = Monitor();
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
FORWARDER_CONNECTION::FORWARDER_CONNECTION(
|
||||||
|
VOID
|
||||||
|
) : m_cRefs (1),
|
||||||
|
m_hConnection (NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FORWARDER_CONNECTION::Initialize(
|
||||||
|
DWORD dwPort
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
hr = m_ConnectionKey.Initialize( dwPort );
|
||||||
|
if ( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hConnection = WinHttpConnect(FORWARDING_HANDLER::sm_hSession,
|
||||||
|
L"127.0.0.1",
|
||||||
|
(USHORT) dwPort,
|
||||||
|
0);
|
||||||
|
if (m_hConnection == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Since WinHttp will not emit WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
|
||||||
|
// when closing WebSocket handle on Win8. Register callback at Connect level as a workaround
|
||||||
|
//
|
||||||
|
if (WinHttpSetStatusCallback(m_hConnection,
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
WINHTTP_CALLBACK_FLAG_HANDLES,
|
||||||
|
NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,272 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
#include <IPHlpApi.h>
|
||||||
|
|
||||||
|
HTTP_MODULE_ID g_pModuleId = NULL;
|
||||||
|
IHttpServer * g_pHttpServer = NULL;
|
||||||
|
BOOL g_fAsyncDisconnectAvailable = FALSE;
|
||||||
|
BOOL g_fWinHttpNonBlockingCallbackAvailable = FALSE;
|
||||||
|
PCWSTR g_pszModuleName = NULL;
|
||||||
|
HINSTANCE g_hModule;
|
||||||
|
HINSTANCE g_hWinHttpModule;
|
||||||
|
BOOL g_fWebSocketSupported = FALSE;
|
||||||
|
DWORD g_dwTlsIndex = TLS_OUT_OF_INDEXES;
|
||||||
|
BOOL g_fEnableReferenceCountTracing = FALSE;
|
||||||
|
DWORD g_dwAspNetCoreDebugFlags = 0;
|
||||||
|
BOOL g_fNsiApiNotSupported = FALSE;
|
||||||
|
DWORD g_dwActiveServerProcesses = 0;
|
||||||
|
DWORD g_OptionalWinHttpFlags = 0; //specify additional WinHTTP options when using WinHttpOpenRequest API.
|
||||||
|
DWORD g_dwDebugFlags = 0;
|
||||||
|
PCSTR g_szDebugLabel = "ASPNET_CORE_MODULE";
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
STRA g_strLogs[ASPNETCORE_DEBUG_STRU_ARRAY_SIZE];
|
||||||
|
DWORD g_dwLogCounter = 0;
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(
|
||||||
|
HMODULE hModule,
|
||||||
|
DWORD dwReason,
|
||||||
|
LPVOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (dwReason)
|
||||||
|
{
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
g_hModule = hModule;
|
||||||
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
LoadGlobalConfiguration(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||||
|
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
|
||||||
|
0,
|
||||||
|
KEY_READ,
|
||||||
|
&hKey) == NO_ERROR)
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwData;
|
||||||
|
DWORD cbData;
|
||||||
|
|
||||||
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"OptionalWinHttpFlags",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD))
|
||||||
|
{
|
||||||
|
g_OptionalWinHttpFlags = dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"EnableReferenceCountTracing",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD) && (dwData == 1 || dwData == 0))
|
||||||
|
{
|
||||||
|
g_fEnableReferenceCountTracing = !!dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"DebugFlags",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD))
|
||||||
|
{
|
||||||
|
g_dwAspNetCoreDebugFlags = dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwSize = 0;
|
||||||
|
DWORD dwResult = GetExtendedTcpTable(NULL,
|
||||||
|
&dwSize,
|
||||||
|
FALSE,
|
||||||
|
AF_INET,
|
||||||
|
TCP_TABLE_OWNER_PID_LISTENER,
|
||||||
|
0);
|
||||||
|
if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
g_fNsiApiNotSupported = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
__stdcall
|
||||||
|
RegisterModule(
|
||||||
|
DWORD dwServerVersion,
|
||||||
|
IHttpModuleRegistrationInfo * pModuleInfo,
|
||||||
|
IHttpServer * pHttpServer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine description:
|
||||||
|
|
||||||
|
Function called by IIS immediately after loading the module, used to let
|
||||||
|
IIS know what notifications the module is interested in
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
dwServerVersion - IIS version the module is being loaded on
|
||||||
|
pModuleInfo - info regarding this module
|
||||||
|
pHttpServer - callback functions which can be used by the module at
|
||||||
|
any point
|
||||||
|
|
||||||
|
Return value:
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
CProxyModuleFactory * pFactory = NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
CREATE_DEBUG_PRINT_OBJECT("Asp.Net Core Module");
|
||||||
|
g_dwDebugFlags = DEBUG_FLAGS_ANY;
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
LoadGlobalConfiguration();
|
||||||
|
|
||||||
|
//
|
||||||
|
// 7.0 is 0,7
|
||||||
|
//
|
||||||
|
if (dwServerVersion > MAKELONG(0, 7))
|
||||||
|
{
|
||||||
|
g_fAsyncDisconnectAvailable = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 8.0 is 0,8
|
||||||
|
//
|
||||||
|
if (dwServerVersion >= MAKELONG(0, 8))
|
||||||
|
{
|
||||||
|
// IISOOB:36641 Enable back WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS for Win8.
|
||||||
|
// g_fWinHttpNonBlockingCallbackAvailable = TRUE;
|
||||||
|
g_fWebSocketSupported = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = WINHTTP_HELPER::StaticInitialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND))
|
||||||
|
{
|
||||||
|
g_fWebSocketSupported = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pModuleId = pModuleInfo->GetId();
|
||||||
|
g_pszModuleName = pModuleInfo->GetName();
|
||||||
|
g_pHttpServer = pHttpServer;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
for (int i = 0; i < ASPNETCORE_DEBUG_STRU_ARRAY_SIZE; i++)
|
||||||
|
{
|
||||||
|
g_strLogs[i].Resize(ASPNETCORE_DEBUG_STRU_BUFFER_SIZE + 1);
|
||||||
|
}
|
||||||
|
#endif // DEBUG
|
||||||
|
//
|
||||||
|
// WinHTTP does not create enough threads, ask it to create more.
|
||||||
|
// Starting in Windows 7, this setting is ignored because WinHTTP
|
||||||
|
// uses a thread pool.
|
||||||
|
//
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
DWORD dwThreadCount = (si.dwNumberOfProcessors * 3 + 1) / 2;
|
||||||
|
WinHttpSetOption(NULL,
|
||||||
|
WINHTTP_OPTION_WORKER_THREAD_COUNT,
|
||||||
|
&dwThreadCount,
|
||||||
|
sizeof(dwThreadCount));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the factory before any static initialization.
|
||||||
|
// The CProxyModuleFactory::Terminate method will clean any
|
||||||
|
// static object initialized.
|
||||||
|
//
|
||||||
|
pFactory = new CProxyModuleFactory;
|
||||||
|
if (pFactory == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pModuleInfo->SetRequestNotifications(
|
||||||
|
pFactory,
|
||||||
|
RQ_EXECUTE_REQUEST_HANDLER,
|
||||||
|
0);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFactory = NULL;
|
||||||
|
g_pResponseHeaderHash = new RESPONSE_HEADER_HASH;
|
||||||
|
if (g_pResponseHeaderHash == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = g_pResponseHeaderHash->Initialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = ALLOC_CACHE_HANDLER::StaticInitialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = FORWARDING_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = WEBSOCKET_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (pFactory != NULL)
|
||||||
|
{
|
||||||
|
pFactory->Terminate();
|
||||||
|
pFactory = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,442 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
// static
|
||||||
|
HRESULT
|
||||||
|
PATH::SplitUrl(
|
||||||
|
PCWSTR pszDestinationUrl,
|
||||||
|
BOOL *pfSecure,
|
||||||
|
STRU *pstrDestination,
|
||||||
|
STRU *pstrUrl
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Split the URL specified for forwarding into its specific components
|
||||||
|
The format of the URL looks like
|
||||||
|
http[s]://destination[:port]/path
|
||||||
|
when port is omitted, the default port for that specific protocol is used
|
||||||
|
when host is omitted, it gets the same value as the destination
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszDestinationUrl - the url to be split up
|
||||||
|
pfSecure - SSL to be used in forwarding?
|
||||||
|
pstrDestination - destination
|
||||||
|
pDestinationPort - port
|
||||||
|
pstrUrl - URL
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// First determine if the target is secure
|
||||||
|
//
|
||||||
|
if (_wcsnicmp(pszDestinationUrl, L"http://", 7) == 0)
|
||||||
|
{
|
||||||
|
*pfSecure = FALSE;
|
||||||
|
pszDestinationUrl += 7;
|
||||||
|
}
|
||||||
|
else if (_wcsnicmp(pszDestinationUrl, L"https://", 8) == 0)
|
||||||
|
{
|
||||||
|
*pfSecure = TRUE;
|
||||||
|
pszDestinationUrl += 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pszDestinationUrl == L'\0')
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find the 3rd slash corresponding to the url
|
||||||
|
//
|
||||||
|
LPCWSTR pszSlash = wcschr(pszDestinationUrl, L'/');
|
||||||
|
if (pszSlash == NULL)
|
||||||
|
{
|
||||||
|
if (FAILED(hr = pstrUrl->Copy(L"/", 1)) ||
|
||||||
|
FAILED(hr = pstrDestination->Copy(pszDestinationUrl)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FAILED(hr = pstrUrl->Copy(pszSlash)) ||
|
||||||
|
FAILED(hr = pstrDestination->Copy(pszDestinationUrl,
|
||||||
|
(DWORD)(pszSlash - pszDestinationUrl))))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change a hexadecimal digit to its numerical equivalent
|
||||||
|
#define TOHEX( ch ) \
|
||||||
|
((ch) > L'9' ? \
|
||||||
|
(ch) >= L'a' ? \
|
||||||
|
(ch) - L'a' + 10 : \
|
||||||
|
(ch) - L'A' + 10 \
|
||||||
|
: (ch) - L'0')
|
||||||
|
|
||||||
|
// static
|
||||||
|
HRESULT
|
||||||
|
PATH::UnEscapeUrl(
|
||||||
|
PCWSTR pszUrl,
|
||||||
|
DWORD cchUrl,
|
||||||
|
bool fCopyQuery,
|
||||||
|
STRA * pstrResult
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
CHAR pch[2];
|
||||||
|
pch[1] = '\0';
|
||||||
|
DWORD cchStart = 0;
|
||||||
|
DWORD index = 0;
|
||||||
|
|
||||||
|
while (index < cchUrl &&
|
||||||
|
(fCopyQuery || pszUrl[index] != L'?'))
|
||||||
|
{
|
||||||
|
switch (pszUrl[index])
|
||||||
|
{
|
||||||
|
case L'%':
|
||||||
|
if (iswxdigit(pszUrl[index+1]) && iswxdigit(pszUrl[index+2]))
|
||||||
|
{
|
||||||
|
if (index > cchStart &&
|
||||||
|
FAILED(hr = pstrResult->AppendW(pszUrl + cchStart,
|
||||||
|
index - cchStart)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
cchStart = index+3;
|
||||||
|
|
||||||
|
pch[0] = static_cast<CHAR>(TOHEX(pszUrl[index+1]) * 16 +
|
||||||
|
TOHEX(pszUrl[index+2]));
|
||||||
|
if (FAILED(hr = pstrResult->Append(pch, 1)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
index += 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__fallthrough;
|
||||||
|
default:
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > cchStart)
|
||||||
|
{
|
||||||
|
return pstrResult->AppendW(pszUrl + cchStart,
|
||||||
|
index - cchStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
HRESULT
|
||||||
|
PATH::UnEscapeUrl(
|
||||||
|
PCWSTR pszUrl,
|
||||||
|
DWORD cchUrl,
|
||||||
|
STRU * pstrResult
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
WCHAR pch[2];
|
||||||
|
pch[1] = L'\0';
|
||||||
|
DWORD cchStart = 0;
|
||||||
|
DWORD index = 0;
|
||||||
|
bool fInQuery = FALSE;
|
||||||
|
|
||||||
|
while (index < cchUrl)
|
||||||
|
{
|
||||||
|
switch (pszUrl[index])
|
||||||
|
{
|
||||||
|
case L'%':
|
||||||
|
if (iswxdigit(pszUrl[index+1]) && iswxdigit(pszUrl[index+2]))
|
||||||
|
{
|
||||||
|
if (index > cchStart &&
|
||||||
|
FAILED(hr = pstrResult->Append(pszUrl + cchStart,
|
||||||
|
index - cchStart)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
cchStart = index+3;
|
||||||
|
|
||||||
|
pch[0] = static_cast<WCHAR>(TOHEX(pszUrl[index+1]) * 16 +
|
||||||
|
TOHEX(pszUrl[index+2]));
|
||||||
|
if (FAILED(hr = pstrResult->Append(pch, 1)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
index += 3;
|
||||||
|
if (pch[0] == L'?')
|
||||||
|
{
|
||||||
|
fInQuery = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L'/':
|
||||||
|
if (fInQuery)
|
||||||
|
{
|
||||||
|
if (index > cchStart &&
|
||||||
|
FAILED(hr = pstrResult->Append(pszUrl + cchStart,
|
||||||
|
index - cchStart)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
cchStart = index+1;
|
||||||
|
|
||||||
|
if (FAILED(hr = pstrResult->Append(L"\\", 1)))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__fallthrough;
|
||||||
|
default:
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > cchStart)
|
||||||
|
{
|
||||||
|
return pstrResult->Append(pszUrl + cchStart,
|
||||||
|
index - cchStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PATH::EscapeAbsPath(
|
||||||
|
IHttpRequest * pRequest,
|
||||||
|
STRU * strEscapedUrl
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
STRU strAbsPath;
|
||||||
|
LPCWSTR pszAbsPath = NULL;
|
||||||
|
LPCWSTR pszFindStr = NULL;
|
||||||
|
|
||||||
|
hr = strAbsPath.Copy( pRequest->GetRawHttpRequest()->CookedUrl.pAbsPath,
|
||||||
|
pRequest->GetRawHttpRequest()->CookedUrl.AbsPathLength / sizeof(WCHAR) );
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszAbsPath = strAbsPath.QueryStr();
|
||||||
|
pszFindStr = wcschr(pszAbsPath, L'?');
|
||||||
|
|
||||||
|
while(pszFindStr != NULL)
|
||||||
|
{
|
||||||
|
strEscapedUrl->Append( pszAbsPath, pszFindStr - pszAbsPath);
|
||||||
|
strEscapedUrl->Append(L"%3F");
|
||||||
|
pszAbsPath = pszFindStr + 1;
|
||||||
|
pszFindStr = wcschr(pszAbsPath, L'?');
|
||||||
|
}
|
||||||
|
|
||||||
|
strEscapedUrl->Append(pszAbsPath);
|
||||||
|
strEscapedUrl->Append(pRequest->GetRawHttpRequest()->CookedUrl.pQueryString,
|
||||||
|
pRequest->GetRawHttpRequest()->CookedUrl.QueryStringLength / sizeof(WCHAR));
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
PATH::IsValidAttributeNameChar(
|
||||||
|
WCHAR ch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Values based on ASP.NET rendering for cookie names. RFC 2965 is not clear
|
||||||
|
// what the non-special characters are.
|
||||||
|
//
|
||||||
|
return ch == L'\t' || (ch > 31 && ch < 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
PATH::FindInMultiString(
|
||||||
|
PCWSTR pszMultiString,
|
||||||
|
PCWSTR pszStringToFind
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (*pszMultiString != L'\0')
|
||||||
|
{
|
||||||
|
if (wcscmp(pszMultiString, pszStringToFind) == 0)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
pszMultiString += wcslen(pszMultiString) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
PATH::IsValidQueryStringName(
|
||||||
|
PCWSTR pszName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (*pszName != L'\0')
|
||||||
|
{
|
||||||
|
WCHAR c = *pszName;
|
||||||
|
if (c != L'-' && c != L'_' && c != L'+' &&
|
||||||
|
c != L'.' && c != L'*' && c != L'$' && c != L'%' && c != L',' &&
|
||||||
|
!iswalnum(c))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
pszName++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
PATH::IsValidHeaderName(
|
||||||
|
PCWSTR pszName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (*pszName != L'\0')
|
||||||
|
{
|
||||||
|
WCHAR c = *pszName;
|
||||||
|
if (c != L'-' && c != L'_' && c != L'+' &&
|
||||||
|
c != L'.' && c != L'*' && c != L'$' && c != L'%'
|
||||||
|
&& !iswalnum(c))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
pszName++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PATH::IsPathUnc(
|
||||||
|
__in LPCWSTR pszPath,
|
||||||
|
__out BOOL * pfIsUnc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
STRU strTempPath;
|
||||||
|
|
||||||
|
if ( pszPath == NULL || pfIsUnc == NULL )
|
||||||
|
{
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = MakePathCanonicalizationProof( (LPWSTR) pszPath, &strTempPath );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MakePathCanonicalizationProof will map \\?\UNC, \\.\UNC and \\ to \\?\UNC
|
||||||
|
//
|
||||||
|
(*pfIsUnc) = ( _wcsnicmp( strTempPath.QueryStr(), L"\\\\?\\UNC\\", 8 /* sizeof \\?\UNC\ */) == 0 );
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PATH::ConvertPathToFullPath(
|
||||||
|
_In_ LPCWSTR pszPath,
|
||||||
|
_In_ LPCWSTR pszRootPath,
|
||||||
|
_Out_ STRU* pStruFullPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
STRU strFileFullPath;
|
||||||
|
LPWSTR pszFullPath = NULL;
|
||||||
|
|
||||||
|
// if relative path, prefix with root path and then convert to absolute path.
|
||||||
|
if( pszPath[0] == L'.' )
|
||||||
|
{
|
||||||
|
hr = strFileFullPath.Copy(pszRootPath);
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!strFileFullPath.EndsWith(L"\\"))
|
||||||
|
{
|
||||||
|
hr = strFileFullPath.Append(L"\\");
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strFileFullPath.Append( pszPath );
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszFullPath = new WCHAR[ strFileFullPath.QueryCCH() + 1];
|
||||||
|
if( pszFullPath == NULL )
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_wfullpath( pszFullPath,
|
||||||
|
strFileFullPath.QueryStr(),
|
||||||
|
strFileFullPath.QueryCCH() + 1 ) == NULL )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to canonical path
|
||||||
|
hr = MakePathCanonicalizationProof( pszFullPath, pStruFullPath );
|
||||||
|
if(FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if( pszFullPath != NULL )
|
||||||
|
{
|
||||||
|
delete[] pszFullPath;
|
||||||
|
pszFullPath = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright(c).NET Foundation.All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#pragma warning( disable : 4091)
|
||||||
|
|
||||||
|
//
|
||||||
|
// System related headers
|
||||||
|
//
|
||||||
|
#define _WINSOCKAPI_
|
||||||
|
|
||||||
|
#define NTDDI_VERSION 0x06010000
|
||||||
|
#define WINVER 0x0601
|
||||||
|
#define _WIN32_WINNT 0x0601
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <atlbase.h>
|
||||||
|
#include <pdh.h>
|
||||||
|
|
||||||
|
//#include <ntassert.h>
|
||||||
|
#include <Shlobj.h>
|
||||||
|
#include <httpserv.h>
|
||||||
|
|
||||||
|
// This should remove our issue of compiling for win7 without header files.
|
||||||
|
// We force the Windows 8 version check logic in iiswebsocket.h to succeed even though we're compiling for Windows 7.
|
||||||
|
// Then, we set the version defines back to Windows 7 to for the remainder of the compilation.
|
||||||
|
#undef NTDDI_VERSION
|
||||||
|
#undef WINVER
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define NTDDI_VERSION 0x06020000
|
||||||
|
#define WINVER 0x0602
|
||||||
|
#define _WIN32_WINNT 0x0602
|
||||||
|
#include <iiswebsocket.h>
|
||||||
|
#undef NTDDI_VERSION
|
||||||
|
#undef WINVER
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
|
||||||
|
#define NTDDI_VERSION 0x06010000
|
||||||
|
#define WINVER 0x0601
|
||||||
|
#define _WIN32_WINNT 0x0601
|
||||||
|
|
||||||
|
#include <httptrace.h>
|
||||||
|
#include <winhttp.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Option available starting Windows 8.
|
||||||
|
// 111 is the value in SDK on May 15, 2012.
|
||||||
|
//
|
||||||
|
#ifndef WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS
|
||||||
|
#define WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS 111
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ASPNETCORE_EVENT_PROVIDER L"IIS AspNetCore Module"
|
||||||
|
#define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module"
|
||||||
|
|
||||||
|
#define TIMESPAN_IN_MILLISECONDS(x) ((x)/((LONGLONG)(10000)))
|
||||||
|
#define TIMESPAN_IN_SECONDS(x) ((TIMESPAN_IN_MILLISECONDS(x))/((LONGLONG)(1000)))
|
||||||
|
#define TIMESPAN_IN_MINUTES(x) ((TIMESPAN_IN_SECONDS(x))/((LONGLONG)(60)))
|
||||||
|
|
||||||
|
#ifdef max
|
||||||
|
#undef max
|
||||||
|
template<typename T> inline T max(T a, T b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef min
|
||||||
|
#undef min
|
||||||
|
template<typename T> inline T min(T a, T b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline bool IsSpace(char ch)
|
||||||
|
{
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case 32: // ' '
|
||||||
|
case 9: // '\t'
|
||||||
|
case 10: // '\n'
|
||||||
|
case 13: // '\r'
|
||||||
|
case 11: // '\v'
|
||||||
|
case 12: // '\f'
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <hashfn.h>
|
||||||
|
#include <hashtable.h>
|
||||||
|
#include <stringa.h>
|
||||||
|
#include <stringu.h>
|
||||||
|
#include <treehash.h>
|
||||||
|
|
||||||
|
#include <dbgutil.h>
|
||||||
|
#include "ahutil.h"
|
||||||
|
#include "multisz.h"
|
||||||
|
#include "multisza.h"
|
||||||
|
#include "sttimer.h"
|
||||||
|
#include <listentry.h>
|
||||||
|
#include <base64.h>
|
||||||
|
#include <datetime.h>
|
||||||
|
#include <reftrace.h>
|
||||||
|
#include <acache.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "filewatcher.h"
|
||||||
|
#include "environmentvariablehash.h"
|
||||||
|
#include "..\aspnetcore_msg.h"
|
||||||
|
#include "aspnetcoreconfig.h"
|
||||||
|
#include "serverprocess.h"
|
||||||
|
#include "processmanager.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include "applicationmanager.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "debugutil.h"
|
||||||
|
#include "protocolconfig.h"
|
||||||
|
#include "responseheaderhash.h"
|
||||||
|
#include "forwarderconnection.h"
|
||||||
|
#include "winhttphelper.h"
|
||||||
|
#include "websockethandler.h"
|
||||||
|
#include "forwardinghandler.h"
|
||||||
|
#include "proxymodule.h"
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
DWORD
|
||||||
|
WIN32_FROM_HRESULT(
|
||||||
|
HRESULT hr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((FAILED(hr)) &&
|
||||||
|
(HRESULT_FACILITY(hr) == FACILITY_WIN32))
|
||||||
|
{
|
||||||
|
return HRESULT_CODE(hr);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
HRESULT
|
||||||
|
HRESULT_FROM_GETLASTERROR()
|
||||||
|
{
|
||||||
|
return ( GetLastError() != NO_ERROR )
|
||||||
|
? HRESULT_FROM_WIN32( GetLastError() )
|
||||||
|
: E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern BOOL g_fAsyncDisconnectAvailable;
|
||||||
|
extern PVOID g_pModuleId;
|
||||||
|
extern BOOL g_fWebSocketSupported;
|
||||||
|
extern BOOL g_fEnableReferenceCountTracing;
|
||||||
|
extern DWORD g_dwActiveServerProcesses;
|
||||||
|
|
@ -0,0 +1,294 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PROCESS_MANAGER::Initialize(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
WSADATA wsaData;
|
||||||
|
int result;
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
|
||||||
|
if( !sm_fWSAStartupDone )
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
fLocked = TRUE;
|
||||||
|
|
||||||
|
if( !sm_fWSAStartupDone )
|
||||||
|
{
|
||||||
|
if( (result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( result );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
sm_fWSAStartupDone = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
fLocked = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dwRapidFailTickStart = GetTickCount();
|
||||||
|
|
||||||
|
if( m_hNULHandle == NULL )
|
||||||
|
{
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
m_hNULHandle = CreateFileW( L"NUL",
|
||||||
|
FILE_WRITE_DATA,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
&saAttr,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL );
|
||||||
|
if( m_hNULHandle == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_GETLASTERROR();
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if(fLocked)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_MANAGER::~PROCESS_MANAGER()
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
|
||||||
|
if( m_ppServerProcessList != NULL )
|
||||||
|
{
|
||||||
|
for( DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
|
||||||
|
{
|
||||||
|
if( m_ppServerProcessList[i] != NULL )
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[i]->DereferenceServerProcess();
|
||||||
|
m_ppServerProcessList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] m_ppServerProcessList;
|
||||||
|
m_ppServerProcessList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_hNULHandle != NULL )
|
||||||
|
{
|
||||||
|
CloseHandle( m_hNULHandle );
|
||||||
|
m_hNULHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sm_fWSAStartupDone )
|
||||||
|
{
|
||||||
|
WSACleanup();
|
||||||
|
sm_fWSAStartupDone = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PROCESS_MANAGER::GetProcess(
|
||||||
|
_In_ IHttpContext *context,
|
||||||
|
_In_ ASPNETCORE_CONFIG *pConfig,
|
||||||
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fSharedLock = FALSE;
|
||||||
|
BOOL fExclusiveLock = FALSE;
|
||||||
|
PCWSTR apsz[1];
|
||||||
|
STACK_STRU( strEventMsg, 256 );
|
||||||
|
DWORD dwProcessIndex = 0;
|
||||||
|
SERVER_PROCESS **ppSelectedServerProcess = NULL;
|
||||||
|
|
||||||
|
if (!m_fServerProcessListReady)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
fExclusiveLock = TRUE;
|
||||||
|
|
||||||
|
if (!m_fServerProcessListReady)
|
||||||
|
{
|
||||||
|
m_dwProcessesPerApplication = pConfig->QueryProcessesPerApplication();
|
||||||
|
m_ppServerProcessList = new SERVER_PROCESS*[m_dwProcessesPerApplication];
|
||||||
|
if(m_ppServerProcessList == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(DWORD i=0;i<m_dwProcessesPerApplication;++i)
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_fServerProcessListReady = TRUE;
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
fExclusiveLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockShared( &m_srwLock );
|
||||||
|
fSharedLock = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// round robin through to the next available process.
|
||||||
|
//
|
||||||
|
|
||||||
|
dwProcessIndex = (DWORD) InterlockedIncrement64( (LONGLONG*) &m_dwRouteToProcessIndex );
|
||||||
|
dwProcessIndex = dwProcessIndex % m_dwProcessesPerApplication;
|
||||||
|
ppSelectedServerProcess = &m_ppServerProcessList[dwProcessIndex];
|
||||||
|
|
||||||
|
if( *ppSelectedServerProcess != NULL &&
|
||||||
|
m_ppServerProcessList[dwProcessIndex]->IsReady() )
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
||||||
|
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockShared( &m_srwLock );
|
||||||
|
fSharedLock = FALSE;
|
||||||
|
// should make the lock per process so that we can start processes simultaneously ?
|
||||||
|
|
||||||
|
if(m_ppServerProcessList[dwProcessIndex] == NULL || !m_ppServerProcessList[dwProcessIndex]->IsReady())
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
fExclusiveLock = TRUE;
|
||||||
|
|
||||||
|
if( m_ppServerProcessList[dwProcessIndex] != NULL )
|
||||||
|
{
|
||||||
|
if( !m_ppServerProcessList[dwProcessIndex]->IsReady() )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// terminate existing process that is not ready
|
||||||
|
// before creating new one.
|
||||||
|
//
|
||||||
|
|
||||||
|
ShutdownProcessNoLock( m_ppServerProcessList[dwProcessIndex] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// server is already up and ready to serve requests.
|
||||||
|
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
||||||
|
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( RapidFailsPerMinuteExceeded(pConfig->QueryRapidFailsPerMinute()) )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// rapid fails per minute exceeded, do not create new process.
|
||||||
|
//
|
||||||
|
|
||||||
|
if( SUCCEEDED( strEventMsg.SafeSnwprintf(
|
||||||
|
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG,
|
||||||
|
pConfig->QueryRapidFailsPerMinute() ) ) )
|
||||||
|
{
|
||||||
|
apsz[0] = strEventMsg.QueryStr();
|
||||||
|
|
||||||
|
//
|
||||||
|
// not checking return code because if ReportEvent
|
||||||
|
// fails, we cannot do anything.
|
||||||
|
//
|
||||||
|
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
|
{
|
||||||
|
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
EVENTLOG_INFORMATION_TYPE,
|
||||||
|
0,
|
||||||
|
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED,
|
||||||
|
NULL,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
apsz,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_ppServerProcessList[dwProcessIndex] == NULL )
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[dwProcessIndex] = new SERVER_PROCESS();
|
||||||
|
if( m_ppServerProcessList[dwProcessIndex] == NULL )
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_ppServerProcessList[dwProcessIndex]->Initialize(
|
||||||
|
this,
|
||||||
|
pConfig->QueryProcessPath(),
|
||||||
|
pConfig->QueryArguments(),
|
||||||
|
pConfig->QueryStartupTimeLimitInMS(),
|
||||||
|
pConfig->QueryShutdownTimeLimitInMS(),
|
||||||
|
pConfig->QueryWindowsAuthEnabled(),
|
||||||
|
pConfig->QueryBasicAuthEnabled(),
|
||||||
|
pConfig->QueryAnonymousAuthEnabled(),
|
||||||
|
pConfig->QueryEnvironmentVariables(),
|
||||||
|
pConfig->QueryStdoutLogEnabled(),
|
||||||
|
pConfig->QueryStdoutLogFile()
|
||||||
|
);
|
||||||
|
if( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_ppServerProcessList[dwProcessIndex]->StartProcess(context);
|
||||||
|
if( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !m_ppServerProcessList[dwProcessIndex]->IsReady() )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( ERROR_CREATE_FAILED );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
||||||
|
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
if(m_ppServerProcessList[dwProcessIndex] != NULL )
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[dwProcessIndex]->DereferenceServerProcess();
|
||||||
|
m_ppServerProcessList[dwProcessIndex] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fSharedLock )
|
||||||
|
{
|
||||||
|
ReleaseSRWLockShared( &m_srwLock );
|
||||||
|
fSharedLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fExclusiveLock )
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
fExclusiveLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PROTOCOL_CONFIG::Initialize()
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
STRU strTemp;
|
||||||
|
|
||||||
|
m_fKeepAlive = TRUE;
|
||||||
|
m_msTimeout = 120000;
|
||||||
|
m_fPreserveHostHeader = TRUE;
|
||||||
|
m_fReverseRewriteHeaders = FALSE;
|
||||||
|
|
||||||
|
if (FAILED(hr = m_strXForwardedForName.CopyW(L"X-Forwarded-For")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = m_strSslHeaderName.CopyW(L"X-Forwarded-Proto")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = m_strClientCertName.CopyW(L"MS-ASPNETCORE-CLIENTCERT")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fIncludePortInXForwardedFor = TRUE;
|
||||||
|
m_dwMinResponseBuffer = 0; // no response buffering
|
||||||
|
m_dwResponseBufferLimit = 4096*1024;
|
||||||
|
m_dwMaxResponseHeaderSize = 65536;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PROTOCOL_CONFIG::OverrideConfig(
|
||||||
|
ASPNETCORE_CONFIG *pAspNetCoreConfig
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_msTimeout = pAspNetCoreConfig->QueryRequestTimeoutInMS();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
__override
|
||||||
|
HRESULT
|
||||||
|
CProxyModuleFactory::GetHttpModule(
|
||||||
|
CHttpModule ** ppModule,
|
||||||
|
IModuleAllocator * pAllocator
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CProxyModule *pModule = new (pAllocator) CProxyModule();
|
||||||
|
if (pModule == NULL)
|
||||||
|
{
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppModule = pModule;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
VOID
|
||||||
|
CProxyModuleFactory::Terminate(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine description:
|
||||||
|
|
||||||
|
Function called by IIS for global (non-request-specific) notifications
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Return value:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FORWARDING_HANDLER::StaticTerminate();
|
||||||
|
|
||||||
|
WEBSOCKET_HANDLER::StaticTerminate();
|
||||||
|
|
||||||
|
if (g_pResponseHeaderHash != NULL)
|
||||||
|
{
|
||||||
|
g_pResponseHeaderHash->Clear();
|
||||||
|
delete g_pResponseHeaderHash;
|
||||||
|
g_pResponseHeaderHash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLOC_CACHE_HANDLER::StaticTerminate();
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CProxyModule::CProxyModule(
|
||||||
|
) : m_pHandler(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CProxyModule::~CProxyModule()
|
||||||
|
{
|
||||||
|
if (m_pHandler != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// This will be called when the main notification is cleaned up
|
||||||
|
// i.e., the request is done with IIS pipeline
|
||||||
|
//
|
||||||
|
m_pHandler->DereferenceForwardingHandler();
|
||||||
|
m_pHandler = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
CProxyModule::OnExecuteRequestHandler(
|
||||||
|
IHttpContext * pHttpContext,
|
||||||
|
IHttpEventProvider *
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_pHandler = new FORWARDING_HANDLER(pHttpContext);
|
||||||
|
if (m_pHandler == NULL)
|
||||||
|
{
|
||||||
|
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, E_OUTOFMEMORY);
|
||||||
|
return RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_pHandler->OnExecuteRequestHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
CProxyModule::OnAsyncCompletion(
|
||||||
|
IHttpContext *,
|
||||||
|
DWORD dwNotification,
|
||||||
|
BOOL fPostNotification,
|
||||||
|
IHttpEventProvider *,
|
||||||
|
IHttpCompletionInfo * pCompletionInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(dwNotification);
|
||||||
|
UNREFERENCED_PARAMETER(fPostNotification);
|
||||||
|
DBG_ASSERT(dwNotification == RQ_EXECUTE_REQUEST_HANDLER);
|
||||||
|
DBG_ASSERT(fPostNotification == FALSE);
|
||||||
|
|
||||||
|
return m_pHandler->OnAsyncCompletion(
|
||||||
|
pCompletionInfo->GetCompletionBytes(),
|
||||||
|
pCompletionInfo->GetCompletionStatus());
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
RESPONSE_HEADER_HASH * g_pResponseHeaderHash = NULL;
|
||||||
|
|
||||||
|
HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] =
|
||||||
|
{
|
||||||
|
{ "Cache-Control", HttpHeaderCacheControl },
|
||||||
|
{ "Connection", HttpHeaderConnection },
|
||||||
|
{ "Date", HttpHeaderDate },
|
||||||
|
{ "Keep-Alive", HttpHeaderKeepAlive },
|
||||||
|
{ "Pragma", HttpHeaderPragma },
|
||||||
|
{ "Trailer", HttpHeaderTrailer },
|
||||||
|
{ "Transfer-Encoding", HttpHeaderTransferEncoding },
|
||||||
|
{ "Upgrade", HttpHeaderUpgrade },
|
||||||
|
{ "Via", HttpHeaderVia },
|
||||||
|
{ "Warning", HttpHeaderWarning },
|
||||||
|
{ "Allow", HttpHeaderAllow },
|
||||||
|
{ "Content-Length", HttpHeaderContentLength },
|
||||||
|
{ "Content-Type", HttpHeaderContentType },
|
||||||
|
{ "Content-Encoding", HttpHeaderContentEncoding },
|
||||||
|
{ "Content-Language", HttpHeaderContentLanguage },
|
||||||
|
{ "Content-Location", HttpHeaderContentLocation },
|
||||||
|
{ "Content-MD5", HttpHeaderContentMd5 },
|
||||||
|
{ "Content-Range", HttpHeaderContentRange },
|
||||||
|
{ "Expires", HttpHeaderExpires },
|
||||||
|
{ "Last-Modified", HttpHeaderLastModified },
|
||||||
|
{ "Accept-Ranges", HttpHeaderAcceptRanges },
|
||||||
|
{ "Age", HttpHeaderAge },
|
||||||
|
{ "ETag", HttpHeaderEtag },
|
||||||
|
{ "Location", HttpHeaderLocation },
|
||||||
|
{ "Proxy-Authenticate", HttpHeaderProxyAuthenticate },
|
||||||
|
{ "Retry-After", HttpHeaderRetryAfter },
|
||||||
|
{ "Server", HttpHeaderServer },
|
||||||
|
// Set it to something which cannot be a header name, in effect
|
||||||
|
// making Server an unknown header. w:w is used to avoid collision with Keep-Alive.
|
||||||
|
{ "w:w\r\n", HttpHeaderServer },
|
||||||
|
// Set it to something which cannot be a header name, in effect
|
||||||
|
// making Set-Cookie an unknown header
|
||||||
|
{ "y:y\r\n", HttpHeaderSetCookie },
|
||||||
|
{ "Vary", HttpHeaderVary },
|
||||||
|
// Set it to something which cannot be a header name, in effect
|
||||||
|
// making WWW-Authenticate an unknown header
|
||||||
|
{ "z:z\r\n", HttpHeaderWwwAuthenticate }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
RESPONSE_HEADER_HASH::Initialize(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Initialize global header hash table
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 31 response headers.
|
||||||
|
// Make sure to update the number of buckets it new headers
|
||||||
|
// are added. Test it to avoid collisions.
|
||||||
|
//
|
||||||
|
C_ASSERT(_countof(sm_rgHeaders) == 31);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 79 buckets will have less collisions for the 31 response headers.
|
||||||
|
// Known collisions are "Age" colliding with "Expire" and "Location"
|
||||||
|
// colliding with both "Expire" and "Age".
|
||||||
|
//
|
||||||
|
hr = HASH_TABLE::Initialize(79);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( DWORD Index = 0; Index < _countof(sm_rgHeaders); ++Index )
|
||||||
|
{
|
||||||
|
if (FAILED(hr = InsertRecord(&sm_rgHeaders[Index])))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,176 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.hxx"
|
||||||
|
|
||||||
|
PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE
|
||||||
|
WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade;
|
||||||
|
|
||||||
|
PFN_WINHTTP_WEBSOCKET_SEND
|
||||||
|
WINHTTP_HELPER::sm_pfnWinHttpWebSocketSend;
|
||||||
|
|
||||||
|
PFN_WINHTTP_WEBSOCKET_RECEIVE
|
||||||
|
WINHTTP_HELPER::sm_pfnWinHttpWebSocketReceive;
|
||||||
|
|
||||||
|
PFN_WINHTTP_WEBSOCKET_SHUTDOWN
|
||||||
|
WINHTTP_HELPER::sm_pfnWinHttpWebSocketShutdown;
|
||||||
|
|
||||||
|
PFN_WINHTTP_WEBSOCKET_QUERY_CLOSE_STATUS
|
||||||
|
WINHTTP_HELPER::sm_pfnWinHttpWebSocketQueryCloseStatus;
|
||||||
|
|
||||||
|
//static
|
||||||
|
HRESULT
|
||||||
|
WINHTTP_HELPER::StaticInitialize(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if (!g_fWebSocketSupported)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the function pointers for WinHttp Websocket API's.
|
||||||
|
//
|
||||||
|
|
||||||
|
HMODULE hWinHttp = GetModuleHandleA("winhttp.dll");
|
||||||
|
if (hWinHttp == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
sm_pfnWinHttpWebSocketCompleteUpgrade = (PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE)
|
||||||
|
GetProcAddress(hWinHttp, "WinHttpWebSocketCompleteUpgrade");
|
||||||
|
if (sm_pfnWinHttpWebSocketCompleteUpgrade == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
sm_pfnWinHttpWebSocketQueryCloseStatus = (PFN_WINHTTP_WEBSOCKET_QUERY_CLOSE_STATUS)
|
||||||
|
GetProcAddress(hWinHttp, "WinHttpWebSocketQueryCloseStatus");
|
||||||
|
if (sm_pfnWinHttpWebSocketQueryCloseStatus == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
sm_pfnWinHttpWebSocketReceive = (PFN_WINHTTP_WEBSOCKET_RECEIVE)
|
||||||
|
GetProcAddress(hWinHttp, "WinHttpWebSocketReceive");
|
||||||
|
if (sm_pfnWinHttpWebSocketReceive == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
sm_pfnWinHttpWebSocketSend = (PFN_WINHTTP_WEBSOCKET_SEND)
|
||||||
|
GetProcAddress(hWinHttp, "WinHttpWebSocketSend");
|
||||||
|
if (sm_pfnWinHttpWebSocketSend == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
sm_pfnWinHttpWebSocketShutdown = (PFN_WINHTTP_WEBSOCKET_SHUTDOWN)
|
||||||
|
GetProcAddress(hWinHttp, "WinHttpWebSocketShutdown");
|
||||||
|
if (sm_pfnWinHttpWebSocketShutdown == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//static
|
||||||
|
VOID
|
||||||
|
WINHTTP_HELPER::GetFlagsFromBufferType(
|
||||||
|
__in WINHTTP_WEB_SOCKET_BUFFER_TYPE BufferType,
|
||||||
|
__out BOOL * pfUtf8Encoded,
|
||||||
|
__out BOOL * pfFinalFragment,
|
||||||
|
__out BOOL * pfClose
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (BufferType)
|
||||||
|
{
|
||||||
|
case WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE:
|
||||||
|
*pfUtf8Encoded = FALSE;
|
||||||
|
*pfFinalFragment = TRUE;
|
||||||
|
*pfClose = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE:
|
||||||
|
*pfUtf8Encoded = FALSE;
|
||||||
|
*pfFinalFragment = FALSE;
|
||||||
|
*pfClose = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE:
|
||||||
|
*pfUtf8Encoded = TRUE;
|
||||||
|
*pfFinalFragment = TRUE;
|
||||||
|
*pfClose = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE:
|
||||||
|
*pfUtf8Encoded = TRUE;
|
||||||
|
*pfFinalFragment = FALSE;
|
||||||
|
*pfClose = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE:
|
||||||
|
*pfUtf8Encoded = FALSE;
|
||||||
|
*pfFinalFragment = FALSE;
|
||||||
|
*pfClose = TRUE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
VOID
|
||||||
|
WINHTTP_HELPER::GetBufferTypeFromFlags(
|
||||||
|
__in BOOL fUtf8Encoded,
|
||||||
|
__in BOOL fFinalFragment,
|
||||||
|
__in BOOL fClose,
|
||||||
|
__out WINHTTP_WEB_SOCKET_BUFFER_TYPE* pBufferType
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fClose)
|
||||||
|
{
|
||||||
|
*pBufferType = WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (fUtf8Encoded)
|
||||||
|
{
|
||||||
|
if (fFinalFragment)
|
||||||
|
{
|
||||||
|
*pBufferType = WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pBufferType = WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fFinalFragment)
|
||||||
|
{
|
||||||
|
*pBufferType = WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pBufferType = WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>IISLib</RootNamespace>
|
||||||
|
<ProjectName>IISLib</ProjectName>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="acache.h" />
|
||||||
|
<ClInclude Include="ahutil.h" />
|
||||||
|
<ClInclude Include="base64.h" />
|
||||||
|
<ClInclude Include="buffer.h" />
|
||||||
|
<ClInclude Include="datetime.h" />
|
||||||
|
<ClInclude Include="dbgutil.h" />
|
||||||
|
<ClInclude Include="hashfn.h" />
|
||||||
|
<ClInclude Include="hashtable.h" />
|
||||||
|
<ClInclude Include="listentry.h" />
|
||||||
|
<ClInclude Include="macros.h" />
|
||||||
|
<ClInclude Include="multisz.h" />
|
||||||
|
<ClInclude Include="multisza.h" />
|
||||||
|
<ClInclude Include="ntassert.h" />
|
||||||
|
<ClInclude Include="percpu.h" />
|
||||||
|
<ClInclude Include="precomp.h" />
|
||||||
|
<ClInclude Include="prime.h" />
|
||||||
|
<ClInclude Include="pudebug.h" />
|
||||||
|
<ClInclude Include="reftrace.h" />
|
||||||
|
<ClInclude Include="rwlock.h" />
|
||||||
|
<ClInclude Include="stringa.h" />
|
||||||
|
<ClInclude Include="stringu.h" />
|
||||||
|
<ClInclude Include="tracelog.h" />
|
||||||
|
<ClInclude Include="treehash.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="acache.cxx" />
|
||||||
|
<ClCompile Include="ahutil.cpp" />
|
||||||
|
<ClCompile Include="base64.cpp" />
|
||||||
|
<ClCompile Include="multisz.cpp" />
|
||||||
|
<ClCompile Include="multisza.cpp" />
|
||||||
|
<ClCompile Include="reftrace.c" />
|
||||||
|
<ClCompile Include="stringa.cpp" />
|
||||||
|
<ClCompile Include="stringu.cpp" />
|
||||||
|
<ClCompile Include="tracelog.c" />
|
||||||
|
<ClCompile Include="util.cxx" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,443 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
LONG ALLOC_CACHE_HANDLER::sm_nFillPattern = 0xACA50000;
|
||||||
|
HANDLE ALLOC_CACHE_HANDLER::sm_hHeap;
|
||||||
|
|
||||||
|
//
|
||||||
|
// This class is used to implement the free list. We cast the free'd
|
||||||
|
// memory block to a FREE_LIST_HEADER*. The signature is used to guard against
|
||||||
|
// double deletion. We also fill memory with a pattern.
|
||||||
|
//
|
||||||
|
class FREE_LIST_HEADER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLIST_ENTRY ListEntry;
|
||||||
|
DWORD dwSignature;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FREE_SIGNATURE = (('A') | ('C' << 8) | ('a' << 16) | (('$' << 24) | 0x80)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ALLOC_CACHE_HANDLER::ALLOC_CACHE_HANDLER(
|
||||||
|
VOID
|
||||||
|
) : m_nThreshold(0),
|
||||||
|
m_cbSize(0),
|
||||||
|
m_pFreeLists(NULL),
|
||||||
|
m_nTotal(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLOC_CACHE_HANDLER::~ALLOC_CACHE_HANDLER(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (m_pFreeLists != NULL)
|
||||||
|
{
|
||||||
|
CleanupLookaside();
|
||||||
|
m_pFreeLists->Dispose();
|
||||||
|
m_pFreeLists = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ALLOC_CACHE_HANDLER::Initialize(
|
||||||
|
DWORD cbSize,
|
||||||
|
LONG nThreshold
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
m_nThreshold = nThreshold;
|
||||||
|
if ( m_nThreshold > 0xffff)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// This will be compared against QueryDepthSList return value (USHORT).
|
||||||
|
//
|
||||||
|
m_nThreshold = 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsPageheapEnabled() )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Disable acache.
|
||||||
|
//
|
||||||
|
m_nThreshold = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure the block is big enough to hold a FREE_LIST_HEADER.
|
||||||
|
//
|
||||||
|
m_cbSize = cbSize;
|
||||||
|
m_cbSize = max(m_cbSize, sizeof(FREE_LIST_HEADER));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Round up the block size to a multiple of the size of a LONG (for
|
||||||
|
// the fill pattern in Free()).
|
||||||
|
//
|
||||||
|
m_cbSize = (m_cbSize + sizeof(LONG) - 1) & ~(sizeof(LONG) - 1);
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1600 // VC10
|
||||||
|
auto Init = [] (SLIST_HEADER* pHead)
|
||||||
|
{
|
||||||
|
InitializeSListHead(pHead);
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
class Functor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void operator()(SLIST_HEADER* pHead)
|
||||||
|
{
|
||||||
|
InitializeSListHead(pHead);
|
||||||
|
}
|
||||||
|
} Init;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hr = PER_CPU<SLIST_HEADER>::Create(Init,
|
||||||
|
&m_pFreeLists );
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nFillPattern = InterlockedIncrement(&sm_nFillPattern);
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
HRESULT
|
||||||
|
ALLOC_CACHE_HANDLER::StaticInitialize(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Since the memory allocated is fixed size,
|
||||||
|
// a heap is not really needed, allocations can be done
|
||||||
|
// using VirtualAllocEx[Numa]. For now use Windows Heap.
|
||||||
|
//
|
||||||
|
// Be aware that creating one private heap consumes more
|
||||||
|
// virtual address space for the worker process.
|
||||||
|
//
|
||||||
|
sm_hHeap = GetProcessHeap();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
VOID
|
||||||
|
ALLOC_CACHE_HANDLER::StaticTerminate(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
sm_hHeap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ALLOC_CACHE_HANDLER::CleanupLookaside(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
This function cleans up the lookaside list by removing storage space.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Free up all the entries in the list.
|
||||||
|
// Don't use InterlockedFlushSList, in order to work
|
||||||
|
// memory must be 16 bytes aligned and currently it is 64.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1600 // VC10
|
||||||
|
auto Predicate = [=] (SLIST_HEADER * pListHeader)
|
||||||
|
{
|
||||||
|
PSLIST_ENTRY pl;
|
||||||
|
LONG NodesToDelete = QueryDepthSList( pListHeader );
|
||||||
|
|
||||||
|
pl = InterlockedPopEntrySList( pListHeader );
|
||||||
|
while ( pl != NULL && --NodesToDelete >= 0 )
|
||||||
|
{
|
||||||
|
InterlockedDecrement( &m_nTotal);
|
||||||
|
|
||||||
|
::HeapFree( sm_hHeap, 0, pl );
|
||||||
|
|
||||||
|
pl = InterlockedPopEntrySList(pListHeader);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
class Functor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Functor(ALLOC_CACHE_HANDLER * pThis) : _pThis(pThis)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void operator()(SLIST_HEADER * pListHeader)
|
||||||
|
{
|
||||||
|
PSLIST_ENTRY pl;
|
||||||
|
LONG NodesToDelete = QueryDepthSList( pListHeader );
|
||||||
|
|
||||||
|
pl = InterlockedPopEntrySList( pListHeader );
|
||||||
|
while ( pl != NULL && --NodesToDelete >= 0 )
|
||||||
|
{
|
||||||
|
InterlockedDecrement( &_pThis->m_nTotal);
|
||||||
|
|
||||||
|
::HeapFree( sm_hHeap, 0, pl );
|
||||||
|
|
||||||
|
pl = InterlockedPopEntrySList(pListHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ALLOC_CACHE_HANDLER * _pThis;
|
||||||
|
} Predicate(this);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_pFreeLists ->ForEach(Predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID
|
||||||
|
ALLOC_CACHE_HANDLER::Alloc(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LPVOID pMemory = NULL;
|
||||||
|
|
||||||
|
if ( m_nThreshold > 0 )
|
||||||
|
{
|
||||||
|
SLIST_HEADER * pListHeader = m_pFreeLists ->GetLocal();
|
||||||
|
pMemory = (LPVOID) InterlockedPopEntrySList(pListHeader); // get the real object
|
||||||
|
|
||||||
|
if (pMemory != NULL)
|
||||||
|
{
|
||||||
|
FREE_LIST_HEADER* pfl = (FREE_LIST_HEADER*) pMemory;
|
||||||
|
//
|
||||||
|
// If the signature is wrong then somebody's been scribbling
|
||||||
|
// on memory that they've freed.
|
||||||
|
//
|
||||||
|
DBG_ASSERT(pfl->dwSignature == FREE_LIST_HEADER::FREE_SIGNATURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pMemory == NULL )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No free entry. Need to alloc a new object.
|
||||||
|
//
|
||||||
|
pMemory = (LPVOID) ::HeapAlloc( sm_hHeap,
|
||||||
|
0,
|
||||||
|
m_cbSize );
|
||||||
|
|
||||||
|
if ( pMemory != NULL )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Update counters.
|
||||||
|
//
|
||||||
|
m_nTotal++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pMemory == NULL )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FREE_LIST_HEADER* pfl = (FREE_LIST_HEADER*) pMemory;
|
||||||
|
pfl->dwSignature = 0; // clear; just in case caller never overwrites
|
||||||
|
}
|
||||||
|
|
||||||
|
return pMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ALLOC_CACHE_HANDLER::Free(
|
||||||
|
__in LPVOID pMemory
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Assume that this is allocated using the Alloc() function.
|
||||||
|
//
|
||||||
|
DBG_ASSERT(NULL != pMemory);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use a signature to check against double deletions.
|
||||||
|
//
|
||||||
|
FREE_LIST_HEADER* pfl = (FREE_LIST_HEADER*) pMemory;
|
||||||
|
DBG_ASSERT(pfl->dwSignature != FREE_LIST_HEADER::FREE_SIGNATURE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start filling the space beyond the portion overlaid by the initial
|
||||||
|
// FREE_LIST_HEADER. Fill at most 6 DWORDS.
|
||||||
|
//
|
||||||
|
LONG* pl = (LONG*) (pfl+1);
|
||||||
|
|
||||||
|
for (LONG cb = (LONG)min(6 * sizeof(LONG),m_cbSize) - sizeof(FREE_LIST_HEADER);
|
||||||
|
cb > 0;
|
||||||
|
cb -= sizeof(LONG))
|
||||||
|
{
|
||||||
|
*pl++ = m_nFillPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now, set the signature.
|
||||||
|
//
|
||||||
|
pfl->dwSignature = FREE_LIST_HEADER::FREE_SIGNATURE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store the items in the alloc cache.
|
||||||
|
//
|
||||||
|
SLIST_HEADER * pListHeader = m_pFreeLists ->GetLocal();
|
||||||
|
|
||||||
|
if ( QueryDepthSList(pListHeader) >= m_nThreshold )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Threshold for free entries is exceeded. Free the object to
|
||||||
|
// process pool.
|
||||||
|
//
|
||||||
|
::HeapFree( sm_hHeap, 0, pMemory );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Store the given pointer in the single linear list
|
||||||
|
//
|
||||||
|
InterlockedPushEntrySList(pListHeader, &pfl->ListEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
ALLOC_CACHE_HANDLER::QueryDepthForAllSLists(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
Aggregates the total count of elements in all lists.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
Total count (snapshot).
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
DWORD Count = 0;
|
||||||
|
|
||||||
|
if (m_pFreeLists != NULL)
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1600 // VC10
|
||||||
|
auto Predicate = [&Count] (SLIST_HEADER * pListHeader)
|
||||||
|
{
|
||||||
|
Count += QueryDepthSList(pListHeader);
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
class Functor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Functor(DWORD& Count) : _Count(Count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void operator()(SLIST_HEADER * pListHeader)
|
||||||
|
{
|
||||||
|
_Count += QueryDepthSList(pListHeader);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
DWORD& _Count;
|
||||||
|
} Predicate(Count);
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// [&Count] means that the method can modify local variable Count.
|
||||||
|
//
|
||||||
|
m_pFreeLists ->ForEach(Predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
BOOL
|
||||||
|
ALLOC_CACHE_HANDLER::IsPageheapEnabled(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL fRet = FALSE;
|
||||||
|
BOOL fLockedHeap = FALSE;
|
||||||
|
HMODULE hModule = NULL;
|
||||||
|
HANDLE hHeap = NULL;
|
||||||
|
PROCESS_HEAP_ENTRY heapEntry = {0};
|
||||||
|
|
||||||
|
//
|
||||||
|
// If verifier.dll is loaded - we are running under app verifier == pageheap is enabled
|
||||||
|
//
|
||||||
|
hModule = GetModuleHandle( L"verifier.dll" );
|
||||||
|
if ( hModule != NULL )
|
||||||
|
{
|
||||||
|
hModule = NULL;
|
||||||
|
fRet = TRUE;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a heap for calling heapwalk
|
||||||
|
// otherwise HeapWalk turns off lookasides for a useful heap
|
||||||
|
//
|
||||||
|
hHeap = ::HeapCreate( 0, 0, 0 );
|
||||||
|
if ( hHeap == NULL )
|
||||||
|
{
|
||||||
|
fRet = FALSE;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
fRet = ::HeapLock( hHeap );
|
||||||
|
if ( !fRet )
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
fLockedHeap = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If HeapWalk is unsupported -> then running page heap
|
||||||
|
//
|
||||||
|
fRet = ::HeapWalk( hHeap, &heapEntry );
|
||||||
|
if ( !fRet )
|
||||||
|
{
|
||||||
|
if ( GetLastError() == ERROR_INVALID_FUNCTION )
|
||||||
|
{
|
||||||
|
fRet = TRUE;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fRet = FALSE;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if ( fLockedHeap )
|
||||||
|
{
|
||||||
|
fLockedHeap = FALSE;
|
||||||
|
DBG_REQUIRE( ::HeapUnlock( hHeap ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hHeap )
|
||||||
|
{
|
||||||
|
DBG_REQUIRE( ::HeapDestroy( hHeap ) );
|
||||||
|
hHeap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fRet;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "percpu.h"
|
||||||
|
|
||||||
|
class ALLOC_CACHE_HANDLER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ALLOC_CACHE_HANDLER(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
~ALLOC_CACHE_HANDLER(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
DWORD cbSize,
|
||||||
|
LONG nThreshold
|
||||||
|
);
|
||||||
|
|
||||||
|
LPVOID
|
||||||
|
Alloc(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Free(
|
||||||
|
__in LPVOID pMemory
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanupLookaside(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QueryDepthForAllSLists(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
LONG m_nThreshold;
|
||||||
|
DWORD m_cbSize;
|
||||||
|
|
||||||
|
PER_CPU<SLIST_HEADER> * m_pFreeLists;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Total heap allocations done over the lifetime.
|
||||||
|
// Note that this is not interlocked, it is just a hint for debugging.
|
||||||
|
//
|
||||||
|
volatile LONG m_nTotal;
|
||||||
|
|
||||||
|
LONG m_nFillPattern;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
StaticInitialize(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
StaticTerminate(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOL
|
||||||
|
IsPageheapEnabled();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static LONG sm_nFillPattern;
|
||||||
|
static HANDLE sm_hHeap;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// You can use ALLOC_CACHE_HANDLER as a per-class allocator
|
||||||
|
// in your C++ classes. Add the following to your class definition:
|
||||||
|
//
|
||||||
|
// protected:
|
||||||
|
// static ALLOC_CACHE_HANDLER* sm_palloc;
|
||||||
|
// public:
|
||||||
|
// static void* operator new(size_t s)
|
||||||
|
// {
|
||||||
|
// IRTLASSERT(s == sizeof(C));
|
||||||
|
// IRTLASSERT(sm_palloc != NULL);
|
||||||
|
// return sm_palloc->Alloc();
|
||||||
|
// }
|
||||||
|
// static void operator delete(void* pv)
|
||||||
|
// {
|
||||||
|
// IRTLASSERT(pv != NULL);
|
||||||
|
// if (sm_palloc != NULL)
|
||||||
|
// sm_palloc->Free(pv);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Obviously, you must initialize sm_palloc before you can allocate
|
||||||
|
// any objects of this class.
|
||||||
|
//
|
||||||
|
// Note that if you derive a class from this base class, the derived class
|
||||||
|
// must also provide its own operator new and operator delete. If not, the
|
||||||
|
// base class's allocator will be called, but the size of the derived
|
||||||
|
// object will almost certainly be larger than that of the base object.
|
||||||
|
// Furthermore, the allocator will not be used for arrays of objects
|
||||||
|
// (override operator new[] and operator delete[]), but this is a
|
||||||
|
// harder problem since the allocator works with one fixed size.
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,258 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include<Windows.h>
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetElementProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN CONST WCHAR * szPropName,
|
||||||
|
IN CONST VARIANT * varPropValue
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetElementStringProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN CONST WCHAR * szPropName,
|
||||||
|
IN CONST WCHAR * szPropValue
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementStringProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN CONST WCHAR * szPropName,
|
||||||
|
OUT BSTR * pbstrPropValue
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementStringProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN CONST WCHAR * szPropName,
|
||||||
|
OUT STRU * pstrPropValue
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementBoolProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN LPCWSTR pszPropertyName,
|
||||||
|
OUT BOOL * pBool
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementBoolProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN LPCWSTR pszPropertyName,
|
||||||
|
OUT bool * pBool
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementChildByName(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN LPCWSTR pszElementName,
|
||||||
|
OUT IAppHostElement ** ppChildElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementDWORDProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN LPCWSTR pszPropertyName,
|
||||||
|
OUT DWORD * pdwValue
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementLONGLONGProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN LPCWSTR pszPropertyName,
|
||||||
|
OUT LONGLONG * pllValue
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetElementRawTimeSpanProperty(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN LPCWSTR pszPropertyName,
|
||||||
|
OUT ULONGLONG * pulonglong
|
||||||
|
);
|
||||||
|
|
||||||
|
#define FIND_ELEMENT_CASE_SENSITIVE 0x00000000
|
||||||
|
#define FIND_ELEMENT_CASE_INSENSITIVE 0x00000001
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DeleteElementFromCollection(
|
||||||
|
IAppHostElementCollection *pCollection,
|
||||||
|
CONST WCHAR * szKeyName,
|
||||||
|
CONST WCHAR * szKeyValue,
|
||||||
|
ULONG BehaviorFlags,
|
||||||
|
BOOL * pfDeleted
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DeleteAllElementsFromCollection(
|
||||||
|
IAppHostElementCollection *pCollection,
|
||||||
|
CONST WCHAR * szKeyName,
|
||||||
|
CONST WCHAR * szKeyValue,
|
||||||
|
ULONG BehaviorFlags,
|
||||||
|
UINT * pNumDeleted
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindElementInCollection(
|
||||||
|
IAppHostElementCollection *pCollection,
|
||||||
|
CONST WCHAR * szKeyName,
|
||||||
|
CONST WCHAR * szKeyValue,
|
||||||
|
ULONG BehaviorFlags,
|
||||||
|
OUT ULONG * pIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
VariantAssign(
|
||||||
|
IN OUT VARIANT * pv,
|
||||||
|
IN CONST WCHAR * sz
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetLocationFromFile(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
IN CONST WCHAR * szLocationPath,
|
||||||
|
OUT IAppHostConfigLocation ** ppLocation,
|
||||||
|
OUT BOOL * pFound
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetSectionFromLocation(
|
||||||
|
IN IAppHostConfigLocation * pLocation,
|
||||||
|
IN CONST WCHAR * szSectionName,
|
||||||
|
OUT IAppHostElement ** ppSectionElement,
|
||||||
|
OUT BOOL * pFound
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetAdminElement(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
IN CONST WCHAR * szElementName,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ClearAdminElement(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
IN CONST WCHAR * szElementName
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ClearElementFromAllSites(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
IN CONST WCHAR * szElementName
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ClearElementFromAllLocations(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
IN CONST WCHAR * szElementName
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ClearLocationElements(
|
||||||
|
IN IAppHostConfigLocation * pLocation,
|
||||||
|
IN CONST WCHAR * szElementName
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
CompareElementName(
|
||||||
|
IN IAppHostElement * pElement,
|
||||||
|
IN CONST WCHAR * szNameToMatch,
|
||||||
|
OUT BOOL * pMatched
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
ClearChildElementsByName(
|
||||||
|
IN IAppHostChildElementCollection * pCollection,
|
||||||
|
IN CONST WCHAR * szElementName,
|
||||||
|
OUT BOOL * pFound
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetSitesCollection(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
OUT IAppHostElementCollection ** pSitesCollection
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetLocationCollection(
|
||||||
|
IN IAppHostAdminManager * pAdminMgr,
|
||||||
|
IN CONST WCHAR * szConfigPath,
|
||||||
|
OUT IAppHostConfigLocationCollection ** pLocationCollection
|
||||||
|
);
|
||||||
|
|
||||||
|
struct ENUM_INDEX
|
||||||
|
{
|
||||||
|
VARIANT Index;
|
||||||
|
ULONG Count;
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindFirstElement(
|
||||||
|
IN IAppHostElementCollection * pCollection,
|
||||||
|
OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindNextElement(
|
||||||
|
IN IAppHostElementCollection * pCollection,
|
||||||
|
IN OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindFirstChildElement(
|
||||||
|
IN IAppHostChildElementCollection * pCollection,
|
||||||
|
OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindNextChildElement(
|
||||||
|
IN IAppHostChildElementCollection * pCollection,
|
||||||
|
IN OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindFirstLocation(
|
||||||
|
IN IAppHostConfigLocationCollection * pCollection,
|
||||||
|
OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostConfigLocation ** pLocation
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindNextLocation(
|
||||||
|
IN IAppHostConfigLocationCollection * pCollection,
|
||||||
|
IN OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostConfigLocation ** pLocation
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindFirstLocationElement(
|
||||||
|
IN IAppHostConfigLocation * pLocation,
|
||||||
|
OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
FindNextLocationElement(
|
||||||
|
IN IAppHostConfigLocation * pLocation,
|
||||||
|
IN OUT ENUM_INDEX * pIndex,
|
||||||
|
OUT IAppHostElement ** pElement
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT GetSharedConfigEnabled(
|
||||||
|
BOOL * pfIsSharedConfig
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,482 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Encode(
|
||||||
|
__in_bcount(cbDecodedBufferSize) VOID * pDecodedBuffer,
|
||||||
|
IN DWORD cbDecodedBufferSize,
|
||||||
|
__out_ecount_opt(cchEncodedStringSize) PWSTR pszEncodedString,
|
||||||
|
IN DWORD cchEncodedStringSize,
|
||||||
|
__out_opt DWORD * pcchEncoded
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Decode a base64-encoded string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pDecodedBuffer (IN) - buffer to encode.
|
||||||
|
cbDecodedBufferSize (IN) - size of buffer to encode.
|
||||||
|
cchEncodedStringSize (IN) - size of the buffer for the encoded string.
|
||||||
|
pszEncodedString (OUT) = the encoded string.
|
||||||
|
pcchEncoded (OUT) - size in characters of the encoded string.
|
||||||
|
|
||||||
|
Return Values:
|
||||||
|
|
||||||
|
0 - success.
|
||||||
|
E_OUTOFMEMORY
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
static WCHAR rgchEncodeTable[64] = {
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD ib;
|
||||||
|
DWORD ich;
|
||||||
|
DWORD cchEncoded;
|
||||||
|
BYTE b0, b1, b2;
|
||||||
|
BYTE * pbDecodedBuffer = (BYTE *) pDecodedBuffer;
|
||||||
|
|
||||||
|
// Calculate encoded string size.
|
||||||
|
cchEncoded = 1 + (cbDecodedBufferSize + 2) / 3 * 4;
|
||||||
|
|
||||||
|
if (NULL != pcchEncoded) {
|
||||||
|
*pcchEncoded = cchEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cchEncodedStringSize == 0 && pszEncodedString == NULL) {
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cchEncodedStringSize < cchEncoded) {
|
||||||
|
// Given buffer is too small to hold encoded string.
|
||||||
|
return ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode data byte triplets into four-byte clusters.
|
||||||
|
ib = ich = 0;
|
||||||
|
while (ib < cbDecodedBufferSize) {
|
||||||
|
b0 = pbDecodedBuffer[ib++];
|
||||||
|
b1 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0;
|
||||||
|
b2 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The checks below for buffer overflow seems redundant to me.
|
||||||
|
// But it's the only way I can find to keep OACR quiet so it
|
||||||
|
// will have to do.
|
||||||
|
//
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[b0 >> 2];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[((b0 << 4) & 0x30) | ((b1 >> 4) & 0x0f)];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[((b1 << 2) & 0x3c) | ((b2 >> 6) & 0x03)];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[b2 & 0x3f];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad the last cluster as necessary to indicate the number of data bytes
|
||||||
|
// it represents.
|
||||||
|
switch (cbDecodedBufferSize % 3) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pszEncodedString[ich - 2] = '=';
|
||||||
|
__fallthrough;
|
||||||
|
case 2:
|
||||||
|
pszEncodedString[ich - 1] = '=';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null-terminate the encoded string.
|
||||||
|
pszEncodedString[ich++] = '\0';
|
||||||
|
|
||||||
|
DBG_ASSERT(ich == cchEncoded);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Decode(
|
||||||
|
__in PCWSTR pszEncodedString,
|
||||||
|
__out_opt VOID * pDecodeBuffer,
|
||||||
|
__in DWORD cbDecodeBufferSize,
|
||||||
|
__out_opt DWORD * pcbDecoded
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Decode a base64-encoded string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszEncodedString (IN) - base64-encoded string to decode.
|
||||||
|
cbDecodeBufferSize (IN) - size in bytes of the decode buffer.
|
||||||
|
pbDecodeBuffer (OUT) - holds the decoded data.
|
||||||
|
pcbDecoded (OUT) - number of data bytes in the decoded data (if success or
|
||||||
|
STATUS_BUFFER_TOO_SMALL).
|
||||||
|
|
||||||
|
Return Values:
|
||||||
|
|
||||||
|
0 - success.
|
||||||
|
E_OUTOFMEMORY
|
||||||
|
E_INVALIDARG
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
#define NA (255)
|
||||||
|
#define DECODE(x) (((ULONG)(x) < sizeof(rgbDecodeTable)) ? rgbDecodeTable[x] : NA)
|
||||||
|
|
||||||
|
static BYTE rgbDecodeTable[128] = {
|
||||||
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 0-15
|
||||||
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 16-31
|
||||||
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62, NA, NA, NA, 63, // 32-47
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NA, NA, NA, 0, NA, NA, // 48-63
|
||||||
|
NA, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
|
||||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NA, NA, NA, NA, NA, // 80-95
|
||||||
|
NA, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
|
||||||
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, NA, NA, NA, NA, // 112-127
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD cbDecoded;
|
||||||
|
DWORD cchEncodedSize;
|
||||||
|
DWORD ich;
|
||||||
|
DWORD ib;
|
||||||
|
BYTE b0, b1, b2, b3;
|
||||||
|
BYTE * pbDecodeBuffer = (BYTE *) pDecodeBuffer;
|
||||||
|
|
||||||
|
cchEncodedSize = (DWORD)wcslen(pszEncodedString);
|
||||||
|
if (NULL != pcbDecoded) {
|
||||||
|
*pcbDecoded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((0 == cchEncodedSize) || (0 != (cchEncodedSize % 4))) {
|
||||||
|
// Input string is not sized correctly to be base64.
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate decoded buffer size.
|
||||||
|
cbDecoded = (cchEncodedSize + 3) / 4 * 3;
|
||||||
|
if (pszEncodedString[cchEncodedSize-1] == '=') {
|
||||||
|
if (pszEncodedString[cchEncodedSize-2] == '=') {
|
||||||
|
// Only one data byte is encoded in the last cluster.
|
||||||
|
cbDecoded -= 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Only two data bytes are encoded in the last cluster.
|
||||||
|
cbDecoded -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != pcbDecoded) {
|
||||||
|
*pcbDecoded = cbDecoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbDecodeBufferSize == 0 && pDecodeBuffer == NULL) {
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbDecoded > cbDecodeBufferSize) {
|
||||||
|
// Supplied buffer is too small.
|
||||||
|
return ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode each four-byte cluster into the corresponding three data bytes.
|
||||||
|
ich = ib = 0;
|
||||||
|
while (ich < cchEncodedSize) {
|
||||||
|
b0 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
b1 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
b2 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
b3 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
|
||||||
|
if ((NA == b0) || (NA == b1) || (NA == b2) || (NA == b3)) {
|
||||||
|
// Contents of input string are not base64.
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbDecodeBuffer[ib++] = (b0 << 2) | (b1 >> 4);
|
||||||
|
|
||||||
|
if (ib < cbDecoded) {
|
||||||
|
pbDecodeBuffer[ib++] = (b1 << 4) | (b2 >> 2);
|
||||||
|
|
||||||
|
if (ib < cbDecoded) {
|
||||||
|
pbDecodeBuffer[ib++] = (b2 << 6) | b3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_ASSERT(ib == cbDecoded);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Encode(
|
||||||
|
__in_bcount(cbDecodedBufferSize) VOID * pDecodedBuffer,
|
||||||
|
IN DWORD cbDecodedBufferSize,
|
||||||
|
__out_ecount_opt(cchEncodedStringSize) PSTR pszEncodedString,
|
||||||
|
IN DWORD cchEncodedStringSize,
|
||||||
|
__out_opt DWORD * pcchEncoded
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Decode a base64-encoded string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pDecodedBuffer (IN) - buffer to encode.
|
||||||
|
cbDecodedBufferSize (IN) - size of buffer to encode.
|
||||||
|
cchEncodedStringSize (IN) - size of the buffer for the encoded string.
|
||||||
|
pszEncodedString (OUT) = the encoded string.
|
||||||
|
pcchEncoded (OUT) - size in characters of the encoded string.
|
||||||
|
|
||||||
|
Return Values:
|
||||||
|
|
||||||
|
0 - success.
|
||||||
|
E_OUTOFMEMORY
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
static CHAR rgchEncodeTable[64] = {
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD ib;
|
||||||
|
DWORD ich;
|
||||||
|
DWORD cchEncoded;
|
||||||
|
BYTE b0, b1, b2;
|
||||||
|
BYTE * pbDecodedBuffer = (BYTE *) pDecodedBuffer;
|
||||||
|
|
||||||
|
// Calculate encoded string size.
|
||||||
|
cchEncoded = 1 + (cbDecodedBufferSize + 2) / 3 * 4;
|
||||||
|
|
||||||
|
if (NULL != pcchEncoded) {
|
||||||
|
*pcchEncoded = cchEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cchEncodedStringSize == 0 && pszEncodedString == NULL) {
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cchEncodedStringSize < cchEncoded) {
|
||||||
|
// Given buffer is too small to hold encoded string.
|
||||||
|
return ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode data byte triplets into four-byte clusters.
|
||||||
|
ib = ich = 0;
|
||||||
|
while (ib < cbDecodedBufferSize) {
|
||||||
|
b0 = pbDecodedBuffer[ib++];
|
||||||
|
b1 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0;
|
||||||
|
b2 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The checks below for buffer overflow seems redundant to me.
|
||||||
|
// But it's the only way I can find to keep OACR quiet so it
|
||||||
|
// will have to do.
|
||||||
|
//
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[b0 >> 2];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[((b0 << 4) & 0x30) | ((b1 >> 4) & 0x0f)];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[((b1 << 2) & 0x3c) | ((b2 >> 6) & 0x03)];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszEncodedString[ich++] = rgchEncodeTable[b2 & 0x3f];
|
||||||
|
if ( ich >= cchEncodedStringSize )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad the last cluster as necessary to indicate the number of data bytes
|
||||||
|
// it represents.
|
||||||
|
switch (cbDecodedBufferSize % 3) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pszEncodedString[ich - 2] = '=';
|
||||||
|
__fallthrough;
|
||||||
|
case 2:
|
||||||
|
pszEncodedString[ich - 1] = '=';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null-terminate the encoded string.
|
||||||
|
pszEncodedString[ich++] = '\0';
|
||||||
|
|
||||||
|
DBG_ASSERT(ich == cchEncoded);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Decode(
|
||||||
|
__in PCSTR pszEncodedString,
|
||||||
|
__out_opt VOID * pDecodeBuffer,
|
||||||
|
__in DWORD cbDecodeBufferSize,
|
||||||
|
__out_opt DWORD * pcbDecoded
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Decode a base64-encoded string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszEncodedString (IN) - base64-encoded string to decode.
|
||||||
|
cbDecodeBufferSize (IN) - size in bytes of the decode buffer.
|
||||||
|
pbDecodeBuffer (OUT) - holds the decoded data.
|
||||||
|
pcbDecoded (OUT) - number of data bytes in the decoded data (if success or
|
||||||
|
STATUS_BUFFER_TOO_SMALL).
|
||||||
|
|
||||||
|
Return Values:
|
||||||
|
|
||||||
|
0 - success.
|
||||||
|
E_OUTOFMEMORY
|
||||||
|
E_INVALIDARG
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
#define NA (255)
|
||||||
|
#define DECODE(x) (((ULONG)(x) < sizeof(rgbDecodeTable)) ? rgbDecodeTable[x] : NA)
|
||||||
|
|
||||||
|
static BYTE rgbDecodeTable[128] = {
|
||||||
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 0-15
|
||||||
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 16-31
|
||||||
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62, NA, NA, NA, 63, // 32-47
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NA, NA, NA, 0, NA, NA, // 48-63
|
||||||
|
NA, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
|
||||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NA, NA, NA, NA, NA, // 80-95
|
||||||
|
NA, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
|
||||||
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, NA, NA, NA, NA, // 112-127
|
||||||
|
};
|
||||||
|
|
||||||
|
DWORD cbDecoded;
|
||||||
|
DWORD cchEncodedSize;
|
||||||
|
DWORD ich;
|
||||||
|
DWORD ib;
|
||||||
|
BYTE b0, b1, b2, b3;
|
||||||
|
BYTE * pbDecodeBuffer = (BYTE *) pDecodeBuffer;
|
||||||
|
|
||||||
|
cchEncodedSize = (DWORD)strlen(pszEncodedString);
|
||||||
|
if (NULL != pcbDecoded) {
|
||||||
|
*pcbDecoded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((0 == cchEncodedSize) || (0 != (cchEncodedSize % 4))) {
|
||||||
|
// Input string is not sized correctly to be base64.
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate decoded buffer size.
|
||||||
|
cbDecoded = (cchEncodedSize + 3) / 4 * 3;
|
||||||
|
if (pszEncodedString[cchEncodedSize-1] == '=') {
|
||||||
|
if (pszEncodedString[cchEncodedSize-2] == '=') {
|
||||||
|
// Only one data byte is encoded in the last cluster.
|
||||||
|
cbDecoded -= 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Only two data bytes are encoded in the last cluster.
|
||||||
|
cbDecoded -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != pcbDecoded) {
|
||||||
|
*pcbDecoded = cbDecoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbDecodeBufferSize == 0 && pDecodeBuffer == NULL) {
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbDecoded > cbDecodeBufferSize) {
|
||||||
|
// Supplied buffer is too small.
|
||||||
|
return ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode each four-byte cluster into the corresponding three data bytes.
|
||||||
|
ich = ib = 0;
|
||||||
|
while (ich < cchEncodedSize) {
|
||||||
|
b0 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
b1 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
b2 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
b3 = DECODE(pszEncodedString[ich]); ich++;
|
||||||
|
|
||||||
|
if ((NA == b0) || (NA == b1) || (NA == b2) || (NA == b3)) {
|
||||||
|
// Contents of input string are not base64.
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbDecodeBuffer[ib++] = (b0 << 2) | (b1 >> 4);
|
||||||
|
|
||||||
|
if (ib < cbDecoded) {
|
||||||
|
pbDecodeBuffer[ib++] = (b1 << 4) | (b2 >> 2);
|
||||||
|
|
||||||
|
if (ib < cbDecoded) {
|
||||||
|
pbDecodeBuffer[ib++] = (b2 << 6) | b3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_ASSERT(ib == cbDecoded);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _BASE64_H_
|
||||||
|
#define _BASE64_H_
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Encode(
|
||||||
|
__in_bcount( cbDecodedBufferSize ) VOID * pDecodedBuffer,
|
||||||
|
IN DWORD cbDecodedBufferSize,
|
||||||
|
__out_ecount_opt( cchEncodedStringSize ) PWSTR pszEncodedString,
|
||||||
|
IN DWORD cchEncodedStringSize,
|
||||||
|
__out_opt DWORD * pcchEncoded
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Decode(
|
||||||
|
__in PCWSTR pszEncodedString,
|
||||||
|
__out_opt VOID * pDecodeBuffer,
|
||||||
|
__in DWORD cbDecodeBufferSize,
|
||||||
|
__out_opt DWORD * pcbDecoded
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Encode(
|
||||||
|
__in_bcount( cbDecodedBufferSize ) VOID * pDecodedBuffer,
|
||||||
|
IN DWORD cbDecodedBufferSize,
|
||||||
|
__out_ecount_opt( cchEncodedStringSize ) PSTR pszEncodedString,
|
||||||
|
IN DWORD cchEncodedStringSize,
|
||||||
|
__out_opt DWORD * pcchEncoded
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Base64Decode(
|
||||||
|
__in PCSTR pszEncodedString,
|
||||||
|
__out_opt VOID * pDecodeBuffer,
|
||||||
|
__in DWORD cbDecodeBufferSize,
|
||||||
|
__out_opt DWORD * pcbDecoded
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // _BASE64_HXX_
|
||||||
|
|
||||||
|
|
@ -0,0 +1,271 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <crtdbg.h>
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// BUFFER_T class shouldn't be used directly. Use BUFFER specialization class instead.
|
||||||
|
// The only BUFFER_T partners are STRU and STRA classes.
|
||||||
|
// BUFFER_T cannot hold other but primitive types since it doesn't call
|
||||||
|
// constructor and destructor.
|
||||||
|
//
|
||||||
|
// Note: Size is in bytes.
|
||||||
|
//
|
||||||
|
template<typename T, DWORD LENGTH>
|
||||||
|
class BUFFER_T
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
BUFFER_T()
|
||||||
|
: m_cbBuffer( sizeof(m_rgBuffer) ),
|
||||||
|
m_fHeapAllocated( false ),
|
||||||
|
m_pBuffer(m_rgBuffer)
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
|
||||||
|
Default constructor where the inline buffer is used.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BUFFER_T(
|
||||||
|
__inout_bcount(cbInit) T* pbInit,
|
||||||
|
__in DWORD cbInit
|
||||||
|
) : m_pBuffer( pbInit ),
|
||||||
|
m_cbBuffer( cbInit ),
|
||||||
|
m_fHeapAllocated( false )
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
|
||||||
|
Instantiate BUFFER, initially using pbInit as buffer
|
||||||
|
This is useful for stack-buffers and inline-buffer class members
|
||||||
|
(see STACK_BUFFER and INLINE_BUFFER_INIT below)
|
||||||
|
|
||||||
|
BUFFER does not free pbInit.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pbInit - Initial buffer to use.
|
||||||
|
cbInit - Size of pbInit in bytes (not in elements).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
_ASSERTE( NULL != pbInit );
|
||||||
|
_ASSERTE( cbInit > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
~BUFFER_T()
|
||||||
|
{
|
||||||
|
if( IsHeapAllocated() )
|
||||||
|
{
|
||||||
|
_ASSERTE( NULL != m_pBuffer );
|
||||||
|
HeapFree( GetProcessHeap(), 0, m_pBuffer );
|
||||||
|
m_pBuffer = NULL;
|
||||||
|
m_cbBuffer = 0;
|
||||||
|
m_fHeapAllocated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T*
|
||||||
|
QueryPtr(
|
||||||
|
VOID
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return pointer to data buffer.
|
||||||
|
//
|
||||||
|
return m_pBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
QuerySize(
|
||||||
|
VOID
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Return number of bytes.
|
||||||
|
//
|
||||||
|
return m_cbBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
__success(return == true)
|
||||||
|
bool
|
||||||
|
Resize(
|
||||||
|
const SIZE_T cbNewSize,
|
||||||
|
const bool fZeroMemoryBeyondOldSize = false
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
|
||||||
|
Resizes the buffer.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
cbNewSize - Size in bytes to grow to.
|
||||||
|
fZeroMemoryBeyondOldSize
|
||||||
|
- Whether to zero the region of memory of the
|
||||||
|
new buffer beyond the original size.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
TRUE on success, FALSE on failure.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
PVOID pNewMem;
|
||||||
|
|
||||||
|
if ( cbNewSize <= m_cbBuffer )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cbNewSize > MAXDWORD )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwHeapAllocFlags = fZeroMemoryBeyondOldSize ? HEAP_ZERO_MEMORY : 0;
|
||||||
|
|
||||||
|
if( IsHeapAllocated() )
|
||||||
|
{
|
||||||
|
pNewMem = HeapReAlloc( GetProcessHeap(), dwHeapAllocFlags, m_pBuffer, cbNewSize );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNewMem = HeapAlloc( GetProcessHeap(), dwHeapAllocFlags, cbNewSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pNewMem == NULL )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !IsHeapAllocated() )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// First time this block is allocated. Copy over old contents.
|
||||||
|
//
|
||||||
|
memcpy_s( pNewMem, static_cast<DWORD>(cbNewSize), m_pBuffer, m_cbBuffer );
|
||||||
|
m_fHeapAllocated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pBuffer = reinterpret_cast<T*>(pNewMem);
|
||||||
|
m_cbBuffer = static_cast<DWORD>(cbNewSize);
|
||||||
|
|
||||||
|
_ASSERTE( m_pBuffer != NULL );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsHeapAllocated(
|
||||||
|
VOID
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return m_fHeapAllocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The default inline buffer.
|
||||||
|
// This member should be at the beginning for alignment purposes.
|
||||||
|
//
|
||||||
|
T m_rgBuffer[LENGTH];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Is m_pBuffer dynamically allocated?
|
||||||
|
//
|
||||||
|
bool m_fHeapAllocated;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Size of the buffer as requested by client in bytes.
|
||||||
|
//
|
||||||
|
DWORD m_cbBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pointer to buffer.
|
||||||
|
//
|
||||||
|
__field_bcount_full(m_cbBuffer)
|
||||||
|
T* m_pBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resizes the buffer by 2 if the ideal size is bigger
|
||||||
|
// than the buffer length. That give us lg(n) allocations.
|
||||||
|
//
|
||||||
|
// Use template inferring like:
|
||||||
|
//
|
||||||
|
// BUFFER buff;
|
||||||
|
// hr = ResizeBufferByTwo(buff, 100);
|
||||||
|
//
|
||||||
|
template<typename T, DWORD LENGTH>
|
||||||
|
HRESULT
|
||||||
|
ResizeBufferByTwo(
|
||||||
|
BUFFER_T<T,LENGTH>& Buffer,
|
||||||
|
SIZE_T cbIdealSize,
|
||||||
|
bool fZeroMemoryBeyondOldSize = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (cbIdealSize > Buffer.QuerySize())
|
||||||
|
{
|
||||||
|
if (!Buffer.Resize(max(cbIdealSize, static_cast<SIZE_T>(Buffer.QuerySize() * 2)),
|
||||||
|
fZeroMemoryBeyondOldSize))
|
||||||
|
{
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Lots of code uses BUFFER class to store a bunch of different
|
||||||
|
// structures, so m_rgBuffer needs to be 8 byte aligned when it is used
|
||||||
|
// as an opaque buffer.
|
||||||
|
//
|
||||||
|
#define INLINED_BUFFER_LEN 32
|
||||||
|
typedef BUFFER_T<BYTE, INLINED_BUFFER_LEN> BUFFER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assumption of macros below for pointer alignment purposes
|
||||||
|
//
|
||||||
|
C_ASSERT( sizeof(VOID*) <= sizeof(ULONGLONG) );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Declare a BUFFER that will use stack memory of <size>
|
||||||
|
// bytes. If the buffer overflows then a heap buffer will be allocated.
|
||||||
|
//
|
||||||
|
#define STACK_BUFFER( _name, _size ) \
|
||||||
|
ULONGLONG __aqw##_name[ ( ( (_size) + sizeof(ULONGLONG) - 1 ) / sizeof(ULONGLONG) ) ]; \
|
||||||
|
BUFFER _name( (BYTE*)__aqw##_name, sizeof(__aqw##_name) )
|
||||||
|
|
||||||
|
//
|
||||||
|
// Macros for declaring and initializing a BUFFER that will use inline memory
|
||||||
|
// of <size> bytes as a member of an object.
|
||||||
|
//
|
||||||
|
#define INLINE_BUFFER( _name, _size ) \
|
||||||
|
ULONGLONG __aqw##_name[ ( ( (_size) + sizeof(ULONGLONG) - 1 ) / sizeof(ULONGLONG) ) ]; \
|
||||||
|
BUFFER _name;
|
||||||
|
|
||||||
|
#define INLINE_BUFFER_INIT( _name ) \
|
||||||
|
_name( (BYTE*)__aqw##_name, sizeof( __aqw##_name ) )
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _DATETIME_H_
|
||||||
|
#define _DATETIME_H_
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
StringTimeToFileTime(
|
||||||
|
PCSTR pszTime,
|
||||||
|
ULONGLONG * pulTime
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _DBGUTIL_H_
|
||||||
|
#define _DBGUTIL_H_
|
||||||
|
|
||||||
|
#include <crtdbg.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO
|
||||||
|
// Using _CrtDbg implementation. If hooking is desired
|
||||||
|
// wrappers should be provided here so that we can reimplement
|
||||||
|
// if neecessary.
|
||||||
|
//
|
||||||
|
// IF_DEBUG/DEBUG FLAGS
|
||||||
|
//
|
||||||
|
// registry configuration
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debug error levels for DEBUG_FLAGS_VAR.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DEBUG_FLAG_INFO 0x00000001
|
||||||
|
#define DEBUG_FLAG_WARN 0x00000002
|
||||||
|
#define DEBUG_FLAG_ERROR 0x00000004
|
||||||
|
|
||||||
|
//
|
||||||
|
// Predefined error level values. These are backwards from the
|
||||||
|
// windows definitions.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DEBUG_FLAGS_INFO (DEBUG_FLAG_ERROR | DEBUG_FLAG_WARN | DEBUG_FLAG_INFO)
|
||||||
|
#define DEBUG_FLAGS_WARN (DEBUG_FLAG_ERROR | DEBUG_FLAG_WARN)
|
||||||
|
#define DEBUG_FLAGS_ERROR (DEBUG_FLAG_ERROR)
|
||||||
|
#define DEBUG_FLAGS_ANY (DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global variables to control tracing. Generally per module
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DEBUG_FLAGS_VAR
|
||||||
|
#define DEBUG_FLAGS_VAR g_dwDebugFlags
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEBUG_LABEL_VAR
|
||||||
|
#define DEBUG_LABEL_VAR g_szDebugLabel
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern PCSTR DEBUG_LABEL_VAR;
|
||||||
|
extern DWORD DEBUG_FLAGS_VAR;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Module should make this declaration globally.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DECLARE_DEBUG_PRINT_OBJECT( _pszLabel_ ) \
|
||||||
|
PCSTR DEBUG_LABEL_VAR = _pszLabel_; \
|
||||||
|
DWORD DEBUG_FLAGS_VAR = DEBUG_FLAGS_ANY; \
|
||||||
|
|
||||||
|
#define DECLARE_DEBUG_PRINT_OBJECT2( _pszLabel_, _dwLevel_ ) \
|
||||||
|
PCSTR DEBUG_LABEL_VAR = _pszLabel_; \
|
||||||
|
DWORD DEBUG_FLAGS_VAR = _dwLevel_; \
|
||||||
|
|
||||||
|
//
|
||||||
|
// This doesn't do anything now. Should be safe to call in dll main.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CREATE_DEBUG_PRINT_OBJECT
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trace macros
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DBG_CONTEXT _CRT_WARN, __FILE__, __LINE__, DEBUG_LABEL_VAR
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define DBGINFO(args) \
|
||||||
|
{if (DEBUG_FLAGS_VAR & DEBUG_FLAG_INFO) { _CrtDbgReport args; }}
|
||||||
|
#define DBGWARN(args) \
|
||||||
|
{if (DEBUG_FLAGS_VAR & DEBUG_FLAG_WARN) { _CrtDbgReport args; }}
|
||||||
|
#define DBGERROR(args) \
|
||||||
|
{if (DEBUG_FLAGS_VAR & DEBUG_FLAG_ERROR) { _CrtDbgReport args; }}
|
||||||
|
#else
|
||||||
|
#define DBGINFO
|
||||||
|
#define DBGWARN
|
||||||
|
#define DBGERROR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DBGPRINTF DBGINFO
|
||||||
|
|
||||||
|
//
|
||||||
|
// Simple error traces
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DBGERROR_HR( _hr_ ) \
|
||||||
|
DBGERROR((DBG_CONTEXT, "hr=0x%x\n", _hr_))
|
||||||
|
|
||||||
|
#define DBGERROR_STATUS( _status_ ) \
|
||||||
|
DBGERROR((DBG_CONTEXT, "status=%d\n", _status_))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,325 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef __HASHFN_H__
|
||||||
|
#define __HASHFN_H__
|
||||||
|
|
||||||
|
|
||||||
|
// Produce a scrambled, randomish number in the range 0 to RANDOM_PRIME-1.
|
||||||
|
// Applying this to the results of the other hash functions is likely to
|
||||||
|
// produce a much better distribution, especially for the identity hash
|
||||||
|
// functions such as Hash(char c), where records will tend to cluster at
|
||||||
|
// the low end of the hashtable otherwise. LKRhash applies this internally
|
||||||
|
// to all hash signatures for exactly this reason.
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashScramble(DWORD dwHash)
|
||||||
|
{
|
||||||
|
// Here are 10 primes slightly greater than 10^9
|
||||||
|
// 1000000007, 1000000009, 1000000021, 1000000033, 1000000087,
|
||||||
|
// 1000000093, 1000000097, 1000000103, 1000000123, 1000000181.
|
||||||
|
|
||||||
|
// default value for "scrambling constant"
|
||||||
|
const DWORD RANDOM_CONSTANT = 314159269UL;
|
||||||
|
// large prime number, also used for scrambling
|
||||||
|
const DWORD RANDOM_PRIME = 1000000007UL;
|
||||||
|
|
||||||
|
return (RANDOM_CONSTANT * dwHash) % RANDOM_PRIME ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Faster scrambling function suggested by Eric Jacobsen
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashRandomizeBits(DWORD dw)
|
||||||
|
{
|
||||||
|
return (((dw * 1103515245 + 12345) >> 16)
|
||||||
|
| ((dw * 69069 + 1) & 0xffff0000));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Small prime number used as a multiplier in the supplied hash functions
|
||||||
|
const DWORD HASH_MULTIPLIER = 101;
|
||||||
|
|
||||||
|
#undef HASH_SHIFT_MULTIPLY
|
||||||
|
|
||||||
|
#ifdef HASH_SHIFT_MULTIPLY
|
||||||
|
# define HASH_MULTIPLY(dw) (((dw) << 7) - (dw))
|
||||||
|
#else
|
||||||
|
# define HASH_MULTIPLY(dw) ((dw) * HASH_MULTIPLIER)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Fast, simple hash function that tends to give a good distribution.
|
||||||
|
// Apply HashScramble to the result if you're using this for something
|
||||||
|
// other than LKRhash.
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashString(
|
||||||
|
const char* psz,
|
||||||
|
DWORD dwHash = 0)
|
||||||
|
{
|
||||||
|
// force compiler to use unsigned arithmetic
|
||||||
|
const unsigned char* upsz = (const unsigned char*) psz;
|
||||||
|
|
||||||
|
for ( ; *upsz; ++upsz)
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + *upsz;
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashString(
|
||||||
|
__in_ecount(cch) const char* psz,
|
||||||
|
__in DWORD cch,
|
||||||
|
__in DWORD dwHash
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// force compiler to use unsigned arithmetic
|
||||||
|
const unsigned char* upsz = (const unsigned char*) psz;
|
||||||
|
|
||||||
|
for (DWORD Index = 0;
|
||||||
|
Index < cch;
|
||||||
|
++Index, ++upsz)
|
||||||
|
{
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + *upsz;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Unicode version of above
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashString(
|
||||||
|
const wchar_t* pwsz,
|
||||||
|
DWORD dwHash = 0)
|
||||||
|
{
|
||||||
|
for ( ; *pwsz; ++pwsz)
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + *pwsz;
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on length of the string instead of null-terminating character
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashString(
|
||||||
|
__in_ecount(cch) const wchar_t* pwsz,
|
||||||
|
__in DWORD cch,
|
||||||
|
__in DWORD dwHash
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (DWORD Index = 0;
|
||||||
|
Index < cch;
|
||||||
|
++Index, ++pwsz)
|
||||||
|
{
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + *pwsz;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Quick-'n'-dirty case-insensitive string hash function.
|
||||||
|
// Make sure that you follow up with _stricmp or _mbsicmp. You should
|
||||||
|
// also cache the length of strings and check those first. Caching
|
||||||
|
// an uppercase version of a string can help too.
|
||||||
|
// Again, apply HashScramble to the result if using with something other
|
||||||
|
// than LKRhash.
|
||||||
|
// Note: this is not really adequate for MBCS strings.
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashStringNoCase(
|
||||||
|
const char* psz,
|
||||||
|
DWORD dwHash = 0)
|
||||||
|
{
|
||||||
|
const unsigned char* upsz = (const unsigned char*) psz;
|
||||||
|
|
||||||
|
for ( ; *upsz; ++upsz)
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash)
|
||||||
|
+ (*upsz & 0xDF); // strip off lowercase bit
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashStringNoCase(
|
||||||
|
__in_ecount(cch)
|
||||||
|
const char* psz,
|
||||||
|
SIZE_T cch,
|
||||||
|
DWORD dwHash)
|
||||||
|
{
|
||||||
|
const unsigned char* upsz = (const unsigned char*) psz;
|
||||||
|
|
||||||
|
for (SIZE_T Index = 0;
|
||||||
|
Index < cch;
|
||||||
|
++Index, ++upsz)
|
||||||
|
{
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash)
|
||||||
|
+ (*upsz & 0xDF); // strip off lowercase bit
|
||||||
|
}
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Unicode version of above
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashStringNoCase(
|
||||||
|
const wchar_t* pwsz,
|
||||||
|
DWORD dwHash = 0)
|
||||||
|
{
|
||||||
|
for ( ; *pwsz; ++pwsz)
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + (*pwsz & 0xFFDF);
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unicode version of above with length
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashStringNoCase(
|
||||||
|
__in_ecount(cch)
|
||||||
|
const wchar_t* pwsz,
|
||||||
|
SIZE_T cch,
|
||||||
|
DWORD dwHash)
|
||||||
|
{
|
||||||
|
for (SIZE_T Index = 0;
|
||||||
|
Index < cch;
|
||||||
|
++Index, ++pwsz)
|
||||||
|
{
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + (*pwsz & 0xFFDF);
|
||||||
|
}
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// HashBlob returns the hash of a blob of arbitrary binary data.
|
||||||
|
//
|
||||||
|
// Warning: HashBlob is generally not the right way to hash a class object.
|
||||||
|
// Consider:
|
||||||
|
// class CFoo {
|
||||||
|
// public:
|
||||||
|
// char m_ch;
|
||||||
|
// double m_d;
|
||||||
|
// char* m_psz;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// inline DWORD Hash(const CFoo& rFoo)
|
||||||
|
// { return HashBlob(&rFoo, sizeof(CFoo)); }
|
||||||
|
//
|
||||||
|
// This is the wrong way to hash a CFoo for two reasons: (a) there will be
|
||||||
|
// a 7-byte gap between m_ch and m_d imposed by the alignment restrictions
|
||||||
|
// of doubles, which will be filled with random data (usually non-zero for
|
||||||
|
// stack variables), and (b) it hashes the address (rather than the
|
||||||
|
// contents) of the string m_psz. Similarly,
|
||||||
|
//
|
||||||
|
// bool operator==(const CFoo& rFoo1, const CFoo& rFoo2)
|
||||||
|
// { return memcmp(&rFoo1, &rFoo2, sizeof(CFoo)) == 0; }
|
||||||
|
//
|
||||||
|
// does the wrong thing. Much better to do this:
|
||||||
|
//
|
||||||
|
// DWORD Hash(const CFoo& rFoo)
|
||||||
|
// {
|
||||||
|
// return HashString(rFoo.m_psz,
|
||||||
|
// HASH_MULTIPLIER * Hash(rFoo.m_ch)
|
||||||
|
// + Hash(rFoo.m_d));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Again, apply HashScramble if using with something other than LKRhash.
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
HashBlob(
|
||||||
|
const void* pv,
|
||||||
|
size_t cb,
|
||||||
|
DWORD dwHash = 0)
|
||||||
|
{
|
||||||
|
const BYTE * pb = static_cast<const BYTE *>(pv);
|
||||||
|
|
||||||
|
while (cb-- > 0)
|
||||||
|
dwHash = HASH_MULTIPLY(dwHash) + *pb++;
|
||||||
|
|
||||||
|
return dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Overloaded hash functions for all the major builtin types.
|
||||||
|
// Again, apply HashScramble to result if using with something other than
|
||||||
|
// LKRhash.
|
||||||
|
//
|
||||||
|
|
||||||
|
inline DWORD Hash(const char* psz)
|
||||||
|
{ return HashString(psz); }
|
||||||
|
|
||||||
|
inline DWORD Hash(const unsigned char* pusz)
|
||||||
|
{ return HashString(reinterpret_cast<const char*>(pusz)); }
|
||||||
|
|
||||||
|
inline DWORD Hash(const signed char* pssz)
|
||||||
|
{ return HashString(reinterpret_cast<const char*>(pssz)); }
|
||||||
|
|
||||||
|
inline DWORD Hash(const wchar_t* pwsz)
|
||||||
|
{ return HashString(pwsz); }
|
||||||
|
|
||||||
|
inline DWORD
|
||||||
|
Hash(
|
||||||
|
const GUID* pguid,
|
||||||
|
DWORD dwHash = 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
return * reinterpret_cast<const DWORD *>(const_cast<GUID*>(pguid)) + dwHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identity hash functions: scalar values map to themselves
|
||||||
|
inline DWORD Hash(char c)
|
||||||
|
{ return c; }
|
||||||
|
|
||||||
|
inline DWORD Hash(unsigned char uc)
|
||||||
|
{ return uc; }
|
||||||
|
|
||||||
|
inline DWORD Hash(signed char sc)
|
||||||
|
{ return sc; }
|
||||||
|
|
||||||
|
inline DWORD Hash(short sh)
|
||||||
|
{ return sh; }
|
||||||
|
|
||||||
|
inline DWORD Hash(unsigned short ush)
|
||||||
|
{ return ush; }
|
||||||
|
|
||||||
|
inline DWORD Hash(int i)
|
||||||
|
{ return i; }
|
||||||
|
|
||||||
|
inline DWORD Hash(unsigned int u)
|
||||||
|
{ return u; }
|
||||||
|
|
||||||
|
inline DWORD Hash(long l)
|
||||||
|
{ return l; }
|
||||||
|
|
||||||
|
inline DWORD Hash(unsigned long ul)
|
||||||
|
{ return ul; }
|
||||||
|
|
||||||
|
inline DWORD Hash(float f)
|
||||||
|
{
|
||||||
|
// be careful of rounding errors when computing keys
|
||||||
|
union {
|
||||||
|
float f;
|
||||||
|
DWORD dw;
|
||||||
|
} u;
|
||||||
|
u.f = f;
|
||||||
|
return u.dw;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline DWORD Hash(double dbl)
|
||||||
|
{
|
||||||
|
// be careful of rounding errors when computing keys
|
||||||
|
union {
|
||||||
|
double dbl;
|
||||||
|
DWORD dw[2];
|
||||||
|
} u;
|
||||||
|
u.dbl = dbl;
|
||||||
|
return u.dw[0] * HASH_MULTIPLIER + u.dw[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __HASHFN_H__
|
||||||
|
|
@ -0,0 +1,666 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#include "rwlock.h"
|
||||||
|
#include "prime.h"
|
||||||
|
|
||||||
|
template <class _Record>
|
||||||
|
class HASH_NODE
|
||||||
|
{
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
friend class HASH_TABLE;
|
||||||
|
|
||||||
|
HASH_NODE(
|
||||||
|
_Record * pRecord,
|
||||||
|
DWORD dwHash
|
||||||
|
) : _pNext (NULL),
|
||||||
|
_pRecord (pRecord),
|
||||||
|
_dwHash (dwHash)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~HASH_NODE()
|
||||||
|
{
|
||||||
|
_ASSERTE(_pRecord == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Next node in the hash table look-aside
|
||||||
|
HASH_NODE<_Record> *_pNext;
|
||||||
|
|
||||||
|
// actual record
|
||||||
|
_Record * _pRecord;
|
||||||
|
|
||||||
|
// hash value
|
||||||
|
DWORD _dwHash;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
class HASH_TABLE
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef BOOL
|
||||||
|
(PFN_DELETE_IF)(
|
||||||
|
_Record * pRecord,
|
||||||
|
PVOID pvContext
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID
|
||||||
|
(PFN_APPLY)(
|
||||||
|
_Record * pRecord,
|
||||||
|
PVOID pvContext
|
||||||
|
);
|
||||||
|
|
||||||
|
public:
|
||||||
|
HASH_TABLE(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
: _ppBuckets( NULL ),
|
||||||
|
_nBuckets( 0 ),
|
||||||
|
_nItems( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~HASH_TABLE();
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
ReferenceRecord(
|
||||||
|
_Record * pRecord
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
DereferenceRecord(
|
||||||
|
_Record * pRecord
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
_Key
|
||||||
|
ExtractKey(
|
||||||
|
_Record * pRecord
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
DWORD
|
||||||
|
CalcKeyHash(
|
||||||
|
_Key key
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
BOOL
|
||||||
|
EqualKeys(
|
||||||
|
_Key key1,
|
||||||
|
_Key key2
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
Count(
|
||||||
|
VOID
|
||||||
|
) const;
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsInitialized(
|
||||||
|
VOID
|
||||||
|
) const;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
DWORD nBucketSize
|
||||||
|
);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
FindKey(
|
||||||
|
_Key key,
|
||||||
|
_Record ** ppRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
HRESULT
|
||||||
|
InsertRecord(
|
||||||
|
_Record * pRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
DeleteKey(
|
||||||
|
_Key key
|
||||||
|
);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
DeleteIf(
|
||||||
|
PFN_DELETE_IF pfnDeleteIf,
|
||||||
|
PVOID pvContext
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Apply(
|
||||||
|
PFN_APPLY pfnApply,
|
||||||
|
PVOID pvContext
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
__success(*ppNode != NULL && return != FALSE)
|
||||||
|
BOOL
|
||||||
|
FindNodeInternal(
|
||||||
|
_Key key,
|
||||||
|
DWORD dwHash,
|
||||||
|
__deref_out
|
||||||
|
HASH_NODE<_Record> ** ppNode,
|
||||||
|
__deref_opt_out
|
||||||
|
HASH_NODE<_Record> *** pppPreviousNodeNextPointer = NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DeleteNode(
|
||||||
|
HASH_NODE<_Record> * pNode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pNode->_pRecord != NULL)
|
||||||
|
{
|
||||||
|
DereferenceRecord(pNode->_pRecord);
|
||||||
|
pNode->_pRecord = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RehashTableIfNeeded(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
HASH_NODE<_Record> ** _ppBuckets;
|
||||||
|
DWORD _nBuckets;
|
||||||
|
DWORD _nItems;
|
||||||
|
//
|
||||||
|
// Allow to use lock object in const methods.
|
||||||
|
//
|
||||||
|
mutable
|
||||||
|
CWSDRWLock _tableLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
HRESULT
|
||||||
|
HASH_TABLE<_Record,_Key>::Initialize(
|
||||||
|
DWORD nBuckets
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if ( nBuckets == 0 )
|
||||||
|
{
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nBuckets >= MAXDWORD/sizeof(HASH_NODE<_Record> *))
|
||||||
|
{
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ASSERTE(_ppBuckets == NULL );
|
||||||
|
if ( _ppBuckets != NULL )
|
||||||
|
{
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = _tableLock.Init();
|
||||||
|
if ( FAILED( hr ) )
|
||||||
|
{
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ppBuckets = (HASH_NODE<_Record> **)HeapAlloc(
|
||||||
|
GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
nBuckets*sizeof(HASH_NODE<_Record> *));
|
||||||
|
if (_ppBuckets == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
_nBuckets = nBuckets;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
Failed:
|
||||||
|
|
||||||
|
if (_ppBuckets)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
_ppBuckets);
|
||||||
|
_ppBuckets = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
HASH_TABLE<_Record,_Key>::~HASH_TABLE()
|
||||||
|
{
|
||||||
|
if (_ppBuckets == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ASSERTE(_nItems == 0);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
_ppBuckets);
|
||||||
|
_ppBuckets = NULL;
|
||||||
|
_nBuckets = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class _Record, class _Key>
|
||||||
|
DWORD
|
||||||
|
HASH_TABLE<_Record,_Key>::Count() const
|
||||||
|
{
|
||||||
|
return _nItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class _Record, class _Key>
|
||||||
|
bool
|
||||||
|
HASH_TABLE<_Record,_Key>::IsInitialized(
|
||||||
|
VOID
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return _ppBuckets != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
VOID
|
||||||
|
HASH_TABLE<_Record,_Key>::Clear()
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> *pCurrent;
|
||||||
|
HASH_NODE<_Record> *pNext;
|
||||||
|
|
||||||
|
// This is here in the off cases where someone instantiates a hashtable
|
||||||
|
// and then does an automatic "clear" before its destruction WITHOUT
|
||||||
|
// ever initializing it.
|
||||||
|
if ( ! _tableLock.QueryInited() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.ExclusiveAcquire();
|
||||||
|
|
||||||
|
for (DWORD i=0; i<_nBuckets; i++)
|
||||||
|
{
|
||||||
|
pCurrent = _ppBuckets[i];
|
||||||
|
_ppBuckets[i] = NULL;
|
||||||
|
while (pCurrent != NULL)
|
||||||
|
{
|
||||||
|
pNext = pCurrent->_pNext;
|
||||||
|
DeleteNode(pCurrent);
|
||||||
|
pCurrent = pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_nItems = 0;
|
||||||
|
_tableLock.ExclusiveRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
__success(*ppNode != NULL && return != FALSE)
|
||||||
|
BOOL
|
||||||
|
HASH_TABLE<_Record,_Key>::FindNodeInternal(
|
||||||
|
_Key key,
|
||||||
|
DWORD dwHash,
|
||||||
|
__deref_out
|
||||||
|
HASH_NODE<_Record> ** ppNode,
|
||||||
|
__deref_opt_out
|
||||||
|
HASH_NODE<_Record> *** pppPreviousNodeNextPointer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Return value indicates whether the item is found
|
||||||
|
key, dwHash - key and hash for the node to find
|
||||||
|
ppNode - on successful return, the node found, on failed return, the first
|
||||||
|
node with hash value greater than the node to be found
|
||||||
|
pppPreviousNodeNextPointer - the pointer to previous node's _pNext
|
||||||
|
|
||||||
|
This routine may be called under either read or write lock
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> **ppPreviousNodeNextPointer;
|
||||||
|
HASH_NODE<_Record> *pNode;
|
||||||
|
BOOL fFound = FALSE;
|
||||||
|
|
||||||
|
ppPreviousNodeNextPointer = _ppBuckets + (dwHash % _nBuckets);
|
||||||
|
pNode = *ppPreviousNodeNextPointer;
|
||||||
|
while (pNode != NULL)
|
||||||
|
{
|
||||||
|
if (pNode->_dwHash == dwHash)
|
||||||
|
{
|
||||||
|
if (EqualKeys(key,
|
||||||
|
ExtractKey(pNode->_pRecord)))
|
||||||
|
{
|
||||||
|
fFound = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pNode->_dwHash > dwHash)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppPreviousNodeNextPointer = &(pNode->_pNext);
|
||||||
|
pNode = *ppPreviousNodeNextPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
__analysis_assume( (pNode == NULL && fFound == FALSE) ||
|
||||||
|
(pNode != NULL && fFound == TRUE ) );
|
||||||
|
*ppNode = pNode;
|
||||||
|
if (pppPreviousNodeNextPointer != NULL)
|
||||||
|
{
|
||||||
|
*pppPreviousNodeNextPointer = ppPreviousNodeNextPointer;
|
||||||
|
}
|
||||||
|
return fFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
VOID
|
||||||
|
HASH_TABLE<_Record,_Key>::FindKey(
|
||||||
|
_Key key,
|
||||||
|
_Record ** ppRecord
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> *pNode;
|
||||||
|
|
||||||
|
*ppRecord = NULL;
|
||||||
|
|
||||||
|
DWORD dwHash = CalcKeyHash(key);
|
||||||
|
|
||||||
|
_tableLock.SharedAcquire();
|
||||||
|
|
||||||
|
if (FindNodeInternal(key, dwHash, &pNode) &&
|
||||||
|
pNode->_pRecord != NULL)
|
||||||
|
{
|
||||||
|
ReferenceRecord(pNode->_pRecord);
|
||||||
|
*ppRecord = pNode->_pRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.SharedRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
HRESULT
|
||||||
|
HASH_TABLE<_Record,_Key>::InsertRecord(
|
||||||
|
_Record * pRecord
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
This method inserts a node for this record and also empty nodes for paths
|
||||||
|
in the heirarchy leading upto this path
|
||||||
|
|
||||||
|
The insert is done under only a read-lock - this is possible by keeping
|
||||||
|
the hashes in a bucket in increasing order and using interlocked operations
|
||||||
|
to actually insert the item in the hash-bucket lookaside list and the parent
|
||||||
|
children list
|
||||||
|
|
||||||
|
Returns HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) if the record already exists.
|
||||||
|
Never leak this error to the end user because "*file* already exists" may be confusing.
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
_Key key = ExtractKey(pRecord);
|
||||||
|
DWORD dwHash = CalcKeyHash(key);
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
HASH_NODE<_Record> * pNewNode;
|
||||||
|
HASH_NODE<_Record> * pNextNode;
|
||||||
|
HASH_NODE<_Record> ** ppPreviousNodeNextPointer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ownership of pRecord is not transferred to pNewNode yet, so remember
|
||||||
|
// to either set it to null before deleting pNewNode or add an extra
|
||||||
|
// reference later - this is to make sure we do not do an extra ref/deref
|
||||||
|
// which users may view as getting flushed out of the hash-table
|
||||||
|
//
|
||||||
|
pNewNode = new HASH_NODE<_Record>(pRecord, dwHash);
|
||||||
|
if (pNewNode == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.SharedAcquire();
|
||||||
|
fLocked = TRUE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Find the right place to add this node
|
||||||
|
//
|
||||||
|
if (FindNodeInternal(key, dwHash, &pNextNode, &ppPreviousNodeNextPointer))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// If node already there, return error
|
||||||
|
//
|
||||||
|
pNewNode->_pRecord = NULL;
|
||||||
|
DeleteNode(pNewNode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// We should never leak this error to the end user
|
||||||
|
// because "file already exists" may be confusing.
|
||||||
|
//
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If another node got inserted in between, we will have to retry
|
||||||
|
//
|
||||||
|
pNewNode->_pNext = pNextNode;
|
||||||
|
} while (InterlockedCompareExchangePointer((PVOID *)ppPreviousNodeNextPointer,
|
||||||
|
pNewNode,
|
||||||
|
pNextNode) != pNextNode);
|
||||||
|
// pass ownership of pRecord now
|
||||||
|
if (pRecord != NULL)
|
||||||
|
{
|
||||||
|
ReferenceRecord(pRecord);
|
||||||
|
pRecord = NULL;
|
||||||
|
}
|
||||||
|
InterlockedIncrement((LONG *)&_nItems);
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (fLocked)
|
||||||
|
{
|
||||||
|
_tableLock.SharedRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
RehashTableIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
VOID
|
||||||
|
HASH_TABLE<_Record,_Key>::DeleteKey(
|
||||||
|
_Key key
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> *pNode;
|
||||||
|
HASH_NODE<_Record> **ppPreviousNodeNextPointer;
|
||||||
|
|
||||||
|
DWORD dwHash = CalcKeyHash(key);
|
||||||
|
|
||||||
|
_tableLock.ExclusiveAcquire();
|
||||||
|
|
||||||
|
if (FindNodeInternal(key, dwHash, &pNode, &ppPreviousNodeNextPointer))
|
||||||
|
{
|
||||||
|
*ppPreviousNodeNextPointer = pNode->_pNext;
|
||||||
|
DeleteNode(pNode);
|
||||||
|
_nItems--;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.ExclusiveRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
VOID
|
||||||
|
HASH_TABLE<_Record,_Key>::DeleteIf(
|
||||||
|
PFN_DELETE_IF pfnDeleteIf,
|
||||||
|
PVOID pvContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> *pNode;
|
||||||
|
HASH_NODE<_Record> **ppPreviousNodeNextPointer;
|
||||||
|
|
||||||
|
_tableLock.ExclusiveAcquire();
|
||||||
|
|
||||||
|
for (DWORD i=0; i<_nBuckets; i++)
|
||||||
|
{
|
||||||
|
ppPreviousNodeNextPointer = _ppBuckets + i;
|
||||||
|
pNode = *ppPreviousNodeNextPointer;
|
||||||
|
while (pNode != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Non empty nodes deleted based on DeleteIf, empty nodes deleted
|
||||||
|
// if they have no children
|
||||||
|
//
|
||||||
|
if (pfnDeleteIf(pNode->_pRecord, pvContext))
|
||||||
|
{
|
||||||
|
*ppPreviousNodeNextPointer = pNode->_pNext;
|
||||||
|
DeleteNode(pNode);
|
||||||
|
_nItems--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ppPreviousNodeNextPointer = &pNode->_pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNode = *ppPreviousNodeNextPointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.ExclusiveRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
VOID
|
||||||
|
HASH_TABLE<_Record,_Key>::Apply(
|
||||||
|
PFN_APPLY pfnApply,
|
||||||
|
PVOID pvContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> *pNode;
|
||||||
|
|
||||||
|
_tableLock.SharedAcquire();
|
||||||
|
|
||||||
|
for (DWORD i=0; i<_nBuckets; i++)
|
||||||
|
{
|
||||||
|
pNode = _ppBuckets[i];
|
||||||
|
while (pNode != NULL)
|
||||||
|
{
|
||||||
|
if (pNode->_pRecord != NULL)
|
||||||
|
{
|
||||||
|
pfnApply(pNode->_pRecord, pvContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
pNode = pNode->_pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.SharedRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _Record, class _Key>
|
||||||
|
VOID
|
||||||
|
HASH_TABLE<_Record,_Key>::RehashTableIfNeeded(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HASH_NODE<_Record> **ppBuckets;
|
||||||
|
DWORD nBuckets;
|
||||||
|
HASH_NODE<_Record> *pNode;
|
||||||
|
HASH_NODE<_Record> *pNextNode;
|
||||||
|
HASH_NODE<_Record> **ppNextPointer;
|
||||||
|
HASH_NODE<_Record> *pNewNextNode;
|
||||||
|
DWORD nNewBuckets;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If number of items has become too many, we will double the hash table
|
||||||
|
// size (we never reduce it however)
|
||||||
|
//
|
||||||
|
if (_nItems <= PRIME::GetPrime(2*_nBuckets))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tableLock.ExclusiveAcquire();
|
||||||
|
|
||||||
|
nNewBuckets = PRIME::GetPrime(2*_nBuckets);
|
||||||
|
|
||||||
|
if (_nItems <= nNewBuckets)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
nBuckets = nNewBuckets;
|
||||||
|
if (nBuckets >= 0xffffffff/sizeof(HASH_NODE<_Record> *))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
ppBuckets = (HASH_NODE<_Record> **)HeapAlloc(
|
||||||
|
GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
nBuckets*sizeof(HASH_NODE<_Record> *));
|
||||||
|
if (ppBuckets == NULL)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Take out nodes from the old hash table and insert in the new one, make
|
||||||
|
// sure to keep the hashes in increasing order
|
||||||
|
//
|
||||||
|
for (DWORD i=0; i<_nBuckets; i++)
|
||||||
|
{
|
||||||
|
pNode = _ppBuckets[i];
|
||||||
|
while (pNode != NULL)
|
||||||
|
{
|
||||||
|
pNextNode = pNode->_pNext;
|
||||||
|
|
||||||
|
ppNextPointer = ppBuckets + (pNode->_dwHash % nBuckets);
|
||||||
|
pNewNextNode = *ppNextPointer;
|
||||||
|
while (pNewNextNode != NULL &&
|
||||||
|
pNewNextNode->_dwHash <= pNode->_dwHash)
|
||||||
|
{
|
||||||
|
ppNextPointer = &pNewNextNode->_pNext;
|
||||||
|
pNewNextNode = pNewNextNode->_pNext;
|
||||||
|
}
|
||||||
|
pNode->_pNext = pNewNextNode;
|
||||||
|
*ppNextPointer = pNode;
|
||||||
|
|
||||||
|
pNode = pNextNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, _ppBuckets);
|
||||||
|
_ppBuckets = ppBuckets;
|
||||||
|
_nBuckets = nBuckets;
|
||||||
|
ppBuckets = NULL;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
_tableLock.ExclusiveRelease();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _LIST_ENTRY_H
|
||||||
|
#define _LIST_ENTRY_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// Doubly-linked list manipulation routines.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#define InitializeListHead32(ListHead) (\
|
||||||
|
(ListHead)->Flink = (ListHead)->Blink = PtrToUlong((ListHead)))
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
InitializeListHead(
|
||||||
|
IN PLIST_ENTRY ListHead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ListHead->Flink = ListHead->Blink = ListHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
BOOLEAN
|
||||||
|
IsListEmpty(
|
||||||
|
IN const LIST_ENTRY * ListHead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (BOOLEAN)(ListHead->Flink == ListHead);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
BOOLEAN
|
||||||
|
RemoveEntryList(
|
||||||
|
IN PLIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Blink;
|
||||||
|
PLIST_ENTRY Flink;
|
||||||
|
|
||||||
|
Flink = Entry->Flink;
|
||||||
|
Blink = Entry->Blink;
|
||||||
|
Blink->Flink = Flink;
|
||||||
|
Flink->Blink = Blink;
|
||||||
|
return (BOOLEAN)(Flink == Blink);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
PLIST_ENTRY
|
||||||
|
RemoveHeadList(
|
||||||
|
IN PLIST_ENTRY ListHead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Flink;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
|
||||||
|
Entry = ListHead->Flink;
|
||||||
|
Flink = Entry->Flink;
|
||||||
|
ListHead->Flink = Flink;
|
||||||
|
Flink->Blink = ListHead;
|
||||||
|
return Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
PLIST_ENTRY
|
||||||
|
RemoveTailList(
|
||||||
|
IN PLIST_ENTRY ListHead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Blink;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
|
||||||
|
Entry = ListHead->Blink;
|
||||||
|
Blink = Entry->Blink;
|
||||||
|
ListHead->Blink = Blink;
|
||||||
|
Blink->Flink = ListHead;
|
||||||
|
return Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
InsertTailList(
|
||||||
|
IN PLIST_ENTRY ListHead,
|
||||||
|
IN PLIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Blink;
|
||||||
|
|
||||||
|
Blink = ListHead->Blink;
|
||||||
|
Entry->Flink = ListHead;
|
||||||
|
Entry->Blink = Blink;
|
||||||
|
Blink->Flink = Entry;
|
||||||
|
ListHead->Blink = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
InsertHeadList(
|
||||||
|
IN PLIST_ENTRY ListHead,
|
||||||
|
IN PLIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Flink;
|
||||||
|
|
||||||
|
Flink = ListHead->Flink;
|
||||||
|
Entry->Flink = Flink;
|
||||||
|
Entry->Blink = ListHead;
|
||||||
|
Flink->Blink = Entry;
|
||||||
|
ListHead->Flink = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
AppendTailList(
|
||||||
|
IN PLIST_ENTRY ListHead,
|
||||||
|
IN PLIST_ENTRY ListToAppend
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY ListEnd = ListHead->Blink;
|
||||||
|
|
||||||
|
ListHead->Blink->Flink = ListToAppend;
|
||||||
|
ListHead->Blink = ListToAppend->Blink;
|
||||||
|
ListToAppend->Blink->Flink = ListHead;
|
||||||
|
ListToAppend->Blink = ListEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
PSINGLE_LIST_ENTRY
|
||||||
|
PopEntryList(
|
||||||
|
PSINGLE_LIST_ENTRY ListHead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PSINGLE_LIST_ENTRY FirstEntry;
|
||||||
|
FirstEntry = ListHead->Next;
|
||||||
|
if (FirstEntry != NULL) {
|
||||||
|
ListHead->Next = FirstEntry->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirstEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
PushEntryList(
|
||||||
|
PSINGLE_LIST_ENTRY ListHead,
|
||||||
|
PSINGLE_LIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Entry->Next = ListHead->Next;
|
||||||
|
ListHead->Next = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _MACROS_H
|
||||||
|
#define _MACROS_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// The DIFF macro should be used around an expression involving pointer
|
||||||
|
// subtraction. The expression passed to DIFF is cast to a size_t type,
|
||||||
|
// allowing the result to be easily assigned to any 32-bit variable or
|
||||||
|
// passed to a function expecting a 32-bit argument.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define DIFF(x) ((size_t)(x))
|
||||||
|
|
||||||
|
// Change a hexadecimal digit to its numerical equivalent
|
||||||
|
#define TOHEX( ch ) \
|
||||||
|
((ch) > L'9' ? \
|
||||||
|
(ch) >= L'a' ? \
|
||||||
|
(ch) - L'a' + 10 : \
|
||||||
|
(ch) - L'A' + 10 \
|
||||||
|
: (ch) - L'0')
|
||||||
|
|
||||||
|
|
||||||
|
// Change a number to its Hexadecimal equivalent
|
||||||
|
|
||||||
|
#define TODIGIT( nDigit ) \
|
||||||
|
(CHAR)((nDigit) > 9 ? \
|
||||||
|
(nDigit) - 10 + 'A' \
|
||||||
|
: (nDigit) + '0')
|
||||||
|
|
||||||
|
|
||||||
|
inline int
|
||||||
|
SAFEIsSpace(UCHAR c)
|
||||||
|
{
|
||||||
|
return isspace( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
SAFEIsAlNum(UCHAR c)
|
||||||
|
{
|
||||||
|
return isalnum( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
SAFEIsAlpha(UCHAR c)
|
||||||
|
{
|
||||||
|
return isalpha( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
SAFEIsXDigit(UCHAR c)
|
||||||
|
{
|
||||||
|
return isxdigit( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
SAFEIsDigit(UCHAR c)
|
||||||
|
{
|
||||||
|
return isdigit( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _MACROS_H
|
||||||
|
|
@ -0,0 +1,474 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
|
||||||
|
#pragma warning (disable : 4267)
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
#include "multisz.h"
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private Definitions
|
||||||
|
//
|
||||||
|
|
||||||
|
#define MAXULONG 4294967295
|
||||||
|
#define ISWHITE( ch ) ((ch) == L' ' || (ch) == L'\t' || (ch) == L'\r')
|
||||||
|
|
||||||
|
//
|
||||||
|
// When appending data, this is the extra amount we request to avoid
|
||||||
|
// reallocations
|
||||||
|
//
|
||||||
|
#define STR_SLOP 128
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
MULTISZ::CalcLength( const WCHAR * str,
|
||||||
|
LPDWORD pcStrings )
|
||||||
|
{
|
||||||
|
DWORD count = 0;
|
||||||
|
DWORD total = 1;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
while( *str ) {
|
||||||
|
len = ::wcslen( str ) + 1;
|
||||||
|
total += len;
|
||||||
|
str += len;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pcStrings != NULL ) {
|
||||||
|
*pcStrings = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
|
||||||
|
} // MULTISZ::CalcLength
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZ::FindString( const WCHAR * str )
|
||||||
|
{
|
||||||
|
|
||||||
|
WCHAR * multisz;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sanity check.
|
||||||
|
//
|
||||||
|
|
||||||
|
DBG_ASSERT( QueryStr() != NULL );
|
||||||
|
DBG_ASSERT( str != NULL );
|
||||||
|
DBG_ASSERT( *str != '\0' );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Scan it.
|
||||||
|
//
|
||||||
|
|
||||||
|
multisz = QueryStr();
|
||||||
|
|
||||||
|
while( *multisz != '\0' ) {
|
||||||
|
|
||||||
|
if( !::wcscmp( multisz, str ) ) {
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
multisz += ::wcslen( multisz ) + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
} // MULTISZ::FindString
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZ::FindStringNoCase( const WCHAR * str )
|
||||||
|
{
|
||||||
|
|
||||||
|
WCHAR * multisz;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sanity check.
|
||||||
|
//
|
||||||
|
|
||||||
|
DBG_ASSERT( QueryStr() != NULL );
|
||||||
|
DBG_ASSERT( str != NULL );
|
||||||
|
DBG_ASSERT( *str != '\0' );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Scan it.
|
||||||
|
//
|
||||||
|
|
||||||
|
multisz = QueryStr();
|
||||||
|
|
||||||
|
while( *multisz != '\0' ) {
|
||||||
|
|
||||||
|
if( !_wcsicmp( multisz, str ) ) {
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
multisz += wcslen( multisz ) + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
} // MULTISZ::FindStringNoCase
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MULTISZ::AuxInit( const WCHAR * pInit )
|
||||||
|
{
|
||||||
|
BOOL fRet;
|
||||||
|
|
||||||
|
if ( pInit )
|
||||||
|
{
|
||||||
|
DWORD cStrings;
|
||||||
|
int cbCopy = CalcLength( pInit, &cStrings ) * sizeof(WCHAR);
|
||||||
|
fRet = Resize( cbCopy );
|
||||||
|
|
||||||
|
if ( fRet ) {
|
||||||
|
CopyMemory( QueryPtr(), pInit, cbCopy );
|
||||||
|
m_cchLen = (cbCopy)/sizeof(WCHAR);
|
||||||
|
m_cStrings = cStrings;
|
||||||
|
} else {
|
||||||
|
// BUFFER::SetValid( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MULTISZ::AuxInit()
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
|
||||||
|
NAME: MULTISZ::AuxAppend
|
||||||
|
|
||||||
|
SYNOPSIS: Appends the string onto the multisz.
|
||||||
|
|
||||||
|
ENTRY: Object to append
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
BOOL MULTISZ::AuxAppend( const WCHAR * pStr, UINT cbStr, BOOL fAddSlop )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( pStr != NULL );
|
||||||
|
|
||||||
|
UINT cbThis = QueryCB();
|
||||||
|
|
||||||
|
DBG_ASSERT( cbThis >= 2 );
|
||||||
|
|
||||||
|
if( cbThis == 4 ) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// It's empty, so start at the beginning.
|
||||||
|
//
|
||||||
|
|
||||||
|
cbThis = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//
|
||||||
|
// It's not empty, so back up over the final terminating NULL.
|
||||||
|
//
|
||||||
|
|
||||||
|
cbThis -= sizeof(WCHAR);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only resize when we have to. When we do resize, we tack on
|
||||||
|
// some extra space to avoid extra reallocations.
|
||||||
|
//
|
||||||
|
// Note: QuerySize returns the requested size of the string buffer,
|
||||||
|
// *not* the strlen of the buffer
|
||||||
|
//
|
||||||
|
|
||||||
|
//AcIncrement( CacMultiszAppend);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check for the arithmetic overflow
|
||||||
|
//
|
||||||
|
// ( 2 * sizeof( WCHAR ) ) is for the double terminator
|
||||||
|
//
|
||||||
|
ULONGLONG cb64Required = (ULONGLONG)cbThis + cbStr + 2 * sizeof(WCHAR);
|
||||||
|
if ( cb64Required > MAXULONG )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_ARITHMETIC_OVERFLOW );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ( QuerySize() < (DWORD) cb64Required )
|
||||||
|
{
|
||||||
|
ULONGLONG cb64AllocSize = cb64Required + (fAddSlop ? STR_SLOP : 0 );
|
||||||
|
//
|
||||||
|
// Check for the arithmetic overflow
|
||||||
|
//
|
||||||
|
if ( cb64AllocSize > MAXULONG )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_ARITHMETIC_OVERFLOW );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ( !Resize( (DWORD) cb64AllocSize ) )
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the exact string and tack on the double terminator
|
||||||
|
memcpy( (BYTE *) QueryPtr() + cbThis,
|
||||||
|
pStr,
|
||||||
|
cbStr);
|
||||||
|
*(WCHAR *)((BYTE *)QueryPtr() + cbThis + cbStr) = L'\0';
|
||||||
|
*(WCHAR *)((BYTE *)QueryPtr() + cbThis + cbStr + sizeof(WCHAR) ) = L'\0';
|
||||||
|
|
||||||
|
m_cchLen = CalcLength( (const WCHAR *)QueryPtr(), &m_cStrings );
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
} // MULTISZ::AuxAppend()
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZ::CopyToBuffer( WCHAR * lpszBuffer, LPDWORD lpcch) const
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
Copies the string into the WCHAR buffer passed in if the buffer
|
||||||
|
is sufficient to hold the translated string.
|
||||||
|
If the buffer is small, the function returns small and sets *lpcch
|
||||||
|
to contain the required number of characters.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
lpszBuffer pointer to WCHAR buffer which on return contains
|
||||||
|
the UNICODE version of string on success.
|
||||||
|
lpcch pointer to DWORD containing the length of the buffer.
|
||||||
|
If *lpcch == 0 then the function returns TRUE with
|
||||||
|
the count of characters required stored in *lpcch.
|
||||||
|
Also in this case lpszBuffer is not affected.
|
||||||
|
Returns:
|
||||||
|
TRUE on success.
|
||||||
|
FALSE on failure. Use GetLastError() for further details.
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
BOOL fReturn = TRUE;
|
||||||
|
|
||||||
|
if ( lpcch == NULL) {
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER);
|
||||||
|
return ( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *lpcch == 0) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inquiring the size of buffer alone
|
||||||
|
//
|
||||||
|
*lpcch = QueryCCH() + 1; // add one character for terminating null
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy after conversion from ANSI to Unicode
|
||||||
|
//
|
||||||
|
int iRet;
|
||||||
|
iRet = MultiByteToWideChar( CP_ACP,
|
||||||
|
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
|
||||||
|
QueryStrA(), QueryCCH() + 1,
|
||||||
|
lpszBuffer, (int )*lpcch);
|
||||||
|
|
||||||
|
if ( iRet == 0 || iRet != (int ) *lpcch) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Error in conversion.
|
||||||
|
//
|
||||||
|
fReturn = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( fReturn);
|
||||||
|
} // MULTISZ::CopyToBuffer()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZ::CopyToBuffer( __out_ecount_opt(*lpcch) WCHAR * lpszBuffer, LPDWORD lpcch) const
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
Copies the string into the WCHAR buffer passed in if the buffer
|
||||||
|
is sufficient to hold the translated string.
|
||||||
|
If the buffer is small, the function returns small and sets *lpcch
|
||||||
|
to contain the required number of characters.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
lpszBuffer pointer to WCHAR buffer which on return contains
|
||||||
|
the string on success.
|
||||||
|
lpcch pointer to DWORD containing the length of the buffer.
|
||||||
|
If *lpcch == 0 then the function returns TRUE with
|
||||||
|
the count of characters required stored in lpcch.
|
||||||
|
Also in this case lpszBuffer is not affected.
|
||||||
|
Returns:
|
||||||
|
TRUE on success.
|
||||||
|
FALSE on failure. Use GetLastError() for further details.
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
BOOL fReturn = TRUE;
|
||||||
|
|
||||||
|
if ( lpcch == NULL) {
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER);
|
||||||
|
return ( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
register DWORD cch = QueryCCH();
|
||||||
|
|
||||||
|
if ( *lpcch >= cch) {
|
||||||
|
|
||||||
|
DBG_ASSERT( lpszBuffer);
|
||||||
|
memcpy( lpszBuffer, QueryStr(), cch * sizeof(WCHAR));
|
||||||
|
} else {
|
||||||
|
DBG_ASSERT( *lpcch < cch);
|
||||||
|
SetLastError( ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
fReturn = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpcch = cch;
|
||||||
|
|
||||||
|
return ( fReturn);
|
||||||
|
} // MULTISZ::CopyToBuffer()
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZ::Equals(
|
||||||
|
MULTISZ* pmszRhs
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// Compares this to pmszRhs, returns TRUE if equal
|
||||||
|
//
|
||||||
|
{
|
||||||
|
DBG_ASSERT( NULL != pmszRhs );
|
||||||
|
|
||||||
|
PCWSTR pszLhs = First( );
|
||||||
|
PCWSTR pszRhs = pmszRhs->First( );
|
||||||
|
|
||||||
|
if( m_cStrings != pmszRhs->m_cStrings )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( NULL != pszLhs )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( NULL != pszRhs );
|
||||||
|
|
||||||
|
if( 0 != wcscmp( pszLhs, pszRhs ) )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszLhs = Next( pszLhs );
|
||||||
|
pszRhs = pmszRhs->Next( pszRhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SplitCommaDelimitedString(
|
||||||
|
PCWSTR pszList,
|
||||||
|
BOOL fTrimEntries,
|
||||||
|
BOOL fRemoveEmptyEntries,
|
||||||
|
MULTISZ * pmszList
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Split comma delimited string into a multisz. Additional leading empty
|
||||||
|
entries after the first are discarded.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszList - List to split up
|
||||||
|
fTrimEntries - Whether each entry should be trimmed before added to multisz
|
||||||
|
fRemoveEmptyEntries - Whether empty entires should be discarded
|
||||||
|
pmszList - Filled with MULTISZ list
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if ( pszList == NULL ||
|
||||||
|
pmszList == NULL )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmszList->Reset();
|
||||||
|
|
||||||
|
/*
|
||||||
|
pszCurrent: start of the current entry which may be the comma that
|
||||||
|
precedes the next entry if the entry is empty
|
||||||
|
|
||||||
|
pszNext: the comma that precedes the next entry. If
|
||||||
|
pszCurrent == pszNext, then the entry is empty
|
||||||
|
|
||||||
|
pszEnd: just past the end of the current entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
for ( PCWSTR pszCurrent = pszList,
|
||||||
|
pszNext = wcschr( pszCurrent, L',' )
|
||||||
|
;
|
||||||
|
;
|
||||||
|
pszCurrent = pszNext + 1,
|
||||||
|
pszNext = wcschr( pszCurrent, L',' ) )
|
||||||
|
{
|
||||||
|
PCWSTR pszEnd = NULL;
|
||||||
|
|
||||||
|
if ( pszNext != NULL )
|
||||||
|
{
|
||||||
|
pszEnd = pszNext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pszEnd = pszCurrent + wcslen( pszCurrent );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fTrimEntries )
|
||||||
|
{
|
||||||
|
while ( pszCurrent < pszEnd && ISWHITE( pszCurrent[ 0 ] ) )
|
||||||
|
{
|
||||||
|
pszCurrent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( pszEnd > pszCurrent && ISWHITE( pszEnd[ -1 ] ) )
|
||||||
|
{
|
||||||
|
pszEnd--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pszCurrent != pszEnd || !fRemoveEmptyEntries )
|
||||||
|
{
|
||||||
|
if ( !pmszList->Append( pszCurrent, (DWORD) ( pszEnd - pszCurrent ) ) )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pszNext == NULL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(default:4267)
|
||||||
|
|
@ -0,0 +1,225 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _MULTISZ_H_
|
||||||
|
#define _MULTISZ_H_
|
||||||
|
|
||||||
|
#include "stringu.h"
|
||||||
|
#include "ntassert.h"
|
||||||
|
|
||||||
|
/*++
|
||||||
|
class MULTISZ:
|
||||||
|
|
||||||
|
Intention:
|
||||||
|
A light-weight multi-string class supporting encapsulated string class.
|
||||||
|
|
||||||
|
This object is derived from BUFFER class.
|
||||||
|
It maintains following state:
|
||||||
|
|
||||||
|
m_fValid - whether this object is valid -
|
||||||
|
used only by MULTISZ() init functions
|
||||||
|
* NYI: I need to kill this someday *
|
||||||
|
m_cchLen - string length cached when we update the string.
|
||||||
|
m_cStrings - number of strings.
|
||||||
|
|
||||||
|
Member Functions:
|
||||||
|
There are two categories of functions:
|
||||||
|
1) Safe Functions - which do integrity checking of state
|
||||||
|
2) UnSafe Functions - which do not do integrity checking, but
|
||||||
|
enable writing to the data stream freely.
|
||||||
|
(someday this will be enabled as Safe versions without
|
||||||
|
problem for users)
|
||||||
|
|
||||||
|
--*/
|
||||||
|
class MULTISZ : public BUFFER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MULTISZ()
|
||||||
|
: BUFFER (),
|
||||||
|
m_cchLen ( 0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{ Reset(); }
|
||||||
|
|
||||||
|
// creates a stack version of the MULTISZ object - uses passed in stack buffer
|
||||||
|
// MULTISZ does not free this pbInit on its own.
|
||||||
|
MULTISZ( __in_bcount(cbInit) WCHAR * pbInit, DWORD cbInit)
|
||||||
|
: BUFFER( (BYTE *) pbInit, cbInit),
|
||||||
|
m_cchLen (0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MULTISZ( const WCHAR * pchInit )
|
||||||
|
: BUFFER (),
|
||||||
|
m_cchLen ( 0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{ AuxInit(pchInit); }
|
||||||
|
|
||||||
|
MULTISZ( const MULTISZ & str )
|
||||||
|
: BUFFER (),
|
||||||
|
m_cchLen ( 0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{ AuxInit( str.QueryStr()); }
|
||||||
|
|
||||||
|
// BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
|
||||||
|
//
|
||||||
|
// Checks and returns TRUE if this string has no valid data else FALSE
|
||||||
|
//
|
||||||
|
BOOL IsEmpty( VOID) const { return ( *QueryStr() == L'\0'); }
|
||||||
|
|
||||||
|
BOOL Append( const WCHAR * pchInit ) {
|
||||||
|
return ((pchInit != NULL) ? (AuxAppend( pchInit,
|
||||||
|
(DWORD) (::wcslen(pchInit)) * sizeof(WCHAR)
|
||||||
|
)) :
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL Append( const WCHAR * pchInit, DWORD cchLen ) {
|
||||||
|
return ((pchInit != NULL) ? (AuxAppend( pchInit,
|
||||||
|
cchLen * sizeof(WCHAR))) :
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Append( STRU & str )
|
||||||
|
{ return AuxAppend( str.QueryStr(),
|
||||||
|
(str.QueryCCH()) * sizeof(WCHAR)); }
|
||||||
|
|
||||||
|
// Resets the internal string to be NULL string. Buffer remains cached.
|
||||||
|
VOID Reset( VOID)
|
||||||
|
{ DBG_ASSERT( QueryPtr() != NULL);
|
||||||
|
QueryStr()[0] = L'\0';
|
||||||
|
QueryStr()[1] = L'\0';
|
||||||
|
m_cchLen = 2;
|
||||||
|
m_cStrings = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Copy( const WCHAR * pchInit, IN DWORD cbLen ) {
|
||||||
|
if ( QueryPtr() ) { Reset(); }
|
||||||
|
return ( (pchInit != NULL) ?
|
||||||
|
AuxAppend( pchInit, cbLen, FALSE ):
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Copy( const MULTISZ & str )
|
||||||
|
{ return ( Copy(str.QueryStr(), str.QueryCB())); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns the number of bytes in the string including the terminating
|
||||||
|
// NULLs
|
||||||
|
//
|
||||||
|
UINT QueryCB( VOID ) const
|
||||||
|
{ return ( m_cchLen * sizeof(WCHAR)); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns # of characters in the string including the terminating NULLs
|
||||||
|
//
|
||||||
|
UINT QueryCCH( VOID ) const { return (m_cchLen); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns # of strings in the multisz.
|
||||||
|
//
|
||||||
|
|
||||||
|
DWORD QueryStringCount( VOID ) const { return m_cStrings; }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Makes a copy of the stored string in given buffer
|
||||||
|
//
|
||||||
|
BOOL CopyToBuffer( __out_ecount_opt(*lpcch) WCHAR * lpszBuffer, LPDWORD lpcch) const;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the string buffer
|
||||||
|
//
|
||||||
|
WCHAR * QueryStrA( VOID ) const { return ( QueryStr()); }
|
||||||
|
WCHAR * QueryStr( VOID ) const { return ((WCHAR *) QueryPtr()); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Makes a clone of the current string in the string pointer passed in.
|
||||||
|
//
|
||||||
|
BOOL
|
||||||
|
Clone( OUT MULTISZ * pstrClone) const
|
||||||
|
{
|
||||||
|
return ((pstrClone == NULL) ?
|
||||||
|
(SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
|
||||||
|
(pstrClone->Copy( *this))
|
||||||
|
);
|
||||||
|
} // MULTISZ::Clone()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Recalculates the length of *this because we've modified the buffers
|
||||||
|
// directly
|
||||||
|
//
|
||||||
|
|
||||||
|
VOID RecalcLen( VOID )
|
||||||
|
{ m_cchLen = MULTISZ::CalcLength( QueryStr(), &m_cStrings ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate total character length of a MULTI_SZ, including the
|
||||||
|
// terminating NULLs.
|
||||||
|
//
|
||||||
|
|
||||||
|
static DWORD CalcLength( const WCHAR * str,
|
||||||
|
LPDWORD pcStrings = NULL );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine if the MULTISZ contains a specific string.
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL FindString( const WCHAR * str );
|
||||||
|
|
||||||
|
BOOL FindString( STRU & str )
|
||||||
|
{ return FindString( str.QueryStr() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine if the MULTISZ contains a specific string - case-insensitive
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL FindStringNoCase( const WCHAR * str );
|
||||||
|
|
||||||
|
BOOL FindStringNoCase( STRU & str )
|
||||||
|
{ return FindStringNoCase( str.QueryStr() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Used for scanning a multisz.
|
||||||
|
//
|
||||||
|
|
||||||
|
const WCHAR * First( VOID ) const
|
||||||
|
{ return *QueryStr() == L'\0' ? NULL : QueryStr(); }
|
||||||
|
|
||||||
|
const WCHAR * Next( const WCHAR * Current ) const
|
||||||
|
{ Current += ::wcslen( Current ) + 1;
|
||||||
|
return *Current == L'\0' ? NULL : Current; }
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
Equals(
|
||||||
|
MULTISZ* pmszRhs
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DWORD m_cchLen;
|
||||||
|
DWORD m_cStrings;
|
||||||
|
VOID AuxInit( const WCHAR * pInit );
|
||||||
|
BOOL AuxAppend( const WCHAR * pInit,
|
||||||
|
UINT cbStr, BOOL fAddSlop = TRUE );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Quick macro for declaring a MULTISZ that will use stack memory of <size>
|
||||||
|
// bytes. If the buffer overflows then a heap buffer will be allocated
|
||||||
|
//
|
||||||
|
|
||||||
|
#define STACK_MULTISZ( name, size ) WCHAR __ach##name[size]; \
|
||||||
|
MULTISZ name( __ach##name, sizeof( __ach##name ))
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SplitCommaDelimitedString(
|
||||||
|
PCWSTR pszList,
|
||||||
|
BOOL fTrimEntries,
|
||||||
|
BOOL fRemoveEmptyEntries,
|
||||||
|
MULTISZ * pmszList
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // !_MULTISZ_HXX_
|
||||||
|
|
||||||
|
|
@ -0,0 +1,408 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma warning (disable : 4267)
|
||||||
|
#include "precomp.h"
|
||||||
|
#include "multisza.h"
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private Definitions
|
||||||
|
//
|
||||||
|
|
||||||
|
#define MAXULONG 4294967295
|
||||||
|
#define ISWHITE( ch ) ((ch) == L' ' || (ch) == L'\t' || (ch) == L'\r')
|
||||||
|
|
||||||
|
//
|
||||||
|
// When appending data, this is the extra amount we request to avoid
|
||||||
|
// reallocations
|
||||||
|
//
|
||||||
|
#define STR_SLOP 128
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
MULTISZA::CalcLength( const CHAR * str,
|
||||||
|
LPDWORD pcStrings )
|
||||||
|
{
|
||||||
|
DWORD count = 0;
|
||||||
|
DWORD total = 1;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
while( *str ) {
|
||||||
|
len = ::strlen( str ) + 1;
|
||||||
|
total += len;
|
||||||
|
str += len;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pcStrings != NULL ) {
|
||||||
|
*pcStrings = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
|
||||||
|
} // MULTISZA::CalcLength
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZA::FindString( const CHAR * str )
|
||||||
|
{
|
||||||
|
|
||||||
|
CHAR * multisz;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sanity check.
|
||||||
|
//
|
||||||
|
|
||||||
|
DBG_ASSERT( QueryStr() != NULL );
|
||||||
|
DBG_ASSERT( str != NULL );
|
||||||
|
DBG_ASSERT( *str != '\0' );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Scan it.
|
||||||
|
//
|
||||||
|
|
||||||
|
multisz = QueryStr();
|
||||||
|
|
||||||
|
while( *multisz != '\0' ) {
|
||||||
|
|
||||||
|
if( !::strcmp( multisz, str ) ) {
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
multisz += ::strlen( multisz ) + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
} // MULTISZA::FindString
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZA::FindStringNoCase( const CHAR * str )
|
||||||
|
{
|
||||||
|
|
||||||
|
CHAR * multisz;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sanity check.
|
||||||
|
//
|
||||||
|
|
||||||
|
DBG_ASSERT( QueryStr() != NULL );
|
||||||
|
DBG_ASSERT( str != NULL );
|
||||||
|
DBG_ASSERT( *str != '\0' );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Scan it.
|
||||||
|
//
|
||||||
|
|
||||||
|
multisz = QueryStr();
|
||||||
|
|
||||||
|
while( *multisz != '\0' ) {
|
||||||
|
|
||||||
|
if( !_stricmp( multisz, str ) ) {
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
multisz += strlen( multisz ) + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
} // MULTISZA::FindStringNoCase
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MULTISZA::AuxInit( const CHAR * pInit )
|
||||||
|
{
|
||||||
|
BOOL fRet;
|
||||||
|
|
||||||
|
if ( pInit )
|
||||||
|
{
|
||||||
|
DWORD cStrings;
|
||||||
|
int cbCopy = CalcLength( pInit, &cStrings ) * sizeof(CHAR);
|
||||||
|
fRet = Resize( cbCopy );
|
||||||
|
|
||||||
|
if ( fRet ) {
|
||||||
|
CopyMemory( QueryPtr(), pInit, cbCopy );
|
||||||
|
m_cchLen = (cbCopy)/sizeof(CHAR);
|
||||||
|
m_cStrings = cStrings;
|
||||||
|
} else {
|
||||||
|
// BUFFER::SetValid( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MULTISZA::AuxInit()
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
|
||||||
|
NAME: MULTISZA::AuxAppend
|
||||||
|
|
||||||
|
SYNOPSIS: Appends the string onto the MULTISZA.
|
||||||
|
|
||||||
|
ENTRY: Object to append
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
BOOL MULTISZA::AuxAppend( const CHAR * pStr, UINT cbStr, BOOL fAddSlop )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( pStr != NULL );
|
||||||
|
|
||||||
|
UINT cbThis = QueryCB();
|
||||||
|
|
||||||
|
if( cbThis == 2 ) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// It's empty, so start at the beginning.
|
||||||
|
//
|
||||||
|
|
||||||
|
cbThis = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//
|
||||||
|
// It's not empty, so back up over the final terminating NULL.
|
||||||
|
//
|
||||||
|
|
||||||
|
cbThis -= sizeof(CHAR);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only resize when we have to. When we do resize, we tack on
|
||||||
|
// some extra space to avoid extra reallocations.
|
||||||
|
//
|
||||||
|
// Note: QuerySize returns the requested size of the string buffer,
|
||||||
|
// *not* the strlen of the buffer
|
||||||
|
//
|
||||||
|
|
||||||
|
//AcIncrement( CacMultiszAppend);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check for the arithmetic overflow
|
||||||
|
//
|
||||||
|
// ( 2 * sizeof( CHAR ) ) is for the double terminator
|
||||||
|
//
|
||||||
|
ULONGLONG cb64Required = (ULONGLONG)cbThis + cbStr + 2 * sizeof(CHAR);
|
||||||
|
if ( cb64Required > MAXULONG )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_ARITHMETIC_OVERFLOW );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ( QuerySize() < (DWORD) cb64Required )
|
||||||
|
{
|
||||||
|
ULONGLONG cb64AllocSize = cb64Required + (fAddSlop ? STR_SLOP : 0 );
|
||||||
|
//
|
||||||
|
// Check for the arithmetic overflow
|
||||||
|
//
|
||||||
|
if ( cb64AllocSize > MAXULONG )
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_ARITHMETIC_OVERFLOW );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ( !Resize( (DWORD) cb64AllocSize ) )
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the exact string and tack on the double terminator
|
||||||
|
memcpy( (BYTE *) QueryPtr() + cbThis,
|
||||||
|
pStr,
|
||||||
|
cbStr);
|
||||||
|
*(CHAR *)((BYTE *)QueryPtr() + cbThis + cbStr) = L'\0';
|
||||||
|
*(CHAR *)((BYTE *)QueryPtr() + cbThis + cbStr + sizeof(CHAR) ) = L'\0';
|
||||||
|
|
||||||
|
m_cchLen = CalcLength( (const CHAR *)QueryPtr(), &m_cStrings );
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
} // MULTISZA::AuxAppend()
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZA::CopyToBuffer( __out_ecount_opt(*lpcch) CHAR * lpszBuffer, LPDWORD lpcch) const
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
Copies the string into the CHAR buffer passed in if the buffer
|
||||||
|
is sufficient to hold the translated string.
|
||||||
|
If the buffer is small, the function returns small and sets *lpcch
|
||||||
|
to contain the required number of characters.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
lpszBuffer pointer to CHAR buffer which on return contains
|
||||||
|
the string on success.
|
||||||
|
lpcch pointer to DWORD containing the length of the buffer.
|
||||||
|
If *lpcch == 0 then the function returns TRUE with
|
||||||
|
the count of characters required stored in lpcch.
|
||||||
|
Also in this case lpszBuffer is not affected.
|
||||||
|
Returns:
|
||||||
|
TRUE on success.
|
||||||
|
FALSE on failure. Use GetLastError() for further details.
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
BOOL fReturn = TRUE;
|
||||||
|
|
||||||
|
if ( lpcch == NULL) {
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER);
|
||||||
|
return ( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
register DWORD cch = QueryCCH();
|
||||||
|
|
||||||
|
if ( *lpcch >= cch) {
|
||||||
|
|
||||||
|
DBG_ASSERT( lpszBuffer);
|
||||||
|
memcpy( lpszBuffer, QueryStr(), cch * sizeof(CHAR));
|
||||||
|
} else {
|
||||||
|
DBG_ASSERT( *lpcch < cch);
|
||||||
|
SetLastError( ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
fReturn = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpcch = cch;
|
||||||
|
|
||||||
|
return ( fReturn);
|
||||||
|
} // MULTISZA::CopyToBuffer()
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MULTISZA::Equals(
|
||||||
|
MULTISZA* pmszRhs
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// Compares this to pmszRhs, returns TRUE if equal
|
||||||
|
//
|
||||||
|
{
|
||||||
|
DBG_ASSERT( NULL != pmszRhs );
|
||||||
|
|
||||||
|
PCSTR pszLhs = First( );
|
||||||
|
PCSTR pszRhs = pmszRhs->First( );
|
||||||
|
|
||||||
|
if( m_cStrings != pmszRhs->m_cStrings )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( NULL != pszLhs )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( NULL != pszRhs );
|
||||||
|
|
||||||
|
if( 0 != strcmp( pszLhs, pszRhs ) )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszLhs = Next( pszLhs );
|
||||||
|
pszRhs = pmszRhs->Next( pszRhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SplitCommaDelimitedString(
|
||||||
|
PCSTR pszList,
|
||||||
|
BOOL fTrimEntries,
|
||||||
|
BOOL fRemoveEmptyEntries,
|
||||||
|
MULTISZA * pmszList
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Split comma delimited string into a MULTISZA. Additional leading empty
|
||||||
|
entries after the first are discarded.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszList - List to split up
|
||||||
|
fTrimEntries - Whether each entry should be trimmed before added to MULTISZA
|
||||||
|
fRemoveEmptyEntries - Whether empty entires should be discarded
|
||||||
|
pmszList - Filled with MULTISZA list
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if ( pszList == NULL ||
|
||||||
|
pmszList == NULL )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( FALSE );
|
||||||
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmszList->Reset();
|
||||||
|
|
||||||
|
/*
|
||||||
|
pszCurrent: start of the current entry which may be the comma that
|
||||||
|
precedes the next entry if the entry is empty
|
||||||
|
|
||||||
|
pszNext: the comma that precedes the next entry. If
|
||||||
|
pszCurrent == pszNext, then the entry is empty
|
||||||
|
|
||||||
|
pszEnd: just past the end of the current entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
for ( PCSTR pszCurrent = pszList,
|
||||||
|
pszNext = strchr( pszCurrent, L',' )
|
||||||
|
;
|
||||||
|
;
|
||||||
|
pszCurrent = pszNext + 1,
|
||||||
|
pszNext = strchr( pszCurrent, L',' ) )
|
||||||
|
{
|
||||||
|
PCSTR pszEnd = NULL;
|
||||||
|
|
||||||
|
if ( pszNext != NULL )
|
||||||
|
{
|
||||||
|
pszEnd = pszNext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pszEnd = pszCurrent + strlen( pszCurrent );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fTrimEntries )
|
||||||
|
{
|
||||||
|
while ( pszCurrent < pszEnd && ISWHITE( pszCurrent[ 0 ] ) )
|
||||||
|
{
|
||||||
|
pszCurrent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( pszEnd > pszCurrent && ISWHITE( pszEnd[ -1 ] ) )
|
||||||
|
{
|
||||||
|
pszEnd--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pszCurrent != pszEnd || !fRemoveEmptyEntries )
|
||||||
|
{
|
||||||
|
if ( !pmszList->Append( pszCurrent, (DWORD) ( pszEnd - pszCurrent ) ) )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pszNext == NULL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
#pragma warning(default:4267)
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _MULTISZA_H_
|
||||||
|
#define _MULTISZA_H_
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include "stringa.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*++
|
||||||
|
class MULTISZ:
|
||||||
|
|
||||||
|
Intention:
|
||||||
|
A light-weight multi-string class supporting encapsulated string class.
|
||||||
|
|
||||||
|
This object is derived from BUFFER class.
|
||||||
|
It maintains following state:
|
||||||
|
|
||||||
|
m_fValid - whether this object is valid -
|
||||||
|
used only by MULTISZ() init functions
|
||||||
|
* NYI: I need to kill this someday *
|
||||||
|
m_cchLen - string length cached when we update the string.
|
||||||
|
m_cStrings - number of strings.
|
||||||
|
|
||||||
|
Member Functions:
|
||||||
|
There are two categories of functions:
|
||||||
|
1) Safe Functions - which do integrity checking of state
|
||||||
|
2) UnSafe Functions - which do not do integrity checking, but
|
||||||
|
enable writing to the data stream freely.
|
||||||
|
(someday this will be enabled as Safe versions without
|
||||||
|
problem for users)
|
||||||
|
|
||||||
|
--*/
|
||||||
|
class MULTISZA : public BUFFER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MULTISZA()
|
||||||
|
: BUFFER (),
|
||||||
|
m_cchLen ( 0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{ Reset(); }
|
||||||
|
|
||||||
|
// creates a stack version of the MULTISZA object - uses passed in stack buffer
|
||||||
|
// MULTISZA does not free this pbInit on its own.
|
||||||
|
MULTISZA( __in_bcount(cbInit) CHAR * pbInit, DWORD cbInit)
|
||||||
|
: BUFFER( (BYTE *) pbInit, cbInit),
|
||||||
|
m_cchLen (0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MULTISZA( const CHAR * pchInit )
|
||||||
|
: BUFFER (),
|
||||||
|
m_cchLen ( 0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{ AuxInit(pchInit); }
|
||||||
|
|
||||||
|
MULTISZA( const MULTISZA & str )
|
||||||
|
: BUFFER (),
|
||||||
|
m_cchLen ( 0),
|
||||||
|
m_cStrings(0)
|
||||||
|
{ AuxInit( str.QueryStr()); }
|
||||||
|
|
||||||
|
// BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
|
||||||
|
//
|
||||||
|
// Checks and returns TRUE if this string has no valid data else FALSE
|
||||||
|
//
|
||||||
|
BOOL IsEmpty( VOID) const { return ( *QueryStr() == L'\0'); }
|
||||||
|
|
||||||
|
BOOL Append( const CHAR * pchInit ) {
|
||||||
|
return ((pchInit != NULL) ? (AuxAppend( pchInit,
|
||||||
|
(DWORD) (::strlen(pchInit)) * sizeof(CHAR)
|
||||||
|
)) :
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL Append( const CHAR * pchInit, DWORD cchLen ) {
|
||||||
|
return ((pchInit != NULL) ? (AuxAppend( pchInit,
|
||||||
|
cchLen * sizeof(CHAR))) :
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Append( STRA & str )
|
||||||
|
{ return AuxAppend( str.QueryStr(),
|
||||||
|
(str.QueryCCH()) * sizeof(CHAR)); }
|
||||||
|
|
||||||
|
// Resets the internal string to be NULL string. Buffer remains cached.
|
||||||
|
VOID Reset( VOID)
|
||||||
|
{ DBG_ASSERT( QueryPtr() != NULL);
|
||||||
|
QueryStr()[0] = L'\0';
|
||||||
|
QueryStr()[1] = L'\0';
|
||||||
|
m_cchLen = 2;
|
||||||
|
m_cStrings = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Copy( const CHAR * pchInit, IN DWORD cbLen ) {
|
||||||
|
if ( QueryPtr() ) { Reset(); }
|
||||||
|
return ( (pchInit != NULL) ?
|
||||||
|
AuxAppend( pchInit, cbLen, FALSE ):
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Copy( const MULTISZA & str )
|
||||||
|
{ return ( Copy(str.QueryStr(), str.QueryCB())); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns the number of bytes in the string including the terminating
|
||||||
|
// NULLs
|
||||||
|
//
|
||||||
|
UINT QueryCB( VOID ) const
|
||||||
|
{ return ( m_cchLen * sizeof(CHAR)); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns # of characters in the string including the terminating NULLs
|
||||||
|
//
|
||||||
|
UINT QueryCCH( VOID ) const { return (m_cchLen); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns # of strings in the MULTISZA.
|
||||||
|
//
|
||||||
|
|
||||||
|
DWORD QueryStringCount( VOID ) const { return m_cStrings; }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Makes a copy of the stored string in given buffer
|
||||||
|
//
|
||||||
|
BOOL CopyToBuffer( __out_ecount_opt(*lpcch) CHAR * lpszBuffer, LPDWORD lpcch) const;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the string buffer
|
||||||
|
//
|
||||||
|
CHAR * QueryStrA( VOID ) const { return ( QueryStr()); }
|
||||||
|
CHAR * QueryStr( VOID ) const { return ((CHAR *) QueryPtr()); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Makes a clone of the current string in the string pointer passed in.
|
||||||
|
//
|
||||||
|
BOOL
|
||||||
|
Clone( OUT MULTISZA * pstrClone) const
|
||||||
|
{
|
||||||
|
return ((pstrClone == NULL) ?
|
||||||
|
(SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
|
||||||
|
(pstrClone->Copy( *this))
|
||||||
|
);
|
||||||
|
} // MULTISZA::Clone()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Recalculates the length of *this because we've modified the buffers
|
||||||
|
// directly
|
||||||
|
//
|
||||||
|
|
||||||
|
VOID RecalcLen( VOID )
|
||||||
|
{ m_cchLen = MULTISZA::CalcLength( QueryStr(), &m_cStrings ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate total character length of a MULTI_SZ, including the
|
||||||
|
// terminating NULLs.
|
||||||
|
//
|
||||||
|
|
||||||
|
static DWORD CalcLength( const CHAR * str,
|
||||||
|
LPDWORD pcStrings = NULL );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine if the MULTISZA contains a specific string.
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL FindString( const CHAR * str );
|
||||||
|
|
||||||
|
BOOL FindString( STRA & str )
|
||||||
|
{ return FindString( str.QueryStr() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine if the MULTISZA contains a specific string - case-insensitive
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL FindStringNoCase( const CHAR * str );
|
||||||
|
|
||||||
|
BOOL FindStringNoCase( STRA & str )
|
||||||
|
{ return FindStringNoCase( str.QueryStr() ); }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Used for scanning a MULTISZA.
|
||||||
|
//
|
||||||
|
|
||||||
|
const CHAR * First( VOID ) const
|
||||||
|
{ return *QueryStr() == L'\0' ? NULL : QueryStr(); }
|
||||||
|
|
||||||
|
const CHAR * Next( const CHAR * Current ) const
|
||||||
|
{ Current += ::strlen( Current ) + 1;
|
||||||
|
return *Current == L'\0' ? NULL : Current; }
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
Equals(
|
||||||
|
MULTISZA* pmszRhs
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DWORD m_cchLen;
|
||||||
|
DWORD m_cStrings;
|
||||||
|
VOID AuxInit( const CHAR * pInit );
|
||||||
|
BOOL AuxAppend( const CHAR * pInit,
|
||||||
|
UINT cbStr, BOOL fAddSlop = TRUE );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Quick macro for declaring a MULTISZA that will use stack memory of <size>
|
||||||
|
// bytes. If the buffer overflows then a heap buffer will be allocated
|
||||||
|
//
|
||||||
|
|
||||||
|
#define STACK_MULTISZA( name, size ) CHAR __ach##name[size]; \
|
||||||
|
MULTISZA name( __ach##name, sizeof( __ach##name ))
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SplitCommaDelimitedString(
|
||||||
|
PCSTR pszList,
|
||||||
|
BOOL fTrimEntries,
|
||||||
|
BOOL fRemoveEmptyEntries,
|
||||||
|
MULTISZA * pmszList
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // !_MULTISZA_HXX_
|
||||||
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _ASSERTE
|
||||||
|
#undef _ASSERTE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
#undef ASSERT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( DBG ) && DBG
|
||||||
|
#define SX_ASSERT( _x ) ( (VOID)( ( ( _x ) ) ? TRUE : ( __annotation( L"Debug", L"AssertFail", L#_x ), DbgRaiseAssertionFailure(), FALSE ) ) )
|
||||||
|
#define SX_ASSERTMSG( _m, _x ) ( (VOID)( ( ( _x ) ) ? TRUE : ( __annotation( L"Debug", L"AssertFail", L##_m ), DbgRaiseAssertionFailure(), FALSE ) ) )
|
||||||
|
#define SX_VERIFY( _x ) SX_ASSERT( _x )
|
||||||
|
#define _ASSERTE( _x ) SX_ASSERT( _x )
|
||||||
|
#define ASSERT( _x ) SX_ASSERT( _x )
|
||||||
|
#define assert( _x ) SX_ASSERT( _x )
|
||||||
|
#define DBG_ASSERT( _x ) SX_ASSERT( _x )
|
||||||
|
#define DBG_REQUIRE( _x ) SX_ASSERT( _x )
|
||||||
|
#else
|
||||||
|
#define SX_ASSERT( _x ) ( (VOID)0 )
|
||||||
|
#define SX_ASSERTMSG( _m, _x ) ( (VOID)0 )
|
||||||
|
#define SX_VERIFY( _x ) ( (VOID)( ( _x ) ? TRUE : FALSE ) )
|
||||||
|
#define _ASSERTE( _x ) ( (VOID)0 )
|
||||||
|
#define assert( _x ) ( (VOID)0 )
|
||||||
|
#define DBG_ASSERT( _x ) ( (VOID)0 )
|
||||||
|
#define DBG_REQUIRE( _x ) ((VOID)(_x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,305 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class PER_CPU
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<typename FunctionInitializer>
|
||||||
|
inline
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
Create(
|
||||||
|
FunctionInitializer Initializer,
|
||||||
|
__deref_out PER_CPU<T> ** ppInstance
|
||||||
|
);
|
||||||
|
|
||||||
|
inline
|
||||||
|
T *
|
||||||
|
GetLocal(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
template<typename FunctionForEach>
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
ForEach(
|
||||||
|
FunctionForEach Function
|
||||||
|
);
|
||||||
|
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
Dispose(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
PER_CPU(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Don't perform any operation during constructor.
|
||||||
|
// Constructor will never be called.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
~PER_CPU(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Don't perform any operation during destructor.
|
||||||
|
// Constructor will never be called.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FunctionInitializer>
|
||||||
|
HRESULT
|
||||||
|
Initialize(
|
||||||
|
FunctionInitializer Initializer,
|
||||||
|
DWORD NumberOfVariables,
|
||||||
|
DWORD Alignment
|
||||||
|
);
|
||||||
|
|
||||||
|
T *
|
||||||
|
GetObject(
|
||||||
|
DWORD Index
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
GetProcessorInformation(
|
||||||
|
__out DWORD * pCacheLineSize,
|
||||||
|
__out DWORD * pNumberOfProcessors
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pointer to the begining of the inlined array.
|
||||||
|
//
|
||||||
|
PVOID m_pVariables;
|
||||||
|
SIZE_T m_Alignment;
|
||||||
|
SIZE_T m_VariablesCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename FunctionInitializer>
|
||||||
|
inline
|
||||||
|
// static
|
||||||
|
HRESULT
|
||||||
|
PER_CPU<T>::Create(
|
||||||
|
FunctionInitializer Initializer,
|
||||||
|
__deref_out PER_CPU<T> ** ppInstance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD CacheLineSize = 0;
|
||||||
|
DWORD ObjectCacheLineSize = 0;
|
||||||
|
DWORD NumberOfProcessors = 0;
|
||||||
|
PER_CPU<T> * pInstance = NULL;
|
||||||
|
|
||||||
|
hr = GetProcessorInformation(&CacheLineSize,
|
||||||
|
&NumberOfProcessors);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof(T) > CacheLineSize)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Round to the next multiple of the cache line size.
|
||||||
|
//
|
||||||
|
ObjectCacheLineSize = (sizeof(T) + CacheLineSize-1) & (CacheLineSize-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectCacheLineSize = CacheLineSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the size of the PER_CPU<T> object, including the array.
|
||||||
|
// The first cache line is for the member variables and the array
|
||||||
|
// starts in the next cache line.
|
||||||
|
//
|
||||||
|
SIZE_T Size = CacheLineSize + NumberOfProcessors * ObjectCacheLineSize;
|
||||||
|
|
||||||
|
pInstance = (PER_CPU<T>*) _aligned_malloc(Size, CacheLineSize);
|
||||||
|
if (pInstance == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
ZeroMemory(pInstance, Size);
|
||||||
|
|
||||||
|
//
|
||||||
|
// The array start in the 2nd cache line.
|
||||||
|
//
|
||||||
|
pInstance->m_pVariables = reinterpret_cast<PBYTE>(pInstance) + CacheLineSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pass a disposer for disposing initialized items in case of failure.
|
||||||
|
//
|
||||||
|
hr = pInstance->Initialize(Initializer,
|
||||||
|
NumberOfProcessors,
|
||||||
|
ObjectCacheLineSize);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppInstance = pInstance;
|
||||||
|
pInstance = NULL;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (pInstance != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Free the instance without disposing it.
|
||||||
|
//
|
||||||
|
pInstance->Dispose();
|
||||||
|
pInstance = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline
|
||||||
|
T *
|
||||||
|
PER_CPU<T>::GetLocal(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Use GetCurrentProcessorNumber (up to 64 logical processors) instead of
|
||||||
|
// GetCurrentProcessorNumberEx (more than 64 logical processors) because
|
||||||
|
// the number of processors are not densely packed per group.
|
||||||
|
// The idea of distributing variables per CPU is to have
|
||||||
|
// a scalability multiplier (could be NUMA node instead).
|
||||||
|
//
|
||||||
|
// Make sure the index don't go beyond the array size, if that happens,
|
||||||
|
// there won't be even distribution, but still better
|
||||||
|
// than one single variable.
|
||||||
|
//
|
||||||
|
return GetObject(GetCurrentProcessorNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline
|
||||||
|
T *
|
||||||
|
PER_CPU<T>::GetObject(
|
||||||
|
DWORD Index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(static_cast<PBYTE>(m_pVariables) + Index * m_Alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename FunctionForEach>
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
PER_CPU<T>::ForEach(
|
||||||
|
FunctionForEach Function
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for(DWORD Index = 0; Index < m_VariablesCount; ++Index)
|
||||||
|
{
|
||||||
|
T * pObject = GetObject(Index);
|
||||||
|
Function(pObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
VOID
|
||||||
|
PER_CPU<T>::Dispose(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_aligned_free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<typename FunctionInitializer>
|
||||||
|
inline
|
||||||
|
HRESULT
|
||||||
|
PER_CPU<T>::Initialize(
|
||||||
|
FunctionInitializer Initializer,
|
||||||
|
DWORD NumberOfVariables,
|
||||||
|
DWORD Alignment
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Initialize each object using the initializer function.
|
||||||
|
If initialization for any object fails, it dispose the
|
||||||
|
objects that were successfully initialized.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Initializer - Function for initialize one object.
|
||||||
|
Signature: HRESULT Func(T*)
|
||||||
|
Dispose - Function for disposing initialized objects in case of failure.
|
||||||
|
Signature: void Func(T*)
|
||||||
|
NumberOfVariables - The length of the array of variables.
|
||||||
|
Alignment - Alignment to use for avoiding false sharing.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
HRESULT - E_OUTOFMEMORY
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD Index = 0;
|
||||||
|
|
||||||
|
m_VariablesCount = NumberOfVariables;
|
||||||
|
m_Alignment = Alignment;
|
||||||
|
|
||||||
|
for (; Index < m_VariablesCount; ++Index)
|
||||||
|
{
|
||||||
|
T * pObject = GetObject(Index);
|
||||||
|
Initializer(pObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
// static
|
||||||
|
HRESULT
|
||||||
|
PER_CPU<T>::GetProcessorInformation(
|
||||||
|
__out DWORD * pCacheLineSize,
|
||||||
|
__out DWORD * pNumberOfProcessors
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Gets the CPU cache-line size for the current system.
|
||||||
|
This information is used for avoiding CPU false sharing.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pCacheLineSize - The processor cache-line size.
|
||||||
|
pNumberOfProcessors - Maximum number of processors per group.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
HRESULT - E_OUTOFMEMORY
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
SYSTEM_INFO SystemInfo = { };
|
||||||
|
|
||||||
|
GetSystemInfo(&SystemInfo);
|
||||||
|
*pNumberOfProcessors = SystemInfo.dwNumberOfProcessors;
|
||||||
|
*pCacheLineSize = SYSTEM_CACHE_ALIGNMENT_SIZE;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ahadmin.h>
|
||||||
|
#pragma warning( disable:4127 )
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <atlcomcli.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <intsafe.h>
|
||||||
|
|
||||||
|
#include "macros.h"
|
||||||
|
#include "stringu.h"
|
||||||
|
#include "stringa.h"
|
||||||
|
#include "dbgutil.h"
|
||||||
|
#include "ntassert.h"
|
||||||
|
#include "ahutil.h"
|
||||||
|
#include "acache.h"
|
||||||
|
//#include "base64.hxx"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pre-calculated prime numbers (up to 10,049,369).
|
||||||
|
//
|
||||||
|
extern __declspec(selectany) const DWORD g_Primes [] = {
|
||||||
|
3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631,
|
||||||
|
761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103,
|
||||||
|
12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631,
|
||||||
|
130363, 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403,
|
||||||
|
968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559,
|
||||||
|
5999471, 7199369, 7849369, 8649369, 9249369, 10049369
|
||||||
|
};
|
||||||
|
|
||||||
|
class PRIME
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static
|
||||||
|
DWORD
|
||||||
|
GetPrime(
|
||||||
|
DWORD dwMinimum
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Try to use the precalculated numbers.
|
||||||
|
//
|
||||||
|
for ( DWORD Index = 0; Index < _countof( g_Primes ); Index++ )
|
||||||
|
{
|
||||||
|
DWORD dwCandidate = g_Primes[Index];
|
||||||
|
if ( dwCandidate >= dwMinimum )
|
||||||
|
{
|
||||||
|
return dwCandidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do calculation.
|
||||||
|
//
|
||||||
|
for ( DWORD dwCandidate = dwMinimum | 1;
|
||||||
|
dwCandidate < MAXDWORD;
|
||||||
|
dwCandidate += 2 )
|
||||||
|
{
|
||||||
|
if ( IsPrime( dwCandidate ) )
|
||||||
|
{
|
||||||
|
return dwCandidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dwMinimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOL
|
||||||
|
IsPrime(
|
||||||
|
DWORD dwCandidate
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((dwCandidate & 1) == 0)
|
||||||
|
{
|
||||||
|
return ( dwCandidate == 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwMax = static_cast<DWORD>(sqrt(static_cast<double>(dwCandidate)));
|
||||||
|
|
||||||
|
for ( DWORD Index = 3; Index <= dwMax; Index += 2 )
|
||||||
|
{
|
||||||
|
if ( (dwCandidate % Index) == 0 )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIME() {}
|
||||||
|
~PRIME() {}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,736 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
# ifndef _PUDEBUG_H_
|
||||||
|
# define _PUDEBUG_H_
|
||||||
|
|
||||||
|
#ifndef _NO_TRACING_
|
||||||
|
# define _NO_TRACING_
|
||||||
|
#endif // _NO_TRACING_
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Include Headers
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
# endif // __cplusplus
|
||||||
|
|
||||||
|
# include <windows.h>
|
||||||
|
|
||||||
|
# ifndef dllexp
|
||||||
|
# define dllexp __declspec( dllexport)
|
||||||
|
# endif // dllexp
|
||||||
|
|
||||||
|
#include <specstrings.h>
|
||||||
|
|
||||||
|
#ifndef IN_OUT
|
||||||
|
#define IN_OUT __inout
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Macros
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
enum PRINT_REASONS {
|
||||||
|
PrintNone = 0x0, // Nothing to be printed
|
||||||
|
PrintError = 0x1, // An error message
|
||||||
|
PrintWarning = 0x2, // A warning message
|
||||||
|
PrintLog = 0x3, // Just logging. Indicates a trace of where ...
|
||||||
|
PrintMsg = 0x4, // Echo input message
|
||||||
|
PrintCritical = 0x5, // Print and Exit
|
||||||
|
PrintAssertion= 0x6 // Printing for an assertion failure
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum DEBUG_OUTPUT_FLAGS {
|
||||||
|
DbgOutputNone = 0x0, // None
|
||||||
|
DbgOutputKdb = 0x1, // Output to Kernel Debugger
|
||||||
|
DbgOutputLogFile = 0x2, // Output to LogFile
|
||||||
|
DbgOutputTruncate = 0x4, // Truncate Log File if necessary
|
||||||
|
DbgOutputStderr = 0x8, // Send output to std error
|
||||||
|
DbgOutputBackup = 0x10, // Make backup of debug file ?
|
||||||
|
DbgOutputMemory = 0x20, // Dump to memory buffer
|
||||||
|
DbgOutputAll = 0xFFFFFFFF // All the bits set.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# define MAX_LABEL_LENGTH ( 100)
|
||||||
|
|
||||||
|
|
||||||
|
// The following flags are used internally to track what level of tracing we
|
||||||
|
// are currently using. Bitmapped for extensibility.
|
||||||
|
#define DEBUG_FLAG_ODS 0x00000001
|
||||||
|
//#define DEBUG_FLAG_INFO 0x00000002
|
||||||
|
//#define DEBUG_FLAG_WARN 0x00000004
|
||||||
|
//#define DEBUG_FLAG_ERROR 0x00000008
|
||||||
|
// The following are used internally to determine whether to log or not based
|
||||||
|
// on what the current state is
|
||||||
|
//#define DEBUG_FLAGS_INFO (DEBUG_FLAG_ODS | DEBUG_FLAG_INFO)
|
||||||
|
//#define DEBUG_FLAGS_WARN (DEBUG_FLAG_ODS | DEBUG_FLAG_INFO | DEBUG_FLAG_WARN)
|
||||||
|
//#define DEBUG_FLAGS_ERROR (DEBUG_FLAG_ODS | DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR)
|
||||||
|
|
||||||
|
#define DEBUG_FLAGS_ANY (DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR)
|
||||||
|
|
||||||
|
//
|
||||||
|
// user of DEBUG infrastructure may choose unique variable name for DEBUG_FLAGS
|
||||||
|
// that's specially useful for cases where DEBUG infrastructure is used within
|
||||||
|
// static library (static library may prefer to maintain it's own DebugFlags independent
|
||||||
|
// on the main program it links to
|
||||||
|
//
|
||||||
|
#ifndef DEBUG_FLAGS_VAR
|
||||||
|
#define DEBUG_FLAGS_VAR g_dwDebugFlags
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern
|
||||||
|
#ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
# endif // _cplusplus
|
||||||
|
DWORD DEBUG_FLAGS_VAR ; // Debugging Flags
|
||||||
|
|
||||||
|
# define DECLARE_DEBUG_VARIABLE()
|
||||||
|
|
||||||
|
# define SET_DEBUG_FLAGS( dwFlags) DEBUG_FLAGS_VAR = dwFlags
|
||||||
|
# define GET_DEBUG_FLAGS() ( DEBUG_FLAGS_VAR )
|
||||||
|
|
||||||
|
# define LOAD_DEBUG_FLAGS_FROM_REG(hkey, dwDefault) \
|
||||||
|
DEBUG_FLAGS_VAR = PuLoadDebugFlagsFromReg((hkey), (dwDefault))
|
||||||
|
|
||||||
|
# define LOAD_DEBUG_FLAGS_FROM_REG_STR(pszRegKey, dwDefault) \
|
||||||
|
DEBUG_FLAGS_VAR = PuLoadDebugFlagsFromRegStr((pszRegKey), (dwDefault))
|
||||||
|
|
||||||
|
# define SAVE_DEBUG_FLAGS_IN_REG(hkey, dwDbg) \
|
||||||
|
PuSaveDebugFlagsInReg((hkey), (dwDbg))
|
||||||
|
|
||||||
|
# define DEBUG_IF( arg, s) if ( DEBUG_ ## arg & GET_DEBUG_FLAGS()) { \
|
||||||
|
s \
|
||||||
|
} else {}
|
||||||
|
|
||||||
|
# define IF_DEBUG( arg) if ( DEBUG_## arg & GET_DEBUG_FLAGS())
|
||||||
|
|
||||||
|
|
||||||
|
/*++
|
||||||
|
class DEBUG_PRINTS
|
||||||
|
|
||||||
|
This class is responsible for printing messages to log file / kernel debugger
|
||||||
|
|
||||||
|
Currently the class supports only member functions for <ANSI> char.
|
||||||
|
( not unicode-strings).
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _DEBUG_PRINTS {
|
||||||
|
|
||||||
|
CHAR m_rgchLabel[MAX_LABEL_LENGTH];
|
||||||
|
CHAR m_rgchLogFilePath[MAX_PATH];
|
||||||
|
CHAR m_rgchLogFileName[MAX_PATH];
|
||||||
|
HANDLE m_LogFileHandle;
|
||||||
|
HANDLE m_StdErrHandle;
|
||||||
|
BOOL m_fInitialized;
|
||||||
|
BOOL m_fBreakOnAssert;
|
||||||
|
DWORD m_dwOutputFlags;
|
||||||
|
VOID *m_pMemoryLog;
|
||||||
|
} DEBUG_PRINTS, FAR * LPDEBUG_PRINTS;
|
||||||
|
|
||||||
|
|
||||||
|
LPDEBUG_PRINTS
|
||||||
|
PuCreateDebugPrintsObject(
|
||||||
|
IN const char * pszPrintLabel,
|
||||||
|
IN DWORD dwOutputFlags);
|
||||||
|
|
||||||
|
//
|
||||||
|
// frees the debug prints object and closes any file if necessary.
|
||||||
|
// Returns NULL on success or returns pDebugPrints on failure.
|
||||||
|
//
|
||||||
|
LPDEBUG_PRINTS
|
||||||
|
PuDeleteDebugPrintsObject(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints);
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PuDbgPrint(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName,
|
||||||
|
IN const char * pszFormat,
|
||||||
|
...);
|
||||||
|
// arglist
|
||||||
|
VOID
|
||||||
|
PuDbgPrintW(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName,
|
||||||
|
IN const WCHAR * pszFormat,
|
||||||
|
...); // arglist
|
||||||
|
|
||||||
|
// PuDbgPrintError is similar to PuDbgPrint() but allows
|
||||||
|
// one to print error code in friendly manner
|
||||||
|
VOID
|
||||||
|
PuDbgPrintError(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName,
|
||||||
|
IN DWORD dwError,
|
||||||
|
IN const char * pszFormat,
|
||||||
|
...); // arglist
|
||||||
|
|
||||||
|
/*++
|
||||||
|
PuDbgDump() does not do any formatting of output.
|
||||||
|
It just dumps the given message onto the debug destinations.
|
||||||
|
--*/
|
||||||
|
VOID
|
||||||
|
PuDbgDump(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName,
|
||||||
|
IN const char * pszDump
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// PuDbgAssertFailed() *must* be __cdecl to properly capture the
|
||||||
|
// thread context at the time of the failure.
|
||||||
|
//
|
||||||
|
|
||||||
|
INT
|
||||||
|
__cdecl
|
||||||
|
PuDbgAssertFailed(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName,
|
||||||
|
IN const char * pszExpression,
|
||||||
|
IN const char * pszMessage);
|
||||||
|
|
||||||
|
INT
|
||||||
|
WINAPI
|
||||||
|
PuDbgPrintAssertFailed(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName,
|
||||||
|
IN const char * pszExpression,
|
||||||
|
IN const char * pszMessage);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PuDbgCaptureContext (
|
||||||
|
OUT PCONTEXT ContextRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PuDbgPrintCurrentTime(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFilePath,
|
||||||
|
IN int nLineNum,
|
||||||
|
IN const char * pszFunctionName
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PuSetDbgOutputFlags(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN DWORD dwFlags);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuGetDbgOutputFlags(
|
||||||
|
IN const LPDEBUG_PRINTS pDebugPrints);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Following functions return Win32 error codes.
|
||||||
|
// NO_ERROR if success
|
||||||
|
//
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuOpenDbgPrintFile(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints,
|
||||||
|
IN const char * pszFileName,
|
||||||
|
IN const char * pszPathForFile);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuReOpenDbgPrintFile(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuCloseDbgPrintFile(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuOpenDbgMemoryLog(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuCloseDbgMemoryLog(
|
||||||
|
IN_OUT LPDEBUG_PRINTS pDebugPrints);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuLoadDebugFlagsFromReg(IN HKEY hkey, IN DWORD dwDefault);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuLoadDebugFlagsFromRegStr(IN LPCSTR pszRegKey, IN DWORD dwDefault);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
PuSaveDebugFlagsInReg(IN HKEY hkey, IN DWORD dwDbg);
|
||||||
|
|
||||||
|
|
||||||
|
# define PuPrintToKdb( pszOutput) \
|
||||||
|
if ( pszOutput != NULL) { \
|
||||||
|
OutputDebugString( pszOutput); \
|
||||||
|
} else {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
};
|
||||||
|
# endif // __cplusplus
|
||||||
|
|
||||||
|
// begin_user_unmodifiable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Macros
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
extern
|
||||||
|
#ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
# endif // _cplusplus
|
||||||
|
DEBUG_PRINTS * g_pDebug; // define a global debug variable
|
||||||
|
|
||||||
|
# if DBG
|
||||||
|
|
||||||
|
// For the CHK build we want ODS enabled. For an explanation of these flags see
|
||||||
|
// the comment just after the definition of DBG_CONTEXT
|
||||||
|
# define DECLARE_DEBUG_PRINTS_OBJECT() \
|
||||||
|
DEBUG_PRINTS * g_pDebug = NULL; \
|
||||||
|
DWORD DEBUG_FLAGS_VAR = DEBUG_FLAG_ERROR;
|
||||||
|
|
||||||
|
#else // !DBG
|
||||||
|
|
||||||
|
# define DECLARE_DEBUG_PRINTS_OBJECT() \
|
||||||
|
DEBUG_PRINTS * g_pDebug = NULL; \
|
||||||
|
DWORD DEBUG_FLAGS_VAR = 0;
|
||||||
|
|
||||||
|
#endif // !DBG
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call the following macro as part of your initialization for program
|
||||||
|
// planning to use the debugging class.
|
||||||
|
//
|
||||||
|
/** DEBUGDEBUG
|
||||||
|
# define CREATE_DEBUG_PRINT_OBJECT( pszLabel) \
|
||||||
|
g_pDebug = PuCreateDebugPrintsObject( pszLabel, DEFAULT_OUTPUT_FLAGS);\
|
||||||
|
if ( g_pDebug == NULL) { \
|
||||||
|
OutputDebugStringA( "Unable to Create Debug Print Object \n"); \
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call the following macro once as part of the termination of program
|
||||||
|
// which uses the debugging class.
|
||||||
|
//
|
||||||
|
# define DELETE_DEBUG_PRINT_OBJECT( ) \
|
||||||
|
g_pDebug = PuDeleteDebugPrintsObject( g_pDebug);
|
||||||
|
|
||||||
|
|
||||||
|
# define VALID_DEBUG_PRINT_OBJECT() \
|
||||||
|
( ( g_pDebug != NULL) && g_pDebug->m_fInitialized)
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use the DBG_CONTEXT without any surrounding braces.
|
||||||
|
// This is used to pass the values for global DebugPrintObject
|
||||||
|
// and File/Line information
|
||||||
|
//
|
||||||
|
//# define DBG_CONTEXT g_pDebug, __FILE__, __LINE__, __FUNCTION__
|
||||||
|
|
||||||
|
// The 3 main tracing macros, each one corresponds to a different level of
|
||||||
|
// tracing
|
||||||
|
|
||||||
|
// The 3 main tracing macros, each one corresponds to a different level of
|
||||||
|
// tracing
|
||||||
|
//# define DBGINFO(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_INFO) { PuDbgPrint args; }}
|
||||||
|
//# define DBGWARN(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_WARN) { PuDbgPrint args; }}
|
||||||
|
//# define DBGERROR(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_ERROR) { PuDbgPrint args; }}
|
||||||
|
|
||||||
|
# define DBGINFOW(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_INFO) { PuDbgPrintW args; }}
|
||||||
|
# define DBGWARNW(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_WARN) { PuDbgPrintW args; }}
|
||||||
|
# define DBGERRORW(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_ERROR) { PuDbgPrintW args; }}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DBGPRINTF() is printing function ( much like printf) but always called
|
||||||
|
// with the DBG_CONTEXT as follows
|
||||||
|
// DBGPRINTF( ( DBG_CONTEXT, format-string, arguments for format list));
|
||||||
|
//
|
||||||
|
# define DBGPRINTF DBGINFO
|
||||||
|
|
||||||
|
//
|
||||||
|
// DPERROR() is printing function ( much like printf) but always called
|
||||||
|
// with the DBG_CONTEXT as follows
|
||||||
|
// DPERROR( ( DBG_CONTEXT, error, format-string,
|
||||||
|
// arguments for format list));
|
||||||
|
//
|
||||||
|
# define DPERROR( args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_ERROR) { PuDbgPrintError args; }}
|
||||||
|
|
||||||
|
# if DBG
|
||||||
|
|
||||||
|
# define DBG_CODE(s) s /* echoes code in debugging mode */
|
||||||
|
|
||||||
|
// The same 3 main tracing macros however in this case the macros are only compiled
|
||||||
|
// into the CHK build. This is necessary because some tracing info used functions or
|
||||||
|
// variables which are not compiled into the FRE build.
|
||||||
|
# define CHKINFO(args) { PuDbgPrint args; }
|
||||||
|
# define CHKWARN(args) { PuDbgPrint args; }
|
||||||
|
# define CHKERROR(args) { PuDbgPrint args; }
|
||||||
|
|
||||||
|
# define CHKINFOW(args) { PuDbgPrintW args; }
|
||||||
|
# define CHKWARNW(args) { PuDbgPrintW args; }
|
||||||
|
# define CHKERRORW(args) { PuDbgPrintW args; }
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DBG_ASSERT
|
||||||
|
# ifdef _PREFAST_
|
||||||
|
# define DBG_ASSERT(exp) ((void)0) /* Do Nothing */
|
||||||
|
# define DBG_ASSERT_MSG(exp, pszMsg) ((void)0) /* Do Nothing */
|
||||||
|
# define DBG_REQUIRE( exp) ((void) (exp))
|
||||||
|
# else // !_PREFAST_
|
||||||
|
# define DBG_ASSERT( exp ) \
|
||||||
|
( (VOID)( ( exp ) || ( DebugBreak(), \
|
||||||
|
PuDbgPrintAssertFailed( DBG_CONTEXT, #exp, "" ) ) ) )
|
||||||
|
|
||||||
|
# define DBG_ASSERT_MSG( exp, pszMsg) \
|
||||||
|
( (VOID)( ( exp ) || ( DebugBreak(), \
|
||||||
|
PuDbgPrintAssertFailed( DBG_CONTEXT, #exp, pszMsg ) ) ) )
|
||||||
|
|
||||||
|
# define DBG_REQUIRE( exp ) \
|
||||||
|
DBG_ASSERT( exp )
|
||||||
|
# endif // !_PREFAST_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
# define DBG_LOG() PuDbgPrint( DBG_CONTEXT, "\n" )
|
||||||
|
|
||||||
|
# define DBG_OPEN_LOG_FILE( pszFile, pszPath ) \
|
||||||
|
PuOpenDbgPrintFile( g_pDebug, (pszFile), (pszPath) )
|
||||||
|
|
||||||
|
# define DBG_CLOSE_LOG_FILE( ) \
|
||||||
|
PuCloseDbgPrintFile( g_pDebug )
|
||||||
|
|
||||||
|
# define DBG_OPEN_MEMORY_LOG( ) \
|
||||||
|
PuOpenDbgMemoryLog( g_pDebug )
|
||||||
|
|
||||||
|
|
||||||
|
# define DBGDUMP( args ) PuDbgDump args
|
||||||
|
|
||||||
|
# define DBGPRINT_CURRENT_TIME() PuDbgPrintCurrentTime( DBG_CONTEXT )
|
||||||
|
|
||||||
|
# else // !DBG
|
||||||
|
|
||||||
|
# define DBG_CODE(s) ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define CHKINFO(args) ((void)0) /* Do Nothing */
|
||||||
|
# define CHKWARN(args) ((void)0) /* Do Nothing */
|
||||||
|
# define CHKERROR(args) ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define CHKINFOW(args) ((void)0) /* Do Nothing */
|
||||||
|
# define CHKWARNW(args) ((void)0) /* Do Nothing */
|
||||||
|
# define CHKERRORW(args) ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
#ifndef DBG_ASSERT
|
||||||
|
# define DBG_ASSERT(exp) ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define DBG_ASSERT_MSG(exp, pszMsg) ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define DBG_REQUIRE( exp) ((void) (exp))
|
||||||
|
#endif // !DBG_ASSERT
|
||||||
|
|
||||||
|
# define DBGDUMP( args) ((void)0) /* Do nothing */
|
||||||
|
|
||||||
|
# define DBG_LOG() ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define DBG_OPEN_LOG_FILE( pszFile, pszPath) ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define DBG_OPEN_MEMORY_LOG() ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define DBG_CLOSE_LOG_FILE() ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# define DBGPRINT_CURRENT_TIME() ((void)0) /* Do Nothing */
|
||||||
|
|
||||||
|
# endif // !DBG
|
||||||
|
|
||||||
|
|
||||||
|
// end_user_unmodifiable
|
||||||
|
|
||||||
|
// begin_user_unmodifiable
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
# undef ASSERT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
# define ASSERT( exp) DBG_ASSERT( exp)
|
||||||
|
|
||||||
|
|
||||||
|
// end_user_unmodifiable
|
||||||
|
|
||||||
|
// begin_user_modifiable
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debugging constants consist of two pieces.
|
||||||
|
// All constants in the range 0x0 to 0x8000 are reserved
|
||||||
|
// User extensions may include additional constants (bit flags)
|
||||||
|
//
|
||||||
|
|
||||||
|
# define DEBUG_API_ENTRY 0x00000001L
|
||||||
|
# define DEBUG_API_EXIT 0x00000002L
|
||||||
|
# define DEBUG_INIT_CLEAN 0x00000004L
|
||||||
|
# define DEBUG_ERROR 0x00000008L
|
||||||
|
|
||||||
|
// End of Reserved Range
|
||||||
|
# define DEBUG_RESERVED 0x00000FFFL
|
||||||
|
|
||||||
|
// end_user_modifiable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Platform Type related variables and macros
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enum for product types
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef enum _PLATFORM_TYPE {
|
||||||
|
|
||||||
|
PtInvalid = 0, // Invalid
|
||||||
|
PtNtWorkstation = 1, // NT Workstation
|
||||||
|
PtNtServer = 2, // NT Server
|
||||||
|
|
||||||
|
} PLATFORM_TYPE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// IISGetPlatformType is the function used to the platform type
|
||||||
|
//
|
||||||
|
|
||||||
|
extern
|
||||||
|
#ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
# endif // _cplusplus
|
||||||
|
PLATFORM_TYPE
|
||||||
|
IISGetPlatformType(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// External Macros
|
||||||
|
//
|
||||||
|
|
||||||
|
#define InetIsNtServer( _pt ) ((_pt) == PtNtServer)
|
||||||
|
#define InetIsNtWksta( _pt ) ((_pt) == PtNtWorkstation)
|
||||||
|
#define InetIsValidPT(_pt) ((_pt) != PtInvalid)
|
||||||
|
|
||||||
|
extern
|
||||||
|
#ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
# endif // _cplusplus
|
||||||
|
PLATFORM_TYPE g_PlatformType;
|
||||||
|
|
||||||
|
|
||||||
|
// Use the DECLARE_PLATFORM_TYPE macro to declare the platform type
|
||||||
|
#define DECLARE_PLATFORM_TYPE() \
|
||||||
|
PLATFORM_TYPE g_PlatformType = PtInvalid;
|
||||||
|
|
||||||
|
// Use the INITIALIZE_PLATFORM_TYPE to init the platform type
|
||||||
|
// This should typically go inside the DLLInit or equivalent place.
|
||||||
|
#define INITIALIZE_PLATFORM_TYPE() \
|
||||||
|
g_PlatformType = IISGetPlatformType();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Additional Macros to use the Platform Type
|
||||||
|
//
|
||||||
|
|
||||||
|
#define TsIsNtServer( ) InetIsNtServer(g_PlatformType)
|
||||||
|
#define TsIsNtWksta( ) InetIsNtWksta(g_PlatformType)
|
||||||
|
#define IISIsValidPlatform() InetIsValidPT(g_PlatformType)
|
||||||
|
#define IISPlatformType() (g_PlatformType)
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Some utility functions for Critical Sections
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// IISSetCriticalSectionSpinCount() provides a thunk for the
|
||||||
|
// original NT4.0sp3 API SetCriticalSectionSpinCount() for CS with Spin counts
|
||||||
|
// Users of this function should definitely dynlink with kernel32.dll,
|
||||||
|
// Otherwise errors will surface to a large extent
|
||||||
|
//
|
||||||
|
extern
|
||||||
|
# ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
# endif // _cplusplus
|
||||||
|
DWORD
|
||||||
|
IISSetCriticalSectionSpinCount(
|
||||||
|
LPCRITICAL_SECTION lpCriticalSection,
|
||||||
|
DWORD dwSpinCount
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Macro for the calls to SetCriticalSectionSpinCount()
|
||||||
|
//
|
||||||
|
# define SET_CRITICAL_SECTION_SPIN_COUNT( lpCS, dwSpins) \
|
||||||
|
IISSetCriticalSectionSpinCount( (lpCS), (dwSpins))
|
||||||
|
|
||||||
|
//
|
||||||
|
// IIS_DEFAULT_CS_SPIN_COUNT is the default value of spins used by
|
||||||
|
// Critical sections defined within IIS.
|
||||||
|
// NYI: We should have to switch the individual values based on experiments!
|
||||||
|
// Current value is an arbitrary choice
|
||||||
|
//
|
||||||
|
# define IIS_DEFAULT_CS_SPIN_COUNT (1000)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initializes a critical section and sets its spin count
|
||||||
|
// to IIS_DEFAULT_CS_SPIN_COUNT. Equivalent to
|
||||||
|
// InitializeCriticalSectionAndSpinCount(lpCS, IIS_DEFAULT_CS_SPIN_COUNT),
|
||||||
|
// but provides a safe thunking layer for older systems that don't provide
|
||||||
|
// this API.
|
||||||
|
//
|
||||||
|
extern
|
||||||
|
# ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
# endif // _cplusplus
|
||||||
|
BOOL
|
||||||
|
IISInitializeCriticalSection(
|
||||||
|
LPCRITICAL_SECTION lpCriticalSection
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Macro for the calls to InitializeCriticalSection()
|
||||||
|
//
|
||||||
|
# define INITIALIZE_CRITICAL_SECTION(lpCS) IISInitializeCriticalSection(lpCS)
|
||||||
|
|
||||||
|
# endif /* _DEBUG_HXX_ */
|
||||||
|
|
||||||
|
//
|
||||||
|
// The following macros allow the automatic naming of certain Win32 objects.
|
||||||
|
// See IIS\SVCS\IISRTL\WIN32OBJ.C for details on the naming convention.
|
||||||
|
//
|
||||||
|
// Set IIS_NAMED_WIN32_OBJECTS to a non-zero value to enable named events,
|
||||||
|
// semaphores, and mutexes.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
#define IIS_NAMED_WIN32_OBJECTS 1
|
||||||
|
#else
|
||||||
|
#define IIS_NAMED_WIN32_OBJECTS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
PuDbgCreateEvent(
|
||||||
|
__in LPSTR FileName,
|
||||||
|
IN ULONG LineNumber,
|
||||||
|
__in LPSTR MemberName,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN BOOL ManualReset,
|
||||||
|
IN BOOL InitialState
|
||||||
|
);
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
PuDbgCreateSemaphore(
|
||||||
|
__in LPSTR FileName,
|
||||||
|
IN ULONG LineNumber,
|
||||||
|
__in LPSTR MemberName,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN LONG InitialCount,
|
||||||
|
IN LONG MaximumCount
|
||||||
|
);
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
PuDbgCreateMutex(
|
||||||
|
__in LPSTR FileName,
|
||||||
|
IN ULONG LineNumber,
|
||||||
|
__in LPSTR MemberName,
|
||||||
|
IN PVOID Address,
|
||||||
|
IN BOOL InitialOwner
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IIS_NAMED_WIN32_OBJECTS
|
||||||
|
|
||||||
|
#define IIS_CREATE_EVENT( membername, address, manual, state ) \
|
||||||
|
PuDbgCreateEvent( \
|
||||||
|
(LPSTR)__FILE__, \
|
||||||
|
(ULONG)__LINE__, \
|
||||||
|
(membername), \
|
||||||
|
(PVOID)(address), \
|
||||||
|
(manual), \
|
||||||
|
(state) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define IIS_CREATE_SEMAPHORE( membername, address, initial, maximum ) \
|
||||||
|
PuDbgCreateSemaphore( \
|
||||||
|
(LPSTR)__FILE__, \
|
||||||
|
(ULONG)__LINE__, \
|
||||||
|
(membername), \
|
||||||
|
(PVOID)(address), \
|
||||||
|
(initial), \
|
||||||
|
(maximum) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define IIS_CREATE_MUTEX( membername, address, initial ) \
|
||||||
|
PuDbgCreateMutex( \
|
||||||
|
(LPSTR)__FILE__, \
|
||||||
|
(ULONG)__LINE__, \
|
||||||
|
(membername), \
|
||||||
|
(PVOID)(address), \
|
||||||
|
(initial) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#else // !IIS_NAMED_WIN32_OBJECTS
|
||||||
|
|
||||||
|
#define IIS_CREATE_EVENT( membername, address, manual, state ) \
|
||||||
|
CreateEventA( \
|
||||||
|
NULL, \
|
||||||
|
(manual), \
|
||||||
|
(state), \
|
||||||
|
NULL \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define IIS_CREATE_SEMAPHORE( membername, address, initial, maximum ) \
|
||||||
|
CreateSemaphoreA( \
|
||||||
|
NULL, \
|
||||||
|
(initial), \
|
||||||
|
(maximum), \
|
||||||
|
NULL \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define IIS_CREATE_MUTEX( membername, address, initial ) \
|
||||||
|
CreateMutexA( \
|
||||||
|
NULL, \
|
||||||
|
(initial), \
|
||||||
|
NULL \
|
||||||
|
)
|
||||||
|
|
||||||
|
#endif // IIS_NAMED_WIN32_OBJECTS
|
||||||
|
|
||||||
|
|
||||||
|
/************************ End of File ***********************/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "dbgutil.h"
|
||||||
|
#include "pudebug.h"
|
||||||
|
#include "reftrace.h"
|
||||||
|
|
||||||
|
|
||||||
|
PTRACE_LOG
|
||||||
|
CreateRefTraceLog(
|
||||||
|
IN LONG LogSize,
|
||||||
|
IN LONG ExtraBytesInHeader
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Creates a new (empty) ref count trace log buffer.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
LogSize - The number of entries in the log.
|
||||||
|
|
||||||
|
ExtraBytesInHeader - The number of extra bytes to include in the
|
||||||
|
log header. This is useful for adding application-specific
|
||||||
|
data to the log.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
PTRACE_LOG - Pointer to the newly created log if successful,
|
||||||
|
NULL otherwise.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
|
||||||
|
return CreateTraceLog(
|
||||||
|
LogSize,
|
||||||
|
ExtraBytesInHeader,
|
||||||
|
sizeof(REF_TRACE_LOG_ENTRY)
|
||||||
|
);
|
||||||
|
|
||||||
|
} // CreateRefTraceLog
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DestroyRefTraceLog(
|
||||||
|
IN PTRACE_LOG Log
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Destroys a ref count trace log buffer created with CreateRefTraceLog().
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Log - The ref count trace log buffer to destroy.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
|
||||||
|
DestroyTraceLog( Log );
|
||||||
|
|
||||||
|
} // DestroyRefTraceLog
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// N.B. For RtlCaptureBacktrace() to work properly, the calling function
|
||||||
|
// *must* be __cdecl, and must have a "normal" stack frame. So, we decorate
|
||||||
|
// WriteRefTraceLog[Ex]() with the __cdecl modifier and disable the frame
|
||||||
|
// pointer omission (FPO) optimization.
|
||||||
|
//
|
||||||
|
|
||||||
|
//#pragma optimize( "y", off ) // disable frame pointer omission (FPO)
|
||||||
|
#pragma optimize( "", off ) // disable frame pointer omission (FPO)
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__cdecl
|
||||||
|
WriteRefTraceLog(
|
||||||
|
IN PTRACE_LOG Log,
|
||||||
|
IN LONG NewRefCount,
|
||||||
|
IN CONST VOID * Context
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Writes a new entry to the specified ref count trace log. The entry
|
||||||
|
written contains the updated reference count and a stack backtrace
|
||||||
|
leading up to the current caller.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Log - The log to write to.
|
||||||
|
|
||||||
|
NewRefCount - The updated reference count.
|
||||||
|
|
||||||
|
Context - An uninterpreted context to associate with the log entry.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
Index of entry in log.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
|
||||||
|
return WriteRefTraceLogEx(
|
||||||
|
Log,
|
||||||
|
NewRefCount,
|
||||||
|
Context,
|
||||||
|
REF_TRACE_EMPTY_CONTEXT, // suppress use of optional extra contexts
|
||||||
|
REF_TRACE_EMPTY_CONTEXT,
|
||||||
|
REF_TRACE_EMPTY_CONTEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
} // WriteRefTraceLog
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__cdecl
|
||||||
|
WriteRefTraceLogEx(
|
||||||
|
IN PTRACE_LOG Log,
|
||||||
|
IN LONG NewRefCount,
|
||||||
|
IN CONST VOID * Context,
|
||||||
|
IN CONST VOID * Context1, // optional extra context
|
||||||
|
IN CONST VOID * Context2, // optional extra context
|
||||||
|
IN CONST VOID * Context3 // optional extra context
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Writes a new "extended" entry to the specified ref count trace log.
|
||||||
|
The entry written contains the updated reference count, stack backtrace
|
||||||
|
leading up to the current caller and extra context information.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Log - The log to write to.
|
||||||
|
|
||||||
|
NewRefCount - The updated reference count.
|
||||||
|
|
||||||
|
Context - An uninterpreted context to associate with the log entry.
|
||||||
|
Context1 - An uninterpreted context to associate with the log entry.
|
||||||
|
Context2 - An uninterpreted context to associate with the log entry.
|
||||||
|
Context3 - An uninterpreted context to associate with the log entry.
|
||||||
|
|
||||||
|
NOTE Context1/2/3 are "optional" in that the caller may suppress
|
||||||
|
debug display of these values by passing REF_TRACE_EMPTY_CONTEXT
|
||||||
|
for each of them.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
Index of entry in log.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
|
||||||
|
REF_TRACE_LOG_ENTRY entry;
|
||||||
|
ULONG hash;
|
||||||
|
DWORD cStackFramesSkipped;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the entry.
|
||||||
|
//
|
||||||
|
|
||||||
|
RtlZeroMemory(
|
||||||
|
&entry,
|
||||||
|
sizeof(entry)
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set log entry members.
|
||||||
|
//
|
||||||
|
|
||||||
|
entry.NewRefCount = NewRefCount;
|
||||||
|
entry.Context = Context;
|
||||||
|
entry.Thread = GetCurrentThreadId();
|
||||||
|
entry.Context1 = Context1;
|
||||||
|
entry.Context2 = Context2;
|
||||||
|
entry.Context3 = Context3;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Capture the stack backtrace. Normally, we skip two stack frames:
|
||||||
|
// one for this routine, and one for RtlCaptureBacktrace() itself.
|
||||||
|
// For non-Ex callers who come in via WriteRefTraceLog,
|
||||||
|
// we skip three stack frames.
|
||||||
|
//
|
||||||
|
|
||||||
|
if ( entry.Context1 == REF_TRACE_EMPTY_CONTEXT
|
||||||
|
&& entry.Context2 == REF_TRACE_EMPTY_CONTEXT
|
||||||
|
&& entry.Context3 == REF_TRACE_EMPTY_CONTEXT
|
||||||
|
) {
|
||||||
|
|
||||||
|
cStackFramesSkipped = 2;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cStackFramesSkipped = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCaptureStackBackTrace(
|
||||||
|
cStackFramesSkipped,
|
||||||
|
REF_TRACE_LOG_STACK_DEPTH,
|
||||||
|
entry.Stack,
|
||||||
|
&hash
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write it to the log.
|
||||||
|
//
|
||||||
|
|
||||||
|
return WriteTraceLog(
|
||||||
|
Log,
|
||||||
|
&entry
|
||||||
|
);
|
||||||
|
|
||||||
|
} // WriteRefTraceLogEx
|
||||||
|
|
||||||
|
#pragma optimize( "", on ) // restore frame pointer omission (FPO)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#ifndef _REFTRACE_H_
|
||||||
|
#define _REFTRACE_H_
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include "tracelog.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is the number of stack backtrace values captured in each
|
||||||
|
// trace log entry. This value is chosen to make the log entry
|
||||||
|
// exactly twelve dwords long, making it a bit easier to interpret
|
||||||
|
// from within the debugger without the debugger extension.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define REF_TRACE_LOG_STACK_DEPTH 9
|
||||||
|
|
||||||
|
// No-op value for the Context1,2,3 parameters of WriteRefTraceLogEx
|
||||||
|
//#define REF_TRACE_EMPTY_CONTEXT ((PVOID) -1)
|
||||||
|
#define REF_TRACE_EMPTY_CONTEXT NULL
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// This defines the entry written to the trace log.
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct _REF_TRACE_LOG_ENTRY {
|
||||||
|
|
||||||
|
LONG NewRefCount;
|
||||||
|
CONST VOID * Context;
|
||||||
|
CONST VOID * Context1;
|
||||||
|
CONST VOID * Context2;
|
||||||
|
CONST VOID * Context3;
|
||||||
|
DWORD Thread;
|
||||||
|
PVOID Stack[REF_TRACE_LOG_STACK_DEPTH];
|
||||||
|
|
||||||
|
} REF_TRACE_LOG_ENTRY, *PREF_TRACE_LOG_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Manipulators.
|
||||||
|
//
|
||||||
|
|
||||||
|
PTRACE_LOG
|
||||||
|
CreateRefTraceLog(
|
||||||
|
IN LONG LogSize,
|
||||||
|
IN LONG ExtraBytesInHeader
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DestroyRefTraceLog(
|
||||||
|
IN PTRACE_LOG Log
|
||||||
|
);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__cdecl
|
||||||
|
WriteRefTraceLog(
|
||||||
|
IN PTRACE_LOG Log,
|
||||||
|
IN LONG NewRefCount,
|
||||||
|
IN CONST VOID * Context
|
||||||
|
);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__cdecl
|
||||||
|
WriteRefTraceLogEx(
|
||||||
|
IN PTRACE_LOG Log,
|
||||||
|
IN LONG NewRefCount,
|
||||||
|
IN CONST VOID * Context,
|
||||||
|
IN CONST VOID * Context1,
|
||||||
|
IN CONST VOID * Context2,
|
||||||
|
IN CONST VOID * Context3
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
} // extern "C"
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _REFTRACE_H_
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue