Make IISIntegration use Reference instead of PackageReference (and reactionary work) (#4311)

This commit is contained in:
Justin Kotalik 2018-12-12 16:59:44 -05:00 committed by GitHub
parent 74753428e9
commit 429719b91d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
308 changed files with 626 additions and 35826 deletions

View File

@ -14,9 +14,5 @@ jobs:
jobDisplayName: "Build and test: Windows"
agentOs: Windows
beforeBuild:
- powershell: "& ./src/IISIntegration/tools/UpdateIISExpressCertificate.ps1"
- powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1"
displayName: Setup IISExpress test certificates
- template: jobs/iisintegration-job.yml
parameters:
variables:
_FolderName: IISIntegration

View File

@ -4,10 +4,10 @@ jobs:
jobName: 'IISIntegration'
jobDisplayName: 'IISIntegration'
beforeBuild:
- powershell: "& ./src/IISIntegration/tools/UpdateIISExpressCertificate.ps1; & ./src/IISIntegration/tools/SetupTestEnvironment.ps1 Setup"
- powershell: "& ./src/servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/servers/IIS/tools/SetupTestEnvironment.ps1 Setup"
displayName: Prepare repo
afterBuild:
- powershell: "& ./src/IISIntegration/tools/SetupTestEnvironment.ps1 Shutdown"
- powershell: "& ./src/servers/IIS/tools/SetupTestEnvironment.ps1 Shutdown"
displayName: Stop AppVerifier
condition: always()
- task: PublishBuildArtifacts@1
@ -16,5 +16,5 @@ jobs:
inputs:
artifactName: logs
artifactType: Container
pathtoPublish: src/IISIntegration/artifacts/logs
buildDirectory: src/IISIntegration
pathtoPublish: src/servers/IIS/artifacts/logs
buildDirectory: src/servers/IIS

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ scripts/tmp/
.tools/
launchSettings.json
korebuild-lock.txt
.gradle/

View File

@ -30,8 +30,7 @@
<PackageArtifact Include="Microsoft.AspNetCore.Antiforgery" AllMetapackage="true" AppMetapackage="true" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.App" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.ApplicationInsights.HostingStartup" AllMetapackage="true" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.AspNetCoreModule" Category="noship" Condition=" '$(OS)' == 'Windows_NT' " />
<PackageArtifact Include="Microsoft.AspNetCore.AspNetCoreModuleV1" Category="noship" Condition=" '$(OS)' == 'Windows_NT' " />
<PackageArtifact Include="Microsoft.AspNetCore.AspNetCoreModuleV1" Category="noship" />
<PackageArtifact Include="Microsoft.AspNetCore.Authentication.Abstractions" AllMetapackage="true" AppMetapackage="true" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Category="ship" />
<PackageArtifact Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Category="ship" />

View File

@ -9,7 +9,6 @@
<ItemGroup>
<RepositoryBuildOrder Include="Razor" Order="6" RootPath="$(RepositoryRoot)src\Razor\" />
<RepositoryBuildOrder Include="EntityFrameworkCore" Order="8" />
<RepositoryBuildOrder Include="IISIntegration" Order="10" RootPath="$(RepositoryRoot)src\IISIntegration\" />
<RepositoryBuildOrder Include="ServerTests" Order="11" RootPath="$(RepositoryRoot)src\ServerTests\" />
<RepositoryBuildOrder Include="Security" Order="13" RootPath="$(RepositoryRoot)src\Security\" />
<RepositoryBuildOrder Include="MetaPackages" Order="13" RootPath="$(RepositoryRoot)src\MetaPackages\" />

View File

@ -64,6 +64,7 @@
$(RepositoryRoot)src\Tools\dotnet-watch\test\TestProjects\**\*.csproj
" />
<ProjectToBuild Include="@(NativeProjects)" Condition="'$(OS)' == 'Windows_NT'"/>
<ProjectToBuild Include="
$(RepositoryRoot)src\Features\JsonPatch\**\*.*proj;
$(RepositoryRoot)src\DataProtection\**\*.*proj;
@ -71,7 +72,8 @@
$(RepositoryRoot)src\Hosting\**\*.*proj;
$(RepositoryRoot)src\Http\**\*.*proj;
$(RepositoryRoot)src\Html\**\*.*proj;
$(RepositoryRoot)src\Servers\**\*.*proj;
$(RepositoryRoot)src\Servers\**\*.csproj;
$(RepositoryRoot)src\Servers\**\*.pkgproj;
$(RepositoryRoot)src\Tools\**\*.*proj;
$(RepositoryRoot)src\Middleware\**\*.*proj;
"

View File

@ -36,7 +36,6 @@
</PropertyGroup>
<ItemGroup>
<Repository Include="IISIntegration" RootPath="$(RepositoryRoot)src\IISIntegration\" />
<Repository Include="MetaPackages" PatchPolicy="CascadeVersions" RootPath="$(RepositoryRoot)src\MetaPackages\" />
<Repository Include="Scaffolding" PatchPolicy="AlwaysUpdate" />
<Repository Include="Templating" PatchPolicy="AlwaysUpdateAndCascadeVersions" RootPath="$(RepositoryRoot)src\Templating\" />

View File

@ -296,6 +296,25 @@
<BaselinePackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.1.1, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.Server.IISIntegration-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Server.IISIntegration' ">
<BaselinePackageVersion>2.1.2</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.Server.IISIntegration' AND '$(TargetFramework)' == 'netstandard2.0' ">
<BaselinePackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.AspNetCore.HttpOverrides" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[2.1.1, )" />
<BaselinePackageReference Include="Microsoft.Extensions.Options" Version="[2.1.1, )" />
<BaselinePackageReference Include="System.Buffers" Version="[4.5.0, )" />
<BaselinePackageReference Include="System.IO.Pipelines" Version="[4.5.2, )" />
<BaselinePackageReference Include="System.Memory" Version="[4.5.1, )" />
<BaselinePackageReference Include="System.Numerics.Vectors" Version="[4.5.0, )" />
<BaselinePackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="[4.5.2, )" />
<BaselinePackageReference Include="System.Security.Principal.Windows" Version="[4.5.1, )" />
</ItemGroup>
<!-- Package: Microsoft.AspNetCore.JsonPatch-->
<PropertyGroup Condition=" '$(PackageId)' == 'Microsoft.AspNetCore.JsonPatch' ">
<BaselinePackageVersion>2.1.1</BaselinePackageVersion>

View File

@ -43,6 +43,7 @@
<Package Id="Microsoft.AspNetCore.Rewrite" Version="2.1.1" />
<Package Id="Microsoft.AspNetCore.Routing.Abstractions" Version="2.1.1" />
<Package Id="Microsoft.AspNetCore.Routing" Version="2.1.1" />
<Package Id="Microsoft.AspNetCore.Server.IISIntegration" Version="2.1.2" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Core" Version="2.1.3" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.1.3" />
<Package Id="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" Version="2.1.3" />

View File

@ -36,6 +36,7 @@
<LatestPackageReference Include="Microsoft.Extensions.Localization" Version="$(MicrosoftExtensionsLocalizationPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion)" />
@ -48,12 +49,16 @@
<LatestPackageReference Include="Microsoft.Extensions.WebEncoders.Sources" Version="$(MicrosoftExtensionsWebEncodersSourcesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.WebEncoders" Version="$(MicrosoftExtensionsWebEncodersPackageVersion)" />
<LatestPackageReference Include="Microsoft.NETCore.Windows.ApiSets" Version="$(MicrosoftNETCoreWindowsApiSetsPackageVersion)" />
<LatestPackageReference Include="System.Buffers" Version="$(SystemBuffersPackageVersion)" />
<LatestPackageReference Include="System.Data.SqlClient" Version="$(SystemDataSqlClientPackageVersion)" />
<LatestPackageReference Include="System.IO.Pipelines" Version="$(SystemIOPipelinesPackageVersion)" />
<LatestPackageReference Include="System.Memory" Version="$(SystemMemoryPackageVersion)" />
<LatestPackageReference Include="System.Net.Http.WinHttpHandler" Version="$(SystemNetHttpWinHttpHandlerPackageVersion)" />
<LatestPackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
<LatestPackageReference Include="System.Net.Http.WinHttpHandler" Version="$(SystemNetHttpWinHttpHandlerPackageVersion)" />
<LatestPackageReference Include="System.Numerics.Vectors" Version="$(SystemNumericsVectorsPackageVersion)" />
<LatestPackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemRuntimeCompilerServicesUnsafePackageVersion)" />
<LatestPackageReference Include="System.Security.Cryptography.Cng" Version="$(SystemSecurityCryptographyCngPackageVersion)" />
<LatestPackageReference Include="System.Security.Principal.Windows" Version="$(SystemSecurityPrincipalWindowsPackageVersion)" />
<LatestPackageReference Include="System.Text.Encodings.Web" Version="$(SystemTextEncodingsWebPackageVersion)" />
</ItemGroup>

View File

@ -32,6 +32,7 @@
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Html.Abstractions" ProjectPath="$(RepositoryRoot)src\Html\Abstractions\src\Microsoft.AspNetCore.Html.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Connections.Abstractions" ProjectPath="$(RepositoryRoot)src\Servers\Connections.Abstractions\src\Microsoft.AspNetCore.Connections.Abstractions.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.HttpSys" ProjectPath="$(RepositoryRoot)src\Servers\HttpSys\src\Microsoft.AspNetCore.Server.HttpSys.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.IISIntegration" ProjectPath="$(RepositoryRoot)src\Servers\IIS\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.Kestrel.Core" ProjectPath="$(RepositoryRoot)src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.Kestrel.Https" ProjectPath="$(RepositoryRoot)src\Servers\Kestrel\Https\src\Microsoft.AspNetCore.Server.Kestrel.Https.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Server.Kestrel" ProjectPath="$(RepositoryRoot)src\Servers\Kestrel\Kestrel\src\Microsoft.AspNetCore.Server.Kestrel.csproj" />

View File

@ -3,4 +3,6 @@
<Import Project="$(MicroBuildPluginDirectory)\MicroBuild.Plugins.*\**\build\MicroBuild.Plugins.*.targets" Condition="'$(DisableMicroBuild)' != 'true' AND '$(MicroBuildPluginDirectory)' != ''" />
<Target Name="Pack" />
<Target Name="Restore" />
</Project>

View File

@ -1,23 +0,0 @@
<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/AspNetCore</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)..\..\eng\AspNetCore.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>

View File

@ -1,7 +0,0 @@
<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>

View File

@ -1,300 +0,0 @@

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\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}") = "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
{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}
{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

View File

@ -1,3 +0,0 @@
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.

View File

@ -1,3 +0,0 @@
@ECHO OFF
SET RepoRoot="%~dp0..\.."
%RepoRoot%\build.cmd -LockFile %RepoRoot%\korebuild-lock.txt -Path %~dp0 %*

View File

@ -1,7 +0,0 @@
#!/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" "$@"

View File

@ -1,31 +0,0 @@
<?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>

View File

@ -1,55 +0,0 @@
<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>

View File

@ -1,37 +0,0 @@
{
"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)"
}
}
}
}

View File

@ -1,26 +0,0 @@
<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>
<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>

View File

@ -1,84 +0,0 @@
<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="&quot;$(VisualStudioMSBuildx86Path)&quot; &quot;$(RepositoryRoot)src\AspNetCoreModuleV1\AspNetCore\AspNetCore.vcxproj&quot; $(BuildArgs) -p:Platform=%(Platforms.Identity) -bl:$(LogOutputDir)native.%(Platforms.Identity).binlog"
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
<Exec Command="&quot;$(VisualStudioMSBuildx86Path)&quot; &quot;$(RepositoryRoot)src\AspNetCoreModuleV2\AspNetCore\AspNetCore.vcxproj&quot; $(BuildArgs) -p:Platform=%(Platforms.Identity) -bl:$(LogOutputDir)native.%(Platforms.Identity).binlog"
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
<Exec Command="&quot;$(VisualStudioMSBuildx86Path)&quot; &quot;$(RepositoryRoot)src\AspNetCoreModuleV2\RequestHandler\RequestHandler.vcxproj&quot; $(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>
</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>
</Target>
</Project>

View File

@ -1,17 +0,0 @@
<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>

View File

@ -1,92 +0,0 @@
<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) &quot;$(ProjectDepsFilePath)&quot;" />
</Target>
<Target Name="InjectRequestHandlerOnPublish" AfterTargets="GeneratePublishDependencyFile" DependsOnTargets="PrepareInjectionApp" Condition="'$(ANCMVersion)' == 'V2' Or '$(ANCMVersion)' == ''">
<Exec Command="$(InjectDepsApp) $(InjectDepsArguments) &quot;$(PublishDepsFilePath)&quot;" />
</Target>
</Project>

View File

@ -1,17 +0,0 @@
{
"$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"
]
}
}
}

View File

@ -1,29 +0,0 @@
<?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>

View File

@ -1,31 +0,0 @@
<?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>

View File

@ -1,15 +0,0 @@
<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>

View File

@ -1,28 +0,0 @@
{
"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"
}
}
}
}

View File

@ -1,20 +0,0 @@
<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>

View File

@ -1,37 +0,0 @@
{
"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)"
}
}
}
}

View File

@ -1,88 +0,0 @@
// 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();
}
}
}

View File

@ -1,9 +0,0 @@
<?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>

View File

@ -1,260 +0,0 @@
<?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>{EC82302F-D2F0-4727-99D1-EABC0DD9DC3B}</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>
<ClInclude Include="Inc\applicationinfo.h" />
<ClInclude Include="Inc\appoffline.h" />
<ClInclude Include="inc\globalmodule.h" />
<ClInclude Include="Inc\applicationmanager.h" />
<ClInclude Include="Inc\filewatcher.h" />
<ClInclude Include="Inc\proxymodule.h" />
<ClInclude Include="Src\precomp.hxx" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Src\applicationinfo.cpp" />
<ClCompile Include="Src\applicationmanager.cxx" />
<ClCompile Include="Src\dllmain.cpp" />
<ClCompile Include="Src\filewatcher.cxx" />
<ClCompile Include="src\globalmodule.cpp" />
<ClCompile Include="Src\proxymodule.cxx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
</ProjectReference>
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
<Project>{09d9d1d6-2951-4e14-bc35-76a23cf9391a}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="ancm.mof" />
<None Include="Source.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="aspnetcoremodule.rc" />
</ItemGroup>
<ItemGroup>
<Content Include="aspnetcore_schema.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="ancm.mof">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Xml Include="aspnetcore_schema.xml" />
</ItemGroup>
<Import Project="..\..\..\build\native.targets" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,251 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#define API_BUFFER_TOO_SMALL 0x80008098
extern BOOL g_fRecycleProcessCalled;
typedef
HRESULT
(WINAPI * PFN_ASPNETCORE_CREATE_APPLICATION)(
_In_ IHttpServer *pServer,
_In_ ASPNETCORE_CONFIG *pConfig,
_Out_ APPLICATION **pApplication
);
typedef
HRESULT
(WINAPI * PFN_ASPNETCORE_CREATE_REQUEST_HANDLER)(
_In_ IHttpContext *pHttpContext,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication,
_Out_ REQUEST_HANDLER **pRequestHandler
);
//
// The key used for hash-table lookups, consists of the port on which the http process is created.
//
class APPLICATION_INFO_KEY
{
public:
APPLICATION_INFO_KEY(
VOID
) : INLINE_STRU_INIT(m_struKey)
{
}
HRESULT
Initialize(
_In_ LPCWSTR pszKey
)
{
return m_struKey.Copy(pszKey);
}
BOOL
GetIsEqual(
const APPLICATION_INFO_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 APPLICATION_INFO
{
public:
APPLICATION_INFO(IHttpServer *pServer) :
m_pServer(pServer),
m_cRefs(1), m_fAppOfflineFound(FALSE),
m_pAppOfflineHtm(NULL), m_pFileWatcherEntry(NULL),
m_pConfiguration(NULL),
m_pfnAspNetCoreCreateApplication(NULL),
m_pfnAspNetCoreCreateRequestHandler(NULL)
{
InitializeSRWLock(&m_srwLock);
}
APPLICATION_INFO_KEY *
QueryApplicationInfoKey()
{
return &m_applicationInfoKey;
}
virtual
~APPLICATION_INFO();
HRESULT
Initialize(
_In_ ASPNETCORE_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
);
VOID
ReferenceApplicationInfo() const
{
InterlockedIncrement(&m_cRefs);
}
VOID
DereferenceApplicationInfo() const
{
if (InterlockedDecrement(&m_cRefs) == 0)
{
delete this;
}
}
APP_OFFLINE_HTM* QueryAppOfflineHtm()
{
return m_pAppOfflineHtm;
}
BOOL
AppOfflineFound()
{
return m_fAppOfflineFound;
}
VOID
UpdateAppOfflineFileHandle();
HRESULT
StartMonitoringAppOffline();
ASPNETCORE_CONFIG*
QueryConfig()
{
return m_pConfiguration;
}
//
// ExtractApplication will increase the reference counter of the application
// Caller is responsible for dereference the application.
// Otherwise memory leak
//
VOID
ExtractApplication(APPLICATION** ppApplication)
{
AcquireSRWLockShared(&m_srwLock);
if (m_pApplication != NULL)
{
m_pApplication->ReferenceApplication();
}
*ppApplication = m_pApplication;
ReleaseSRWLockShared(&m_srwLock);
}
VOID
RecycleApplication();
VOID
ShutDownApplication();
HRESULT
EnsureApplicationCreated();
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER
QueryCreateRequestHandler()
{
return m_pfnAspNetCoreCreateRequestHandler;
}
private:
HRESULT FindRequestHandlerAssembly();
HRESULT FindNativeAssemblyFromGlobalLocation(STRU* struFilename);
HRESULT FindNativeAssemblyFromHostfxr(STRU* struFilename);
static VOID DoRecycleApplication(LPVOID lpParam);
mutable LONG m_cRefs;
APPLICATION_INFO_KEY m_applicationInfoKey;
BOOL m_fAppOfflineFound;
APP_OFFLINE_HTM *m_pAppOfflineHtm;
FILE_WATCHER_ENTRY *m_pFileWatcherEntry;
ASPNETCORE_CONFIG *m_pConfiguration;
APPLICATION *m_pApplication;
SRWLOCK m_srwLock;
IHttpServer *m_pServer;
PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication;
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER m_pfnAspNetCoreCreateRequestHandler;
};
class APPLICATION_INFO_HASH :
public HASH_TABLE<APPLICATION_INFO, APPLICATION_INFO_KEY *>
{
public:
APPLICATION_INFO_HASH()
{}
APPLICATION_INFO_KEY *
ExtractKey(
APPLICATION_INFO *pApplicationInfo
)
{
return pApplicationInfo->QueryApplicationInfoKey();
}
DWORD
CalcKeyHash(
APPLICATION_INFO_KEY *key
)
{
return key->CalcKeyHash();
}
BOOL
EqualKeys(
APPLICATION_INFO_KEY *key1,
APPLICATION_INFO_KEY *key2
)
{
return key1->GetIsEqual(key2);
}
VOID
ReferenceRecord(
APPLICATION_INFO *pApplicationInfo
)
{
pApplicationInfo->ReferenceApplicationInfo();
}
VOID
DereferenceRecord(
APPLICATION_INFO *pApplicationInfo
)
{
pApplicationInfo->DereferenceApplicationInfo();
}
static
VOID
ReferenceCopyToTable(
APPLICATION_INFO * pEntry,
PVOID pvData
)
{
APPLICATION_INFO_HASH *pHash = static_cast<APPLICATION_INFO_HASH *>(pvData);
DBG_ASSERT(pHash);
pHash->InsertRecord(pEntry);
}
private:
APPLICATION_INFO_HASH(const APPLICATION_INFO_HASH &);
void operator=(const APPLICATION_INFO_HASH &);
};

View File

@ -1,154 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#define DEFAULT_HASH_BUCKETS 17
//
// This class will manage the lifecycle of all Asp.Net Core applciation
// It should be global singleton.
// Should always call GetInstance to get the object instance
//
struct CONFIG_CHANGE_CONTEXT
{
PCWSTR pstrPath;
MULTISZ MultiSz;
};
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;
}
}
static
BOOL
FindConfigChangedApplication(
_In_ APPLICATION_INFO * pEntry,
_In_ PVOID pvContext
);
static
VOID
ShutdownApplication(
_In_ APPLICATION_INFO * pEntry,
_In_ PVOID pvContext
);
HRESULT
GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ ASPNETCORE_CONFIG* pConfig,
_Out_ APPLICATION_INFO ** ppApplicationInfo
);
HRESULT
RecycleApplicationFromManager(
_In_ LPCWSTR pszApplicationId
);
VOID
ShutDown();
~APPLICATION_MANAGER()
{
if (m_pFileWatcher != NULL)
{
delete m_pFileWatcher;
m_pFileWatcher = NULL;
}
if(m_pApplicationInfoHash != NULL)
{
m_pApplicationInfoHash->Clear();
delete m_pApplicationInfoHash;
m_pApplicationInfoHash = NULL;
}
}
FILE_WATCHER*
GetFileWatcher()
{
return m_pFileWatcher;
}
HRESULT Initialize()
{
HRESULT hr = S_OK;
if(m_pApplicationInfoHash == NULL)
{
m_pApplicationInfoHash = new APPLICATION_INFO_HASH();
if(m_pApplicationInfoHash == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = m_pApplicationInfoHash->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_pApplicationInfoHash(NULL),
m_pFileWatcher(NULL),
m_hostingModel(HOSTING_UNKNOWN)
{
InitializeSRWLock(&m_srwLock);
}
FILE_WATCHER *m_pFileWatcher;
APPLICATION_INFO_HASH *m_pApplicationInfoHash;
static APPLICATION_MANAGER *sm_pApplicationManager;
SRWLOCK m_srwLock;
APP_HOSTING_MODEL m_hostingModel;
};

View File

@ -1,101 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
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 (HRESULT_FROM_WIN32(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;
};

View File

@ -1,127 +0,0 @@
// Copyright (c) .NET Foundation. 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_INFO;
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;
volatile BOOL m_fThreadExit;
};
class FILE_WATCHER_ENTRY
{
public:
FILE_WATCHER_ENTRY(FILE_WATCHER * pFileMonitor);
OVERLAPPED _overlapped;
HRESULT
Create(
_In_ PCWSTR pszDirectoryToMonitor,
_In_ PCWSTR pszFileNameToMonitor,
_In_ APPLICATION_INFO* pApplicationInfo,
_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_INFO* _pApplicationInfo;
STRU _strFileName;
STRU _strDirectoryName;
LONG _lStopMonitorCalled;
mutable LONG _cRefs;
BOOL _fIsValid;
SRWLOCK _srwLock;
};

View File

@ -1,49 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#ifndef __FX_VER_H__
#define __FX_VER_H__
#include <string>
// Note: This is not SemVer (esp., in comparing pre-release part, fx_ver_t does not
// compare multiple dot separated identifiers individually.) ex: 1.0.0-beta.2 vs. 1.0.0-beta.11
struct fx_ver_t
{
fx_ver_t(int major, int minor, int patch);
fx_ver_t(int major, int minor, int patch, const std::wstring& pre);
fx_ver_t(int major, int minor, int patch, const std::wstring& pre, const std::wstring& build);
int get_major() const { return m_major; }
int get_minor() const { return m_minor; }
int get_patch() const { return m_patch; }
void set_major(int m) { m_major = m; }
void set_minor(int m) { m_minor = m; }
void set_patch(int p) { m_patch = p; }
bool is_prerelease() const { return !m_pre.empty(); }
std::wstring as_str() const;
std::wstring prerelease_glob() const;
std::wstring patch_glob() const;
bool operator ==(const fx_ver_t& b) const;
bool operator !=(const fx_ver_t& b) const;
bool operator <(const fx_ver_t& b) const;
bool operator >(const fx_ver_t& b) const;
bool operator <=(const fx_ver_t& b) const;
bool operator >=(const fx_ver_t& b) const;
static bool parse(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production = false);
private:
int m_major;
int m_minor;
int m_patch;
std::wstring m_pre;
std::wstring m_build;
static int compare(const fx_ver_t&a, const fx_ver_t& b);
};
#endif // __FX_VER_H__

View File

@ -1,37 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class ASPNET_CORE_GLOBAL_MODULE : public CGlobalModule
{
public:
ASPNET_CORE_GLOBAL_MODULE(
APPLICATION_MANAGER* pApplicationManager
);
~ASPNET_CORE_GLOBAL_MODULE()
{
}
VOID Terminate()
{
// Remove the class from memory.
delete this;
}
GLOBAL_NOTIFICATION_STATUS
OnGlobalStopListening(
_In_ IGlobalStopListeningProvider * pProvider
);
GLOBAL_NOTIFICATION_STATUS
OnGlobalConfigurationChange(
_In_ IGlobalConfigurationChangeProvider * pProvider
);
private:
APPLICATION_MANAGER * m_pApplicationManager;
};

View File

@ -1,64 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer *g_pHttpServer;
extern HMODULE g_hAspnetCoreRH;
class ASPNET_CORE_PROXY_MODULE : public CHttpModule
{
public:
ASPNET_CORE_PROXY_MODULE();
~ASPNET_CORE_PROXY_MODULE();
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:
APPLICATION_INFO *m_pApplicationInfo;
APPLICATION *m_pApplication;
REQUEST_HANDLER *m_pHandler;
};
class ASPNET_CORE_PROXY_MODULE_FACTORY : public IHttpModuleFactory
{
public:
HRESULT
GetHttpModule(
CHttpModule ** ppModule,
IModuleAllocator * pAllocator
);
VOID
Terminate();
};

View File

@ -1,4 +0,0 @@
LIBRARY aspnetcore
EXPORTS
RegisterModule

View File

@ -1,208 +0,0 @@
#pragma classflags("forceupdate")
#pragma namespace ("\\\\.\\Root\\WMI")
#pragma autorecover
/*
* AspNetCore module trace events layout
* Uncomment the following class to run mof2trace to generate header file
* comment it back before checking it in */
[Dynamic,
Description("IIS: WWW Server"),
Guid("{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}"),
locale("MS\\0x409")]
class IIS_Trace:EventTrace
{
[Description ("Enable Flags") : amended,
ValueDescriptions{
"AspNetCore module events" } : amended,
DefineValues{
"ETW_IIS_ANCM" },
Values{
"ANCM" },
ValueMap{
"0x10000" }
]
uint32 Flags;
[Description ("Levels") : amended,
ValueDescriptions{
"Abnormal exit or termination",
"Severe errors",
"Warnings",
"Information",
"Detailed information" } : amended,
DefineValues{
"TRACE_LEVEL_FATAL",
"TRACE_LEVEL_ERROR",
"TRACE_LEVEL_WARNING",
"TRACE_LEVEL_INFORMATION",
"TRACE_LEVEL_VERBOSE" },
Values{
"Fatal",
"Error",
"Warning",
"Information",
"Verbose" },
ValueMap{
"0x1",
"0x2",
"0x3",
"0x4",
"0x5" },
ValueType("index")
]
uint32 Level;
};
*/
[Dynamic,
Description("ANCM runtime events") : amended,
Guid("{82ADEAD7-12B2-4781-BDCA-5A4B6C757191}"),
EventVersion(1),
DisplayName("ANCM"),
EventANCMRuntime,
locale("MS\\0x409")
]
class ANCM_Events:IIS_Trace
{
};
[Dynamic,
Description("Start application success") : amended,
EventType(1),
EventLevel(4),
EventTypeName("ANCM_START_APPLICATION_SUCCESS") : amended
]
class ANCMAppStart:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
[WmiDataId(2),
Description("Application Description") : amended,
StringTermination("NullTerminated"),
format("w"),
read]
string AppDescription;
};
[Dynamic,
Description("Start application failed") : amended,
EventType(2),
EventLevel(2),
EventTypeName("ANCM_START_APPLICATION_FAIL") : amended
]
class ANCMAppStartFail:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
[WmiDataId(2),
Description("Application Start Failure Description") : amended,
StringTermination("NullTerminated"),
format("w"),
read]
string FailureDescription;
};
[Dynamic,
Description("Start forwarding request") : amended,
EventType(3),
EventLevel(4),
EventTypeName("ANCM_REQUEST_FORWARD_START") : amended
]
class ANCMForwardStart:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
};
[Dynamic,
Description("Finish forwarding request") : amended,
EventType(4),
EventLevel(4),
EventTypeName("ANCM_REQUEST_FORWARD_END") : amended
]
class ANCMForwardEnd:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
};
[Dynamic,
Description("Forwarding request failure") : amended,
EventType(5),
EventLevel(2),
EventTypeName("ANCM_REQUEST_FORWARD_FAIL") : amended
]
class ANCMForwardFail:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
[WmiDataId(2),
Description("Error code") : amended,
format("x"),
read]
uint32 ErrorCode;
};
[Dynamic,
Description("Receiving callback from WinHttp") : amended,
EventType(6),
EventLevel(4),
EventTypeName("ANCM_WINHTTP_CALLBACK") : amended
]
class ANCMWinHttpCallBack:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
[WmiDataId(2),
Description("InternetStatus") : amended,
format("x"),
read]
uint32 InternetStatus;
};
[Dynamic,
Description("Inprocess executing request failure") : amended,
EventType(7),
EventLevel(2),
EventTypeName("ANCM_EXECUTE_REQUEST_FAIL") : amended
]
class ANCMExecuteFailed:ANCM_Events
{
[WmiDataId(1),
Description("Context ID") : amended,
extension("Guid"),
ActivityID,
read]
object ContextId;
[WmiDataId(2),
Description("InternetStatus") : amended,
format("x"),
read]
uint32 ErrorCode;
};

View File

@ -1,47 +0,0 @@
<!--
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>

View File

@ -1,120 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include <windows.h>
#include "version.h"
#include "..\CommonLib\Aspnetcore_msg.rc"
#include "..\CommonLib\resources.h"
/////////////////////////////////////////////////////////////////////////////
// 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
"..\CommonLib\resources.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 Corporation"
VALUE "FileDescription", FileDescription
VALUE "FileVersion", FileVersionStr
VALUE "InternalName", "aspnetcore"
VALUE "LegalCopyright", "Copyright (C) Microsoft Corporation"
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

View File

@ -1,650 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
APPLICATION_INFO::~APPLICATION_INFO()
{
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->DereferenceFileWatcherEntry();
m_pFileWatcherEntry = NULL;
}
if (m_pApplication != NULL)
{
// shutdown the application
m_pApplication->ShutDown();
m_pApplication->DereferenceApplication();
m_pApplication = NULL;
}
// configuration should be dereferenced after application shutdown
// since the former will use it during shutdown
if (m_pConfiguration != NULL)
{
// Need to dereference the configuration instance
m_pConfiguration->DereferenceConfiguration();
m_pConfiguration = NULL;
}
}
HRESULT
APPLICATION_INFO::Initialize(
_In_ ASPNETCORE_CONFIG *pConfiguration,
_In_ FILE_WATCHER *pFileWatcher
)
{
HRESULT hr = S_OK;
DBG_ASSERT(pConfiguration);
DBG_ASSERT(pFileWatcher);
m_pConfiguration = pConfiguration;
// reference the configuration instance to prevent it will be not release
// earlier in case of configuration change and shutdown
m_pConfiguration->ReferenceConfiguration();
hr = m_applicationInfoKey.Initialize(pConfiguration->QueryConfigPath()->QueryStr());
if (FAILED(hr))
{
goto Finished;
}
if (m_pFileWatcherEntry == NULL)
{
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(pFileWatcher);
if (m_pFileWatcherEntry == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
}
UpdateAppOfflineFileHandle();
Finished:
return hr;
}
HRESULT
APPLICATION_INFO::StartMonitoringAppOffline()
{
HRESULT hr = S_OK;
if (m_pFileWatcherEntry != NULL)
{
hr = m_pFileWatcherEntry->Create(m_pConfiguration->QueryApplicationPhysicalPath()->QueryStr(), L"app_offline.htm", this, NULL);
}
return hr;
}
//
// Called by the file watcher when the app_offline.htm's file status has been changed.
// If it finds it, we will call recycle on the application.
//
VOID
APPLICATION_INFO::UpdateAppOfflineFileHandle()
{
STRU strFilePath;
UTILITY::ConvertPathToFullPath(L".\\app_offline.htm",
m_pConfiguration->QueryApplicationPhysicalPath()->QueryStr(),
&strFilePath);
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
ReferenceApplicationInfo();
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) &&
GetLastError() == ERROR_FILE_NOT_FOUND)
{
// Check if app offline was originally present.
// if it was, log that app_offline has been dropped.
if (m_fAppOfflineFound)
{
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_REMOVED_MSG)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_INFORMATION_TYPE,
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_REMOVED,
strEventMsg.QueryStr());
}
}
m_fAppOfflineFound = FALSE;
}
else
{
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;
}
}
m_fAppOfflineFound = TRUE;
// recycle the application
if (m_pApplication != NULL)
{
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG,
m_pApplication->QueryConfig()->QueryApplicationPath()->QueryStr())))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_INFORMATION_TYPE,
ASPNETCORE_EVENT_RECYCLE_APPOFFLINE,
strEventMsg.QueryStr());
}
RecycleApplication();
}
}
DereferenceApplicationInfo();
}
HRESULT
APPLICATION_INFO::EnsureApplicationCreated()
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
APPLICATION* pApplication = NULL;
STACK_STRU(struFileName, 300); // >MAX_PATH
STRU struHostFxrDllLocation;
if (m_pApplication != NULL)
{
goto Finished;
}
if (m_pApplication == NULL)
{
AcquireSRWLockExclusive(&m_srwLock);
fLocked = TRUE;
if (m_pApplication != NULL)
{
goto Finished;
}
//
// in case of app offline, we don't want to create a new application now
//
if (!m_fAppOfflineFound)
{
// Move the request handler check inside of the lock
// such that only one request finds and loads it.
// FindRequestHandlerAssembly obtains a global lock, but after releasing the lock,
// there is a period where we could call
hr = FindRequestHandlerAssembly();
if (FAILED(hr))
{
goto Finished;
}
if (m_pfnAspNetCoreCreateApplication == NULL)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
goto Finished;
}
hr = m_pfnAspNetCoreCreateApplication(m_pServer, m_pConfiguration, &pApplication);
if (FAILED(hr))
{
goto Finished;
}
m_pApplication = pApplication;
}
}
Finished:
if (fLocked)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
return hr;
}
HRESULT
APPLICATION_INFO::FindRequestHandlerAssembly()
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
STACK_STRU(struFileName, 256);
if (g_fAspnetcoreRHLoadedError)
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
goto Finished;
}
else if (!g_fAspnetcoreRHAssemblyLoaded)
{
AcquireSRWLockExclusive(&g_srwLock);
fLocked = TRUE;
if (g_fAspnetcoreRHLoadedError)
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
goto Finished;
}
if (g_fAspnetcoreRHAssemblyLoaded)
{
goto Finished;
}
if (m_pConfiguration->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
if (FAILED(hr = FindNativeAssemblyFromHostfxr(&struFileName)))
{
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_INPROCESS_RH_MISSING_MSG)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_INFORMATION_TYPE,
ASPNETCORE_EVENT_INPROCESS_RH_MISSING,
strEventMsg.QueryStr());
}
goto Finished;
}
}
else
{
if (FAILED(hr = FindNativeAssemblyFromGlobalLocation(&struFileName)))
{
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_INFORMATION_TYPE,
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING,
strEventMsg.QueryStr());
}
goto Finished;
}
}
g_hAspnetCoreRH = LoadLibraryW(struFileName.QueryStr());
if (g_hAspnetCoreRH == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_pfnAspNetCoreCreateApplication = (PFN_ASPNETCORE_CREATE_APPLICATION)
GetProcAddress(g_hAspnetCoreRH, "CreateApplication");
if (g_pfnAspNetCoreCreateApplication == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_pfnAspNetCoreCreateRequestHandler = (PFN_ASPNETCORE_CREATE_REQUEST_HANDLER)
GetProcAddress(g_hAspnetCoreRH, "CreateRequestHandler");
if (g_pfnAspNetCoreCreateRequestHandler == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
g_fAspnetcoreRHAssemblyLoaded = TRUE;
}
Finished:
//
// Question: we remember the load failure so that we will not try again.
// User needs to check whether the fuction pointer is NULL
//
m_pfnAspNetCoreCreateApplication = g_pfnAspNetCoreCreateApplication;
m_pfnAspNetCoreCreateRequestHandler = g_pfnAspNetCoreCreateRequestHandler;
if (!g_fAspnetcoreRHLoadedError && FAILED(hr))
{
g_fAspnetcoreRHLoadedError = TRUE;
}
if (fLocked)
{
ReleaseSRWLockExclusive(&g_srwLock);
}
return hr;
}
HRESULT
APPLICATION_INFO::FindNativeAssemblyFromGlobalLocation(STRU* struFilename)
{
HRESULT hr = S_OK;
DWORD dwSize = MAX_PATH;
BOOL fDone = FALSE;
DWORD dwPosition = 0;
// Though we could call LoadLibrary(L"aspnetcorerh.dll") relying the OS to solve
// the path (the targeted dll is the same folder of w3wp.exe/iisexpress)
// let's still load with full path to avoid security issue
if (FAILED(hr = struFilename->Resize(dwSize + 20)))
{
goto Finished;
}
while (!fDone)
{
DWORD dwReturnedSize = GetModuleFileNameW(g_hModule, struFilename->QueryStr(), dwSize);
if (dwReturnedSize == 0)
{
hr = HRESULT_FROM_WIN32(GetLastError());
fDone = TRUE;
goto Finished;
}
else if ((dwReturnedSize == dwSize) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
dwSize *= 2; // smaller buffer. increase the buffer and retry
if (FAILED(hr = struFilename->Resize(dwSize + 20))) // + 20 for aspnetcorerh.dll
{
goto Finished;
}
}
else
{
fDone = TRUE;
}
}
if (FAILED(hr = struFilename->SyncWithBuffer()))
{
goto Finished;
}
dwPosition = struFilename->LastIndexOf(L'\\', 0);
struFilename->QueryStr()[dwPosition] = L'\0';
if (FAILED(hr = struFilename->SyncWithBuffer()) ||
FAILED(hr = struFilename->Append(L"\\")) ||
FAILED(hr = struFilename->Append(g_pwzAspnetcoreRequestHandlerName)))
{
goto Finished;
}
Finished:
return hr;
}
//
// Tries to find aspnetcorerh.dll from the application
// Calls into hostfxr.dll to find it.
// Will leave hostfxr.dll loaded as it will be used again to call hostfxr_main.
//
HRESULT
APPLICATION_INFO::FindNativeAssemblyFromHostfxr(
STRU* struFilename
)
{
HRESULT hr = S_OK;
STRU struApplicationFullPath;
STRU struNativeSearchPaths;
STRU struNativeDllLocation;
HMODULE hmHostFxrDll = NULL;
INT intHostFxrExitCode = 0;
INT intIndex = -1;
INT intPrevIndex = 0;
BOOL fFound = FALSE;
DWORD dwBufferSize = 1024 * 10;
DWORD dwRequiredBufferSize = 0;
DBG_ASSERT(struFileName != NULL);
hmHostFxrDll = LoadLibraryW(m_pConfiguration->QueryHostFxrFullPath());
if (hmHostFxrDll == NULL)
{
// Could not load hostfxr
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
hostfxr_get_native_search_directories_fn pFnHostFxrSearchDirectories = (hostfxr_get_native_search_directories_fn)
GetProcAddress(hmHostFxrDll, "hostfxr_get_native_search_directories");
if (pFnHostFxrSearchDirectories == NULL)
{
// Host fxr version is incorrect (need a higher version).
// TODO log error
hr = E_FAIL;
goto Finished;
}
if (FAILED(hr = struNativeSearchPaths.Resize(dwBufferSize)))
{
goto Finished;
}
while (TRUE)
{
intHostFxrExitCode = pFnHostFxrSearchDirectories(
m_pConfiguration->QueryHostFxrArgCount(),
m_pConfiguration->QueryHostFxrArguments(),
struNativeSearchPaths.QueryStr(),
dwBufferSize,
&dwRequiredBufferSize
);
if (intHostFxrExitCode == 0)
{
break;
}
else if (dwRequiredBufferSize > dwBufferSize)
{
dwBufferSize = dwRequiredBufferSize + 1; // for null terminator
if (FAILED(hr = struNativeSearchPaths.Resize(dwBufferSize)))
{
goto Finished;
}
}
else
{
hr = E_FAIL;
// Log "Error finding native search directories from aspnetcore application.
goto Finished;
}
}
if (FAILED(hr = struNativeSearchPaths.SyncWithBuffer()))
{
goto Finished;
}
fFound = FALSE;
// The native search directories are semicolon delimited.
// Split on semicolons, append aspnetcorerh.dll, and check if the file exists.
while ((intIndex = struNativeSearchPaths.IndexOf(L";", intPrevIndex)) != -1)
{
if (FAILED(hr = struNativeDllLocation.Copy(&struNativeSearchPaths.QueryStr()[intPrevIndex], intIndex - intPrevIndex)))
{
goto Finished;
}
if (!struNativeDllLocation.EndsWith(L"\\"))
{
if (FAILED(hr = struNativeDllLocation.Append(L"\\")))
{
goto Finished;
}
}
if (FAILED(hr = struNativeDllLocation.Append(g_pwzAspnetcoreRequestHandlerName)))
{
goto Finished;
}
if (UTILITY::CheckIfFileExists(struNativeDllLocation.QueryStr()))
{
if (FAILED(hr = struFilename->Copy(struNativeDllLocation)))
{
goto Finished;
}
fFound = TRUE;
break;
}
intPrevIndex = intIndex + 1;
}
if (!fFound)
{
hr = E_FAIL;
goto Finished;
}
Finished:
if (FAILED(hr) && hmHostFxrDll != NULL)
{
FreeLibrary(hmHostFxrDll);
}
return hr;
}
VOID
APPLICATION_INFO::RecycleApplication()
{
APPLICATION* pApplication = NULL;
HANDLE hThread = INVALID_HANDLE_VALUE;
BOOL fLockAcquired = FALSE;
if (m_pApplication != NULL)
{
AcquireSRWLockExclusive(&m_srwLock);
fLockAcquired = TRUE;
if (m_pApplication != NULL)
{
pApplication = m_pApplication;
if (pApplication->QueryConfig()->QueryHostingModel() == HOSTING_OUT_PROCESS)
{
//
// For inprocess, need to set m_pApplication to NULL first to
// avoid mapping new request to the recycled application.
// Outofprocess application instance will be created for new request
// For inprocess, as recycle will lead to shutdown later, leave m_pApplication
// to not block incoming requests till worker process shutdown
//
m_pApplication = NULL;
}
else
{
//
// For inprocess, need hold the application till shutdown is called
// Bump the reference counter as DoRecycleApplication will do dereference
//
pApplication->ReferenceApplication();
}
hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE)DoRecycleApplication,
pApplication, // thread function arguments
0, // default creation flags
NULL); // receive thread identifier
}
if (hThread == NULL)
{
if (!g_fRecycleProcessCalled)
{
g_fRecycleProcessCalled = TRUE;
g_pHttpServer->RecycleProcess(L"On Demand by AspNetCore Module for recycle application failure");
}
}
else
{
// Closing a thread handle does not terminate the associated thread or remove the thread object.
CloseHandle(hThread);
}
if (fLockAcquired)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
}
}
VOID
APPLICATION_INFO::DoRecycleApplication(
LPVOID lpParam)
{
APPLICATION* pApplication = static_cast<APPLICATION*>(lpParam);
// No lock required
if (pApplication != NULL)
{
// Recycle will call shutdown for out of process
pApplication->Recycle();
// Decrement the ref count as we reference it in RecycleApplication.
pApplication->DereferenceApplication();
}
}
VOID
APPLICATION_INFO::ShutDownApplication()
{
APPLICATION* pApplication = NULL;
BOOL fLockAcquired = FALSE;
// pApplication can be NULL due to app_offline
if (m_pApplication != NULL)
{
AcquireSRWLockExclusive(&m_srwLock);
fLockAcquired = TRUE;
if (m_pApplication != NULL)
{
pApplication = m_pApplication;
// Set m_pApplication to NULL first to prevent anyone from using it
m_pApplication = NULL;
pApplication->ShutDown();
pApplication->DereferenceApplication();
}
if (fLockAcquired)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
}
}

View File

@ -1,458 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
// The application manager is a singleton across ANCM.
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
//
// Retrieves the application info from the application manager
// Will create the application info if it isn't initalized
//
HRESULT
APPLICATION_MANAGER::GetOrCreateApplicationInfo(
_In_ IHttpServer* pServer,
_In_ ASPNETCORE_CONFIG* pConfig,
_Out_ APPLICATION_INFO ** ppApplicationInfo
)
{
HRESULT hr = S_OK;
APPLICATION_INFO *pApplicationInfo = NULL;
APPLICATION_INFO_KEY key;
BOOL fExclusiveLock = FALSE;
BOOL fMixedHostingModelError = FALSE;
BOOL fDuplicatedInProcessApp = FALSE;
PCWSTR pszApplicationId = NULL;
STACK_STRU ( strEventMsg, 256 );
DBG_ASSERT(pServer);
DBG_ASSERT(pConfig);
DBG_ASSERT(ppApplicationInfo);
*ppApplicationInfo = NULL;
// The configuration path is unique for each application and is used for the
// key in the applicationInfoHash.
pszApplicationId = pConfig->QueryConfigPath()->QueryStr();
hr = key.Initialize(pszApplicationId);
if (FAILED(hr))
{
goto Finished;
}
// When accessing the m_pApplicationInfoHash, we need to acquire the application manager
// lock to avoid races on setting state.
AcquireSRWLockShared(&m_srwLock);
if (g_fInShutdown)
{
ReleaseSRWLockShared(&m_srwLock);
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
goto Finished;
}
m_pApplicationInfoHash->FindKey(&key, ppApplicationInfo);
ReleaseSRWLockShared(&m_srwLock);
if (*ppApplicationInfo == NULL)
{
// Check which hosting model we want to support
switch (pConfig->QueryHostingModel())
{
case HOSTING_IN_PROCESS:
if (m_pApplicationInfoHash->Count() > 0)
{
// Only one inprocess app is allowed per IIS worker process
fDuplicatedInProcessApp = TRUE;
hr = HRESULT_FROM_WIN32(ERROR_APP_INIT_FAILURE);
goto Finished;
}
break;
case HOSTING_OUT_PROCESS:
break;
default:
hr = E_UNEXPECTED;
goto Finished;
}
pApplicationInfo = new APPLICATION_INFO(pServer);
if (pApplicationInfo == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
AcquireSRWLockExclusive(&m_srwLock);
fExclusiveLock = TRUE;
if (g_fInShutdown)
{
// Already in shuting down. No need to create the application
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
goto Finished;
}
m_pApplicationInfoHash->FindKey(&key, ppApplicationInfo);
if (*ppApplicationInfo != NULL)
{
// someone else created the application
delete pApplicationInfo;
pApplicationInfo = NULL;
goto Finished;
}
// hosting model check. We do not allow mixed scenario for now
// could be changed in the future
if (m_hostingModel != HOSTING_UNKNOWN)
{
if (m_hostingModel != pConfig->QueryHostingModel())
{
// hosting model does not match, error out
fMixedHostingModelError = TRUE;
hr = HRESULT_FROM_WIN32(ERROR_APP_INIT_FAILURE);
goto Finished;
}
}
hr = pApplicationInfo->Initialize(pConfig, m_pFileWatcher);
if (FAILED(hr))
{
goto Finished;
}
hr = m_pApplicationInfoHash->InsertRecord( pApplicationInfo );
if (FAILED(hr))
{
goto Finished;
}
//
// first application will decide which hosting model allowed by this process
//
if (m_hostingModel == HOSTING_UNKNOWN)
{
m_hostingModel = pConfig->QueryHostingModel();
}
*ppApplicationInfo = pApplicationInfo;
pApplicationInfo->StartMonitoringAppOffline();
// Release the locko after starting to monitor for app offline to avoid races with it being dropped.
ReleaseSRWLockExclusive(&m_srwLock);
fExclusiveLock = FALSE;
pApplicationInfo = NULL;
}
Finished:
if (fExclusiveLock)
{
ReleaseSRWLockExclusive(&m_srwLock);
}
if (pApplicationInfo != NULL)
{
pApplicationInfo->DereferenceApplicationInfo();
pApplicationInfo = NULL;
}
if (FAILED(hr))
{
if (fDuplicatedInProcessApp)
{
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
pszApplicationId)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP,
strEventMsg.QueryStr());
}
}
else if (fMixedHostingModelError)
{
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
pszApplicationId,
pConfig->QueryHostingModel())))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
strEventMsg.QueryStr());
}
}
else
{
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG,
pszApplicationId,
hr)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_ADD_APPLICATION_ERROR,
strEventMsg.QueryStr());
}
}
}
return hr;
}
//
// If the application's configuration was changed,
// append the configuration path to the config change context.
//
BOOL
APPLICATION_MANAGER::FindConfigChangedApplication(
_In_ APPLICATION_INFO * pEntry,
_In_ PVOID pvContext)
{
DBG_ASSERT(pEntry);
DBG_ASSERT(pvContext);
// Config Change context contains the original config path that changed
// and a multiStr containing
CONFIG_CHANGE_CONTEXT* pContext = static_cast<CONFIG_CHANGE_CONTEXT*>(pvContext);
STRU* pstruConfigPath = pEntry->QueryConfig()->QueryConfigPath();
// check if the application path contains our app/subapp by seeing if the config path
// starts with the notification path.
BOOL fChanged = pstruConfigPath->StartsWith(pContext->pstrPath, true);
if (fChanged)
{
DWORD dwLen = (DWORD)wcslen(pContext->pstrPath);
WCHAR wChar = pstruConfigPath->QueryStr()[dwLen];
// We need to check that the last character of the config path
// is either a null terminator or a slash.
// This checks the case where the config path was
// MACHINE/WEBROOT/site and your site path is MACHINE/WEBROOT/siteTest
if (wChar != L'\0' && wChar != L'/')
{
// not current app or sub app
fChanged = FALSE;
}
else
{
pContext->MultiSz.Append(*pstruConfigPath);
}
}
return fChanged;
}
//
// Finds any applications affected by a configuration change and calls Recycle on them
// InProcess: Triggers g_httpServer->RecycleProcess() and keep the application inside of the manager.
// This will cause a shutdown event to occur through the global stop listening event.
// OutOfProcess: Removes all applications in the application manager and calls Recycle, which will call Shutdown,
// on each application.
//
HRESULT
APPLICATION_MANAGER::RecycleApplicationFromManager(
_In_ LPCWSTR pszApplicationId
)
{
HRESULT hr = S_OK;
APPLICATION_INFO_KEY key;
DWORD dwPreviousCounter = 0;
APPLICATION_INFO_HASH* table = NULL;
CONFIG_CHANGE_CONTEXT context;
BOOL fKeepTable = FALSE;
if (g_fInShutdown)
{
// We are already shutting down, ignore this event as a global configuration change event
// can occur after global stop listening for some reason.
return hr;
}
AcquireSRWLockExclusive(&m_srwLock);
if (g_fInShutdown)
{
ReleaseSRWLockExclusive(&m_srwLock);
return hr;
}
hr = key.Initialize(pszApplicationId);
if (FAILED(hr))
{
goto Finished;
}
// Make a shallow copy of existing hashtable as we may need to remove nodes
// This will be used for finding differences in which applications are affected by a config change.
table = new APPLICATION_INFO_HASH();
if (table == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
// few application expected, small bucket size for hash table
if (FAILED(hr = table->Initialize(17 /*prime*/)))
{
goto Finished;
}
context.pstrPath = pszApplicationId;
// Keep track of the preview count of applications to know whether there are applications to delete
dwPreviousCounter = m_pApplicationInfoHash->Count();
// We don't want to hold the application manager lock for long time as it will block all incoming requests
// Don't call application shutdown inside the lock
m_pApplicationInfoHash->Apply(APPLICATION_INFO_HASH::ReferenceCopyToTable, static_cast<PVOID>(table));
DBG_ASSERT(dwPreviousCounter == table->Count());
// Removed the applications which are impacted by the configurtion change
m_pApplicationInfoHash->DeleteIf(FindConfigChangedApplication, (PVOID)&context);
if (dwPreviousCounter != m_pApplicationInfoHash->Count())
{
if (m_hostingModel == HOSTING_IN_PROCESS)
{
// When we are inprocess, we need to keep the application the
// application manager that is being deleted. This is because we will always need to recycle the worker
// process and any requests that hit this worker process must be rejected (while out of process can
// start a new dotnet process). We will immediately call Recycle after this call.
DBG_ASSERT(m_pApplicationInfoHash->Count() == 0);
delete m_pApplicationInfoHash;
// We don't want to delete the table as m_pApplicationInfoHash = table
fKeepTable = TRUE;
m_pApplicationInfoHash = table;
}
}
if (m_pApplicationInfoHash->Count() == 0)
{
m_hostingModel = HOSTING_UNKNOWN;
}
ReleaseSRWLockExclusive(&m_srwLock);
// If we receive a request at this point.
// OutOfProcess: we will create a new application with new configuration
// InProcess: the request would have to be rejected, as we are about to call g_HttpServer->RecycleProcess
// on the worker proocess
if (!context.MultiSz.IsEmpty())
{
PCWSTR path = context.MultiSz.First();
// Iterate through each of the paths that were shut down,
// calling RecycleApplication on each of them.
while (path != NULL)
{
APPLICATION_INFO* pRecord;
// Application got recycled. Log an event
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG,
path)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_INFORMATION_TYPE,
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION,
strEventMsg.QueryStr());
}
hr = key.Initialize(path);
if (FAILED(hr))
{
goto Finished;
}
table->FindKey(&key, &pRecord);
DBG_ASSERT(pRecord != NULL);
// RecycleApplication is called on a separate thread.
pRecord->RecycleApplication();
pRecord->DereferenceApplicationInfo();
path = context.MultiSz.Next(path);
}
}
Finished:
if (table != NULL && !fKeepTable)
{
table->Clear();
delete table;
}
if (FAILED(hr))
{
// Failed to recycle an application. Log an event
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG,
pszApplicationId)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_RECYCLE_APP_FAILURE,
strEventMsg.QueryStr());
}
// Need to recycle the process as we cannot recycle the application
if (!g_fRecycleProcessCalled)
{
g_fRecycleProcessCalled = TRUE;
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand Due Application Recycle Error");
}
}
return hr;
}
//
// Shutsdown all applications in the application hashtable
// Only called by OnGlobalStopListening.
//
VOID
APPLICATION_MANAGER::ShutDown()
{
// We are guaranteed to only have one outstanding OnGlobalStopListening event at a time
// However, it is possible to receive multiple OnGlobalStopListening events
// Protect against this by checking if we already shut down.
g_fInShutdown = TRUE;
if (m_pApplicationInfoHash != NULL)
{
if (m_pFileWatcher != NULL)
{
delete m_pFileWatcher;
m_pFileWatcher = NULL;
}
DBG_ASSERT(m_pApplicationInfoHash);
// During shutdown we lock until we delete the application
AcquireSRWLockExclusive(&m_srwLock);
// Call shutdown on each application in the application manager
m_pApplicationInfoHash->Apply(ShutdownApplication, NULL);
m_pApplicationInfoHash->Clear();
delete m_pApplicationInfoHash;
m_pApplicationInfoHash = NULL;
ReleaseSRWLockExclusive(&m_srwLock);
}
}
//
// Calls shutdown on each application. ApplicationManager's lock is held for duration of
// each shutdown call, guaranteeing another application cannot be created.
//
// static
VOID
APPLICATION_MANAGER::ShutdownApplication(
_In_ APPLICATION_INFO * pEntry,
_In_ PVOID pvContext
)
{
UNREFERENCED_PARAMETER(pvContext);
DBG_ASSERT(pEntry != NULL);
pEntry->ShutDownApplication();
}

View File

@ -1,254 +0,0 @@
// Copyright (c) .NET Foundation. 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;
HANDLE g_hEventLog = NULL;
BOOL g_fRecycleProcessCalled = FALSE;
PCWSTR g_pszModuleName = NULL;
HINSTANCE g_hModule;
HMODULE g_hAspnetCoreRH = NULL;
BOOL g_fAspnetcoreRHAssemblyLoaded = FALSE;
BOOL g_fAspnetcoreRHLoadedError = FALSE;
BOOL g_fInShutdown = FALSE;
DWORD g_dwAspNetCoreDebugFlags = 0;
DWORD g_dwActiveServerProcesses = 0;
SRWLOCK g_srwLock;
DWORD g_dwDebugFlags = 0;
PCSTR g_szDebugLabel = "ASPNET_CORE_MODULE";
PCWSTR g_pwzAspnetcoreRequestHandlerName = L"aspnetcorerh.dll";
PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
VOID
StaticCleanup()
{
APPLICATION_MANAGER::Cleanup();
if (g_hEventLog != NULL)
{
DeregisterEventSource(g_hEventLog);
g_hEventLog = NULL;
}
}
BOOL WINAPI DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_PROCESS_DETACH:
// IIS can cause dll detach to occur before we receive global notifications
// For example, when we switch the bitness of the worker process,
// this is a bug in IIS. To try to avoid AVs, we will set a global flag
g_fInShutdown = TRUE;
StaticCleanup();
default:
break;
}
return 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;
HKEY hKey;
BOOL fDisableANCM = FALSE;
ASPNET_CORE_PROXY_MODULE_FACTORY * pFactory = NULL;
ASPNET_CORE_GLOBAL_MODULE * pGlobalModule = NULL;
APPLICATION_MANAGER * pApplicationManager = NULL;
UNREFERENCED_PARAMETER(dwServerVersion);
#ifdef DEBUG
CREATE_DEBUG_PRINT_OBJECT("Asp.Net Core Module");
g_dwDebugFlags = DEBUG_FLAGS_ANY;
#endif // DEBUG
CREATE_DEBUG_PRINT_OBJECT;
//LoadGlobalConfiguration();
InitializeSRWLock(&g_srwLock);
g_pModuleId = pModuleInfo->GetId();
g_pszModuleName = pModuleInfo->GetName();
g_pHttpServer = pHttpServer;
if (g_pHttpServer->IsCommandLineLaunch())
{
g_hEventLog = RegisterEventSource(NULL, ASPNETCORE_IISEXPRESS_EVENT_PROVIDER);
}
else
{
g_hEventLog = RegisterEventSource(NULL, ASPNETCORE_EVENT_PROVIDER);
}
// check whether the feature is disabled due to security reason
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"DisableANCM",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
fDisableANCM = (dwData != 0);
}
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"DebugFlags",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
g_dwAspNetCoreDebugFlags = dwData;
}
RegCloseKey(hKey);
}
if (fDisableANCM)
{
// Logging
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_MODULE_DISABLED_MSG)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_WARNING_TYPE,
ASPNETCORE_EVENT_MODULE_DISABLED,
strEventMsg.QueryStr());
}
// this will return 500 error to client
// as we did not register the module
goto Finished;
}
//
// Create the factory before any static initialization.
// The ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate method will clean any
// static object initialized.
//
pFactory = new ASPNET_CORE_PROXY_MODULE_FACTORY;
if (pFactory == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pModuleInfo->SetRequestNotifications(
pFactory,
RQ_EXECUTE_REQUEST_HANDLER,
0);
if (FAILED(hr))
{
goto Finished;
}
pFactory = NULL;
pApplicationManager = APPLICATION_MANAGER::GetInstance();
if(pApplicationManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pApplicationManager->Initialize();
if(FAILED(hr))
{
goto Finished;
}
pGlobalModule = NULL;
pGlobalModule = new ASPNET_CORE_GLOBAL_MODULE(pApplicationManager);
if (pGlobalModule == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pModuleInfo->SetGlobalNotifications(
pGlobalModule,
GL_CONFIGURATION_CHANGE | // Configuration change trigers IIS application stop
GL_STOP_LISTENING); // worker process stop or recycle
if (FAILED(hr))
{
goto Finished;
}
pGlobalModule = NULL;
hr = ALLOC_CACHE_HANDLER::StaticInitialize();
if (FAILED(hr))
{
goto Finished;
}
Finished:
if (pGlobalModule != NULL)
{
delete pGlobalModule;
pGlobalModule = NULL;
}
if (pFactory != NULL)
{
pFactory->Terminate();
pFactory = NULL;
}
return hr;
}

View File

@ -1,497 +0,0 @@
// Copyright (c) .NET Foundation. 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),
m_fThreadExit(FALSE)
{
}
FILE_WATCHER::~FILE_WATCHER()
{
if (m_hChangeNotificationThread != NULL)
{
DWORD dwRetryCounter = 20; // totally wait for 1s
DWORD dwExitCode = STILL_ACTIVE;
// signal the file watch thread to exit
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
while (!m_fThreadExit && dwRetryCounter > 0)
{
if (GetExitCodeThread(m_hChangeNotificationThread, &dwExitCode))
{
if (dwExitCode == STILL_ACTIVE)
{
// the file watcher thread will set m_fThreadExit before exit
WaitForSingleObject(m_hChangeNotificationThread, 50);
}
}
else
{
// fail to get thread status
// call terminitethread
TerminateThread(m_hChangeNotificationThread, 1);
m_fThreadExit = TRUE;
}
dwRetryCounter--;
}
if (!m_fThreadExit)
{
TerminateThread(m_hChangeNotificationThread, 1);
}
CloseHandle(m_hChangeNotificationThread);
m_hChangeNotificationThread = NULL;
}
if (NULL != m_hCompletionPort)
{
CloseHandle(m_hCompletionPort);
m_hCompletionPort = 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);
dwErrorStatus = fSuccess ? ERROR_SUCCESS : GetLastError();
if (completionKey == FILE_WATCHER_SHUTDOWN_KEY)
{
break;
}
DBG_ASSERT(pOverlapped != NULL);
if (pOverlapped != NULL)
{
FileWatcherCompletionRoutine(
dwErrorStatus,
cbCompletion,
pOverlapped);
}
pOverlapped = NULL;
cbCompletion = 0;
}
pFileMonitor->m_fThreadExit = TRUE;
ExitThread(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);
DBG_ASSERT(pMonitorEntry != NULL);
pMonitorEntry->HandleChangeCompletion(dwCompletionStatus, cbCompletion);
if (pMonitorEntry->QueryIsValid())
{
//
// Continue monitoring
//
pMonitorEntry->Monitor();
}
//
// Deference the counter not matter whether the monitor is valid
// Valid: Monitor increases the counter, need to reduce one
// InValid: Reduce the counter to free the entry
//
pMonitorEntry->DereferenceFileWatcherEntry();
}
FILE_WATCHER_ENTRY::FILE_WATCHER_ENTRY(FILE_WATCHER * pFileMonitor) :
_pFileMonitor(pFileMonitor),
_hDirectory(INVALID_HANDLE_VALUE),
_hImpersonationToken(NULL),
_pApplicationInfo(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;
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)
{
//
// so far we only monitoring app_offline
//
_pApplicationInfo->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());
DereferenceFileWatcherEntry();
}
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);
if (_hDirectory != INVALID_HANDLE_VALUE)
{
AcquireSRWLockExclusive(&_srwLock);
if (_hDirectory != INVALID_HANDLE_VALUE)
{
CloseHandle(_hDirectory);
_hDirectory = INVALID_HANDLE_VALUE;
DereferenceFileWatcherEntry();
}
ReleaseSRWLockExclusive(&_srwLock);
}
}
HRESULT
FILE_WATCHER_ENTRY::Create(
_In_ PCWSTR pszDirectoryToMonitor,
_In_ PCWSTR pszFileNameToMonitor,
_In_ APPLICATION_INFO* pApplicationInfo,
_In_ HANDLE hImpersonationToken
)
{
HRESULT hr = S_OK;
BOOL fRet = FALSE;
if (pszDirectoryToMonitor == NULL ||
pszFileNameToMonitor == NULL ||
pApplicationInfo == NULL)
{
DBG_ASSERT(FALSE);
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
goto Finished;
}
//
//remember the application
//
_pApplicationInfo = pApplicationInfo;
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;
}

View File

@ -1,65 +0,0 @@
#include "precomp.hxx"
ASPNET_CORE_GLOBAL_MODULE::ASPNET_CORE_GLOBAL_MODULE(
APPLICATION_MANAGER* pApplicationManager)
{
m_pApplicationManager = pApplicationManager;
}
//
// Is called when IIS decided to terminate worker process
// Shut down all core apps
//
GLOBAL_NOTIFICATION_STATUS
ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening(
_In_ IGlobalStopListeningProvider * pProvider
)
{
UNREFERENCED_PARAMETER(pProvider);
if (g_fInShutdown)
{
// Avoid receiving two shutudown notifications.
return GL_NOTIFICATION_CONTINUE;
}
DBG_ASSERT(m_pApplicationManager);
// we should let application manager to shutdown all allication
// and dereference it as some requests may still reference to application manager
m_pApplicationManager->ShutDown();
m_pApplicationManager = NULL;
// Return processing to the pipeline.
return GL_NOTIFICATION_CONTINUE;
}
//
// Is called when configuration changed
// Recycled the corresponding core app if its configuration changed
//
GLOBAL_NOTIFICATION_STATUS
ASPNET_CORE_GLOBAL_MODULE::OnGlobalConfigurationChange(
_In_ IGlobalConfigurationChangeProvider * pProvider
)
{
if (g_fInShutdown)
{
return GL_NOTIFICATION_CONTINUE;
}
// Retrieve the path that has changed.
PCWSTR pwszChangePath = pProvider->GetChangePath();
// Test for an error.
if (NULL != pwszChangePath &&
_wcsicmp(pwszChangePath, L"MACHINE") != 0 &&
_wcsicmp(pwszChangePath, L"MACHINE/WEBROOT") != 0)
{
if (m_pApplicationManager != NULL)
{
m_pApplicationManager->RecycleApplicationFromManager(pwszChangePath);
}
}
// Return processing to the pipeline.
return GL_NOTIFICATION_CONTINUE;
}

View File

@ -1,159 +0,0 @@
// 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>
#include <cstdlib>
#include <vector>
#include <wchar.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
#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 "dbgutil.h"
#include "ahutil.h"
#include "multisz.h"
#include "multisza.h"
#include "base64.h"
#include <listentry.h>
#include <datetime.h>
#include <reftrace.h>
#include <acache.h>
#include <time.h>
#include "..\..\CommonLib\environmentvariablehash.h"
#include "..\..\CommonLib\aspnetcoreconfig.h"
#include "..\..\CommonLib\hostfxr_utility.h"
#include "..\..\CommonLib\application.h"
#include "..\..\CommonLib\utility.h"
#include "..\..\CommonLib\debugutil.h"
#include "..\..\CommonLib\requesthandler.h"
#include "..\..\CommonLib\resources.h"
#include "..\..\CommonLib\aspnetcore_msg.h"
//#include "aspnetcore_event.h"
#include "appoffline.h"
#include "filewatcher.h"
#include "applicationinfo.h"
#include "applicationmanager.h"
#include "globalmodule.h"
#include "proxymodule.h"
#include "applicationinfo.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 PVOID g_pModuleId;
extern BOOL g_fAspnetcoreRHAssemblyLoaded;
extern BOOL g_fAspnetcoreRHLoadedError;
extern BOOL g_fInShutdown;
extern BOOL g_fEnableReferenceCountTracing;
extern DWORD g_dwActiveServerProcesses;
extern HINSTANCE g_hModule;
extern HMODULE g_hAspnetCoreRH;
extern SRWLOCK g_srwLock;
extern PCWSTR g_pwzAspnetcoreRequestHandlerName;
extern HANDLE g_hEventLog;
extern PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
extern PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
#pragma warning( error : 4091)

View File

@ -1,211 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
__override
HRESULT
ASPNET_CORE_PROXY_MODULE_FACTORY::GetHttpModule(
CHttpModule ** ppModule,
IModuleAllocator * pAllocator
)
{
ASPNET_CORE_PROXY_MODULE *pModule = new (pAllocator) ASPNET_CORE_PROXY_MODULE();
if (pModule == NULL)
{
return E_OUTOFMEMORY;
}
*ppModule = pModule;
return S_OK;
}
__override
VOID
ASPNET_CORE_PROXY_MODULE_FACTORY::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();*/
ALLOC_CACHE_HANDLER::StaticTerminate();
delete this;
}
ASPNET_CORE_PROXY_MODULE::ASPNET_CORE_PROXY_MODULE(
) : m_pApplicationInfo(NULL), m_pHandler(NULL)
{
}
ASPNET_CORE_PROXY_MODULE::~ASPNET_CORE_PROXY_MODULE()
{
if (m_pApplicationInfo != NULL)
{
m_pApplicationInfo->DereferenceApplicationInfo();
m_pApplicationInfo = NULL;
}
if (m_pHandler != NULL)
{
m_pHandler->DereferenceRequestHandler();
m_pHandler = NULL;
}
}
__override
REQUEST_NOTIFICATION_STATUS
ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
IHttpContext * pHttpContext,
IHttpEventProvider *
)
{
HRESULT hr = S_OK;
ASPNETCORE_CONFIG *pConfig = NULL;
APPLICATION_MANAGER *pApplicationManager = NULL;
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
APPLICATION* pApplication = NULL;
STACK_STRU(struFileName, 256);
if (g_fInShutdown)
{
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
goto Finished;
}
hr = ASPNETCORE_CONFIG::GetConfig(g_pHttpServer, g_pModuleId, pHttpContext, g_hEventLog, &pConfig);
if (FAILED(hr))
{
goto Finished;
}
pApplicationManager = APPLICATION_MANAGER::GetInstance();
if (pApplicationManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pApplicationManager->GetOrCreateApplicationInfo(
g_pHttpServer,
pConfig,
&m_pApplicationInfo);
if (FAILED(hr))
{
goto Finished;
}
// app_offline check to avoid loading aspnetcorerh.dll unnecessarily
if (m_pApplicationInfo->AppOfflineFound())
{
// servicing app_offline
HTTP_DATA_CHUNK DataChunk;
IHttpResponse *pResponse = NULL;
APP_OFFLINE_HTM *pAppOfflineHtm = NULL;
pResponse = pHttpContext->GetResponse();
pAppOfflineHtm = m_pApplicationInfo->QueryAppOfflineHtm();
DBG_ASSERT(pAppOfflineHtm);
DBG_ASSERT(pResponse);
// Ignore failure hresults as nothing we can do
// Set fTrySkipCustomErrors to true as we want client see the offline content
pResponse->SetStatus(503, "Service Unavailable", 0, hr, NULL, TRUE);
pResponse->SetHeader("Content-Type",
"text/html",
(USHORT)strlen("text/html"),
FALSE
);
DataChunk.DataChunkType = HttpDataChunkFromMemory;
DataChunk.FromMemory.pBuffer = (PVOID)pAppOfflineHtm->m_Contents.QueryStr();
DataChunk.FromMemory.BufferLength = pAppOfflineHtm->m_Contents.QueryCB();
pResponse->WriteEntityChunkByReference(&DataChunk);
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
goto Finished;
}
// make sure assmebly is loaded and application is created
hr = m_pApplicationInfo->EnsureApplicationCreated();
if (FAILED(hr))
{
goto Finished;
}
m_pApplicationInfo->ExtractApplication(&pApplication);
// make sure application is in running state
// cannot recreate the application as we cannot reload clr for inprocess
if (pApplication != NULL &&
pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING &&
pApplication->QueryStatus() != APPLICATION_STATUS::STARTING)
{
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
goto Finished;
}
// Create RequestHandler and process the request
hr = m_pApplicationInfo->QueryCreateRequestHandler()(pHttpContext,
(HTTP_MODULE_ID*) &g_pModuleId,
pApplication,
&m_pHandler);
if (FAILED(hr))
{
goto Finished;
}
retVal = m_pHandler->OnExecuteRequestHandler();
Finished:
if (FAILED(hr))
{
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
if (hr == HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS))
{
pHttpContext->GetResponse()->SetStatus(503, "Service Unavailable", 0, hr);
}
else
{
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
}
}
if (pApplication != NULL)
{
pApplication->DereferenceApplication();
}
return retVal;
}
__override
REQUEST_NOTIFICATION_STATUS
ASPNET_CORE_PROXY_MODULE::OnAsyncCompletion(
IHttpContext *,
DWORD,
BOOL,
IHttpEventProvider *,
IHttpCompletionInfo * pCompletionInfo
)
{
return m_pHandler->OnAsyncCompletion(
pCompletionInfo->GetCompletionBytes(),
pCompletionInfo->GetCompletionStatus());
}

View File

@ -1,226 +0,0 @@
<?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="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{55494E58-E061-4C4C-A0A8-837008E72F85}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>NewCommon</RootNamespace>
<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)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<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|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</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 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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<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|x64'">
<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)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>C:\AspNetCoreModule\src\IISLib;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ShowIncludes>false</ShowIncludes>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalLibraryDirectories>..\iislib</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="application.h" />
<ClInclude Include="aspnetcoreconfig.h" />
<ClInclude Include="debugutil.h" />
<ClInclude Include="disconnectcontext.h" />
<ClInclude Include="environmentvariablehash.h" />
<ClInclude Include="fx_ver.h" />
<ClInclude Include="hostfxr_utility.h" />
<ClInclude Include="requesthandler.h" />
<ClInclude Include="resources.h" />
<ClInclude Include="SRWLockWrapper.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="utility.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="application.cpp" />
<ClCompile Include="aspnetcoreconfig.cxx" />
<ClCompile Include="fx_ver.cxx" />
<ClCompile Include="hostfxr_utility.cpp" />
<ClCompile Include="requesthandler.cxx" />
<ClCompile Include="SRWLockWrapper.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="utility.cxx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="aspnetcore_msg.mc">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">mc %(FullPath)</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compiling Event Messages ...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).rc;%(Filename).h;MSG0409.bin</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,13 +0,0 @@
#include "stdafx.h"
#include "SRWLockWrapper.h"
SRWLockWrapper::SRWLockWrapper(const SRWLOCK& lock)
: m_lock(lock)
{
AcquireSRWLockExclusive(const_cast<SRWLOCK*>(&m_lock));
}
SRWLockWrapper::~SRWLockWrapper()
{
ReleaseSRWLockExclusive(const_cast<SRWLOCK*>(&m_lock));
}

View File

@ -1,9 +0,0 @@
#pragma once
class SRWLockWrapper
{
public:
SRWLockWrapper(const SRWLOCK& lock);
~SRWLockWrapper();
private:
const SRWLOCK& m_lock;
};

View File

@ -1,50 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
APPLICATION::APPLICATION(
_In_ IHttpServer* pHttpServer,
_In_ ASPNETCORE_CONFIG* pConfig) :
m_cRefs(1),
m_pConfig(pConfig),
m_status(APPLICATION_STATUS::UNKNOWN)
{
UNREFERENCED_PARAMETER(pHttpServer);
}
APPLICATION::~APPLICATION()
{
}
APPLICATION_STATUS
APPLICATION::QueryStatus()
{
return m_status;
}
ASPNETCORE_CONFIG*
APPLICATION::QueryConfig()
{
return m_pConfig;
}
VOID
APPLICATION::ReferenceApplication()
const
{
InterlockedIncrement(&m_cRefs);
}
VOID
APPLICATION::DereferenceApplication()
const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}

View File

@ -1,53 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
enum APPLICATION_STATUS
{
UNKNOWN = 0,
STARTING,
RUNNING,
SHUTDOWN,
FAIL
};
class ASPNETCORE_CONFIG;
class APPLICATION
{
public:
APPLICATION(
_In_ IHttpServer* pHttpServer,
_In_ ASPNETCORE_CONFIG* pConfig);
virtual
VOID
ShutDown() = 0;
virtual
VOID
Recycle() = 0;
virtual
~APPLICATION();
APPLICATION_STATUS
QueryStatus();
ASPNETCORE_CONFIG*
QueryConfig();
VOID
ReferenceApplication()
const;
VOID
DereferenceApplication()
const;
protected:
mutable LONG m_cRefs;
volatile APPLICATION_STATUS m_status;
ASPNETCORE_CONFIG* m_pConfig;
};

View File

@ -1,217 +0,0 @@
;/*++
;
; Copyright (c) .NET Foundation. All rights reserved.
; Licensed under the MIT License. See License.txt in the project root for license information.
;
;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=1007
SymbolicName=ASPNETCORE_EVENT_LOAD_CLR_FALIURE
Language=English
%1
.
Messageid=1008
SymbolicName=ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP
Language=English
%1
.
Messageid=1009
SymbolicName=ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR
Language=English
%1
.
Messageid=1010
SymbolicName=ASPNETCORE_EVENT_ADD_APPLICATION_ERROR
Language=English
%1
.
Messageid=1011
SymbolicName=ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT
Language=English
%1
.
Messageid=1012
SymbolicName=ASPNETCORE_EVENT_RECYCLE_APPOFFLINE
Language=English
%1
.
Messageid=1013
SymbolicName=ASPNETCORE_EVENT_MODULE_DISABLED
Language=English
%1
.
Messageid=1014
SymbolicName=ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP
Language=English
%1
.
Messageid=1015
SymbolicName=ASPNETCORE_EVENT_PORTABLE_APP_DOTNET_MISSING
Language=English
%1
.
Messageid=1016
SymbolicName=ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND
Language=English
%1
.
Messageid=1017
SymbolicName=ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND
Language=English
%1
.
Messageid=1018
SymbolicName=ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION
Language=English
%1
.
Messageid=1019
SymbolicName=ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND
Language=English
%1
.
Messageid=1020
SymbolicName=ASPNETCORE_EVENT_PROCESS_START_FAILURE
Language=English
%1
.
Messageid=1021
SymbolicName=ASPNETCORE_EVENT_RECYCLE_CONFIGURATION
Language=English
%1
.
Messageid=1022
SymbolicName=ASPNETCORE_EVENT_RECYCLE_APP_FAILURE
Language=English
%1
.
Messageid=1023
SymbolicName=ASPNETCORE_EVENT_APP_IN_SHUTDOWN
Language=English
%1
.
Messageid=1024
SymbolicName=ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_REMOVED
Language=English
%1
.
Messageid=1025
SymbolicName=ASPNETCORE_EVENT_GENERAL_INFO_MSG
Language=English
%1
.
Messageid=1026
SymbolicName=ASPNETCORE_EVENT_GENERAL_WARNING_MSG
Language=English
%1
.
Messageid=1027
SymbolicName=ASPNETCORE_EVENT_GENERAL_ERROR_MSG
Language=English
%1
.
Messageid=1028
SymbolicName=ASPNETCORE_EVENT_INPROCESS_RH_MISSING
Language=English
%1
.
Messageid=1029
SymbolicName=ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING
Language=English
%1
.
Messageid=1030
SymbolicName=ASPNETCORE_EVENT_PROCESS_SHUTDOWN
Language=English
%1
.
;
;#endif // _ASPNETCORE_MODULE_MSG_H_
;

View File

@ -1,609 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
#include "aspnetcoreconfig.h"
#include "debugutil.h"
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
{
if (m_ppStrArguments != NULL)
{
delete[] m_ppStrArguments;
m_ppStrArguments = NULL;
}
if (m_pEnvironmentVariables != NULL)
{
m_pEnvironmentVariables->Clear();
delete m_pEnvironmentVariables;
m_pEnvironmentVariables = NULL;
}
}
VOID
ASPNETCORE_CONFIG::ReferenceConfiguration(
VOID
) const
{
InterlockedIncrement(&m_cRefs);
}
VOID
ASPNETCORE_CONFIG::DereferenceConfiguration(
VOID
) const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}
HRESULT
ASPNETCORE_CONFIG::GetConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpContext *pHttpContext,
_In_ HANDLE hEventLog,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
)
{
HRESULT hr = S_OK;
IHttpApplication *pHttpApplication = pHttpContext->GetApplication();
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
STRU struHostFxrDllLocation;
PWSTR* pwzArgv;
DWORD dwArgCount;
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(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(pHttpServer, pHttpContext);
if (FAILED(hr))
{
goto Finished;
}
// Modify config for inprocess.
if (pAspNetCoreConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
{
if (FAILED(hr = HOSTFXR_UTILITY::GetHostFxrParameters(
hEventLog,
pAspNetCoreConfig->QueryProcessPath()->QueryStr(),
pAspNetCoreConfig->QueryApplicationPhysicalPath()->QueryStr(),
pAspNetCoreConfig->QueryArguments()->QueryStr(),
&struHostFxrDllLocation,
&dwArgCount,
&pwzArgv)))
{
goto Finished;
}
if (FAILED(hr = pAspNetCoreConfig->SetHostFxrFullPath(struHostFxrDllLocation.QueryStr())))
{
goto Finished;
}
pAspNetCoreConfig->SetHostFxrArguments(dwArgCount, pwzArgv);
}
hr = pHttpApplication->GetModuleContextContainer()->
SetModuleContext(pAspNetCoreConfig, pModuleId);
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
{
delete pAspNetCoreConfig;
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
GetModuleContextContainer()->
GetModuleContext(pModuleId);
_ASSERT(pAspNetCoreConfig != NULL);
hr = S_OK;
}
else
{
goto Finished;
}
}
else
{
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"ASPNETCORE_CONFIG::GetConfig, set config to ModuleContext");
// 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(
IHttpServer *pHttpServer,
IHttpContext *pHttpContext
)
{
STACK_STRU(strHostingModel, 300);
HRESULT hr = S_OK;
STRU strEnvName;
STRU strEnvValue;
STRU strExpandedEnvValue;
STRU strApplicationFullPath;
IAppHostAdminManager *pAdminManager = NULL;
IAppHostElement *pAspNetCoreElement = NULL;
IAppHostElement *pWindowsAuthenticationElement = NULL;
IAppHostElement *pBasicAuthenticationElement = NULL;
IAppHostElement *pAnonymousAuthenticationElement = NULL;
IAppHostElement *pWebSocketElement = NULL;
IAppHostElement *pEnvVarList = NULL;
IAppHostElement *pEnvVar = NULL;
IAppHostElementCollection *pEnvVarCollection = NULL;
ULONGLONG ullRawTimeSpan = 0;
ENUM_INDEX index;
ENVIRONMENT_VAR_ENTRY* pEntry = NULL;
DWORD dwCounter = 0;
DWORD dwPosition = 0;
WCHAR* pszPath = NULL;
BSTR bstrWindowAuthSection = NULL;
BSTR bstrBasicAuthSection = NULL;
BSTR bstrAnonymousAuthSection = NULL;
BSTR bstrAspNetCoreSection = NULL;
BSTR bstrWebsocketSection = 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 = pHttpServer->GetAdminManager();
hr = m_struConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
if (FAILED(hr))
{
goto Finished;
}
hr = m_struApplicationPhysicalPath.Copy(pHttpContext->GetApplication()->GetApplicationPhysicalPath());
if (FAILED(hr))
{
goto Finished;
}
pszPath = m_struConfigPath.QueryStr();
while (pszPath[dwPosition] != NULL)
{
if (pszPath[dwPosition] == '/')
{
dwCounter++;
if (dwCounter == 4)
break;
}
dwPosition++;
}
if (dwCounter == 4)
{
hr = m_struApplicationVirtualPath.Copy(pszPath + dwPosition);
}
else
{
hr = m_struApplicationVirtualPath.Copy(L"/");
}
// Will setup the application virtual path.
if (FAILED(hr))
{
goto Finished;
}
bstrWindowAuthSection = SysAllocString(CS_WINDOWS_AUTHENTICATION_SECTION);
if (bstrWindowAuthSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrWindowAuthSection,
m_struConfigPath.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_ENABLED,
&m_fWindowsAuthEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
bstrBasicAuthSection = SysAllocString(CS_BASIC_AUTHENTICATION_SECTION);
if (bstrBasicAuthSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrBasicAuthSection,
m_struConfigPath.QueryStr(),
&pBasicAuthenticationElement);
if (FAILED(hr))
{
m_fBasicAuthEnabled = FALSE;
}
else
{
hr = GetElementBoolProperty(pBasicAuthenticationElement,
CS_ENABLED,
&m_fBasicAuthEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
bstrAnonymousAuthSection = SysAllocString(CS_ANONYMOUS_AUTHENTICATION_SECTION);
if (bstrAnonymousAuthSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrAnonymousAuthSection,
m_struConfigPath.QueryStr(),
&pAnonymousAuthenticationElement);
if (FAILED(hr))
{
m_fAnonymousAuthEnabled = FALSE;
}
else
{
hr = GetElementBoolProperty(pAnonymousAuthenticationElement,
CS_ENABLED,
&m_fAnonymousAuthEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
bstrWebsocketSection = SysAllocString(CS_WEBSOCKET_SECTION);
if (bstrWebsocketSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrWebsocketSection,
m_struConfigPath.QueryStr(),
&pWebSocketElement);
if (FAILED(hr))
{
m_fWebSocketEnabled = FALSE;
}
else
{
hr = GetElementBoolProperty(pWebSocketElement,
CS_ENABLED,
&m_fWebSocketEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
bstrAspNetCoreSection = SysAllocString(CS_ASPNETCORE_SECTION);
if (bstrAspNetCoreSection == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAdminManager->GetAdminSection(bstrAspNetCoreSection,
m_struConfigPath.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_HOSTING_MODEL,
&strHostingModel);
if (FAILED(hr))
{
// Swallow this error for backward compatability
// Use default behavior for empty string
hr = S_OK;
}
if (strHostingModel.IsEmpty() || strHostingModel.Equals(L"outofprocess", TRUE))
{
m_hostingModel = HOSTING_OUT_PROCESS;
}
else if (strHostingModel.Equals(L"inprocess", TRUE))
{
m_hostingModel = HOSTING_IN_PROCESS;
}
else
{
// block unknown hosting value
hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
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 (pWebSocketElement != NULL)
{
pWebSocketElement->Release();
pWebSocketElement = NULL;
}
if (pWindowsAuthenticationElement != NULL)
{
pWindowsAuthenticationElement->Release();
pWindowsAuthenticationElement = NULL;
}
if (pAnonymousAuthenticationElement != NULL)
{
pAnonymousAuthenticationElement->Release();
pAnonymousAuthenticationElement = NULL;
}
if (pBasicAuthenticationElement != NULL)
{
pBasicAuthenticationElement->Release();
pBasicAuthenticationElement = 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;
}

View File

@ -1,332 +0,0 @@
// Copyright (c) .NET Foundation. 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_WEBSOCKET_SECTION L"system.webServer/webSocket"
#define CS_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 CS_ASPNETCORE_HOSTING_MODEL L"hostingModel"
#define MAX_RAPID_FAILS_PER_MINUTE 100
#define MILLISECONDS_IN_ONE_SECOND 1000
#define MIN_PORT 1025
#define MAX_PORT 48000
#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)))
//#define HEX_TO_ASCII(c) ((CHAR)(((c) < 10) ? ((c) + '0') : ((c) + 'a' - 10)))
#include "stdafx.h"
enum APP_HOSTING_MODEL
{
HOSTING_UNKNOWN = 0,
HOSTING_IN_PROCESS,
HOSTING_OUT_PROCESS
};
class ASPNETCORE_CONFIG : IHttpStoredContext
{
public:
virtual
~ASPNETCORE_CONFIG();
VOID
CleanupStoredContext()
{
DereferenceConfiguration();
}
static
HRESULT
GetConfig(
_In_ IHttpServer *pHttpServer,
_In_ HTTP_MODULE_ID pModuleId,
_In_ IHttpContext *pHttpContext,
_In_ HANDLE hEventLog,
_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*
QueryApplicationPhysicalPath(
VOID
)
{
return &m_struApplicationPhysicalPath;
}
STRU*
QueryApplicationVirtualPath(
VOID
)
{
return &m_struApplicationVirtualPath;
}
STRU*
QueryProcessPath(
VOID
)
{
return &m_struProcessPath;
}
APP_HOSTING_MODEL
QueryHostingModel(
VOID
)
{
return m_hostingModel;
}
BOOL
QueryStdoutLogEnabled()
{
return m_fStdoutLogEnabled;
}
BOOL
QueryWebSocketEnabled()
{
return m_fWebSocketEnabled;
}
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;
}
STRU*
QueryConfigPath()
{
return &m_struConfigPath;
}
CONST
PCWSTR*
QueryHostFxrArguments(
VOID
)
{
return m_ppStrArguments;
}
CONST
DWORD
QueryHostFxrArgCount(
VOID
)
{
return m_dwArgc;
}
CONST
PCWSTR
QueryHostFxrFullPath(
VOID
)
{
return m_struHostFxrLocation.QueryStr();
}
HRESULT
SetHostFxrFullPath(
PCWSTR pStrHostFxrFullPath
)
{
return m_struHostFxrLocation.Copy(pStrHostFxrFullPath);
}
VOID
SetHostFxrArguments(
DWORD dwArgc,
PWSTR* ppStrArguments
)
{
if (m_ppStrArguments != NULL)
{
delete[] m_ppStrArguments;
}
m_dwArgc = dwArgc;
m_ppStrArguments = ppStrArguments;
}
VOID
ReferenceConfiguration(
VOID
) const;
VOID
DereferenceConfiguration(
VOID
) const;
private:
//
// private constructor
//
ASPNETCORE_CONFIG():
m_fStdoutLogEnabled( FALSE ),
m_pEnvironmentVariables( NULL ),
m_cRefs( 1 ),
m_hostingModel( HOSTING_UNKNOWN ),
m_ppStrArguments(NULL)
{
}
HRESULT
Populate(
IHttpServer *pHttpServer,
IHttpContext *pHttpContext
);
mutable LONG m_cRefs;
DWORD m_dwRequestTimeoutInMS;
DWORD m_dwStartupTimeLimitInMS;
DWORD m_dwShutdownTimeLimitInMS;
DWORD m_dwRapidFailsPerMinute;
DWORD m_dwProcessesPerApplication;
STRU m_struArguments;
STRU m_struProcessPath;
STRU m_struStdoutLogFile;
STRU m_struApplication;
STRU m_struApplicationPhysicalPath;
STRU m_struApplicationVirtualPath;
STRU m_struConfigPath;
BOOL m_fStdoutLogEnabled;
BOOL m_fForwardWindowsAuthToken;
BOOL m_fDisableStartUpErrorPage;
BOOL m_fWindowsAuthEnabled;
BOOL m_fBasicAuthEnabled;
BOOL m_fAnonymousAuthEnabled;
BOOL m_fWebSocketEnabled;
APP_HOSTING_MODEL m_hostingModel;
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
STRU m_struHostFxrLocation;
PWSTR* m_ppStrArguments;
DWORD m_dwArgc;
};

View File

@ -1,81 +0,0 @@
// Copyright (c) .NET Foundation. 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;
}

View File

@ -1,131 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#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_WEBSOCKETS_SUPPORTED_ENV_STR L"ASPNETCORE_IIS_WEBSOCKETS_SUPPORTED="
#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"
//
// 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();
}
private:
ENVIRONMENT_VAR_HASH(const ENVIRONMENT_VAR_HASH &);
void operator=(const ENVIRONMENT_VAR_HASH &);
};

View File

@ -1,192 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include "stdafx.h"
fx_ver_t::fx_ver_t(int major, int minor, int patch, const std::wstring& pre, const std::wstring& build)
: m_major(major)
, m_minor(minor)
, m_patch(patch)
, m_pre(pre)
, m_build(build)
{
}
fx_ver_t::fx_ver_t(int major, int minor, int patch, const std::wstring& pre)
: fx_ver_t(major, minor, patch, pre, TEXT(""))
{
}
fx_ver_t::fx_ver_t(int major, int minor, int patch)
: fx_ver_t(major, minor, patch, TEXT(""), TEXT(""))
{
}
bool fx_ver_t::operator ==(const fx_ver_t& b) const
{
return compare(*this, b) == 0;
}
bool fx_ver_t::operator !=(const fx_ver_t& b) const
{
return !operator ==(b);
}
bool fx_ver_t::operator <(const fx_ver_t& b) const
{
return compare(*this, b) < 0;
}
bool fx_ver_t::operator >(const fx_ver_t& b) const
{
return compare(*this, b) > 0;
}
bool fx_ver_t::operator <=(const fx_ver_t& b) const
{
return compare(*this, b) <= 0;
}
bool fx_ver_t::operator >=(const fx_ver_t& b) const
{
return compare(*this, b) >= 0;
}
std::wstring fx_ver_t::as_str() const
{
std::wstringstream stream;
stream << m_major << TEXT(".") << m_minor << TEXT(".") << m_patch;
if (!m_pre.empty())
{
stream << m_pre;
}
if (!m_build.empty())
{
stream << TEXT("+") << m_build;
}
return stream.str();
}
/* static */
int fx_ver_t::compare(const fx_ver_t&a, const fx_ver_t& b)
{
// compare(u.v.w-p+b, x.y.z-q+c)
if (a.m_major != b.m_major)
{
return (a.m_major > b.m_major) ? 1 : -1;
}
if (a.m_minor != b.m_minor)
{
return (a.m_minor > b.m_minor) ? 1 : -1;
}
if (a.m_patch != b.m_patch)
{
return (a.m_patch > b.m_patch) ? 1 : -1;
}
if (a.m_pre.empty() != b.m_pre.empty())
{
// Either a is empty or b is empty
return a.m_pre.empty() ? 1 : -1;
}
// Either both are empty or both are non-empty (may be equal)
int pre_cmp = a.m_pre.compare(b.m_pre);
if (pre_cmp != 0)
{
return pre_cmp;
}
return a.m_build.compare(b.m_build);
}
bool try_stou(const std::wstring& str, unsigned* num)
{
if (str.empty())
{
return false;
}
if (str.find_first_not_of(TEXT("0123456789")) != std::wstring::npos)
{
return false;
}
*num = (unsigned)std::stoul(str);
return true;
}
bool parse_internal(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production)
{
size_t maj_start = 0;
size_t maj_sep = ver.find(TEXT('.'));
if (maj_sep == std::wstring::npos)
{
return false;
}
unsigned major = 0;
if (!try_stou(ver.substr(maj_start, maj_sep), &major))
{
return false;
}
size_t min_start = maj_sep + 1;
size_t min_sep = ver.find(TEXT('.'), min_start);
if (min_sep == std::wstring::npos)
{
return false;
}
unsigned minor = 0;
if (!try_stou(ver.substr(min_start, min_sep - min_start), &minor))
{
return false;
}
unsigned patch = 0;
size_t pat_start = min_sep + 1;
size_t pat_sep = ver.find_first_not_of(TEXT("0123456789"), pat_start);
if (pat_sep == std::wstring::npos)
{
if (!try_stou(ver.substr(pat_start), &patch))
{
return false;
}
*fx_ver = fx_ver_t(major, minor, patch);
return true;
}
if (parse_only_production)
{
// This is a prerelease or has build suffix.
return false;
}
if (!try_stou(ver.substr(pat_start, pat_sep - pat_start), &patch))
{
return false;
}
size_t pre_start = pat_sep;
size_t pre_sep = ver.find(TEXT('+'), pre_start);
if (pre_sep == std::wstring::npos)
{
*fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start));
return true;
}
else
{
size_t build_start = pre_sep + 1;
*fx_ver = fx_ver_t(major, minor, patch, ver.substr(pre_start, pre_sep - pre_start), ver.substr(build_start));
return true;
}
}
/* static */
bool fx_ver_t::parse(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production)
{
bool valid = parse_internal(ver, fx_ver, parse_only_production);
assert(!valid || fx_ver->as_str() == ver);
return valid;
}

View File

@ -1,46 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#pragma once
// Note: This is not SemVer (esp., in comparing pre-release part, fx_ver_t does not
// compare multiple dot separated identifiers individually.) ex: 1.0.0-beta.2 vs. 1.0.0-beta.11
struct fx_ver_t
{
fx_ver_t(int major, int minor, int patch);
fx_ver_t(int major, int minor, int patch, const std::wstring& pre);
fx_ver_t(int major, int minor, int patch, const std::wstring& pre, const std::wstring& build);
int get_major() const { return m_major; }
int get_minor() const { return m_minor; }
int get_patch() const { return m_patch; }
void set_major(int m) { m_major = m; }
void set_minor(int m) { m_minor = m; }
void set_patch(int p) { m_patch = p; }
bool is_prerelease() const { return !m_pre.empty(); }
std::wstring as_str() const;
std::wstring prerelease_glob() const;
std::wstring patch_glob() const;
bool operator ==(const fx_ver_t& b) const;
bool operator !=(const fx_ver_t& b) const;
bool operator <(const fx_ver_t& b) const;
bool operator >(const fx_ver_t& b) const;
bool operator <=(const fx_ver_t& b) const;
bool operator >=(const fx_ver_t& b) const;
static bool parse(const std::wstring& ver, fx_ver_t* fx_ver, bool parse_only_production = false);
private:
int m_major;
int m_minor;
int m_patch;
std::wstring m_pre;
std::wstring m_build;
static int compare(const fx_ver_t&a, const fx_ver_t& b);
};

View File

@ -1,807 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
HOSTFXR_UTILITY::HOSTFXR_UTILITY()
{
}
HOSTFXR_UTILITY::~HOSTFXR_UTILITY()
{
}
//
// Runs a standalone appliction.
// The folder structure looks like this:
// Application/
// hostfxr.dll
// Application.exe
// Application.dll
// etc.
// We get the full path to hostfxr.dll and Application.dll and run hostfxr_main,
// passing in Application.dll.
// Assuming we don't need Application.exe as the dll is the actual application.
//
HRESULT
HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
PCWSTR pwzExeAbsolutePath, // includes .exe file extension.
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
HANDLE hEventLog,
_Inout_ STRU* struHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ PWSTR** ppwzArgv
)
{
HRESULT hr = S_OK;
STRU struDllPath;
STRU struArguments;
STRU struHostFxrPath;
STRU struRuntimeConfigLocation;
DWORD dwPosition;
// Obtain the app name from the processPath section.
if ( FAILED( hr = struDllPath.Copy( pwzExeAbsolutePath ) ) )
{
goto Finished;
}
dwPosition = struDllPath.LastIndexOf( L'.', 0 );
if ( dwPosition == -1 )
{
hr = E_FAIL;
goto Finished;
}
hr = UTILITY::ConvertPathToFullPath( L".\\hostfxr.dll", pcwzApplicationPhysicalPath, &struHostFxrPath );
if ( FAILED( hr ) )
{
goto Finished;
}
struDllPath.QueryStr()[dwPosition] = L'\0';
if (FAILED(hr = struDllPath.SyncWithBuffer()))
{
goto Finished;
}
if ( !UTILITY::CheckIfFileExists( struHostFxrPath.QueryStr() ) )
{
// Most likely a full framework app.
// Check that the runtime config file doesn't exist in the folder as another heuristic.
if (FAILED(hr = struRuntimeConfigLocation.Copy(struDllPath)) ||
FAILED(hr = struRuntimeConfigLocation.Append( L".runtimeconfig.json" )))
{
goto Finished;
}
if (!UTILITY::CheckIfFileExists(struRuntimeConfigLocation.QueryStr()))
{
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP,
ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_MSG,
pcwzApplicationPhysicalPath,
hr);
}
else
{
// If a runtime config file does exist, report a file not found on the app.exe
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND,
ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG,
pcwzApplicationPhysicalPath,
hr);
}
goto Finished;
}
if (FAILED(hr = struHostFxrDllLocation->Copy(struHostFxrPath)))
{
goto Finished;
}
if (FAILED(hr = struDllPath.Append(L".dll")))
{
goto Finished;
}
if (!UTILITY::CheckIfFileExists(struDllPath.QueryStr()))
{
// Treat access issue as File not found
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
goto Finished;
}
if (FAILED(hr = struArguments.Copy(struDllPath)) ||
FAILED(hr = struArguments.Append(L" ")) ||
FAILED(hr = struArguments.Append(pcwzArguments)))
{
goto Finished;
}
if (FAILED(hr = ParseHostfxrArguments(
struArguments.QueryStr(),
pwzExeAbsolutePath,
pcwzApplicationPhysicalPath,
hEventLog,
pdwArgCount,
ppwzArgv)))
{
goto Finished;
}
Finished:
return hr;
}
HRESULT
HOSTFXR_UTILITY::GetHostFxrParameters(
HANDLE hEventLog,
PCWSTR pcwzProcessPath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
_Inout_ STRU* struHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** pbstrArgv
)
{
HRESULT hr = S_OK;
STRU struSystemPathVariable;
STRU struAbsolutePathToHostFxr;
STRU struAbsolutePathToDotnet;
STRU struEventMsg;
STACK_STRU(struExpandedProcessPath, MAX_PATH);
STACK_STRU(struExpandedArguments, MAX_PATH);
// Copy and Expand the processPath and Arguments.
if (FAILED(hr = struExpandedProcessPath.CopyAndExpandEnvironmentStrings(pcwzProcessPath))
|| FAILED(hr = struExpandedArguments.CopyAndExpandEnvironmentStrings(pcwzArguments)))
{
goto Finished;
}
// Convert the process path an absolute path to our current application directory.
// If the path is already an absolute path, it will be unchanged.
hr = UTILITY::ConvertPathToFullPath(
struExpandedProcessPath.QueryStr(),
pcwzApplicationPhysicalPath,
&struAbsolutePathToDotnet
);
if (FAILED(hr))
{
goto Finished;
}
// Check if the absolute path is to dotnet or not.
if (struAbsolutePathToDotnet.EndsWith(L"dotnet.exe") || struAbsolutePathToDotnet.EndsWith(L"dotnet"))
{
//
// The processPath ends with dotnet.exe or dotnet
// like: C:\Program Files\dotnet\dotnet.exe, C:\Program Files\dotnet\dotnet, dotnet.exe, or dotnet.
// Get the absolute path to dotnet. If the path is already an absolute path, it will return that path
//
if (FAILED(hr = HOSTFXR_UTILITY::GetAbsolutePathToDotnet(&struAbsolutePathToDotnet))) // Make sure to append the dotnet.exe path correctly here (pass in regular path)?
{
goto Finished;
}
if (FAILED(hr = GetAbsolutePathToHostFxr(&struAbsolutePathToDotnet, hEventLog, &struAbsolutePathToHostFxr)))
{
goto Finished;
}
if (FAILED(hr = ParseHostfxrArguments(
struExpandedArguments.QueryStr(),
struAbsolutePathToDotnet.QueryStr(),
pcwzApplicationPhysicalPath,
hEventLog,
pdwArgCount,
pbstrArgv)))
{
goto Finished;
}
if (FAILED(hr = struHostFxrDllLocation->Copy(struAbsolutePathToHostFxr)))
{
goto Finished;
}
}
else
{
//
// The processPath is a path to the application executable
// like: C:\test\MyApp.Exe or MyApp.Exe
// Check if the file exists, and if it does, get the parameters for a standalone application
//
if (UTILITY::CheckIfFileExists(struAbsolutePathToDotnet.QueryStr()))
{
hr = GetStandaloneHostfxrParameters(
struAbsolutePathToDotnet.QueryStr(),
pcwzApplicationPhysicalPath,
struExpandedArguments.QueryStr(),
hEventLog,
struHostFxrDllLocation,
pdwArgCount,
pbstrArgv);
}
else
{
//
// If the processPath file does not exist and it doesn't include dotnet.exe or dotnet
// then it is an invalid argument.
//
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);;
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_GENERAL_ERROR_MSG,
ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG,
struExpandedProcessPath.QueryStr(),
hr);
}
}
Finished:
return hr;
}
//
// Forms the argument list in HOSTFXR_PARAMETERS.
// Sets the ArgCount and Arguments.
// Arg structure:
// argv[0] = Path to exe activating hostfxr.
// argv[1] = L"exec"
// argv[2] = absolute path to dll.
//
HRESULT
HOSTFXR_UTILITY::ParseHostfxrArguments(
PCWSTR pwzArgumentsFromConfig,
PCWSTR pwzExePath,
PCWSTR pcwzApplicationPhysicalPath,
HANDLE hEventLog,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** pbstrArgv
)
{
UNREFERENCED_PARAMETER( hEventLog ); // TODO use event log to set errors.
DBG_ASSERT(dwArgCount != NULL);
DBG_ASSERT(pwzArgv != NULL);
HRESULT hr = S_OK;
INT argc = 0;
BSTR* argv = NULL;
LPWSTR* pwzArgs = NULL;
STRU struTempPath;
INT intArgsProcessed = 0;
// If we call CommandLineToArgvW with an empty string, argc is 5 for some interesting reason.
// Protectively guard against this by check if the string is null or empty.
if (pwzArgumentsFromConfig == NULL || wcscmp(pwzArgumentsFromConfig, L"") == 0)
{
hr = E_INVALIDARG;
goto Finished;
}
pwzArgs = CommandLineToArgvW(pwzArgumentsFromConfig, &argc);
if (pwzArgs == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Failure;
}
argv = new BSTR[argc + 1];
if (argv == NULL)
{
hr = E_OUTOFMEMORY;
goto Failure;
}
argv[0] = SysAllocString(pwzExePath);
if (argv[0] == NULL)
{
hr = E_OUTOFMEMORY;
goto Failure;
}
// Try to convert the application dll from a relative to an absolute path
// Don't record this failure as pwzArgs[0] may already be an absolute path to the dll.
for (intArgsProcessed = 0; intArgsProcessed < argc; intArgsProcessed++)
{
struTempPath.Copy(pwzArgs[intArgsProcessed]);
if (struTempPath.EndsWith(L".dll"))
{
if (SUCCEEDED(UTILITY::ConvertPathToFullPath(pwzArgs[intArgsProcessed], pcwzApplicationPhysicalPath, &struTempPath)))
{
argv[intArgsProcessed + 1] = SysAllocString(struTempPath.QueryStr());
}
else
{
argv[intArgsProcessed + 1] = SysAllocString(pwzArgs[intArgsProcessed]);
}
if (argv[intArgsProcessed + 1] == NULL)
{
hr = E_OUTOFMEMORY;
goto Failure;
}
}
else
{
argv[intArgsProcessed + 1] = SysAllocString(pwzArgs[intArgsProcessed]);
if (argv[intArgsProcessed + 1] == NULL)
{
hr = E_OUTOFMEMORY;
goto Failure;
}
}
}
*pbstrArgv = argv;
*pdwArgCount = argc + 1;
goto Finished;
Failure:
if (argv != NULL)
{
// intArgsProcess - 1 here as if we fail to allocated the ith string
// we don't want to free it.
for (INT i = 0; i < intArgsProcessed - 1; i++)
{
SysFreeString(argv[i]);
}
}
delete[] argv;
Finished:
if (pwzArgs != NULL)
{
LocalFree(pwzArgs);
DBG_ASSERT(pwzArgs == NULL);
}
return hr;
}
HRESULT
HOSTFXR_UTILITY::GetAbsolutePathToDotnet(
_Inout_ STRU* pStruAbsolutePathToDotnet
)
{
HRESULT hr = S_OK;
//
// If we are given an absolute path to dotnet.exe, we are done
//
if (UTILITY::CheckIfFileExists(pStruAbsolutePathToDotnet->QueryStr()))
{
goto Finished;
}
//
// If the path was C:\Program Files\dotnet\dotnet
// We need to try appending .exe and check if the file exists too.
//
if (FAILED(hr = pStruAbsolutePathToDotnet->Append(L".exe")))
{
goto Finished;
}
if (UTILITY::CheckIfFileExists(pStruAbsolutePathToDotnet->QueryStr()))
{
goto Finished;
}
// At this point, we are calling where.exe to find dotnet.
// If we encounter any failures, try getting dotnet.exe from the
// backup location.
if (!InvokeWhereToFindDotnet(pStruAbsolutePathToDotnet))
{
hr = GetAbsolutePathToDotnetFromProgramFiles(pStruAbsolutePathToDotnet);
}
Finished:
return hr;
}
HRESULT
HOSTFXR_UTILITY::GetAbsolutePathToHostFxr(
STRU* pStruAbsolutePathToDotnet,
HANDLE hEventLog,
STRU* pStruAbsolutePathToHostfxr
)
{
HRESULT hr = S_OK;
STRU struHostFxrPath;
STRU struHostFxrSearchExpression;
STRU struHighestDotnetVersion;
STRU struEventMsg;
std::vector<std::wstring> vVersionFolders;
DWORD dwPosition = 0;
if (FAILED(hr = struHostFxrPath.Copy(pStruAbsolutePathToDotnet)))
{
goto Finished;
}
dwPosition = struHostFxrPath.LastIndexOf(L'\\', 0);
if (dwPosition == -1)
{
hr = E_FAIL;
goto Finished;
}
struHostFxrPath.QueryStr()[dwPosition] = L'\0';
if (FAILED(hr = struHostFxrPath.SyncWithBuffer()) ||
FAILED(hr = struHostFxrPath.Append(L"\\")))
{
goto Finished;
}
hr = struHostFxrPath.Append(L"host\\fxr");
if (FAILED(hr))
{
goto Finished;
}
if (!UTILITY::DirectoryExists(&struHostFxrPath))
{
hr = ERROR_BAD_ENVIRONMENT;
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
struEventMsg.QueryStr(),
ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
struHostFxrPath.QueryStr(),
hr);
goto Finished;
}
// Find all folders under host\\fxr\\ for version numbers.
hr = struHostFxrSearchExpression.Copy(struHostFxrPath);
if (FAILED(hr))
{
goto Finished;
}
hr = struHostFxrSearchExpression.Append(L"\\*");
if (FAILED(hr))
{
goto Finished;
}
// As we use the logic from core-setup, we are opting to use std here.
UTILITY::FindDotNetFolders(struHostFxrSearchExpression.QueryStr(), &vVersionFolders);
if (vVersionFolders.size() == 0)
{
hr = HRESULT_FROM_WIN32(ERROR_BAD_ENVIRONMENT);
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND,
ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG,
struHostFxrPath.QueryStr(),
hr);
goto Finished;
}
hr = UTILITY::FindHighestDotNetVersion(vVersionFolders, &struHighestDotnetVersion);
if (FAILED(hr))
{
goto Finished;
}
if (FAILED(hr = struHostFxrPath.Append(L"\\"))
|| FAILED(hr = struHostFxrPath.Append(struHighestDotnetVersion.QueryStr()))
|| FAILED(hr = struHostFxrPath.Append(L"\\hostfxr.dll")))
{
goto Finished;
}
if (!UTILITY::CheckIfFileExists(struHostFxrPath.QueryStr()))
{
// ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG
hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
UTILITY::LogEventF(hEventLog,
EVENTLOG_ERROR_TYPE,
ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND,
ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG,
struHostFxrPath.QueryStr(),
hr);
goto Finished;
}
if (FAILED(hr = pStruAbsolutePathToHostfxr->Copy(struHostFxrPath)))
{
goto Finished;
}
Finished:
return hr;
}
//
// Tries to call where.exe to find the location of dotnet.exe.
// Will check that the bitness of dotnet matches the current
// worker process bitness.
// Returns true if a valid dotnet was found, else false.
//
BOOL
HOSTFXR_UTILITY::InvokeWhereToFindDotnet(
_Inout_ STRU* pStruAbsolutePathToDotnet
)
{
HRESULT hr = S_OK;
// Arguments to call where.exe
STARTUPINFOW startupInfo = { 0 };
PROCESS_INFORMATION processInformation = { 0 };
SECURITY_ATTRIBUTES securityAttributes;
CHAR pzFileContents[READ_BUFFER_SIZE];
HANDLE hStdOutReadPipe = INVALID_HANDLE_VALUE;
HANDLE hStdOutWritePipe = INVALID_HANDLE_VALUE;
LPWSTR pwzDotnetName = NULL;
DWORD dwFilePointer;
BOOL fIsWow64Process;
BOOL fIsCurrentProcess64Bit;
DWORD dwExitCode;
STRU struDotnetSubstring;
STRU struDotnetLocationsString;
DWORD dwNumBytesRead;
DWORD dwBinaryType;
INT index = 0;
INT prevIndex = 0;
BOOL fProcessCreationResult = FALSE;
BOOL fResult = FALSE;
// Set the security attributes for the read/write pipe
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.bInheritHandle = TRUE;
// Reset the path to dotnet as we will be using whether the string is
// empty or not as state
pStruAbsolutePathToDotnet->Reset();
// Create a read/write pipe that will be used for reading the result of where.exe
if (!CreatePipe(&hStdOutReadPipe, &hStdOutWritePipe, &securityAttributes, 0))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
if (!SetHandleInformation(hStdOutReadPipe, HANDLE_FLAG_INHERIT, 0))
{
hr = ERROR_FILE_INVALID;
goto Finished;
}
// Set the stdout and err pipe to the write pipes.
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
startupInfo.hStdOutput = hStdOutWritePipe;
startupInfo.hStdError = hStdOutWritePipe;
// CreateProcess requires a mutable string to be passed to commandline
// See https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083/
pwzDotnetName = SysAllocString(L"\"where.exe\" dotnet.exe");
if (pwzDotnetName == NULL)
{
goto Finished;
}
// Create a process to invoke where.exe
fProcessCreationResult = CreateProcessW(NULL,
pwzDotnetName,
NULL,
NULL,
TRUE,
CREATE_NO_WINDOW,
NULL,
NULL,
&startupInfo,
&processInformation
);
if (!fProcessCreationResult)
{
goto Finished;
}
// Wait for where.exe to return, waiting 2 seconds.
if (WaitForSingleObject(processInformation.hProcess, 2000) != WAIT_OBJECT_0)
{
// Timeout occured, terminate the where.exe process and return.
TerminateProcess(processInformation.hProcess, 2);
hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
goto Finished;
}
//
// where.exe will return 0 on success, 1 if the file is not found
// and 2 if there was an error. Check if the exit code is 1 and set
// a new hr result saying it couldn't find dotnet.exe
//
if (!GetExitCodeProcess(processInformation.hProcess, &dwExitCode))
{
goto Finished;
}
//
// In this block, if anything fails, we will goto our fallback of
// looking in C:/Program Files/
//
if (dwExitCode != 0)
{
goto Finished;
}
// Where succeeded.
// Reset file pointer to the beginning of the file.
dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN);
if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
goto Finished;
}
//
// As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang.
// TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block.
//
if (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL))
{
goto Finished;
}
if (dwNumBytesRead >= READ_BUFFER_SIZE)
{
// This shouldn't ever be this large. We could continue to call ReadFile in a loop,
// however if someone had this many dotnet.exes on their machine.
goto Finished;
}
hr = HRESULT_FROM_WIN32(GetLastError());
if (FAILED(hr = struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead)))
{
goto Finished;
}
// Check the bitness of the currently running process
// matches the dotnet.exe found.
if (!IsWow64Process(GetCurrentProcess(), &fIsWow64Process))
{
// Calling IsWow64Process failed
goto Finished;
}
if (fIsWow64Process)
{
// 32 bit mode
fIsCurrentProcess64Bit = FALSE;
}
else
{
// Check the SystemInfo to see if we are currently 32 or 64 bit.
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
fIsCurrentProcess64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
}
while (TRUE)
{
index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex);
if (index == -1)
{
break;
}
if (FAILED(hr = struDotnetSubstring.Copy(&struDotnetLocationsString.QueryStr()[prevIndex], index - prevIndex)))
{
goto Finished;
}
// \r\n is two wchars, so add 2 here.
prevIndex = index + 2;
if (GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType) &&
fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY))
{
// The bitness of dotnet matched with the current worker process bitness.
if (FAILED(hr = pStruAbsolutePathToDotnet->Copy(struDotnetSubstring)))
{
goto Finished;
}
fResult = TRUE;
break;
}
}
Finished:
if (hStdOutReadPipe != INVALID_HANDLE_VALUE)
{
CloseHandle(hStdOutReadPipe);
}
if (hStdOutWritePipe != INVALID_HANDLE_VALUE)
{
CloseHandle(hStdOutWritePipe);
}
if (processInformation.hProcess != INVALID_HANDLE_VALUE)
{
CloseHandle(processInformation.hProcess);
}
if (processInformation.hThread != INVALID_HANDLE_VALUE)
{
CloseHandle(processInformation.hThread);
}
if (pwzDotnetName != NULL)
{
SysFreeString(pwzDotnetName);
}
return fResult;
}
HRESULT
HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles(
_Inout_ STRU* pStruAbsolutePathToDotnet
)
{
HRESULT hr = S_OK;
BOOL fFound = FALSE;
DWORD dwNumBytesRead = 0;
DWORD dwPathSize = MAX_PATH;
STRU struDotnetSubstring;
while (!fFound)
{
if (FAILED(hr = struDotnetSubstring.Resize(dwPathSize)))
{
goto Finished;
}
dwNumBytesRead = GetEnvironmentVariable(L"ProgramFiles", struDotnetSubstring.QueryStr(), dwPathSize);
if (dwNumBytesRead == 0)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
else if (dwNumBytesRead >= dwPathSize)
{
//
// The path to ProgramFiles should never be this long, but resize and try again.
dwPathSize *= 2 + 30; // for dotnet substring
}
else
{
if (FAILED(hr = struDotnetSubstring.SyncWithBuffer()) ||
FAILED(hr = struDotnetSubstring.Append(L"\\dotnet\\dotnet.exe")))
{
goto Finished;
}
if (!UTILITY::CheckIfFileExists(struDotnetSubstring.QueryStr()))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
if (FAILED(hr = pStruAbsolutePathToDotnet->Copy(struDotnetSubstring)))
{
goto Finished;
}
fFound = TRUE;
}
}
Finished:
return hr;
}

View File

@ -1,78 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
typedef INT(*hostfxr_get_native_search_directories_fn) (CONST INT argc, CONST PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size);
typedef INT(*hostfxr_main_fn) (CONST DWORD argc, CONST PCWSTR argv[]);
#define READ_BUFFER_SIZE 4096
class HOSTFXR_UTILITY
{
public:
HOSTFXR_UTILITY();
~HOSTFXR_UTILITY();
static
HRESULT
GetHostFxrParameters(
HANDLE hEventLog,
PCWSTR pcwzProcessPath,
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
_Inout_ STRU* pStruHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
);
static
HRESULT
GetStandaloneHostfxrParameters(
PCWSTR pwzExeAbsolutePath, // includes .exe file extension.
PCWSTR pcwzApplicationPhysicalPath,
PCWSTR pcwzArguments,
HANDLE hEventLog,
_Inout_ STRU* pStruHostFxrDllLocation,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
);
static
HRESULT
ParseHostfxrArguments(
PCWSTR pwzArgumentsFromConfig,
PCWSTR pwzExePath,
PCWSTR pcwzApplicationPhysicalPath,
HANDLE hEventLog,
_Out_ DWORD* pdwArgCount,
_Out_ BSTR** ppwzArgv
);
static
HRESULT
GetAbsolutePathToDotnet(
STRU* pStruAbsolutePathToDotnet
);
static
HRESULT
GetAbsolutePathToHostFxr(
_In_ STRU* pStruAbsolutePathToDotnet,
_In_ HANDLE hEventLog,
_Out_ STRU* pStruAbsolutePathToHostfxr
);
static
BOOL
InvokeWhereToFindDotnet(
_Inout_ STRU* pStruAbsolutePathToDotnet
);
static
HRESULT
GetAbsolutePathToDotnetFromProgramFiles(
_Inout_ STRU* pStruAbsolutePathToDotnet
);
};

View File

@ -1,44 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"
REQUEST_HANDLER::REQUEST_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication)
: m_cRefs(1)
{
m_pW3Context = pW3Context;
m_pApplication = pApplication;
m_pModuleId = *pModuleId;
}
REQUEST_HANDLER::~REQUEST_HANDLER()
{
}
VOID
REQUEST_HANDLER::ReferenceRequestHandler(
VOID
) const
{
InterlockedIncrement(&m_cRefs);
}
VOID
REQUEST_HANDLER::DereferenceRequestHandler(
VOID
) const
{
DBG_ASSERT(m_cRefs != 0);
LONG cRefs = 0;
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
{
delete this;
}
}

View File

@ -1,59 +0,0 @@
// 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 "stdafx.h"
#include "application.h"
//
// Abstract class
//
class REQUEST_HANDLER
{
public:
REQUEST_HANDLER(
_In_ IHttpContext *pW3Context,
_In_ HTTP_MODULE_ID *pModuleId,
_In_ APPLICATION *pApplication
);
virtual
REQUEST_NOTIFICATION_STATUS
OnExecuteRequestHandler() = 0;
virtual
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
DWORD cbCompletion,
HRESULT hrCompletionStatus
) = 0;
virtual
VOID
TerminateRequest(
bool fClientInitiated
) = 0;
virtual
~REQUEST_HANDLER(
VOID
);
VOID
ReferenceRequestHandler(
VOID
) const;
virtual
VOID
DereferenceRequestHandler(
VOID
) const;
protected:
mutable LONG m_cRefs;
IHttpContext* m_pW3Context;
APPLICATION* m_pApplication;
HTTP_MODULE_ID m_pModuleId;
};

View File

@ -1,47 +0,0 @@
// Copyright (c) .NET Foundation. 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_PROVIDER L"IIS AspNetCore Module"
#define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module"
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and process '%d' 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_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' at stage '%s', ErrorCode = '0x%x', assigned port %d, retryCounter '%d'."
#define ASPNETCORE_EVENT_PROCESS_START_FAILURE_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' with multiple retries. The last try of listening port is '%d'. See pervious warnings for details."
#define ASPNETCORE_EVENT_PROCESS_START_STATUS_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' , ErrorCode = '0x%x', processId '%d', processStatus '%d'."
#define ASPNETCORE_EVENT_PROCESS_START_PORTSETUP_ERROR_MSG L"Application '%s' with physical root '%s' failed to choose listen port '%d' given port rang '%d - %d', EorrorCode = '0x%x'. If environment variable 'ASPNETCORE_PORT' was set, try removing it such that a random port is selected instead."
#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 respond or did not listen on the given port '%d', ErrorCode = '0x%x'"
#define ASPNETCORE_EVENT_PROCESS_SHUTDOWN_MSG L"Application '%s' with physical root '%s' shut down process with Id '%d' listening on port '%d'"
#define ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG L"Warning: Could not create stdoutLogFile %s, ErrorCode = '0x%x'."
#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_APP_SHUTDOWN_FAILURE_MSG L"Failed to gracefully shutdown application '%s'."
#define ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG L"Application '%s' with physical root '%s' failed to load clr and managed application, ErrorCode = '0x%x."
#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG L"Only one inprocess application is allowed per IIS application pool. Please assign the application '%s' to a different IIS application pool."
#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG L"Mixed hosting model is not supported. Application '%s' configured with different hostingModel value '%d' other than the one of running application(s)."
#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR_MSG L"Failed to start application '%s', ErrorCode '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_STDERR_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x. First 4KB characters of captured stderr logs on startup:\r\n%s"
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_STDOUT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x. Last 4KB characters of captured stdout and stderr logs:\r\n%s"
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x. Please check the stderr logs for more information."
#define ASPNETCORE_EVENT_APP_IN_SHUTDOWN_MSG L"Application shutting down."
#define ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_MSG L"Application '%s' was recycled after detecting the app_offline file."
#define ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_REMOVED_MSG L"App_offline.htm has been removed from the application. Application will be recycled."
#define ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG L"Application '%s' was recycled due to configuration change"
#define ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG L"Failed to recycle application due to a configuration change at '%s'. Recycling worker process."
#define ASPNETCORE_EVENT_MODULE_DISABLED_MSG L"AspNetCore Module is disabled"
#define ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP_MSG L"Application '%s' was compiled for .NET Framework. Please compile for .NET core to run the inprocess application or change the process mode to out of process. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_PORTABLE_APP_DOTNET_MISSING_MSG L"Could not find dotnet.exe on the system PATH environment variable for portable application '%s'. Check that a valid path to dotnet is on the PATH and the bitness of dotnet matches the bitness of the IIS worker process. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND_MSG L"Could not find the hostfxr directory '%s' in the dotnet directory. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND_MSG L"Could not find hostfxr.dll in '%s'. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND_MSG L"Could not find application executable in '%s'. ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, ErrorCode = '0x%x. Please check the stderr logs for more information."
#define ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG L"Invalid or unknown processPath provided in web.config: processPath = %s, ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_RH_MISSING_MSG L"Could not find the aspnetcorerh.dll for in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application."
#define ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG L"Could not find the aspnetcorerh.dll for out-of-process application. Please confirm the aspnetcorerh.dll is installed in installed globally for IIS or IISExpress."

View File

@ -1,4 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "stdafx.h"

View File

@ -1,34 +0,0 @@
// 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 "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Windows.h>
#include <httpserv.h>
#include <wchar.h>
#include <vector>
#include <shellapi.h>
#include <sstream>
#include "Shlwapi.h"
#include "..\IISLib\hashtable.h"
#include "..\IISLib\stringu.h"
#include "..\IISLib\stringa.h"
#include "..\IISLib\multisz.h"
#include "..\IISLib\dbgutil.h"
#include "..\IISLib\ahutil.h"
#include "..\IISLib\hashfn.h"
#include "SRWLockWrapper.h"
#include "environmentvariablehash.h"
#include "utility.h"
#include "aspnetcoreconfig.h"
#include "application.h"
#include "requesthandler.h"
#include "fx_ver.h"
#include "hostfxr_utility.h"
#include "resources.h"
#include "aspnetcore_msg.h"

View File

@ -1,8 +0,0 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View File

@ -1,656 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include"stdafx.h"
// static
HRESULT
UTILITY::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
UTILITY::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
UTILITY::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
UTILITY::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
UTILITY::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
UTILITY::FindInMultiString(
PCWSTR pszMultiString,
PCWSTR pszStringToFind
)
{
while (*pszMultiString != L'\0')
{
if (wcscmp(pszMultiString, pszStringToFind) == 0)
{
return TRUE;
}
pszMultiString += wcslen(pszMultiString) + 1;
}
return FALSE;
}
// static
bool
UTILITY::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
UTILITY::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
UTILITY::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
UTILITY::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 ( PathIsRelative(pszPath) )
{
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;
}
HRESULT
UTILITY::EnsureDirectoryPathExist(
_In_ LPCWSTR pszPath
)
{
HRESULT hr = S_OK;
STRU struPath;
DWORD dwPosition = 0;
BOOL fDone = FALSE;
BOOL fUnc = FALSE;
struPath.Copy(pszPath);
hr = IsPathUnc(pszPath, &fUnc);
if (FAILED(hr))
{
goto Finished;
}
if (fUnc)
{
// "\\?\UNC\"
dwPosition = 8;
}
else if (struPath.IndexOf(L'?', 0) != -1)
{
// sceanrio "\\?\"
dwPosition = 4;
}
while (!fDone)
{
dwPosition = struPath.IndexOf(L'\\', dwPosition + 1);
if (dwPosition == -1)
{
// not found '/'
fDone = TRUE;
goto Finished;
}
else if (dwPosition ==0)
{
hr = ERROR_INTERNAL_ERROR;
goto Finished;
}
else if (struPath.QueryStr()[dwPosition-1] == L':')
{
// skip volume case
continue;
}
else
{
struPath.QueryStr()[dwPosition] = L'\0';
}
if (!CreateDirectory(struPath.QueryStr(), NULL) &&
ERROR_ALREADY_EXISTS != GetLastError())
{
hr = HRESULT_FROM_WIN32(GetLastError());
fDone = TRUE;
goto Finished;
}
struPath.QueryStr()[dwPosition] = L'\\';
}
Finished:
return hr;
}
HRESULT
UTILITY::FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
)
{
HRESULT hr = S_OK;
fx_ver_t max_ver(-1, -1, -1);
for (const auto& dir : vFolders)
{
fx_ver_t fx_ver(-1, -1, -1);
if (fx_ver_t::parse(dir, &fx_ver, false))
{
// TODO using max instead of std::max works
max_ver = max(max_ver, fx_ver);
}
}
hr = pstrResult->Copy(max_ver.as_str().c_str());
// we check FAILED(hr) outside of function
return hr;
}
BOOL
UTILITY::DirectoryExists(
_In_ STRU *pstrPath
)
{
WIN32_FILE_ATTRIBUTE_DATA data;
if (pstrPath->IsEmpty())
{
return false;
}
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
}
VOID
UTILITY::FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
)
{
HANDLE handle = NULL;
WIN32_FIND_DATAW data = { 0 };
handle = FindFirstFileExW(pszPath, FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
if (handle == INVALID_HANDLE_VALUE)
{
return;
}
do
{
std::wstring folder(data.cFileName);
pvFolders->push_back(folder);
} while (FindNextFileW(handle, &data));
FindClose(handle);
}
BOOL
UTILITY::CheckIfFileExists(
_In_ PCWSTR pszFilePath
)
{
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
SECURITY_ATTRIBUTES saAttr;
BOOL fFileExists = FALSE;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
hFileHandle = CreateFile(pszFilePath,
GENERIC_READ,
FILE_SHARE_READ,
&saAttr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
fFileExists = hFileHandle != INVALID_HANDLE_VALUE || GetLastError() == ERROR_SHARING_VIOLATION;
if (fFileExists)
{
CloseHandle(hFileHandle);
}
return fFileExists;
}
VOID
UTILITY::LogEvent(
_In_ HANDLE hEventLog,
_In_ WORD dwEventInfoType,
_In_ DWORD dwEventId,
_In_ LPCWSTR pstrMsg
)
{
if (hEventLog != NULL)
{
ReportEventW(hEventLog,
dwEventInfoType,
0, // wCategory
dwEventId,
NULL, // lpUserSid
1, // wNumStrings
0, // dwDataSize,
&pstrMsg,
NULL // lpRawData
);
}
if (dwEventInfoType == EVENTLOG_ERROR_TYPE)
{
fwprintf(stderr, L"ERROR: %s\n", pstrMsg);
}
}
VOID
UTILITY::LogEventF(
_In_ HANDLE hEventLog,
_In_ WORD dwEventInfoType,
_In_ DWORD dwEventId,
_In_ LPCWSTR pstrMsg,
...
)
{
va_list argsList;
va_start(argsList, pstrMsg);
STACK_STRU ( strEventMsg, 256 );
if (SUCCEEDED(strEventMsg.SafeVsnwprintf(
pstrMsg,
argsList)))
{
UTILITY::LogEvent(hEventLog,
dwEventInfoType,
dwEventId,
strEventMsg.QueryStr());
}
va_end( argsList );
}

View File

@ -1,137 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class UTILITY
{
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
);
static
HRESULT
EnsureDirectoryPathExist(
_In_ LPCWSTR pszPath
);
static
BOOL
DirectoryExists(
_In_ STRU *pstrPath
);
static
VOID
FindDotNetFolders(
_In_ PCWSTR pszPath,
_Out_ std::vector<std::wstring> *pvFolders
);
static
HRESULT
FindHighestDotNetVersion(
_In_ std::vector<std::wstring> vFolders,
_Out_ STRU *pstrResult
);
static
BOOL
CheckIfFileExists(
PCWSTR pszFilePath
);
static
VOID
LogEvent(
_In_ HANDLE hEventLog,
_In_ WORD dwEventInfoType,
_In_ DWORD dwEventId,
_In_ LPCWSTR pstrMsg
);
static
VOID
LogEventF(
_In_ HANDLE hEventLog,
_In_ WORD dwEventInfoType,
_In_ DWORD dwEventId,
__in PCWSTR pstrMsg,
...
);
private:
UTILITY() {}
~UTILITY() {}
};

View File

@ -1,201 +0,0 @@
<?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>{09D9D1D6-2951-4E14-BC35-76A23CF9391A}</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>

View File

@ -1,443 +0,0 @@
// 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;
}

View File

@ -1,115 +0,0 @@
// 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

View File

@ -1,258 +0,0 @@
// 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
);

View File

@ -1,482 +0,0 @@
// 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;
}

View File

@ -1,42 +0,0 @@
// 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_

View File

@ -1,271 +0,0 @@
// 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 ) )

View File

@ -1,14 +0,0 @@
// 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

View File

@ -1,102 +0,0 @@
// 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

View File

@ -1,325 +0,0 @@
// 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__

View File

@ -1,666 +0,0 @@
// 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();
}

View File

@ -1,163 +0,0 @@
// 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

View File

@ -1,63 +0,0 @@
// 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

View File

@ -1,474 +0,0 @@
// 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)

View File

@ -1,225 +0,0 @@
// 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_

View File

@ -1,408 +0,0 @@
// 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)

View File

@ -1,226 +0,0 @@
// 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_

View File

@ -1,32 +0,0 @@
// 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

View File

@ -1,305 +0,0 @@
// 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;
}

View File

@ -1,22 +0,0 @@
// 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"

View File

@ -1,85 +0,0 @@
// 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() {}
};

View File

@ -1,736 +0,0 @@
// 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 ***********************/

View File

@ -1,229 +0,0 @@
// 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)

View File

@ -1,87 +0,0 @@
// 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