Panwang/refactor (#277)
* Init check in for refactoring * clean up to make app_offline work * update loadassembly and build * add configpath to aspnetcore_config to make recycle work * Adds in process component to refactor (#249) * outprocess first checkin (still missing marjor components) * Adds In-Process support for shimmed module. (#257) * Init check in for refactoring * clean up to make app_offline work * update loadassembly and build * add configpath to aspnetcore_config to make recycle work * Adds in process component to refactor (#249) * outprocess first checkin (still missing marjor components) * Adds In-Process support for shimmed module. (#257) * load from bin start and catch unhandled exception * Fixes request handler vcxproj * Adds request handler to nuget package * build issues * outofprocess refactoring * adding logging support * enforce Warning As Error for build and enable process recycle for outofprocess * fix AV for win32 build and update build flags * Fixed m_srwLock lock issue * remove dealock in loadmanagedapp and remove UseMFC * Readd lost exception catching * nuget package issue and status code * fixing warnings * Adds Headers * removing web sockets exe for now * remove flags * nuspec stuff * spelling * only look in inetsvr for now (or same folder) * rename method * terminte thread before closing the handle to it * couple changes related with AV * null check and Kill thread for in process if dotnet timed out * fix recursive lock issue reported by appverifier * client disconnect support AV fix * flow 502.5 process start failure error page * Feedback from inperson code review
This commit is contained in:
parent
9a1cc4ba1c
commit
30bbd87d81
|
|
@ -25,15 +25,9 @@ project.lock.json
|
||||||
*.ncrunchsolution
|
*.ncrunchsolution
|
||||||
*.*sdf
|
*.*sdf
|
||||||
*.ipch
|
*.ipch
|
||||||
<<<<<<< HEAD
|
|
||||||
*.vs/
|
|
||||||
.vscode/
|
.vscode/
|
||||||
.testPublish/
|
|
||||||
.build/
|
|
||||||
*.nuget.props
|
*.nuget.props
|
||||||
*.nuget.targets
|
*.nuget.targets
|
||||||
global.json
|
|
||||||
=======
|
|
||||||
*.bin
|
*.bin
|
||||||
*.vs/
|
*.vs/
|
||||||
.testPublish/
|
.testPublish/
|
||||||
|
|
@ -41,12 +35,15 @@ global.json
|
||||||
*.obj
|
*.obj
|
||||||
*.tlog
|
*.tlog
|
||||||
*.CppClean.log
|
*.CppClean.log
|
||||||
|
*msbuild.log
|
||||||
|
|
||||||
src/*/Debug/
|
src/*/Debug/
|
||||||
src/*/x64/Debug/
|
src/*/x64/Debug/
|
||||||
src/*/Release/
|
src/*/Release/
|
||||||
src/*/x64/Release/
|
src/*/x64/Release/
|
||||||
|
x64/
|
||||||
|
|
||||||
|
*vcxproj.filters
|
||||||
*.aps
|
*.aps
|
||||||
*.pdb
|
*.pdb
|
||||||
*.lib
|
*.lib
|
||||||
|
|
@ -59,5 +56,3 @@ src/AspNetCore/version.h
|
||||||
|
|
||||||
*.VC.*db
|
*.VC.*db
|
||||||
global.json
|
global.json
|
||||||
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 15
|
|
||||||
VisualStudioVersion = 15.0.27110.0
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCore\AspNetCore.vcxproj", "{439824F9-1455-4CC4-BD79-B44FA0A16552}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\IISLib\IISLib.vcxproj", "{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{02F461DC-5166-4E88-AAD5-CF110016A647}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FDD2EDF8-1B62-4978-9815-9D95260B8B91}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreModule.Test", "test\AspNetCoreModule.Test\AspNetCoreModule.Test.csproj", "{4DDA7560-AA29-4161-A5EA-A7E8F3997321}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreModule.TestSites.Standard", "test\AspNetCoreModule.TestSites.Standard\AspNetCoreModule.TestSites.Standard.csproj", "{030225D8-4EE8-47E5-B692-2A96B3B51A38}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0EF45656-B25D-40D8-959C-726EAF185E60}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
NuGet.Config = NuGet.Config
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Win32.ActiveCfg = Release|x64
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Debug|Win32.Build.0 = Release|x64
|
|
||||||
{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}.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552}.Release|x64.Build.0 = Release|x64
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Win32.ActiveCfg = Release|x64
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Debug|Win32.Build.0 = Release|x64
|
|
||||||
{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}.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}.Release|x64.Build.0 = Release|x64
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|Win32.Build.0 = Debug|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Win32.ActiveCfg = Release|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|Win32.Build.0 = Release|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|Win32.Build.0 = Debug|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Win32.ActiveCfg = Release|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|Win32.Build.0 = Release|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
|
|
||||||
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
|
|
||||||
{4DDA7560-AA29-4161-A5EA-A7E8F3997321} = {02F461DC-5166-4E88-AAD5-CF110016A647}
|
|
||||||
{030225D8-4EE8-47E5-B692-2A96B3B51A38} = {02F461DC-5166-4E88-AAD5-CF110016A647}
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {0967E9B4-FEE7-40D7-860A-23E340E65840}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
<<<<<<< HEAD
|
<Project>
|
||||||
<Project>
|
|
||||||
<Import
|
<Import
|
||||||
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
|
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
|
||||||
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
|
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
|
||||||
|
|
||||||
=======
|
|
||||||
<Project>
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
<Import Project="version.props" />
|
<Import Project="version.props" />
|
||||||
<Import Project="build\dependencies.props" />
|
<Import Project="build\dependencies.props" />
|
||||||
<Import Project="build\sources.props" />
|
<Import Project="build\sources.props" />
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Product>Microsoft ASP.NET Core</Product>
|
<Product>Microsoft ASP.NET Core</Product>
|
||||||
<RepositoryUrl>https://github.com/aspnet/IISIntegration</RepositoryUrl>
|
<RepositoryUrl>https://github.com/aspnet/IISIntegration</RepositoryUrl>
|
||||||
|
|
@ -28,14 +23,4 @@
|
||||||
<PackageReference Include="Microsoft.NETCore.Compilers" Version="$(MicrosoftNETCoreCompilersPackageVersion)" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.NETCore.Compilers" Version="$(MicrosoftNETCoreCompilersPackageVersion)" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
=======
|
|
||||||
<PropertyGroup>
|
|
||||||
<Product>Microsoft ASP.NET Core</Product>
|
|
||||||
<RepositoryUrl>https://github.com/aspnet/AspNetCoreModule</RepositoryUrl>
|
|
||||||
<RepositoryType>git</RepositoryType>
|
|
||||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
|
|
||||||
<SignAssembly>true</SignAssembly>
|
|
||||||
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
|
||||||
</PropertyGroup>
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISTestSite", "test\IISTest
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.IISServerFunctionalTests", "test\IISIntegration.IISServerFunctionalTests\IISIntegration.IISServerFunctionalTests.csproj", "{C745BBFD-7888-4038-B41B-6D1832D13878}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.IISServerFunctionalTests", "test\IISIntegration.IISServerFunctionalTests\IISIntegration.IISServerFunctionalTests.csproj", "{C745BBFD-7888-4038-B41B-6D1832D13878}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AspNetCore", "src\AspNetCore\AspNetCore.vcxproj", "{439824F9-1455-4CC4-BD79-B44FA0A16552}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\IISLib\IISLib.vcxproj", "{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandler", "src\RequestHandler\RequestHandler.vcxproj", "{D57EA297-6DC2-4BC0-8C91-334863327863}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "src\CommonLib\CommonLib.vcxproj", "{55494E58-E061-4C4C-A0A8-837008E72F85}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -150,6 +158,50 @@ Global
|
||||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x64.ActiveCfg = Release|Any CPU
|
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x64.Build.0 = Release|Any CPU
|
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x86.ActiveCfg = Release|Any CPU
|
{C745BBFD-7888-4038-B41B-6D1832D13878}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{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
|
||||||
|
{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
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Win32.ActiveCfg = Debug|x64
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Debug|Win32.Build.0 = Debug|x64
|
||||||
|
{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}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863}.Release|x64.Build.0 = Release|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Win32.ActiveCfg = Debug|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Win32.Build.0 = Debug|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Debug|Win32.Deploy.0 = Debug|x64
|
||||||
|
{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|x64.Deploy.0 = Debug|x64
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85}.Release|Win32.Deploy.0 = 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|x64.Deploy.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -163,6 +215,10 @@ Global
|
||||||
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
|
{9BC4AFCB-325D-4C81-8228-8CF301CE2F97} = {C74B8F36-FD2F-45C9-9B8A-00E7CF0126A9}
|
||||||
{679FA2A2-898B-4320-884E-C2D294A97CE1} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
{679FA2A2-898B-4320-884E-C2D294A97CE1} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||||
{C745BBFD-7888-4038-B41B-6D1832D13878} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
{C745BBFD-7888-4038-B41B-6D1832D13878} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||||
|
{439824F9-1455-4CC4-BD79-B44FA0A16552} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
|
{4787A64F-9A3E-4867-A55A-70CB4B2B2FFE} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||||
|
{D57EA297-6DC2-4BC0-8C91-334863327863} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
|
||||||
|
{55494E58-E061-4C4C-A0A8-837008E72F85} = {FDD2EDF8-1B62-4978-9815-9D95260B8B91}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
|
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
<<<<<<< HEAD
|
|
||||||
Copyright (c) .NET Foundation and Contributors
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
@ -13,7 +12,7 @@ Unless required by applicable law or agreed to in writing, software distributed
|
||||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
specific language governing permissions and limitations under the License.
|
specific language governing permissions and limitations under the License.
|
||||||
=======
|
|
||||||
ASP.NET Core Module
|
ASP.NET Core Module
|
||||||
|
|
||||||
Copyright (c) .NET Foundation
|
Copyright (c) .NET Foundation
|
||||||
|
|
@ -37,4 +36,3 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
<<<<<<< HEAD
|
|
||||||
ASP.NET Core IIS Integration
|
|
||||||
========
|
|
||||||
|
|
||||||
This repo hosts the ASP.NET Core middleware for IIS integration.
|
This repo hosts the ASP.NET Core middleware for IIS integration.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
=======
|
=======
|
||||||
# ASP.NET Core Module
|
# ASP.NET Core Module
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,2 @@
|
||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
<<<<<<< HEAD
|
|
||||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
|
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
|
||||||
=======
|
|
||||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<Import Project="$(MSBuildThisFileDirectory)\Build.Settings" />
|
<Import Project="$(MSBuildThisFileDirectory)\Build.Settings" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Projects Include="$(SolutionDir)\src\AspNetCore\AspNetCore.vcxproj" />
|
<Projects Include="$(SolutionDir)\src\AspNetCore\AspNetCore.vcxproj" />
|
||||||
|
<Projects Include="$(SolutionDir)\src\RequestHandler\RequestHandler.vcxproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="Build">
|
<Target Name="Build">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<<<<<<< HEAD
|
<Project>
|
||||||
<Project>
|
|
||||||
<Import Project="dependencies.props" />
|
<Import Project="dependencies.props" />
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)src\AspNetCore\AspNetCore.vcxproj" %(BuildConfigurations.Identity)"
|
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)src\AspNetCore\AspNetCore.vcxproj" %(BuildConfigurations.Identity)"
|
||||||
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||||
|
<Exec Command=""$(VisualStudioMSBuildx86Path)" "$(RepositoryRoot)src\RequestHandler\RequestHandler.vcxproj" %(BuildConfigurations.Identity)"
|
||||||
|
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="PackageProjects">
|
<Target Name="PackageProjects">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
<<<<<<< HEAD
|
|
||||||
<Project>
|
|
||||||
=======
|
|
||||||
<Project>
|
<Project>
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
||||||
|
|
||||||
<PropertyGroup Label="RestoreSources">
|
<PropertyGroup Label="RestoreSources">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,2 @@
|
||||||
<<<<<<< HEAD
|
|
||||||
version:2.1.0-preview1-15576
|
|
||||||
commithash:2f3856d2ba4f659fcb9253215b83946a06794a27
|
|
||||||
=======
|
|
||||||
version:2.1.0-preview1-15620
|
version:2.1.0-preview1-15620
|
||||||
commithash:6432b49a2c00310416df39b6fe548ef4af9c6011
|
commithash:6432b49a2c00310416df39b6fe548ef4af9c6011
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
|
|
||||||
"channel": "dev"
|
|
||||||
}
|
|
||||||
=======
|
|
||||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
|
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
|
||||||
"channel": "dev",
|
"channel": "dev",
|
||||||
"toolsets": {
|
"toolsets": {
|
||||||
|
|
@ -17,4 +12,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
<files>
|
<files>
|
||||||
<file src="..\artifacts\build\AspNetCore\bin\Release\Win32\aspnetcore.dll" target="contentFiles\any\any\x86\aspnetcore.dll" />
|
<file src="..\artifacts\build\AspNetCore\bin\Release\Win32\aspnetcore.dll" target="contentFiles\any\any\x86\aspnetcore.dll" />
|
||||||
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\aspnetcore.dll" target="contentFiles\any\any\x64\aspnetcore.dll" />
|
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\aspnetcore.dll" target="contentFiles\any\any\x64\aspnetcore.dll" />
|
||||||
|
<file src="..\artifacts\build\AspNetCore\bin\Release\Win32\aspnetcorerh.dll" target="contentFiles\any\any\x86\aspnetcorerh.dll" />
|
||||||
|
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\aspnetcorerh.dll" target="contentFiles\any\any\x64\aspnetcorerh.dll" />
|
||||||
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\*.xml"/>
|
<file src="..\artifacts\build\AspNetCore\bin\Release\x64\*.xml"/>
|
||||||
<file src="..\tools\installancm.ps1"/>
|
<file src="..\tools\installancm.ps1"/>
|
||||||
<file src="..\LICENSE.txt"/>
|
<file src="..\LICENSE.txt"/>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AspNetCoreModuleX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcore.dll</AspNetCoreModuleX64Location>
|
<AspNetCoreModuleX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcore.dll</AspNetCoreModuleX64Location>
|
||||||
<AspNetCoreModuleX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcore.dll</AspNetCoreModuleX86Location>
|
<AspNetCoreModuleX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcore.dll</AspNetCoreModuleX86Location>
|
||||||
|
<RequestHandlerX64Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x64\aspnetcorerh.dll</RequestHandlerX64Location>
|
||||||
|
<RequestHandlerX86Location>$(MSBuildThisFileDirectory)..\contentFiles\any\any\x86\aspnetcorerh.dll</RequestHandlerX86Location>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
4
run.cmd
4
run.cmd
|
|
@ -1,6 +1,2 @@
|
||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
<<<<<<< HEAD
|
|
||||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
|
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
|
||||||
=======
|
|
||||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
34
run.ps1
34
run.ps1
|
|
@ -29,12 +29,9 @@ Updates KoreBuild to the latest version even if a lock file is present.
|
||||||
.PARAMETER ConfigFile
|
.PARAMETER ConfigFile
|
||||||
The path to the configuration file that stores values. Defaults to korebuild.json.
|
The path to the configuration file that stores values. Defaults to korebuild.json.
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
.PARAMETER ToolsSourceSuffix
|
.PARAMETER ToolsSourceSuffix
|
||||||
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
|
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
|
||||||
|
|
||||||
=======
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
.PARAMETER Arguments
|
.PARAMETER Arguments
|
||||||
Arguments to be passed to the command
|
Arguments to be passed to the command
|
||||||
|
|
||||||
|
|
@ -57,11 +54,7 @@ Example config file:
|
||||||
#>
|
#>
|
||||||
[CmdletBinding(PositionalBinding = $false)]
|
[CmdletBinding(PositionalBinding = $false)]
|
||||||
param(
|
param(
|
||||||
<<<<<<< HEAD
|
|
||||||
[Parameter(Mandatory = $true, Position = 0)]
|
[Parameter(Mandatory = $true, Position = 0)]
|
||||||
=======
|
|
||||||
[Parameter(Mandatory=$true, Position = 0)]
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
[string]$Command,
|
[string]$Command,
|
||||||
[string]$Path = $PSScriptRoot,
|
[string]$Path = $PSScriptRoot,
|
||||||
[Alias('c')]
|
[Alias('c')]
|
||||||
|
|
@ -73,10 +66,7 @@ param(
|
||||||
[Alias('u')]
|
[Alias('u')]
|
||||||
[switch]$Update,
|
[switch]$Update,
|
||||||
[string]$ConfigFile,
|
[string]$ConfigFile,
|
||||||
<<<<<<< HEAD
|
|
||||||
[string]$ToolsSourceSuffix,
|
[string]$ToolsSourceSuffix,
|
||||||
=======
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
[Parameter(ValueFromRemainingArguments = $true)]
|
[Parameter(ValueFromRemainingArguments = $true)]
|
||||||
[string[]]$Arguments
|
[string[]]$Arguments
|
||||||
)
|
)
|
||||||
|
|
@ -93,11 +83,7 @@ function Get-KoreBuild {
|
||||||
$lockFile = Join-Path $Path 'korebuild-lock.txt'
|
$lockFile = Join-Path $Path 'korebuild-lock.txt'
|
||||||
|
|
||||||
if (!(Test-Path $lockFile) -or $Update) {
|
if (!(Test-Path $lockFile) -or $Update) {
|
||||||
<<<<<<< HEAD
|
|
||||||
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
|
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
|
||||||
=======
|
|
||||||
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
||||||
|
|
@ -114,11 +100,7 @@ function Get-KoreBuild {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
||||||
<<<<<<< HEAD
|
|
||||||
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
|
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
|
||||||
=======
|
|
||||||
Get-RemoteFile $remotePath $tmpfile
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
|
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
|
||||||
# Use built-in commands where possible as they are cross-plat compatible
|
# Use built-in commands where possible as they are cross-plat compatible
|
||||||
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
||||||
|
|
@ -146,11 +128,7 @@ function Join-Paths([string]$path, [string[]]$childPaths) {
|
||||||
return $path
|
return $path
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
|
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
|
||||||
=======
|
|
||||||
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
if ($RemotePath -notlike 'http*') {
|
if ($RemotePath -notlike 'http*') {
|
||||||
Copy-Item $RemotePath $LocalPath
|
Copy-Item $RemotePath $LocalPath
|
||||||
return
|
return
|
||||||
|
|
@ -160,11 +138,7 @@ function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
||||||
while ($retries -gt 0) {
|
while ($retries -gt 0) {
|
||||||
$retries -= 1
|
$retries -= 1
|
||||||
try {
|
try {
|
||||||
<<<<<<< HEAD
|
|
||||||
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
|
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
|
||||||
=======
|
|
||||||
Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
@ -191,12 +165,8 @@ if (Test-Path $ConfigFile) {
|
||||||
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
|
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
|
||||||
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
|
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
=======
|
|
||||||
} catch {
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
|
Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
|
||||||
Write-Warning $Error[0]
|
Write-Warning $Error[0]
|
||||||
}
|
}
|
||||||
|
|
@ -223,8 +193,4 @@ try {
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
Remove-Module 'KoreBuild' -ErrorAction Ignore
|
Remove-Module 'KoreBuild' -ErrorAction Ignore
|
||||||
<<<<<<< HEAD
|
|
||||||
}
|
}
|
||||||
=======
|
|
||||||
}
|
|
||||||
>>>>>>> ANCM/dev
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
|
@ -75,16 +74,34 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||||
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
|
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutDir>$(SolutionDir)artifacts\build\$(ProjectName)\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||||
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -104,6 +121,17 @@
|
||||||
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\IISLib;.\Inc</AdditionalIncludeDirectories>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -123,6 +151,17 @@
|
||||||
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
|
||||||
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -144,6 +183,17 @@
|
||||||
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\IISLib;inc</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -155,52 +205,22 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Inc\aspnetcore_event.h" />
|
<ClInclude Include="Inc\applicationinfo.h" />
|
||||||
|
<ClInclude Include="Inc\appoffline.h" />
|
||||||
|
<ClInclude Include="inc\globalmodule.h" />
|
||||||
<ClInclude Include="Inc\resource.h" />
|
<ClInclude Include="Inc\resource.h" />
|
||||||
<ClInclude Include="Inc\application.h" />
|
|
||||||
<ClInclude Include="Inc\applicationmanager.h" />
|
<ClInclude Include="Inc\applicationmanager.h" />
|
||||||
<ClInclude Include="Inc\aspnetcoreconfig.h" />
|
|
||||||
<ClInclude Include="Inc\environmentvariablehash.h" />
|
|
||||||
<ClInclude Include="Inc\debugutil.h" />
|
|
||||||
<ClInclude Include="Inc\filewatcher.h" />
|
<ClInclude Include="Inc\filewatcher.h" />
|
||||||
<ClInclude Include="Inc\forwarderconnection.h" />
|
|
||||||
<ClInclude Include="Inc\forwardinghandler.h" />
|
|
||||||
<ClInclude Include="Inc\path.h" />
|
|
||||||
<ClInclude Include="Inc\processmanager.h" />
|
|
||||||
<ClInclude Include="Inc\protocolconfig.h" />
|
|
||||||
<ClInclude Include="Inc\proxymodule.h" />
|
<ClInclude Include="Inc\proxymodule.h" />
|
||||||
<ClInclude Include="Inc\responseheaderhash.h" />
|
|
||||||
<ClInclude Include="Inc\serverprocess.h" />
|
|
||||||
<ClInclude Include="Inc\sttimer.h" />
|
|
||||||
<ClInclude Include="Inc\websockethandler.h" />
|
|
||||||
<ClInclude Include="Inc\winhttphelper.h" />
|
|
||||||
<ClInclude Include="Inc\fx_ver.h" />
|
|
||||||
<ClInclude Include="Inc\inprocessapplication.h" />
|
|
||||||
<ClInclude Include="Inc\outprocessapplication.h" />
|
|
||||||
<ClInclude Include="Inc\inprocessstoredcontext.h" />
|
|
||||||
<ClInclude Include="Src\precomp.hxx" />
|
<ClInclude Include="Src\precomp.hxx" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Src\inprocessstoredcontext.cxx" />
|
<ClCompile Include="Src\applicationinfo.cpp" />
|
||||||
<ClCompile Include="Src\inprocessapplication.cxx" />
|
|
||||||
<ClCompile Include="Src\managedexports.cxx" />
|
|
||||||
<ClCompile Include="Src\outprocessapplication.cxx" />
|
|
||||||
<ClCompile Include="Src\application.cxx" />
|
|
||||||
<ClCompile Include="Src\applicationmanager.cxx" />
|
<ClCompile Include="Src\applicationmanager.cxx" />
|
||||||
<ClCompile Include="Src\aspnetcoreconfig.cxx" />
|
|
||||||
<ClCompile Include="Src\dllmain.cpp" />
|
<ClCompile Include="Src\dllmain.cpp" />
|
||||||
<ClCompile Include="Src\filewatcher.cxx" />
|
<ClCompile Include="Src\filewatcher.cxx" />
|
||||||
<ClCompile Include="Src\forwarderconnection.cxx" />
|
<ClCompile Include="src\globalmodule.cpp" />
|
||||||
<ClCompile Include="Src\forwardinghandler.cxx" />
|
|
||||||
<ClCompile Include="Src\fx_ver.cxx" />
|
|
||||||
<ClCompile Include="Src\path.cxx" />
|
|
||||||
<ClCompile Include="Src\processmanager.cxx" />
|
|
||||||
<ClCompile Include="Src\protocolconfig.cxx" />
|
|
||||||
<ClCompile Include="Src\proxymodule.cxx" />
|
<ClCompile Include="Src\proxymodule.cxx" />
|
||||||
<ClCompile Include="Src\responseheaderhash.cxx" />
|
|
||||||
<ClCompile Include="Src\serverprocess.cxx" />
|
|
||||||
<ClCompile Include="Src\websockethandler.cxx" />
|
|
||||||
<ClCompile Include="Src\winhttphelper.cxx" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Target Name="CreateVersionHeader" BeforeTargets="PrepareForBuild">
|
<Target Name="CreateVersionHeader" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
@ -221,29 +241,16 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<WriteLinesToFile File="version.h" Lines="@(VersionHeaderContents)" OverWrite="true" />
|
<WriteLinesToFile File="version.h" Lines="@(VersionHeaderContents)" OverWrite="true" />
|
||||||
</Target>
|
</Target>
|
||||||
<ItemGroup>
|
|
||||||
<CustomBuild Include="Src\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>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="aspnetcoremodule.rc" />
|
<ResourceCompile Include="aspnetcoremodule.rc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">
|
||||||
|
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
|
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
|
||||||
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
|
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
|
||||||
|
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -254,6 +261,9 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Xml Include="aspnetcore_schema.xml" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,286 +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
|
|
||||||
|
|
||||||
//
|
|
||||||
// The key used for hash-table lookups, consists of the port on which the http process is created.
|
|
||||||
//
|
|
||||||
class APPLICATION_KEY
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
APPLICATION_KEY(
|
|
||||||
VOID
|
|
||||||
) : INLINE_STRU_INIT(m_struKey)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
Initialize(
|
|
||||||
_In_ LPCWSTR pszKey
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_struKey.Copy(pszKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
GetIsEqual(
|
|
||||||
const APPLICATION_KEY * key2
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return m_struKey.Equals(key2->m_struKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD CalcKeyHash() const
|
|
||||||
{
|
|
||||||
return Hash(m_struKey.QueryStr());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
INLINE_STRU(m_struKey, 1024);
|
|
||||||
};
|
|
||||||
|
|
||||||
class APP_OFFLINE_HTM
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
APP_OFFLINE_HTM(LPCWSTR pszPath) : m_cRefs(1)
|
|
||||||
{
|
|
||||||
m_Path.Copy( pszPath );
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ReferenceAppOfflineHtm() const
|
|
||||||
{
|
|
||||||
InterlockedIncrement(&m_cRefs);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DereferenceAppOfflineHtm() const
|
|
||||||
{
|
|
||||||
if (InterlockedDecrement(&m_cRefs) == 0)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
Load(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BOOL fResult = TRUE;
|
|
||||||
LARGE_INTEGER li = {0};
|
|
||||||
CHAR *pszBuff = NULL;
|
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
handle = CreateFile( m_Path.QueryStr(),
|
|
||||||
GENERIC_READ,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL );
|
|
||||||
|
|
||||||
if( handle == INVALID_HANDLE_VALUE )
|
|
||||||
{
|
|
||||||
if ( GetLastError() == ERROR_FILE_NOT_FOUND )
|
|
||||||
{
|
|
||||||
fResult = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This Load() member function is supposed be called only when the change notification event of file creation or file modification happens.
|
|
||||||
// If file is currenlty locked exclusively by other processes, we might get INVALID_HANDLE_VALUE even though the file exists. In that case, we should return TRUE here.
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!GetFileSizeEx( handle, &li ))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( li.HighPart != 0 )
|
|
||||||
{
|
|
||||||
// > 4gb file size not supported
|
|
||||||
// todo: log a warning at event log
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD bytesRead = 0;
|
|
||||||
|
|
||||||
if(li.LowPart > 0)
|
|
||||||
{
|
|
||||||
pszBuff = new CHAR[ li.LowPart + 1 ];
|
|
||||||
|
|
||||||
if( ReadFile( handle, pszBuff, li.LowPart, &bytesRead, NULL ) )
|
|
||||||
{
|
|
||||||
m_Contents.Copy( pszBuff, bytesRead );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
if( handle != INVALID_HANDLE_VALUE )
|
|
||||||
{
|
|
||||||
CloseHandle(handle);
|
|
||||||
handle = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pszBuff != NULL )
|
|
||||||
{
|
|
||||||
delete[] pszBuff;
|
|
||||||
pszBuff = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable LONG m_cRefs;
|
|
||||||
STRA m_Contents;
|
|
||||||
STRU m_Path;
|
|
||||||
};
|
|
||||||
|
|
||||||
class APPLICATION_MANAGER;
|
|
||||||
|
|
||||||
class APPLICATION
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
APPLICATION() : m_pApplicationManager(NULL), m_cRefs(1),
|
|
||||||
m_fAppOfflineFound(FALSE), m_pAppOfflineHtm(NULL),
|
|
||||||
m_pFileWatcherEntry(NULL), m_pConfiguration(NULL)
|
|
||||||
{
|
|
||||||
InitializeSRWLock(&m_srwLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
APPLICATION_KEY *
|
|
||||||
QueryApplicationKey()
|
|
||||||
{
|
|
||||||
return &m_applicationKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
~APPLICATION();
|
|
||||||
|
|
||||||
virtual
|
|
||||||
HRESULT
|
|
||||||
Initialize(
|
|
||||||
_In_ APPLICATION_MANAGER *pApplicationManager,
|
|
||||||
_In_ ASPNETCORE_CONFIG *pConfiguration) = 0;
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ReferenceApplication() const
|
|
||||||
{
|
|
||||||
InterlockedIncrement(&m_cRefs);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DereferenceApplication() const
|
|
||||||
{
|
|
||||||
if (InterlockedDecrement(&m_cRefs) == 0)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
APP_OFFLINE_HTM* QueryAppOfflineHtm()
|
|
||||||
{
|
|
||||||
return m_pAppOfflineHtm;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
AppOfflineFound()
|
|
||||||
{
|
|
||||||
return m_fAppOfflineFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
VOID
|
|
||||||
OnAppOfflineHandleChange() = 0;
|
|
||||||
|
|
||||||
VOID
|
|
||||||
UpdateAppOfflineFileHandle();
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
StartMonitoringAppOffline();
|
|
||||||
|
|
||||||
ASPNETCORE_CONFIG*
|
|
||||||
QueryConfig()
|
|
||||||
{
|
|
||||||
return m_pConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
ExecuteRequest(
|
|
||||||
_In_ IHttpContext* pHttpContext
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
mutable LONG m_cRefs;
|
|
||||||
APPLICATION_KEY m_applicationKey;
|
|
||||||
APPLICATION_MANAGER *m_pApplicationManager;
|
|
||||||
BOOL m_fAppOfflineFound;
|
|
||||||
APP_OFFLINE_HTM *m_pAppOfflineHtm;
|
|
||||||
FILE_WATCHER_ENTRY *m_pFileWatcherEntry;
|
|
||||||
ASPNETCORE_CONFIG *m_pConfiguration;
|
|
||||||
SRWLOCK m_srwLock;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class APPLICATION_HASH :
|
|
||||||
public HASH_TABLE<APPLICATION, APPLICATION_KEY *>
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
APPLICATION_HASH()
|
|
||||||
{}
|
|
||||||
|
|
||||||
APPLICATION_KEY *
|
|
||||||
ExtractKey(
|
|
||||||
APPLICATION *pApplication
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return pApplication->QueryApplicationKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
CalcKeyHash(
|
|
||||||
APPLICATION_KEY *key
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return key->CalcKeyHash();
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
EqualKeys(
|
|
||||||
APPLICATION_KEY *key1,
|
|
||||||
APPLICATION_KEY *key2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return key1->GetIsEqual(key2);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ReferenceRecord(
|
|
||||||
APPLICATION *pApplication
|
|
||||||
)
|
|
||||||
{
|
|
||||||
pApplication->ReferenceApplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DereferenceRecord(
|
|
||||||
APPLICATION *pApplication
|
|
||||||
)
|
|
||||||
{
|
|
||||||
pApplication->DereferenceApplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
APPLICATION_HASH(const APPLICATION_HASH &);
|
|
||||||
void operator=(const APPLICATION_HASH &);
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
// 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
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
APPLICATION*
|
||||||
|
QueryApplication()
|
||||||
|
{
|
||||||
|
return m_pApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
EnsureApplicationCreated();
|
||||||
|
|
||||||
|
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER
|
||||||
|
QueryCreateRequestHandler()
|
||||||
|
{
|
||||||
|
return m_pfnAspNetCoreCreateRequestHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HRESULT FindRequestHandlerAssembly();
|
||||||
|
HRESULT FindNativeAssemblyFromGlobalLocation(STRU* struFilename);
|
||||||
|
HRESULT FindNativeAssemblyFromLocalBin(STRU* struFilename);
|
||||||
|
HRESULT GetRequestHandlerFromRuntimeStore(STRU* struFilename);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
APPLICATION_INFO_HASH(const APPLICATION_INFO_HASH &);
|
||||||
|
void operator=(const APPLICATION_INFO_HASH &);
|
||||||
|
};
|
||||||
|
|
@ -5,6 +5,11 @@
|
||||||
|
|
||||||
#define DEFAULT_HASH_BUCKETS 293
|
#define DEFAULT_HASH_BUCKETS 293
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
class APPLICATION_MANAGER
|
class APPLICATION_MANAGER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -15,12 +20,12 @@ public:
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if( sm_pApplicationManager == NULL )
|
if ( sm_pApplicationManager == NULL )
|
||||||
{
|
{
|
||||||
sm_pApplicationManager = new APPLICATION_MANAGER();
|
sm_pApplicationManager = new APPLICATION_MANAGER();
|
||||||
}
|
}
|
||||||
|
|
||||||
return sm_pApplicationManager;
|
return sm_pApplicationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -37,29 +42,27 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
GetApplication(
|
GetApplicationInfo(
|
||||||
_In_ IHttpContext* pContext,
|
_In_ IHttpServer* pServer,
|
||||||
_In_ ASPNETCORE_CONFIG* pConfig,
|
_In_ ASPNETCORE_CONFIG* pConfig,
|
||||||
_Out_ APPLICATION ** ppApplication
|
_Out_ APPLICATION_INFO ** ppApplicationInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
RecycleApplication(
|
RecycleApplication(
|
||||||
_In_ LPCWSTR pszApplication
|
_In_ LPCWSTR pszApplicationId
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT
|
VOID
|
||||||
Get502ErrorPage(
|
ShutDown();
|
||||||
_Out_ HTTP_DATA_CHUNK** ppErrorPage
|
|
||||||
);
|
|
||||||
|
|
||||||
~APPLICATION_MANAGER()
|
~APPLICATION_MANAGER()
|
||||||
{
|
{
|
||||||
if(m_pApplicationHash != NULL)
|
if(m_pApplicationInfoHash != NULL)
|
||||||
{
|
{
|
||||||
m_pApplicationHash->Clear();
|
m_pApplicationInfoHash->Clear();
|
||||||
delete m_pApplicationHash;
|
delete m_pApplicationInfoHash;
|
||||||
m_pApplicationHash = NULL;
|
m_pApplicationInfoHash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_pFileWatcher!= NULL )
|
if( m_pFileWatcher!= NULL )
|
||||||
|
|
@ -67,13 +70,6 @@ public:
|
||||||
delete m_pFileWatcher;
|
delete m_pFileWatcher;
|
||||||
m_pFileWatcher = NULL;
|
m_pFileWatcher = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_pHttp502ErrorPage != NULL)
|
|
||||||
{
|
|
||||||
delete m_pHttp502ErrorPage;
|
|
||||||
m_pHttp502ErrorPage = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_WATCHER*
|
FILE_WATCHER*
|
||||||
|
|
@ -86,16 +82,16 @@ public:
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if(m_pApplicationHash == NULL)
|
if(m_pApplicationInfoHash == NULL)
|
||||||
{
|
{
|
||||||
m_pApplicationHash = new APPLICATION_HASH();
|
m_pApplicationInfoHash = new APPLICATION_INFO_HASH();
|
||||||
if(m_pApplicationHash == NULL)
|
if(m_pApplicationInfoHash == NULL)
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_pApplicationHash->Initialize(DEFAULT_HASH_BUCKETS);
|
hr = m_pApplicationInfoHash->Initialize(DEFAULT_HASH_BUCKETS);
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -122,41 +118,18 @@ private:
|
||||||
//
|
//
|
||||||
// we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload
|
// we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload
|
||||||
//
|
//
|
||||||
APPLICATION_MANAGER() : m_pApplicationHash(NULL), m_pFileWatcher(NULL),
|
APPLICATION_MANAGER() : m_pApplicationInfoHash(NULL),
|
||||||
m_pHttp502ErrorPage(NULL), m_hostingModel(HOSTING_UNKNOWN),
|
m_pFileWatcher(NULL),
|
||||||
m_pstrErrorInfo(
|
m_hostingModel(HOSTING_UNKNOWN),
|
||||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> \
|
m_fInShutdown(FALSE)
|
||||||
<html xmlns=\"http://www.w3.org/1999/xhtml\"> \
|
|
||||||
<head> \
|
|
||||||
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" /> \
|
|
||||||
<title> IIS 502.5 Error </title><style type=\"text/css\"></style></head> \
|
|
||||||
<body> <div id = \"content\"> \
|
|
||||||
<div class = \"content-container\"><h3> HTTP Error 502.5 - Process Failure </h3></div> \
|
|
||||||
<div class = \"content-container\"> \
|
|
||||||
<fieldset> <h4> Common causes of this issue: </h4> \
|
|
||||||
<ul><li> The application process failed to start </li> \
|
|
||||||
<li> The application process started but then stopped </li> \
|
|
||||||
<li> The application process started but failed to listen on the configured port </li></ul></fieldset> \
|
|
||||||
</div> \
|
|
||||||
<div class = \"content-container\"> \
|
|
||||||
<fieldset><h4> Troubleshooting steps: </h4> \
|
|
||||||
<ul><li> Check the system event log for error messages </li> \
|
|
||||||
<li> Enable logging the application process' stdout messages </li> \
|
|
||||||
<li> Attach a debugger to the application process and inspect </li></ul></fieldset> \
|
|
||||||
<fieldset><h4> For more information visit: \
|
|
||||||
<a href=\"https://go.microsoft.com/fwlink/?linkid=808681\"> <cite> https://go.microsoft.com/fwlink/?LinkID=808681 </cite></a></h4> \
|
|
||||||
</fieldset> \
|
|
||||||
</div> \
|
|
||||||
</div></body></html>")
|
|
||||||
{
|
{
|
||||||
InitializeSRWLock(&m_srwLock);
|
InitializeSRWLock(&m_srwLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_WATCHER *m_pFileWatcher;
|
FILE_WATCHER *m_pFileWatcher;
|
||||||
APPLICATION_HASH *m_pApplicationHash;
|
APPLICATION_INFO_HASH *m_pApplicationInfoHash;
|
||||||
static APPLICATION_MANAGER *sm_pApplicationManager;
|
static APPLICATION_MANAGER *sm_pApplicationManager;
|
||||||
SRWLOCK m_srwLock;
|
SRWLOCK m_srwLock;
|
||||||
HTTP_DATA_CHUNK *m_pHttp502ErrorPage;
|
|
||||||
LPSTR m_pstrErrorInfo;
|
|
||||||
APP_HOSTING_MODEL m_hostingModel;
|
APP_HOSTING_MODEL m_hostingModel;
|
||||||
|
bool m_fInShutdown;
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
// 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 (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;
|
||||||
|
};
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#define FILE_WATCHER_ENTRY_SIGNATURE ((DWORD) 'FWES')
|
#define FILE_WATCHER_ENTRY_SIGNATURE ((DWORD) 'FWES')
|
||||||
#define FILE_WATCHER_ENTRY_SIGNATURE_FREE ((DWORD) 'sewf')
|
#define FILE_WATCHER_ENTRY_SIGNATURE_FREE ((DWORD) 'sewf')
|
||||||
|
|
||||||
class APPLICATION;
|
class APPLICATION_INFO;
|
||||||
|
|
||||||
class FILE_WATCHER{
|
class FILE_WATCHER{
|
||||||
public:
|
public:
|
||||||
|
|
@ -67,7 +67,7 @@ public:
|
||||||
Create(
|
Create(
|
||||||
_In_ PCWSTR pszDirectoryToMonitor,
|
_In_ PCWSTR pszDirectoryToMonitor,
|
||||||
_In_ PCWSTR pszFileNameToMonitor,
|
_In_ PCWSTR pszFileNameToMonitor,
|
||||||
_In_ APPLICATION* pApplication,
|
_In_ APPLICATION_INFO* pApplicationInfo,
|
||||||
_In_ HANDLE hImpersonationToken
|
_In_ HANDLE hImpersonationToken
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -116,7 +116,7 @@ private:
|
||||||
HANDLE _hImpersonationToken;
|
HANDLE _hImpersonationToken;
|
||||||
HANDLE _hDirectory;
|
HANDLE _hDirectory;
|
||||||
FILE_WATCHER* _pFileMonitor;
|
FILE_WATCHER* _pFileMonitor;
|
||||||
APPLICATION* _pApplication;
|
APPLICATION_INFO* _pApplicationInfo;
|
||||||
STRU _strFileName;
|
STRU _strFileName;
|
||||||
STRU _strDirectoryName;
|
STRU _strDirectoryName;
|
||||||
LONG _lStopMonitorCalled;
|
LONG _lStopMonitorCalled;
|
||||||
|
|
|
||||||
|
|
@ -1,446 +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 "forwarderconnection.h"
|
|
||||||
#include "protocolconfig.h"
|
|
||||||
#include "serverprocess.h"
|
|
||||||
#include "application.h"
|
|
||||||
#include "tracelog.h"
|
|
||||||
#include "websockethandler.h"
|
|
||||||
|
|
||||||
enum FORWARDING_REQUEST_STATUS
|
|
||||||
{
|
|
||||||
FORWARDER_START,
|
|
||||||
FORWARDER_SENDING_REQUEST,
|
|
||||||
FORWARDER_RECEIVING_RESPONSE,
|
|
||||||
FORWARDER_RECEIVED_WEBSOCKET_RESPONSE,
|
|
||||||
FORWARDER_RESET_CONNECTION,
|
|
||||||
FORWARDER_DONE
|
|
||||||
};
|
|
||||||
|
|
||||||
extern HTTP_MODULE_ID g_pModuleId;
|
|
||||||
extern IHttpServer * g_pHttpServer;
|
|
||||||
extern BOOL g_fAsyncDisconnectAvailable;
|
|
||||||
extern PCWSTR g_pszModuleName;
|
|
||||||
extern HMODULE g_hModule;
|
|
||||||
extern HMODULE g_hWinHttpModule;
|
|
||||||
extern DWORD g_dwTlsIndex;
|
|
||||||
extern DWORD g_OptionalWinHttpFlags;
|
|
||||||
|
|
||||||
enum MULTI_PART_POSITION
|
|
||||||
{
|
|
||||||
MULTI_PART_IN_BOUNDARY,
|
|
||||||
MULTI_PART_IN_HEADER,
|
|
||||||
MULTI_PART_IN_CHUNK,
|
|
||||||
MULTI_PART_IN_CHUNK_END
|
|
||||||
};
|
|
||||||
|
|
||||||
class ASYNC_DISCONNECT_CONTEXT;
|
|
||||||
|
|
||||||
#define FORWARDING_HANDLER_SIGNATURE ((DWORD)'FHLR')
|
|
||||||
#define FORWARDING_HANDLER_SIGNATURE_FREE ((DWORD)'fhlr')
|
|
||||||
|
|
||||||
class FORWARDING_HANDLER
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
FORWARDING_HANDLER(
|
|
||||||
__in IHttpContext * pW3Context,
|
|
||||||
__in APPLICATION * pApplication
|
|
||||||
);
|
|
||||||
|
|
||||||
static void * operator new(size_t size);
|
|
||||||
|
|
||||||
static void operator delete(void * pMemory);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ReferenceForwardingHandler(
|
|
||||||
VOID
|
|
||||||
) const;
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DereferenceForwardingHandler(
|
|
||||||
VOID
|
|
||||||
) const;
|
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
OnExecuteRequestHandler();
|
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
OnAsyncCompletion(
|
|
||||||
DWORD cbCompletion,
|
|
||||||
HRESULT hrCompletionStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
IHttpTraceContext *
|
|
||||||
QueryTraceContext()
|
|
||||||
{
|
|
||||||
return m_pW3Context->GetTraceContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
IHttpContext *
|
|
||||||
QueryHttpContext(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_pW3Context;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
VOID
|
|
||||||
CALLBACK
|
|
||||||
OnWinHttpCompletion(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
DWORD_PTR dwContext,
|
|
||||||
DWORD dwInternetStatus,
|
|
||||||
LPVOID lpvStatusInformation,
|
|
||||||
DWORD dwStatusInformationLength
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
FORWARDING_HANDLER * pThis = static_cast<FORWARDING_HANDLER *>(reinterpret_cast<PVOID>(dwContext));
|
|
||||||
if (pThis == NULL)
|
|
||||||
{
|
|
||||||
//error happened, nothing can be done here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DBG_ASSERT(pThis->m_Signature == FORWARDING_HANDLER_SIGNATURE);
|
|
||||||
pThis->OnWinHttpCompletionInternal(hRequest,
|
|
||||||
dwInternetStatus,
|
|
||||||
lpvStatusInformation,
|
|
||||||
dwStatusInformationLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
HRESULT
|
|
||||||
StaticInitialize(
|
|
||||||
BOOL fEnableReferenceCountTracing
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
|
||||||
VOID
|
|
||||||
StaticTerminate();
|
|
||||||
|
|
||||||
static
|
|
||||||
PCWSTR
|
|
||||||
QueryErrorFormat()
|
|
||||||
{
|
|
||||||
return sm_strErrorFormat.QueryStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
HANDLE
|
|
||||||
QueryEventLog()
|
|
||||||
{
|
|
||||||
return sm_hEventLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
TerminateRequest(
|
|
||||||
bool fClientInitiated
|
|
||||||
);
|
|
||||||
|
|
||||||
static HINTERNET sm_hSession;
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
SetStatusAndHeaders(
|
|
||||||
PCSTR pszHeaders,
|
|
||||||
DWORD cchHeaders
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnSharedRequestEntity(
|
|
||||||
ULONGLONG ulOffset,
|
|
||||||
LPCBYTE pvBuffer,
|
|
||||||
DWORD cbBuffer
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetStatus(
|
|
||||||
FORWARDING_REQUEST_STATUS status
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_RequestStatus = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
virtual
|
|
||||||
~FORWARDING_HANDLER(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Begin OnMapRequestHandler phases.
|
|
||||||
//
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
CreateWinHttpRequest(
|
|
||||||
__in const IHttpRequest * pRequest,
|
|
||||||
__in const PROTOCOL_CONFIG * pProtocol,
|
|
||||||
__in HINTERNET hConnect,
|
|
||||||
__inout STRU * pstrUrl,
|
|
||||||
ASPNETCORE_CONFIG* pAspNetCoreConfig,
|
|
||||||
SERVER_PROCESS* pServerProcess
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// End OnMapRequestHandler phases.
|
|
||||||
//
|
|
||||||
|
|
||||||
VOID
|
|
||||||
RemoveRequest();
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
GetHeaders(
|
|
||||||
const PROTOCOL_CONFIG * pProtocol,
|
|
||||||
PCWSTR * ppszHeaders,
|
|
||||||
DWORD * pcchHeaders,
|
|
||||||
ASPNETCORE_CONFIG* pAspNetCoreConfig,
|
|
||||||
SERVER_PROCESS* pServerProcess
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
DoReverseRewrite(
|
|
||||||
__in IHttpResponse *pResponse
|
|
||||||
);
|
|
||||||
|
|
||||||
BYTE *
|
|
||||||
GetNewResponseBuffer(
|
|
||||||
DWORD dwBufferSize
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
FreeResponseBuffers();
|
|
||||||
|
|
||||||
VOID
|
|
||||||
OnWinHttpCompletionInternal(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
DWORD dwInternetStatus,
|
|
||||||
LPVOID lpvStatusInformation,
|
|
||||||
DWORD dwStatusInformationLength
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWinHttpCompletionSendRequestOrWriteComplete(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
DWORD dwInternetStatus,
|
|
||||||
__out bool * pfClientError,
|
|
||||||
__out bool * pfAnotherCompletionExpected
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWinHttpCompletionStatusHeadersAvailable(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
__out bool * pfAnotherCompletionExpected
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWinHttpCompletionStatusDataAvailable(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
DWORD dwBytes,
|
|
||||||
__out bool * pfAnotherCompletionExpected
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWinHttpCompletionStatusReadComplete(
|
|
||||||
__in IHttpResponse * pResponse,
|
|
||||||
DWORD dwStatusInformationLength,
|
|
||||||
__out bool * pfAnotherCompletionExpected
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnSendingRequest(
|
|
||||||
DWORD cbCompletion,
|
|
||||||
HRESULT hrCompletionStatus,
|
|
||||||
__out bool * pfClientError
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnReceivingResponse();
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWebSocketWinHttpSendComplete(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
LPVOID pvStatus,
|
|
||||||
DWORD hrCompletion,
|
|
||||||
DWORD cbCompletion,
|
|
||||||
bool * pfAnotherCompletionExpected
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWebSocketWinHttpReceiveComplete(
|
|
||||||
HINTERNET hRequest,
|
|
||||||
LPVOID pvStatus,
|
|
||||||
DWORD hrCompletion,
|
|
||||||
DWORD cbCompletion,
|
|
||||||
bool * pfAnotherCompletionExpected
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWebSocketIisSendComplete(
|
|
||||||
DWORD hrCompletion,
|
|
||||||
DWORD cbCompletion
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
OnWebSocketIisReceiveComplete(
|
|
||||||
DWORD hrCompletion,
|
|
||||||
DWORD cbCompletion
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
DoIisWebSocketReceive(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
TerminateWebsocket(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
SetHttpSysDisconnectCallback(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
DWORD m_Signature;
|
|
||||||
mutable LONG m_cRefs;
|
|
||||||
|
|
||||||
IHttpContext * m_pW3Context;
|
|
||||||
IHttpContext * m_pChildRequestContext;
|
|
||||||
|
|
||||||
//
|
|
||||||
// WinHTTP request handle is protected using a read-write lock.
|
|
||||||
//
|
|
||||||
SRWLOCK m_RequestLock;
|
|
||||||
HINTERNET m_hRequest;
|
|
||||||
|
|
||||||
APP_OFFLINE_HTM *m_pAppOfflineHtm;
|
|
||||||
APPLICATION *m_pApplication;
|
|
||||||
|
|
||||||
bool m_fWebSocketEnabled;
|
|
||||||
bool m_fHandleClosedDueToClient;
|
|
||||||
bool m_fResponseHeadersReceivedAndSet;
|
|
||||||
BOOL m_fDoReverseRewriteHeaders;
|
|
||||||
BOOL m_fErrorHandled;
|
|
||||||
BOOL m_fWebSocketUpgrade;
|
|
||||||
BOOL m_fFinishRequest;
|
|
||||||
BOOL m_fClientDisconnected;
|
|
||||||
BOOL m_fHasError;
|
|
||||||
DWORD m_msStartTime;
|
|
||||||
DWORD m_BytesToReceive;
|
|
||||||
DWORD m_BytesToSend;
|
|
||||||
DWORD m_cchLastSend;
|
|
||||||
DWORD m_cEntityBuffers;
|
|
||||||
DWORD m_cBytesBuffered;
|
|
||||||
DWORD m_cMinBufferLimit;
|
|
||||||
|
|
||||||
BYTE * m_pEntityBuffer;
|
|
||||||
static const SIZE_T INLINE_ENTITY_BUFFERS = 8;
|
|
||||||
BUFFER_T<BYTE*,INLINE_ENTITY_BUFFERS> m_buffEntityBuffers;
|
|
||||||
|
|
||||||
PCSTR m_pszOriginalHostHeader;
|
|
||||||
|
|
||||||
FORWARDING_REQUEST_STATUS m_RequestStatus;
|
|
||||||
|
|
||||||
ASYNC_DISCONNECT_CONTEXT * m_pDisconnect;
|
|
||||||
|
|
||||||
PCWSTR m_pszHeaders;
|
|
||||||
DWORD m_cchHeaders;
|
|
||||||
|
|
||||||
STRU m_strFullUri;
|
|
||||||
|
|
||||||
ULONGLONG m_cContentLength;
|
|
||||||
|
|
||||||
WEBSOCKET_HANDLER * m_pWebSocket;
|
|
||||||
|
|
||||||
static PROTOCOL_CONFIG sm_ProtocolConfig;
|
|
||||||
|
|
||||||
static STRU sm_strErrorFormat;
|
|
||||||
|
|
||||||
static HANDLE sm_hEventLog;
|
|
||||||
|
|
||||||
static ALLOC_CACHE_HANDLER * sm_pAlloc;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Reference cout tracing for debugging purposes.
|
|
||||||
//
|
|
||||||
static TRACE_LOG * sm_pTraceLog;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ASYNC_DISCONNECT_CONTEXT : public IHttpConnectionStoredContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ASYNC_DISCONNECT_CONTEXT()
|
|
||||||
{
|
|
||||||
m_pHandler = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
CleanupStoredContext()
|
|
||||||
{
|
|
||||||
DBG_ASSERT(m_pHandler == NULL);
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NotifyDisconnect()
|
|
||||||
{
|
|
||||||
FORWARDING_HANDLER *pInitialValue = (FORWARDING_HANDLER*)
|
|
||||||
InterlockedExchangePointer((PVOID*) &m_pHandler, NULL);
|
|
||||||
|
|
||||||
if (pInitialValue != NULL)
|
|
||||||
{
|
|
||||||
pInitialValue->TerminateRequest(TRUE);
|
|
||||||
pInitialValue->DereferenceForwardingHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetHandler(
|
|
||||||
FORWARDING_HANDLER *pHandler
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Take a reference on the forwarding handler.
|
|
||||||
// This reference will be released on either of two conditions:
|
|
||||||
//
|
|
||||||
// 1. When the request processing ends, in which case a ResetHandler()
|
|
||||||
// is called.
|
|
||||||
//
|
|
||||||
// 2. When a disconnect notification arrives.
|
|
||||||
//
|
|
||||||
// We need to make sure that only one of them ends up dereferencing
|
|
||||||
// the object.
|
|
||||||
//
|
|
||||||
|
|
||||||
DBG_ASSERT (pHandler != NULL);
|
|
||||||
DBG_ASSERT (m_pHandler == NULL);
|
|
||||||
|
|
||||||
pHandler->ReferenceForwardingHandler();
|
|
||||||
InterlockedExchangePointer((PVOID*)&m_pHandler, pHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ResetHandler(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FORWARDING_HANDLER *pInitialValue = (FORWARDING_HANDLER*)
|
|
||||||
InterlockedExchangePointer( (PVOID*)&m_pHandler, NULL);
|
|
||||||
|
|
||||||
if (pInitialValue != NULL)
|
|
||||||
{
|
|
||||||
pInitialValue->DereferenceForwardingHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
~ASYNC_DISCONNECT_CONTEXT()
|
|
||||||
{}
|
|
||||||
|
|
||||||
FORWARDING_HANDLER * m_pHandler;
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
|
@ -1,90 +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 IN_PROCESS_STORED_CONTEXT : public IHttpStoredContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IN_PROCESS_STORED_CONTEXT(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
PVOID pvManagedContext
|
|
||||||
);
|
|
||||||
|
|
||||||
~IN_PROCESS_STORED_CONTEXT();
|
|
||||||
|
|
||||||
virtual
|
|
||||||
VOID
|
|
||||||
CleanupStoredContext(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
VOID
|
|
||||||
OnClientDisconnected(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
VOID
|
|
||||||
OnListenerEvicted(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
|
||||||
QueryManagedHttpContext(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
IHttpContext*
|
|
||||||
QueryHttpContext(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
QueryIsManagedRequestComplete(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IndicateManagedRequestComplete(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
QueryAsyncCompletionStatus(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
SetAsyncCompletionStatus(
|
|
||||||
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
|
||||||
HRESULT
|
|
||||||
GetInProcessStoredContext(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
IN_PROCESS_STORED_CONTEXT** ppInProcessStoredContext
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
|
||||||
HRESULT
|
|
||||||
SetInProcessStoredContext(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
|
||||||
PVOID m_pManagedHttpContext;
|
|
||||||
IHttpContext* m_pHttpContext;
|
|
||||||
BOOL m_fManagedRequestComplete;
|
|
||||||
REQUEST_NOTIFICATION_STATUS m_requestNotificationStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
@ -1,40 +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 "application.h"
|
|
||||||
|
|
||||||
class OUT_OF_PROCESS_APPLICATION : public APPLICATION
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
OUT_OF_PROCESS_APPLICATION();
|
|
||||||
|
|
||||||
~OUT_OF_PROCESS_APPLICATION();
|
|
||||||
|
|
||||||
__override
|
|
||||||
HRESULT Initialize(_In_ APPLICATION_MANAGER* pApplicationManager,
|
|
||||||
_In_ ASPNETCORE_CONFIG* pConfiguration);
|
|
||||||
|
|
||||||
__override
|
|
||||||
VOID OnAppOfflineHandleChange();
|
|
||||||
|
|
||||||
__override
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
ExecuteRequest(
|
|
||||||
_In_ IHttpContext* pHttpContext
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
GetProcess(
|
|
||||||
_In_ IHttpContext *context,
|
|
||||||
_Out_ SERVER_PROCESS **ppServerProcess
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_pProcessManager->GetProcess(context, m_pConfiguration, ppServerProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
PROCESS_MANAGER* m_pProcessManager;
|
|
||||||
};
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
|
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "forwardinghandler.h"
|
extern HTTP_MODULE_ID g_pModuleId;
|
||||||
|
extern IHttpServer *g_pHttpServer;
|
||||||
|
extern HMODULE g_hAspnetCoreRH;
|
||||||
|
|
||||||
class CProxyModule : public CHttpModule
|
class ASPNET_CORE_PROXY_MODULE : public CHttpModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CProxyModule();
|
ASPNET_CORE_PROXY_MODULE();
|
||||||
|
|
||||||
~CProxyModule();
|
~ASPNET_CORE_PROXY_MODULE();
|
||||||
|
|
||||||
void * operator new(size_t size, IModuleAllocator * pPlacement)
|
void * operator new(size_t size, IModuleAllocator * pPlacement)
|
||||||
{
|
{
|
||||||
|
|
@ -44,10 +45,12 @@ class CProxyModule : public CHttpModule
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
FORWARDING_HANDLER * m_pHandler;
|
APPLICATION_INFO *m_pApplicationInfo;
|
||||||
|
APPLICATION *m_pApplication;
|
||||||
|
REQUEST_HANDLER *m_pHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CProxyModuleFactory : public IHttpModuleFactory
|
class ASPNET_CORE_PROXY_MODULE_FACTORY : public IHttpModuleFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#define IDS_INVALID_PROPERTY 1000
|
#define IDS_INVALID_PROPERTY 1000
|
||||||
#define IDS_SERVER_ERROR 1001
|
#define IDS_SERVER_ERROR 1001
|
||||||
|
|
||||||
|
// TODO remove this file?
|
||||||
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
|
#define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256
|
||||||
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'."
|
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'."
|
||||||
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded."
|
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded."
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
#include "precomp.hxx"
|
|
||||||
|
|
||||||
APPLICATION::~APPLICATION()
|
|
||||||
{
|
|
||||||
if (m_pAppOfflineHtm != NULL)
|
|
||||||
{
|
|
||||||
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
|
|
||||||
m_pAppOfflineHtm = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pFileWatcherEntry != NULL)
|
|
||||||
{
|
|
||||||
// Mark the entry as invalid,
|
|
||||||
// StopMonitor will close the file handle and trigger a FCN
|
|
||||||
// the entry will delete itself when processing this FCN
|
|
||||||
m_pFileWatcherEntry->MarkEntryInValid();
|
|
||||||
m_pFileWatcherEntry->StopMonitor();
|
|
||||||
m_pFileWatcherEntry = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
APPLICATION::StartMonitoringAppOffline()
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
if (m_pFileWatcherEntry != NULL)
|
|
||||||
{
|
|
||||||
hr = m_pFileWatcherEntry->Create(m_pConfiguration->QueryApplicationFullPath()->QueryStr(), L"app_offline.htm", this, NULL);
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
APPLICATION::UpdateAppOfflineFileHandle()
|
|
||||||
{
|
|
||||||
STRU strFilePath;
|
|
||||||
PATH::ConvertPathToFullPath(L".\\app_offline.htm", m_pConfiguration->QueryApplicationFullPath()->QueryStr(), &strFilePath);
|
|
||||||
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
|
|
||||||
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
|
|
||||||
|
|
||||||
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) && GetLastError() == ERROR_FILE_NOT_FOUND)
|
|
||||||
{
|
|
||||||
m_fAppOfflineFound = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_fAppOfflineFound = TRUE;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OnAppOfflineHandleChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,332 @@
|
||||||
|
// 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 = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) &&
|
||||||
|
GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||||
|
{
|
||||||
|
m_fAppOfflineFound = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_fAppOfflineFound = TRUE;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recycle the application
|
||||||
|
if (m_pApplication != NULL)
|
||||||
|
{
|
||||||
|
m_pApplication->ShutDown();
|
||||||
|
m_pApplication->DereferenceApplication();
|
||||||
|
m_pApplication = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION_INFO::EnsureApplicationCreated()
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
APPLICATION* pApplication = NULL;
|
||||||
|
STACK_STRU(struFileName, 300); // >MAX_PATH
|
||||||
|
STRU hostFxrDllLocation;
|
||||||
|
|
||||||
|
if (m_pApplication != NULL)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = FindRequestHandlerAssembly();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pApplication == NULL)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fLocked = TRUE;
|
||||||
|
if (m_pApplication != NULL)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load assembly and create the application
|
||||||
|
if (m_pConfiguration->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
|
||||||
|
{
|
||||||
|
// Look at inetsvr only for now. TODO add in functionality
|
||||||
|
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
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
|
||||||
|
while (!fDone)
|
||||||
|
{
|
||||||
|
DWORD dwReturnedSize = GetModuleFileName(NULL, 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
|
||||||
|
struFilename->Resize(dwSize + 20); // aspnetcorerh.dll
|
||||||
|
}
|
||||||
|
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(g_pwzAspnetcoreRequestHandlerName)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -6,28 +6,28 @@
|
||||||
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
|
APPLICATION_MANAGER* APPLICATION_MANAGER::sm_pApplicationManager = NULL;
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
APPLICATION_MANAGER::GetApplication(
|
APPLICATION_MANAGER::GetApplicationInfo(
|
||||||
_In_ IHttpContext* pContext,
|
_In_ IHttpServer* pServer,
|
||||||
_In_ ASPNETCORE_CONFIG* pConfig,
|
_In_ ASPNETCORE_CONFIG* pConfig,
|
||||||
_Out_ APPLICATION ** ppApplication
|
_Out_ APPLICATION_INFO ** ppApplicationInfo
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
APPLICATION *pApplication = NULL;
|
APPLICATION_INFO *pApplicationInfo = NULL;
|
||||||
APPLICATION_KEY key;
|
APPLICATION_INFO_KEY key;
|
||||||
BOOL fExclusiveLock = FALSE;
|
BOOL fExclusiveLock = FALSE;
|
||||||
BOOL fMixedHostingModelError = FALSE;
|
BOOL fMixedHostingModelError = FALSE;
|
||||||
BOOL fDuplicatedInProcessApp = FALSE;
|
BOOL fDuplicatedInProcessApp = FALSE;
|
||||||
PCWSTR pszApplicationId = NULL;
|
PCWSTR pszApplicationId = NULL;
|
||||||
LPCWSTR apsz[1];
|
LPCWSTR apsz[1];
|
||||||
STACK_STRU ( strEventMsg, 256 );
|
STACK_STRU ( strEventMsg, 256 );
|
||||||
|
|
||||||
*ppApplication = NULL;
|
*ppApplicationInfo = NULL;
|
||||||
|
|
||||||
DBG_ASSERT(pContext != NULL);
|
DBG_ASSERT(pServer != NULL);
|
||||||
DBG_ASSERT(pContext->GetApplication() != NULL);
|
DBG_ASSERT(pConfig != NULL);
|
||||||
|
|
||||||
pszApplicationId = pContext->GetApplication()->GetApplicationId();
|
pszApplicationId = pConfig->QueryConfigPath()->QueryStr();
|
||||||
|
|
||||||
hr = key.Initialize(pszApplicationId);
|
hr = key.Initialize(pszApplicationId);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -35,33 +35,39 @@ APPLICATION_MANAGER::GetApplication(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pApplicationHash->FindKey(&key, ppApplication);
|
AcquireSRWLockShared(&m_srwLock);
|
||||||
|
if (m_fInShutdown)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockShared(&m_srwLock);
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_SERVER_SHUTDOWN_IN_PROGRESS);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
m_pApplicationInfoHash->FindKey(&key, ppApplicationInfo);
|
||||||
|
ReleaseSRWLockShared(&m_srwLock);
|
||||||
|
|
||||||
if (*ppApplication == NULL)
|
if (*ppApplicationInfo == NULL)
|
||||||
{
|
{
|
||||||
switch (pConfig->QueryHostingModel())
|
switch (pConfig->QueryHostingModel())
|
||||||
{
|
{
|
||||||
case HOSTING_IN_PROCESS:
|
case HOSTING_IN_PROCESS:
|
||||||
if (m_pApplicationHash->Count() > 0)
|
if (m_pApplicationInfoHash->Count() > 0)
|
||||||
{
|
{
|
||||||
// Only one inprocess app is allowed per IIS worker process
|
// Only one inprocess app is allowed per IIS worker process
|
||||||
fDuplicatedInProcessApp = TRUE;
|
fDuplicatedInProcessApp = TRUE;
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_APP_INIT_FAILURE);
|
hr = HRESULT_FROM_WIN32(ERROR_APP_INIT_FAILURE);
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
pApplication = new IN_PROCESS_APPLICATION();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HOSTING_OUT_PROCESS:
|
case HOSTING_OUT_PROCESS:
|
||||||
pApplication = new OUT_OF_PROCESS_APPLICATION();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
hr = E_UNEXPECTED;
|
hr = E_UNEXPECTED;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
pApplicationInfo = new APPLICATION_INFO(pServer);
|
||||||
if (pApplication == NULL)
|
if (pApplicationInfo == NULL)
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -69,13 +75,19 @@ APPLICATION_MANAGER::GetApplication(
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
fExclusiveLock = TRUE;
|
fExclusiveLock = TRUE;
|
||||||
m_pApplicationHash->FindKey(&key, ppApplication);
|
if (m_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 (*ppApplication != NULL)
|
if (*ppApplicationInfo != NULL)
|
||||||
{
|
{
|
||||||
// someone else created the application
|
// someone else created the application
|
||||||
delete pApplication;
|
delete pApplicationInfo;
|
||||||
pApplication = NULL;
|
pApplicationInfo = NULL;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,13 +104,13 @@ APPLICATION_MANAGER::GetApplication(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pApplication->Initialize(this, pConfig);
|
hr = pApplicationInfo->Initialize(pConfig, m_pFileWatcher);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_pApplicationHash->InsertRecord( pApplication );
|
hr = m_pApplicationInfoHash->InsertRecord( pApplicationInfo );
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -112,13 +124,12 @@ APPLICATION_MANAGER::GetApplication(
|
||||||
m_hostingModel = pConfig->QueryHostingModel();
|
m_hostingModel = pConfig->QueryHostingModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*ppApplicationInfo = pApplicationInfo;
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
fExclusiveLock = FALSE;
|
fExclusiveLock = FALSE;
|
||||||
|
|
||||||
pApplication->StartMonitoringAppOffline();
|
pApplicationInfo->StartMonitoringAppOffline();
|
||||||
|
pApplicationInfo = NULL;
|
||||||
*ppApplication = pApplication;
|
|
||||||
pApplication = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
@ -128,21 +139,21 @@ Finished:
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pApplicationInfo != NULL)
|
||||||
|
{
|
||||||
|
pApplicationInfo->DereferenceApplicationInfo();
|
||||||
|
pApplicationInfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
if (pApplication != NULL)
|
|
||||||
{
|
|
||||||
pApplication->DereferenceApplication();
|
|
||||||
pApplication = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fDuplicatedInProcessApp)
|
if (fDuplicatedInProcessApp)
|
||||||
{
|
{
|
||||||
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
|
ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG,
|
||||||
pszApplicationId)))
|
pszApplicationId)))
|
||||||
{
|
{
|
||||||
apsz[0] = strEventMsg.QueryStr();
|
/*apsz[0] = strEventMsg.QueryStr();
|
||||||
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
{
|
{
|
||||||
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
|
@ -154,30 +165,30 @@ Finished:
|
||||||
0,
|
0,
|
||||||
apsz,
|
apsz,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fMixedHostingModelError)
|
else if (fMixedHostingModelError)
|
||||||
{
|
{
|
||||||
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
|
// ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG,
|
||||||
pszApplicationId,
|
// pszApplicationId,
|
||||||
pConfig->QueryHostingModelStr())))
|
// pConfig->QueryHostingModelStr())))
|
||||||
{
|
//{
|
||||||
apsz[0] = strEventMsg.QueryStr();
|
// apsz[0] = strEventMsg.QueryStr();
|
||||||
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
// /*if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
{
|
// {
|
||||||
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
EVENTLOG_ERROR_TYPE,
|
// EVENTLOG_ERROR_TYPE,
|
||||||
0,
|
// 0,
|
||||||
ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
|
// ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR,
|
||||||
NULL,
|
// NULL,
|
||||||
1,
|
// 1,
|
||||||
0,
|
// 0,
|
||||||
apsz,
|
// apsz,
|
||||||
NULL);
|
// NULL);
|
||||||
}
|
// }*/
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -187,7 +198,7 @@ Finished:
|
||||||
hr)))
|
hr)))
|
||||||
{
|
{
|
||||||
apsz[0] = strEventMsg.QueryStr();
|
apsz[0] = strEventMsg.QueryStr();
|
||||||
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
/*if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
{
|
{
|
||||||
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
EVENTLOG_ERROR_TYPE,
|
EVENTLOG_ERROR_TYPE,
|
||||||
|
|
@ -198,7 +209,7 @@ Finished:
|
||||||
0,
|
0,
|
||||||
apsz,
|
apsz,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -208,23 +219,33 @@ Finished:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
APPLICATION_MANAGER::RecycleApplication(
|
APPLICATION_MANAGER::RecycleApplication(
|
||||||
_In_ LPCWSTR pszApplication
|
_In_ LPCWSTR pszApplicationId
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
APPLICATION_KEY key;
|
APPLICATION_INFO_KEY key;
|
||||||
|
|
||||||
hr = key.Initialize(pszApplication);
|
hr = key.Initialize(pszApplicationId);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
m_pApplicationHash->DeleteKey(&key);
|
m_pApplicationInfoHash->DeleteKey(&key);
|
||||||
if (m_pApplicationHash->Count() == 0)
|
|
||||||
|
if (m_pApplicationInfoHash->Count() == 0)
|
||||||
{
|
{
|
||||||
m_hostingModel = HOSTING_UNKNOWN;
|
m_hostingModel = HOSTING_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_fAspnetcoreRHLoadedError)
|
||||||
|
{
|
||||||
|
// We had assembly loading failure
|
||||||
|
// this error blocked the start of all applications
|
||||||
|
// Let's recycle the worker process if user redeployed any application
|
||||||
|
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand due to assembly loading failure");
|
||||||
|
}
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
@ -232,65 +253,17 @@ Finished:
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
VOID
|
||||||
APPLICATION_MANAGER::Get502ErrorPage(
|
APPLICATION_MANAGER::ShutDown()
|
||||||
_Out_ HTTP_DATA_CHUNK** ppErrorPage
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
m_fInShutdown = TRUE;
|
||||||
BOOL fExclusiveLock = FALSE;
|
if (m_pApplicationInfoHash != NULL)
|
||||||
HTTP_DATA_CHUNK *pHttp502ErrorPage = NULL;
|
|
||||||
|
|
||||||
DBG_ASSERT(ppErrorPage != NULL);
|
|
||||||
|
|
||||||
//on-demand create the error page
|
|
||||||
if (m_pHttp502ErrorPage != NULL)
|
|
||||||
{
|
|
||||||
*ppErrorPage = m_pHttp502ErrorPage;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
fExclusiveLock = TRUE;
|
|
||||||
if (m_pHttp502ErrorPage != NULL)
|
|
||||||
{
|
|
||||||
*ppErrorPage = m_pHttp502ErrorPage;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t maxsize = 5000;
|
|
||||||
pHttp502ErrorPage = new HTTP_DATA_CHUNK();
|
|
||||||
if (pHttp502ErrorPage == NULL)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
pHttp502ErrorPage->DataChunkType = HttpDataChunkFromMemory;
|
|
||||||
pHttp502ErrorPage->FromMemory.pBuffer = (PVOID)m_pstrErrorInfo;
|
|
||||||
|
|
||||||
pHttp502ErrorPage->FromMemory.BufferLength = (ULONG)strnlen(m_pstrErrorInfo, maxsize); //(ULONG)(wcslen(m_pstrErrorInfo)); // *sizeof(WCHAR);
|
// clean up the hash table so that the application will be informed on shutdown
|
||||||
if(m_pHttp502ErrorPage != NULL)
|
m_pApplicationInfoHash->Clear();
|
||||||
{
|
|
||||||
delete m_pHttp502ErrorPage;
|
|
||||||
}
|
|
||||||
m_pHttp502ErrorPage = pHttp502ErrorPage;
|
|
||||||
*ppErrorPage = m_pHttp502ErrorPage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
if (fExclusiveLock)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
if (pHttp502ErrorPage != NULL)
|
|
||||||
{
|
|
||||||
delete pHttp502ErrorPage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
@ -6,35 +6,42 @@
|
||||||
|
|
||||||
HTTP_MODULE_ID g_pModuleId = NULL;
|
HTTP_MODULE_ID g_pModuleId = NULL;
|
||||||
IHttpServer * g_pHttpServer = NULL;
|
IHttpServer * g_pHttpServer = NULL;
|
||||||
BOOL g_fAsyncDisconnectAvailable = FALSE;
|
|
||||||
BOOL g_fWinHttpNonBlockingCallbackAvailable = FALSE;
|
|
||||||
BOOL g_fRecycleProcessCalled = FALSE;
|
BOOL g_fRecycleProcessCalled = FALSE;
|
||||||
PCWSTR g_pszModuleName = NULL;
|
PCWSTR g_pszModuleName = NULL;
|
||||||
HINSTANCE g_hModule;
|
HINSTANCE g_hModule;
|
||||||
HINSTANCE g_hWinHttpModule;
|
HMODULE g_hAspnetCoreRH = NULL;
|
||||||
BOOL g_fWebSocketSupported = FALSE;
|
BOOL g_fAspnetcoreRHAssemblyLoaded = FALSE;
|
||||||
|
BOOL g_fAspnetcoreRHLoadedError = FALSE;
|
||||||
DWORD g_dwTlsIndex = TLS_OUT_OF_INDEXES;
|
|
||||||
BOOL g_fEnableReferenceCountTracing = FALSE;
|
|
||||||
DWORD g_dwAspNetCoreDebugFlags = 0;
|
DWORD g_dwAspNetCoreDebugFlags = 0;
|
||||||
BOOL g_fNsiApiNotSupported = FALSE;
|
|
||||||
DWORD g_dwActiveServerProcesses = 0;
|
DWORD g_dwActiveServerProcesses = 0;
|
||||||
DWORD g_OptionalWinHttpFlags = 0; //specify additional WinHTTP options when using WinHttpOpenRequest API.
|
SRWLOCK g_srwLock;
|
||||||
|
|
||||||
DWORD g_dwDebugFlags = 0;
|
DWORD g_dwDebugFlags = 0;
|
||||||
PCSTR g_szDebugLabel = "ASPNET_CORE_MODULE";
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HMODULE hModule,
|
BOOL WINAPI DllMain(HMODULE hModule,
|
||||||
DWORD ul_reason_for_call,
|
DWORD ul_reason_for_call,
|
||||||
LPVOID lpReserved
|
LPVOID lpReserved
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(lpReserved);
|
||||||
|
|
||||||
switch (ul_reason_for_call)
|
switch (ul_reason_for_call)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
g_hModule = hModule;
|
g_hModule = hModule;
|
||||||
DisableThreadLibraryCalls(hModule);
|
DisableThreadLibraryCalls(hModule);
|
||||||
break;
|
break;
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
StaticCleanup();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -42,75 +49,6 @@ BOOL WINAPI DllMain(HMODULE hModule,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
LoadGlobalConfiguration(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HKEY hKey;
|
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
||||||
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
|
|
||||||
0,
|
|
||||||
KEY_READ,
|
|
||||||
&hKey) == NO_ERROR)
|
|
||||||
{
|
|
||||||
DWORD dwType;
|
|
||||||
DWORD dwData;
|
|
||||||
DWORD cbData;
|
|
||||||
|
|
||||||
cbData = sizeof(dwData);
|
|
||||||
if ((RegQueryValueEx(hKey,
|
|
||||||
L"OptionalWinHttpFlags",
|
|
||||||
NULL,
|
|
||||||
&dwType,
|
|
||||||
(LPBYTE)&dwData,
|
|
||||||
&cbData) == NO_ERROR) &&
|
|
||||||
(dwType == REG_DWORD))
|
|
||||||
{
|
|
||||||
g_OptionalWinHttpFlags = dwData;
|
|
||||||
}
|
|
||||||
|
|
||||||
cbData = sizeof(dwData);
|
|
||||||
if ((RegQueryValueEx(hKey,
|
|
||||||
L"EnableReferenceCountTracing",
|
|
||||||
NULL,
|
|
||||||
&dwType,
|
|
||||||
(LPBYTE)&dwData,
|
|
||||||
&cbData) == NO_ERROR) &&
|
|
||||||
(dwType == REG_DWORD) && (dwData == 1 || dwData == 0))
|
|
||||||
{
|
|
||||||
g_fEnableReferenceCountTracing = !!dwData;
|
|
||||||
}
|
|
||||||
|
|
||||||
cbData = sizeof(dwData);
|
|
||||||
if ((RegQueryValueEx(hKey,
|
|
||||||
L"DebugFlags",
|
|
||||||
NULL,
|
|
||||||
&dwType,
|
|
||||||
(LPBYTE)&dwData,
|
|
||||||
&cbData) == NO_ERROR) &&
|
|
||||||
(dwType == REG_DWORD))
|
|
||||||
{
|
|
||||||
g_dwAspNetCoreDebugFlags = dwData;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD dwSize = 0;
|
|
||||||
DWORD dwResult = GetExtendedTcpTable(NULL,
|
|
||||||
&dwSize,
|
|
||||||
FALSE,
|
|
||||||
AF_INET,
|
|
||||||
TCP_TABLE_OWNER_PID_LISTENER,
|
|
||||||
0);
|
|
||||||
if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
|
||||||
g_fNsiApiNotSupported = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
__stdcall
|
__stdcall
|
||||||
RegisterModule(
|
RegisterModule(
|
||||||
|
|
@ -138,8 +76,14 @@ HRESULT
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
CProxyModuleFactory * pFactory = NULL;
|
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
|
#ifdef DEBUG
|
||||||
CREATE_DEBUG_PRINT_OBJECT("Asp.Net Core Module");
|
CREATE_DEBUG_PRINT_OBJECT("Asp.Net Core Module");
|
||||||
|
|
@ -148,63 +92,50 @@ HRESULT
|
||||||
|
|
||||||
CREATE_DEBUG_PRINT_OBJECT;
|
CREATE_DEBUG_PRINT_OBJECT;
|
||||||
|
|
||||||
LoadGlobalConfiguration();
|
//LoadGlobalConfiguration();
|
||||||
|
|
||||||
//
|
InitializeSRWLock(&g_srwLock);
|
||||||
// 7.0 is 0,7
|
|
||||||
//
|
|
||||||
if (dwServerVersion > MAKELONG(0, 7))
|
|
||||||
{
|
|
||||||
g_fAsyncDisconnectAvailable = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 8.0 is 0,8
|
|
||||||
//
|
|
||||||
if (dwServerVersion >= MAKELONG(0, 8))
|
|
||||||
{
|
|
||||||
// IISOOB:36641 Enable back WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS for Win8.
|
|
||||||
// g_fWinHttpNonBlockingCallbackAvailable = TRUE;
|
|
||||||
g_fWebSocketSupported = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = WINHTTP_HELPER::StaticInitialize();
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
if (hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND))
|
|
||||||
{
|
|
||||||
g_fWebSocketSupported = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pModuleId = pModuleInfo->GetId();
|
g_pModuleId = pModuleInfo->GetId();
|
||||||
g_pszModuleName = pModuleInfo->GetName();
|
g_pszModuleName = pModuleInfo->GetName();
|
||||||
g_pHttpServer = pHttpServer;
|
g_pHttpServer = pHttpServer;
|
||||||
g_hWinHttpModule = GetModuleHandle(TEXT("winhttp.dll"));
|
|
||||||
|
|
||||||
//
|
// check whether the feature is disabled due to security reason
|
||||||
// WinHTTP does not create enough threads, ask it to create more.
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||||
// Starting in Windows 7, this setting is ignored because WinHTTP
|
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
|
||||||
// uses a thread pool.
|
0,
|
||||||
//
|
KEY_READ,
|
||||||
SYSTEM_INFO si;
|
&hKey) == NO_ERROR)
|
||||||
GetSystemInfo(&si);
|
{
|
||||||
DWORD dwThreadCount = (si.dwNumberOfProcessors * 3 + 1) / 2;
|
DWORD dwType;
|
||||||
WinHttpSetOption(NULL,
|
DWORD dwData;
|
||||||
WINHTTP_OPTION_WORKER_THREAD_COUNT,
|
DWORD cbData;
|
||||||
&dwThreadCount,
|
|
||||||
sizeof(dwThreadCount));
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"DisableANCM",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD))
|
||||||
|
{
|
||||||
|
fDisableANCM = (dwData != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fDisableANCM)
|
||||||
|
{
|
||||||
|
// Logging
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the factory before any static initialization.
|
// Create the factory before any static initialization.
|
||||||
// The CProxyModuleFactory::Terminate method will clean any
|
// The ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate method will clean any
|
||||||
// static object initialized.
|
// static object initialized.
|
||||||
//
|
//
|
||||||
pFactory = new CProxyModuleFactory;
|
pFactory = new ASPNET_CORE_PROXY_MODULE_FACTORY;
|
||||||
|
|
||||||
if (pFactory == NULL)
|
if (pFactory == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -213,28 +144,45 @@ HRESULT
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pModuleInfo->SetRequestNotifications(
|
hr = pModuleInfo->SetRequestNotifications(
|
||||||
pFactory,
|
pFactory,
|
||||||
RQ_EXECUTE_REQUEST_HANDLER,
|
RQ_EXECUTE_REQUEST_HANDLER,
|
||||||
0);
|
0);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFactory = NULL;
|
pFactory = NULL;
|
||||||
|
pApplicationManager = APPLICATION_MANAGER::GetInstance();
|
||||||
g_pResponseHeaderHash = new RESPONSE_HEADER_HASH;
|
if(pApplicationManager == NULL)
|
||||||
if (g_pResponseHeaderHash == NULL)
|
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = g_pResponseHeaderHash->Initialize();
|
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 | GL_STOP_LISTENING);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
pGlobalModule = NULL;
|
||||||
|
|
||||||
hr = ALLOC_CACHE_HANDLER::StaticInitialize();
|
hr = ALLOC_CACHE_HANDLER::StaticInitialize();
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -242,19 +190,12 @@ HRESULT
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = FORWARDING_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = WEBSOCKET_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
if (pGlobalModule != NULL)
|
||||||
|
{
|
||||||
|
delete pGlobalModule;
|
||||||
|
pGlobalModule = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (pFactory != NULL)
|
if (pFactory != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,17 @@ FILE_WATCHER::~FILE_WATCHER()
|
||||||
{
|
{
|
||||||
if (m_hChangeNotificationThread != NULL)
|
if (m_hChangeNotificationThread != NULL)
|
||||||
{
|
{
|
||||||
|
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
|
||||||
|
WaitForSingleObject(m_hChangeNotificationThread, INFINITE);
|
||||||
CloseHandle(m_hChangeNotificationThread);
|
CloseHandle(m_hChangeNotificationThread);
|
||||||
m_hChangeNotificationThread = NULL;
|
m_hChangeNotificationThread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL != m_hCompletionPort)
|
||||||
|
{
|
||||||
|
CloseHandle(m_hCompletionPort);
|
||||||
|
m_hCompletionPort = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
@ -103,7 +111,7 @@ Win32 error
|
||||||
|
|
||||||
if (completionKey == FILE_WATCHER_SHUTDOWN_KEY)
|
if (completionKey == FILE_WATCHER_SHUTDOWN_KEY)
|
||||||
{
|
{
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_ASSERT(pOverlapped != NULL);
|
DBG_ASSERT(pOverlapped != NULL);
|
||||||
|
|
@ -117,6 +125,8 @@ Win32 error
|
||||||
pOverlapped = NULL;
|
pOverlapped = NULL;
|
||||||
cbCompletion = 0;
|
cbCompletion = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -173,7 +183,7 @@ FILE_WATCHER_ENTRY::FILE_WATCHER_ENTRY(FILE_WATCHER * pFileMonitor) :
|
||||||
_pFileMonitor(pFileMonitor),
|
_pFileMonitor(pFileMonitor),
|
||||||
_hDirectory(INVALID_HANDLE_VALUE),
|
_hDirectory(INVALID_HANDLE_VALUE),
|
||||||
_hImpersonationToken(NULL),
|
_hImpersonationToken(NULL),
|
||||||
_pApplication(NULL),
|
_pApplicationInfo(NULL),
|
||||||
_lStopMonitorCalled(0),
|
_lStopMonitorCalled(0),
|
||||||
_cRefs(1),
|
_cRefs(1),
|
||||||
_fIsValid(TRUE)
|
_fIsValid(TRUE)
|
||||||
|
|
@ -268,7 +278,7 @@ HRESULT
|
||||||
//
|
//
|
||||||
if (_wcsnicmp(pNotificationInfo->FileName,
|
if (_wcsnicmp(pNotificationInfo->FileName,
|
||||||
_strFileName.QueryStr(),
|
_strFileName.QueryStr(),
|
||||||
pNotificationInfo->FileNameLength/sizeof(WCHAR)) == 0)
|
pNotificationInfo->FileNameLength / sizeof(WCHAR)) == 0)
|
||||||
{
|
{
|
||||||
fFileChanged = TRUE;
|
fFileChanged = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -284,7 +294,7 @@ HRESULT
|
||||||
{
|
{
|
||||||
pNotificationInfo = (FILE_NOTIFY_INFORMATION*)
|
pNotificationInfo = (FILE_NOTIFY_INFORMATION*)
|
||||||
((PBYTE)pNotificationInfo +
|
((PBYTE)pNotificationInfo +
|
||||||
pNotificationInfo->NextEntryOffset);
|
pNotificationInfo->NextEntryOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +304,7 @@ HRESULT
|
||||||
//
|
//
|
||||||
// so far we only monitoring app_offline
|
// so far we only monitoring app_offline
|
||||||
//
|
//
|
||||||
_pApplication->UpdateAppOfflineFileHandle();
|
_pApplicationInfo->UpdateAppOfflineFileHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
@ -314,7 +324,7 @@ FILE_WATCHER_ENTRY::Monitor(VOID)
|
||||||
ReferenceFileWatcherEntry();
|
ReferenceFileWatcherEntry();
|
||||||
ZeroMemory(&_overlapped, sizeof(_overlapped));
|
ZeroMemory(&_overlapped, sizeof(_overlapped));
|
||||||
|
|
||||||
if(!ReadDirectoryChangesW(_hDirectory,
|
if (!ReadDirectoryChangesW(_hDirectory,
|
||||||
_buffDirectoryChanges.QueryPtr(),
|
_buffDirectoryChanges.QueryPtr(),
|
||||||
_buffDirectoryChanges.QuerySize(),
|
_buffDirectoryChanges.QuerySize(),
|
||||||
FALSE, // Watching sub dirs. Set to False now as only monitoring app_offline
|
FALSE, // Watching sub dirs. Set to False now as only monitoring app_offline
|
||||||
|
|
@ -355,7 +365,7 @@ HRESULT
|
||||||
FILE_WATCHER_ENTRY::Create(
|
FILE_WATCHER_ENTRY::Create(
|
||||||
_In_ PCWSTR pszDirectoryToMonitor,
|
_In_ PCWSTR pszDirectoryToMonitor,
|
||||||
_In_ PCWSTR pszFileNameToMonitor,
|
_In_ PCWSTR pszFileNameToMonitor,
|
||||||
_In_ APPLICATION* pApplication,
|
_In_ APPLICATION_INFO* pApplicationInfo,
|
||||||
_In_ HANDLE hImpersonationToken
|
_In_ HANDLE hImpersonationToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -364,7 +374,7 @@ FILE_WATCHER_ENTRY::Create(
|
||||||
|
|
||||||
if (pszDirectoryToMonitor == NULL ||
|
if (pszDirectoryToMonitor == NULL ||
|
||||||
pszFileNameToMonitor == NULL ||
|
pszFileNameToMonitor == NULL ||
|
||||||
pApplication == NULL)
|
pApplicationInfo == NULL)
|
||||||
{
|
{
|
||||||
DBG_ASSERT(FALSE);
|
DBG_ASSERT(FALSE);
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
||||||
|
|
@ -374,7 +384,7 @@ FILE_WATCHER_ENTRY::Create(
|
||||||
//
|
//
|
||||||
//remember the application
|
//remember the application
|
||||||
//
|
//
|
||||||
_pApplication = pApplication;
|
_pApplicationInfo = pApplicationInfo;
|
||||||
|
|
||||||
if (FAILED(hr = _strFileName.Copy(pszFileNameToMonitor)))
|
if (FAILED(hr = _strFileName.Copy(pszFileNameToMonitor)))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,195 +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 <cassert>
|
|
||||||
#include <sstream>
|
|
||||||
#include "fx_ver.h"
|
|
||||||
#include "precomp.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;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
#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 (m_pApplicationManager != NULL)
|
||||||
|
{
|
||||||
|
// we should let application manager to shudown 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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pProvider);
|
||||||
|
|
||||||
|
// 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->RecycleApplication(pwszChangePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return processing to the pipeline.
|
||||||
|
return GL_NOTIFICATION_CONTINUE;
|
||||||
|
}
|
||||||
|
|
@ -1,686 +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 "precomp.hxx"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
typedef DWORD(*hostfxr_main_fn) (CONST DWORD argc, CONST WCHAR* argv[]);
|
|
||||||
|
|
||||||
IN_PROCESS_APPLICATION* IN_PROCESS_APPLICATION::s_Application = NULL;
|
|
||||||
|
|
||||||
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION() :
|
|
||||||
m_ProcessExitCode ( 0 ),
|
|
||||||
m_fManagedAppLoaded ( FALSE ),
|
|
||||||
m_fLoadManagedAppError ( FALSE ),
|
|
||||||
m_fInitialized ( FALSE )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
|
|
||||||
{
|
|
||||||
Recycle();
|
|
||||||
}
|
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
IN_PROCESS_APPLICATION::OnAsyncCompletion(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
DWORD cbCompletion,
|
|
||||||
HRESULT hrCompletionStatus
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext = NULL;
|
|
||||||
REQUEST_NOTIFICATION_STATUS dwRequestNotificationStatus = RQ_NOTIFICATION_CONTINUE;
|
|
||||||
|
|
||||||
hr = IN_PROCESS_STORED_CONTEXT::GetInProcessStoredContext(pHttpContext, &pInProcessStoredContext);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
// Finish the request as we couldn't get the callback
|
|
||||||
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 19, hr);
|
|
||||||
return RQ_NOTIFICATION_FINISH_REQUEST;
|
|
||||||
}
|
|
||||||
else if (pInProcessStoredContext->QueryIsManagedRequestComplete())
|
|
||||||
{
|
|
||||||
// means PostCompletion has been called and this is the associated callback.
|
|
||||||
dwRequestNotificationStatus = pInProcessStoredContext->QueryAsyncCompletionStatus();
|
|
||||||
// TODO cleanup whatever disconnect listener there is
|
|
||||||
return dwRequestNotificationStatus;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Call the managed handler for async completion.
|
|
||||||
return m_AsyncCompletionHandler(pInProcessStoredContext->QueryManagedHttpContext(), hrCompletionStatus, cbCompletion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
IN_PROCESS_APPLICATION::DirectoryExists(
|
|
||||||
_In_ STRU *pstrPath
|
|
||||||
)
|
|
||||||
{
|
|
||||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
|
||||||
|
|
||||||
if (pstrPath->IsEmpty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
IN_PROCESS_APPLICATION::GetEnv(
|
|
||||||
_In_ PCWSTR pszEnvironmentVariable,
|
|
||||||
_Out_ STRU *pstrResult
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DWORD dwLength;
|
|
||||||
PWSTR pszBuffer = NULL;
|
|
||||||
BOOL fSucceeded = FALSE;
|
|
||||||
|
|
||||||
if (pszEnvironmentVariable == NULL)
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
pstrResult->Reset();
|
|
||||||
dwLength = GetEnvironmentVariableW(pszEnvironmentVariable, NULL, 0);
|
|
||||||
|
|
||||||
if (dwLength == 0)
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
pszBuffer = new WCHAR[dwLength];
|
|
||||||
if (GetEnvironmentVariableW(pszEnvironmentVariable, pszBuffer, dwLength) == 0)
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
pstrResult->Copy(pszBuffer);
|
|
||||||
|
|
||||||
fSucceeded = TRUE;
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
if (pszBuffer != NULL) {
|
|
||||||
delete[] pszBuffer;
|
|
||||||
}
|
|
||||||
return fSucceeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_APPLICATION::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);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_APPLICATION::SetCallbackHandles(
|
|
||||||
_In_ PFN_REQUEST_HANDLER request_handler,
|
|
||||||
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
|
||||||
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
|
|
||||||
_In_ VOID* pvRequstHandlerContext,
|
|
||||||
_In_ VOID* pvShutdownHandlerContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_RequestHandler = request_handler;
|
|
||||||
m_RequstHandlerContext = pvRequstHandlerContext;
|
|
||||||
m_ShutdownHandler = shutdown_handler;
|
|
||||||
m_ShutdownHandlerContext = pvShutdownHandlerContext;
|
|
||||||
m_AsyncCompletionHandler = async_completion_handler;
|
|
||||||
|
|
||||||
// Initialization complete
|
|
||||||
SetEvent(m_pInitalizeEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize is guarded by a lock inside APPLICATION_MANAGER::GetApplication
|
|
||||||
// It ensures only one application will be initialized and singleton
|
|
||||||
// Error wuill happen if you call Initialized outside APPLICATION_MANAGER::GetApplication
|
|
||||||
//
|
|
||||||
__override
|
|
||||||
HRESULT
|
|
||||||
IN_PROCESS_APPLICATION::Initialize(
|
|
||||||
_In_ APPLICATION_MANAGER* pApplicationManager,
|
|
||||||
_In_ ASPNETCORE_CONFIG* pConfiguration
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
DBG_ASSERT(pApplicationManager != NULL);
|
|
||||||
DBG_ASSERT(pConfiguration != NULL);
|
|
||||||
|
|
||||||
m_pConfiguration = pConfiguration;
|
|
||||||
m_pApplicationManager = pApplicationManager;
|
|
||||||
hr = m_applicationKey.Initialize(pConfiguration->QueryApplicationPath()->QueryStr());
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check app_offline
|
|
||||||
UpdateAppOfflineFileHandle();
|
|
||||||
|
|
||||||
if (m_pFileWatcherEntry == NULL)
|
|
||||||
{
|
|
||||||
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(m_pApplicationManager->GetFileWatcher());
|
|
||||||
if (m_pFileWatcherEntry == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pInitalizeEvent = CreateEvent(
|
|
||||||
NULL, // default security attributes
|
|
||||||
TRUE, // manual reset event
|
|
||||||
FALSE, // not set
|
|
||||||
NULL); // name
|
|
||||||
if (m_pInitalizeEvent == NULL)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
m_fInitialized = TRUE;
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
IN_PROCESS_APPLICATION::LoadManagedApplication()
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
DWORD dwTimeout;
|
|
||||||
DWORD dwResult;
|
|
||||||
BOOL fLocked = FALSE;
|
|
||||||
PCWSTR apsz[1];
|
|
||||||
STACK_STRU(strEventMsg, 256);
|
|
||||||
|
|
||||||
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
|
||||||
{
|
|
||||||
// Core CLR has already been loaded.
|
|
||||||
// Cannot load more than once even there was a failure
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
|
||||||
fLocked = TRUE;
|
|
||||||
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_hThread = CreateThread(
|
|
||||||
NULL, // default security attributes
|
|
||||||
0, // default stack size
|
|
||||||
(LPTHREAD_START_ROUTINE)ExecuteAspNetCoreProcess,
|
|
||||||
this, // thread function arguments
|
|
||||||
0, // default creation flags
|
|
||||||
NULL); // receive thread identifier
|
|
||||||
|
|
||||||
if (m_hThread == NULL)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the debugger is attached, never timeout
|
|
||||||
if (IsDebuggerPresent())
|
|
||||||
{
|
|
||||||
dwTimeout = INFINITE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwTimeout = m_pConfiguration->QueryStartupTimeLimitInMS();
|
|
||||||
}
|
|
||||||
|
|
||||||
const HANDLE pHandles[2]{ m_hThread, m_pInitalizeEvent };
|
|
||||||
|
|
||||||
// Wait on either the thread to complete or the event to be set
|
|
||||||
dwResult = WaitForMultipleObjects(2, pHandles, FALSE, dwTimeout);
|
|
||||||
|
|
||||||
// It all timed out
|
|
||||||
if (dwResult == WAIT_TIMEOUT)
|
|
||||||
{
|
|
||||||
// do we need kill the backend thread
|
|
||||||
hr = HRESULT_FROM_WIN32(dwResult);
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
else if (dwResult == WAIT_FAILED)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The thread ended it means that something failed
|
|
||||||
if (dwResult == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_fManagedAppLoaded = TRUE;
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
if (fLocked)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
// Question: in case of application loading failure, should we allow retry on
|
|
||||||
// following request or block the activation at all
|
|
||||||
m_fLoadManagedAppError = FALSE; // m_hThread != NULL ?
|
|
||||||
|
|
||||||
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
|
||||||
ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG,
|
|
||||||
m_pConfiguration->QueryApplicationPath()->QueryStr(),
|
|
||||||
m_pConfiguration->QueryApplicationFullPath()->QueryStr(),
|
|
||||||
hr)))
|
|
||||||
{
|
|
||||||
apsz[0] = strEventMsg.QueryStr();
|
|
||||||
|
|
||||||
//
|
|
||||||
// not checking return code because if ReportEvent
|
|
||||||
// fails, we cannot do anything.
|
|
||||||
//
|
|
||||||
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
|
||||||
{
|
|
||||||
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
|
||||||
EVENTLOG_ERROR_TYPE,
|
|
||||||
0,
|
|
||||||
ASPNETCORE_EVENT_LOAD_CLR_FALIURE,
|
|
||||||
NULL,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
apsz,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_APPLICATION::Recycle(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (m_fInitialized)
|
|
||||||
{
|
|
||||||
DWORD dwThreadStatus = 0;
|
|
||||||
DWORD dwTimeout = m_pConfiguration->QueryShutdownTimeLimitInMS();
|
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
|
||||||
|
|
||||||
if (!g_pHttpServer->IsCommandLineLaunch() &&
|
|
||||||
!g_fRecycleProcessCalled &&
|
|
||||||
(g_pHttpServer->GetAdminManager() != NULL))
|
|
||||||
{
|
|
||||||
// IIS scenario.
|
|
||||||
// notify IIS first so that new request will be routed to new worker process
|
|
||||||
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_fRecycleProcessCalled = TRUE;
|
|
||||||
|
|
||||||
// First call into the managed server and shutdown
|
|
||||||
if (m_ShutdownHandler != NULL)
|
|
||||||
{
|
|
||||||
m_ShutdownHandler(m_ShutdownHandlerContext);
|
|
||||||
m_ShutdownHandler = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_hThread != NULL &&
|
|
||||||
GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 &&
|
|
||||||
dwThreadStatus == STILL_ACTIVE)
|
|
||||||
{
|
|
||||||
// wait for gracefullshut down, i.e., the exit of the background thread or timeout
|
|
||||||
if (WaitForSingleObject(m_hThread, dwTimeout) != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
// if the thread is still running, we need kill it first before exit to avoid AV
|
|
||||||
if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE)
|
|
||||||
{
|
|
||||||
TerminateThread(m_hThread, STATUS_CONTROL_C_EXIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(m_hThread);
|
|
||||||
m_hThread = NULL;
|
|
||||||
s_Application = NULL;
|
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
if (g_pHttpServer && g_pHttpServer->IsCommandLineLaunch())
|
|
||||||
{
|
|
||||||
// IISExpress scenario
|
|
||||||
// Can only call exit to terminate current process
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_APPLICATION::OnAppOfflineHandleChange()
|
|
||||||
{
|
|
||||||
// only recycle the worker process after managed app was loaded
|
|
||||||
// app_offline scenario managed application has not been loaded yet
|
|
||||||
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
|
||||||
{
|
|
||||||
Recycle();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
IN_PROCESS_APPLICATION::ExecuteRequest(
|
|
||||||
_In_ IHttpContext* pHttpContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (m_RequestHandler != NULL)
|
|
||||||
{
|
|
||||||
return m_RequestHandler(pHttpContext, m_RequstHandlerContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// return error as the application did not register callback
|
|
||||||
//
|
|
||||||
if (ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::IsEnabled(pHttpContext->GetTraceContext()))
|
|
||||||
{
|
|
||||||
ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::RaiseEvent(pHttpContext->GetTraceContext(),
|
|
||||||
NULL,
|
|
||||||
E_APPLICATION_ACTIVATION_EXEC_FAILURE);
|
|
||||||
}
|
|
||||||
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, E_APPLICATION_ACTIVATION_EXEC_FAILURE);
|
|
||||||
return RQ_NOTIFICATION_FINISH_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
IN_PROCESS_APPLICATION::ExecuteApplication(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
STRU strFullPath;
|
|
||||||
STRU strDotnetExeLocation;
|
|
||||||
STRU strHostFxrSearchExpression;
|
|
||||||
STRU strDotnetFolderLocation;
|
|
||||||
STRU strHighestDotnetVersion;
|
|
||||||
STRU strApplicationFullPath;
|
|
||||||
PWSTR strDelimeterContext = NULL;
|
|
||||||
PCWSTR pszDotnetExeLocation = NULL;
|
|
||||||
PCWSTR pszDotnetExeString(L"dotnet.exe");
|
|
||||||
DWORD dwCopyLength;
|
|
||||||
HMODULE hModule;
|
|
||||||
PCWSTR argv[2];
|
|
||||||
hostfxr_main_fn pProc;
|
|
||||||
std::vector<std::wstring> vVersionFolders;
|
|
||||||
bool fFound = FALSE;
|
|
||||||
|
|
||||||
// Get the System PATH value.
|
|
||||||
if (!GetEnv(L"PATH", &strFullPath))
|
|
||||||
{
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split on ';', checking to see if dotnet.exe exists in any folders.
|
|
||||||
pszDotnetExeLocation = wcstok_s(strFullPath.QueryStr(), L";", &strDelimeterContext);
|
|
||||||
|
|
||||||
while (pszDotnetExeLocation != NULL)
|
|
||||||
{
|
|
||||||
dwCopyLength = wcsnlen_s(pszDotnetExeLocation, 260);
|
|
||||||
if (dwCopyLength == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
|
|
||||||
// which doesn't need the dotnet.exe portion of the string
|
|
||||||
// TODO consider reducing allocations.
|
|
||||||
strDotnetExeLocation.Reset();
|
|
||||||
strDotnetFolderLocation.Reset();
|
|
||||||
hr = strDotnetExeLocation.Copy(pszDotnetExeLocation, dwCopyLength);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = strDotnetFolderLocation.Copy(pszDotnetExeLocation, dwCopyLength);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwCopyLength > 0 && pszDotnetExeLocation[dwCopyLength - 1] != L'\\')
|
|
||||||
{
|
|
||||||
hr = strDotnetExeLocation.Append(L"\\");
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = strDotnetExeLocation.Append(pszDotnetExeString);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PathFileExists(strDotnetExeLocation.QueryStr()))
|
|
||||||
{
|
|
||||||
// means we found the folder with a dotnet.exe inside of it.
|
|
||||||
fFound = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pszDotnetExeLocation = wcstok_s(NULL, L";", &strDelimeterContext);
|
|
||||||
}
|
|
||||||
if (!fFound)
|
|
||||||
{
|
|
||||||
// could not find dotnet.exe, error out
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = strDotnetFolderLocation.Append(L"\\host\\fxr");
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DirectoryExists(&strDotnetFolderLocation))
|
|
||||||
{
|
|
||||||
// error, not found the folder
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find all folders under host\\fxr\\ for version numbers.
|
|
||||||
hr = strHostFxrSearchExpression.Copy(strDotnetFolderLocation);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = strHostFxrSearchExpression.Append(L"\\*");
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// As we use the logic from core-setup, we are opting to use std here.
|
|
||||||
// TODO remove all uses of std?
|
|
||||||
FindDotNetFolders(strHostFxrSearchExpression.QueryStr(), &vVersionFolders);
|
|
||||||
|
|
||||||
if (vVersionFolders.size() == 0)
|
|
||||||
{
|
|
||||||
// no core framework was found
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = FindHighestDotNetVersion(vVersionFolders, &strHighestDotnetVersion);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
hr = strDotnetFolderLocation.Append(L"\\");
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = strDotnetFolderLocation.Append(strHighestDotnetVersion.QueryStr());
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = strDotnetFolderLocation.Append(L"\\hostfxr.dll");
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hModule = LoadLibraryW(strDotnetFolderLocation.QueryStr());
|
|
||||||
|
|
||||||
if (hModule == NULL)
|
|
||||||
{
|
|
||||||
// .NET Core not installed (we can log a more detailed error message here)
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the entry point for main
|
|
||||||
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
|
|
||||||
if (pProc == NULL)
|
|
||||||
{
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT; // better hrresult?
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The first argument is mostly ignored
|
|
||||||
argv[0] = strDotnetExeLocation.QueryStr();
|
|
||||||
PATH::ConvertPathToFullPath(m_pConfiguration->QueryArguments()->QueryStr(),
|
|
||||||
m_pConfiguration->QueryApplicationFullPath()->QueryStr(),
|
|
||||||
&strApplicationFullPath);
|
|
||||||
argv[1] = strApplicationFullPath.QueryStr();
|
|
||||||
|
|
||||||
// There can only ever be a single instance of .NET Core
|
|
||||||
// loaded in the process but we need to get config information to boot it up in the
|
|
||||||
// first place. This is happening in an execute request handler and everyone waits
|
|
||||||
// until this initialization is done.
|
|
||||||
|
|
||||||
// We set a static so that managed code can call back into this instance and
|
|
||||||
// set the callbacks
|
|
||||||
s_Application = this;
|
|
||||||
|
|
||||||
m_ProcessExitCode = pProc(2, argv);
|
|
||||||
if (m_ProcessExitCode != 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
//
|
|
||||||
// this method is called by the background thread and should never exit unless shutdown
|
|
||||||
//
|
|
||||||
if (!g_fRecycleProcessCalled)
|
|
||||||
{
|
|
||||||
STRU strEventMsg;
|
|
||||||
LPCWSTR apsz[1];
|
|
||||||
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
|
||||||
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG,
|
|
||||||
m_pConfiguration->QueryApplicationPath()->QueryStr(),
|
|
||||||
m_pConfiguration->QueryApplicationFullPath()->QueryStr(),
|
|
||||||
m_ProcessExitCode
|
|
||||||
)))
|
|
||||||
{
|
|
||||||
apsz[0] = strEventMsg.QueryStr();
|
|
||||||
|
|
||||||
//
|
|
||||||
// not checking return code because if ReportEvent
|
|
||||||
// fails, we cannot do anything.
|
|
||||||
//
|
|
||||||
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
|
||||||
{
|
|
||||||
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
|
||||||
EVENTLOG_ERROR_TYPE,
|
|
||||||
0,
|
|
||||||
ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT,
|
|
||||||
NULL,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
apsz,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
// error. the thread exits after application started
|
|
||||||
// Question: should we shutdown current worker process or keep the application in failure state?
|
|
||||||
// for now, we reccylce to keep the same behavior as that of out-of-process
|
|
||||||
if (m_fManagedAppLoaded)
|
|
||||||
{
|
|
||||||
Recycle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_APPLICATION::ExecuteAspNetCoreProcess(
|
|
||||||
_In_ LPVOID pContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
IN_PROCESS_APPLICATION *pApplication = (IN_PROCESS_APPLICATION*)pContext;
|
|
||||||
DBG_ASSERT(pApplication != NULL);
|
|
||||||
pApplication->ExecuteApplication();
|
|
||||||
//
|
|
||||||
// no need to log the error here as if error happened, the thread will exit
|
|
||||||
// the error will ba catched by caller LoadManagedApplication which will log an error
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
IN_PROCESS_APPLICATION::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))
|
|
||||||
{
|
|
||||||
max_ver = std::max(max_ver, fx_ver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = pstrResult->Copy(max_ver.as_str().c_str());
|
|
||||||
|
|
||||||
// we check FAILED(hr) outside of function
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
@ -1,113 +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"
|
|
||||||
|
|
||||||
IN_PROCESS_STORED_CONTEXT::IN_PROCESS_STORED_CONTEXT(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
PVOID pMangedHttpContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// TODO if we want to go by IIS patterns, we should have these in a separate initialize function
|
|
||||||
m_pManagedHttpContext = pMangedHttpContext;
|
|
||||||
m_pHttpContext = pHttpContext;
|
|
||||||
m_fManagedRequestComplete = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
IN_PROCESS_STORED_CONTEXT::~IN_PROCESS_STORED_CONTEXT()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
|
||||||
IN_PROCESS_STORED_CONTEXT::QueryManagedHttpContext(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_pManagedHttpContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
IHttpContext*
|
|
||||||
IN_PROCESS_STORED_CONTEXT::QueryHttpContext(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_pHttpContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
IN_PROCESS_STORED_CONTEXT::QueryIsManagedRequestComplete(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_fManagedRequestComplete;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_STORED_CONTEXT::IndicateManagedRequestComplete(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_fManagedRequestComplete = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
IN_PROCESS_STORED_CONTEXT::QueryAsyncCompletionStatus(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return m_requestNotificationStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
IN_PROCESS_STORED_CONTEXT::SetAsyncCompletionStatus(
|
|
||||||
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_requestNotificationStatus = requestNotificationStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
IN_PROCESS_STORED_CONTEXT::GetInProcessStoredContext(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
IN_PROCESS_STORED_CONTEXT** ppInProcessStoredContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pHttpContext == NULL)
|
|
||||||
{
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ppInProcessStoredContext == NULL)
|
|
||||||
{
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppInProcessStoredContext = (IN_PROCESS_STORED_CONTEXT*)pHttpContext->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
|
|
||||||
if (*ppInProcessStoredContext == NULL)
|
|
||||||
{
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
IN_PROCESS_STORED_CONTEXT::SetInProcessStoredContext(
|
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pHttpContext == NULL)
|
|
||||||
{
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
if (pInProcessStoredContext == NULL)
|
|
||||||
{
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pHttpContext->GetModuleContextContainer()->SetModuleContext(
|
|
||||||
pInProcessStoredContext,
|
|
||||||
g_pModuleId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,121 +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 "precomp.hxx"
|
|
||||||
|
|
||||||
OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION()
|
|
||||||
: m_pProcessManager(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
OUT_OF_PROCESS_APPLICATION::~OUT_OF_PROCESS_APPLICATION()
|
|
||||||
{
|
|
||||||
if (m_pProcessManager != NULL)
|
|
||||||
{
|
|
||||||
m_pProcessManager->ShutdownAllProcesses();
|
|
||||||
m_pProcessManager->DereferenceProcessManager();
|
|
||||||
m_pProcessManager = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize is guarded by a lock inside APPLICATION_MANAGER::GetApplication
|
|
||||||
// It ensures only one application will be initialized and singleton
|
|
||||||
// Error will happen if you call Initialized outside APPLICATION_MANAGER::GetApplication
|
|
||||||
//
|
|
||||||
__override
|
|
||||||
HRESULT
|
|
||||||
OUT_OF_PROCESS_APPLICATION::Initialize(
|
|
||||||
_In_ APPLICATION_MANAGER* pApplicationManager,
|
|
||||||
_In_ ASPNETCORE_CONFIG* pConfiguration
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
DBG_ASSERT(pApplicationManager != NULL);
|
|
||||||
DBG_ASSERT(pConfiguration != NULL);
|
|
||||||
|
|
||||||
m_pApplicationManager = pApplicationManager;
|
|
||||||
m_pConfiguration = pConfiguration;
|
|
||||||
|
|
||||||
hr = m_applicationKey.Initialize(pConfiguration->QueryApplicationPath()->QueryStr());
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pProcessManager == NULL)
|
|
||||||
{
|
|
||||||
m_pProcessManager = new PROCESS_MANAGER;
|
|
||||||
if (m_pProcessManager == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = m_pProcessManager->Initialize();
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pFileWatcherEntry == NULL)
|
|
||||||
{
|
|
||||||
m_pFileWatcherEntry = new FILE_WATCHER_ENTRY(pApplicationManager->GetFileWatcher());
|
|
||||||
if (m_pFileWatcherEntry == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateAppOfflineFileHandle();
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
if (m_pFileWatcherEntry != NULL)
|
|
||||||
{
|
|
||||||
m_pFileWatcherEntry->DereferenceFileWatcherEntry();
|
|
||||||
m_pFileWatcherEntry = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pProcessManager != NULL)
|
|
||||||
{
|
|
||||||
m_pProcessManager->DereferenceProcessManager();
|
|
||||||
m_pProcessManager = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
__override
|
|
||||||
VOID
|
|
||||||
OUT_OF_PROCESS_APPLICATION::OnAppOfflineHandleChange()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Sending signal to backend process for shutdown
|
|
||||||
//
|
|
||||||
if (m_pProcessManager != NULL)
|
|
||||||
{
|
|
||||||
m_pProcessManager->SendShutdownSignal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__override
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
OUT_OF_PROCESS_APPLICATION::ExecuteRequest(
|
|
||||||
_In_ IHttpContext* pHttpContext
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// TODO:
|
|
||||||
// Ideally we should wrap the fowaring logic inside FORWARDING_HANDLER inside this function
|
|
||||||
// To achieve better abstraction. It is too risky to do it now
|
|
||||||
//
|
|
||||||
return RQ_NOTIFICATION_FINISH_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
@ -54,13 +54,6 @@
|
||||||
#define WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS 111
|
#define WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS 111
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ASPNETCORE_EVENT_PROVIDER L"IIS AspNetCore Module"
|
|
||||||
#define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module"
|
|
||||||
|
|
||||||
#define TIMESPAN_IN_MILLISECONDS(x) ((x)/((LONGLONG)(10000)))
|
|
||||||
#define TIMESPAN_IN_SECONDS(x) ((TIMESPAN_IN_MILLISECONDS(x))/((LONGLONG)(1000)))
|
|
||||||
#define TIMESPAN_IN_MINUTES(x) ((TIMESPAN_IN_SECONDS(x))/((LONGLONG)(60)))
|
|
||||||
|
|
||||||
#ifdef max
|
#ifdef max
|
||||||
#undef max
|
#undef max
|
||||||
template<typename T> inline T max(T a, T b)
|
template<typename T> inline T max(T a, T b)
|
||||||
|
|
@ -97,43 +90,33 @@ inline bool IsSpace(char ch)
|
||||||
#include <hashtable.h>
|
#include <hashtable.h>
|
||||||
#include "stringa.h"
|
#include "stringa.h"
|
||||||
#include "stringu.h"
|
#include "stringu.h"
|
||||||
//#include "treehash.h"
|
|
||||||
|
|
||||||
#include "dbgutil.h"
|
#include "dbgutil.h"
|
||||||
#include "ahutil.h"
|
#include "ahutil.h"
|
||||||
#include "multisz.h"
|
#include "multisz.h"
|
||||||
#include "multisza.h"
|
#include "multisza.h"
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "sttimer.h"
|
|
||||||
#include <listentry.h>
|
#include <listentry.h>
|
||||||
#include <datetime.h>
|
#include <datetime.h>
|
||||||
#include <reftrace.h>
|
#include <reftrace.h>
|
||||||
#include <acache.h>
|
#include <acache.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "environmentvariablehash.h"
|
#include "..\..\CommonLib\environmentvariablehash.h"
|
||||||
#include "..\aspnetcore_msg.h"
|
#include "..\..\CommonLib\aspnetcoreconfig.h"
|
||||||
#include "aspnetcore_event.h"
|
#include "..\..\CommonLib\application.h"
|
||||||
#include "aspnetcoreconfig.h"
|
#include "..\..\CommonLib\utility.h"
|
||||||
#include "serverprocess.h"
|
#include "..\..\CommonLib\debugutil.h"
|
||||||
#include "processmanager.h"
|
#include "..\..\CommonLib\requesthandler.h"
|
||||||
|
//#include "..\aspnetcore_msg.h"
|
||||||
|
//#include "aspnetcore_event.h"
|
||||||
|
#include "appoffline.h"
|
||||||
#include "filewatcher.h"
|
#include "filewatcher.h"
|
||||||
#include "application.h"
|
#include "applicationinfo.h"
|
||||||
#include "applicationmanager.h"
|
#include "applicationmanager.h"
|
||||||
#include "inprocessstoredcontext.h"
|
#include "globalmodule.h"
|
||||||
#include "inprocessapplication.h"
|
|
||||||
#include "outprocessapplication.h"
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "path.h"
|
|
||||||
#include "debugutil.h"
|
|
||||||
#include "protocolconfig.h"
|
|
||||||
#include "responseheaderhash.h"
|
|
||||||
#include "forwarderconnection.h"
|
|
||||||
#include "winhttphelper.h"
|
|
||||||
#include "websockethandler.h"
|
|
||||||
#include "forwardinghandler.h"
|
|
||||||
#include "proxymodule.h"
|
#include "proxymodule.h"
|
||||||
#include "fx_ver.h"
|
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
DWORD
|
DWORD
|
||||||
|
|
@ -158,11 +141,15 @@ HRESULT_FROM_GETLASTERROR()
|
||||||
: E_FAIL;
|
: E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern BOOL g_fAsyncDisconnectAvailable;
|
|
||||||
extern BOOL g_fWinHttpNonBlockingCallbackAvailable;
|
|
||||||
extern PVOID g_pModuleId;
|
extern PVOID g_pModuleId;
|
||||||
extern BOOL g_fWebSocketSupported;
|
extern BOOL g_fAspnetcoreRHAssemblyLoaded;
|
||||||
|
extern BOOL g_fAspnetcoreRHLoadedError;
|
||||||
extern BOOL g_fEnableReferenceCountTracing;
|
extern BOOL g_fEnableReferenceCountTracing;
|
||||||
extern DWORD g_dwActiveServerProcesses;
|
extern DWORD g_dwActiveServerProcesses;
|
||||||
extern DWORD g_OptionalWinHttpFlags;
|
extern HMODULE g_hAspnetCoreRH;
|
||||||
|
extern SRWLOCK g_srwLock;
|
||||||
|
extern PCWSTR g_pwzAspnetcoreRequestHandlerName;
|
||||||
|
|
||||||
|
extern PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
|
||||||
|
extern PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
|
||||||
#pragma warning( error : 4091)
|
#pragma warning( error : 4091)
|
||||||
|
|
@ -1,294 +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"
|
|
||||||
|
|
||||||
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
PROCESS_MANAGER::Initialize(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
WSADATA wsaData;
|
|
||||||
int result;
|
|
||||||
BOOL fLocked = FALSE;
|
|
||||||
|
|
||||||
if( !sm_fWSAStartupDone )
|
|
||||||
{
|
|
||||||
AcquireSRWLockExclusive( &m_srwLock );
|
|
||||||
fLocked = TRUE;
|
|
||||||
|
|
||||||
if( !sm_fWSAStartupDone )
|
|
||||||
{
|
|
||||||
if( (result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 )
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32( result );
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
sm_fWSAStartupDone = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseSRWLockExclusive( &m_srwLock );
|
|
||||||
fLocked = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dwRapidFailTickStart = GetTickCount();
|
|
||||||
|
|
||||||
if( m_hNULHandle == NULL )
|
|
||||||
{
|
|
||||||
SECURITY_ATTRIBUTES saAttr;
|
|
||||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
||||||
saAttr.bInheritHandle = TRUE;
|
|
||||||
saAttr.lpSecurityDescriptor = NULL;
|
|
||||||
|
|
||||||
m_hNULHandle = CreateFileW( L"NUL",
|
|
||||||
FILE_WRITE_DATA,
|
|
||||||
FILE_SHARE_READ,
|
|
||||||
&saAttr,
|
|
||||||
CREATE_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL );
|
|
||||||
if( m_hNULHandle == INVALID_HANDLE_VALUE )
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_GETLASTERROR();
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
|
|
||||||
if(fLocked)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive( &m_srwLock );
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
PROCESS_MANAGER::~PROCESS_MANAGER()
|
|
||||||
{
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
|
||||||
|
|
||||||
if( m_ppServerProcessList != NULL )
|
|
||||||
{
|
|
||||||
for( DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
|
|
||||||
{
|
|
||||||
if( m_ppServerProcessList[i] != NULL )
|
|
||||||
{
|
|
||||||
m_ppServerProcessList[i]->DereferenceServerProcess();
|
|
||||||
m_ppServerProcessList[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] m_ppServerProcessList;
|
|
||||||
m_ppServerProcessList = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_hNULHandle != NULL )
|
|
||||||
{
|
|
||||||
CloseHandle( m_hNULHandle );
|
|
||||||
m_hNULHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( sm_fWSAStartupDone )
|
|
||||||
{
|
|
||||||
WSACleanup();
|
|
||||||
sm_fWSAStartupDone = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
PROCESS_MANAGER::GetProcess(
|
|
||||||
_In_ IHttpContext *context,
|
|
||||||
_In_ ASPNETCORE_CONFIG *pConfig,
|
|
||||||
_Out_ SERVER_PROCESS **ppServerProcess
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
BOOL fSharedLock = FALSE;
|
|
||||||
BOOL fExclusiveLock = FALSE;
|
|
||||||
PCWSTR apsz[1];
|
|
||||||
STACK_STRU( strEventMsg, 256 );
|
|
||||||
DWORD dwProcessIndex = 0;
|
|
||||||
SERVER_PROCESS **ppSelectedServerProcess = NULL;
|
|
||||||
|
|
||||||
if (!m_fServerProcessListReady)
|
|
||||||
{
|
|
||||||
AcquireSRWLockExclusive( &m_srwLock );
|
|
||||||
fExclusiveLock = TRUE;
|
|
||||||
|
|
||||||
if (!m_fServerProcessListReady)
|
|
||||||
{
|
|
||||||
m_dwProcessesPerApplication = pConfig->QueryProcessesPerApplication();
|
|
||||||
m_ppServerProcessList = new SERVER_PROCESS*[m_dwProcessesPerApplication];
|
|
||||||
if(m_ppServerProcessList == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(DWORD i=0;i<m_dwProcessesPerApplication;++i)
|
|
||||||
{
|
|
||||||
m_ppServerProcessList[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_fServerProcessListReady = TRUE;
|
|
||||||
ReleaseSRWLockExclusive( &m_srwLock );
|
|
||||||
fExclusiveLock = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
AcquireSRWLockShared( &m_srwLock );
|
|
||||||
fSharedLock = TRUE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// round robin through to the next available process.
|
|
||||||
//
|
|
||||||
|
|
||||||
dwProcessIndex = (DWORD) InterlockedIncrement64( (LONGLONG*) &m_dwRouteToProcessIndex );
|
|
||||||
dwProcessIndex = dwProcessIndex % m_dwProcessesPerApplication;
|
|
||||||
ppSelectedServerProcess = &m_ppServerProcessList[dwProcessIndex];
|
|
||||||
|
|
||||||
if( *ppSelectedServerProcess != NULL &&
|
|
||||||
m_ppServerProcessList[dwProcessIndex]->IsReady() )
|
|
||||||
{
|
|
||||||
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
|
||||||
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseSRWLockShared( &m_srwLock );
|
|
||||||
fSharedLock = FALSE;
|
|
||||||
// should make the lock per process so that we can start processes simultaneously ?
|
|
||||||
|
|
||||||
if(m_ppServerProcessList[dwProcessIndex] == NULL || !m_ppServerProcessList[dwProcessIndex]->IsReady())
|
|
||||||
{
|
|
||||||
AcquireSRWLockExclusive( &m_srwLock );
|
|
||||||
fExclusiveLock = TRUE;
|
|
||||||
|
|
||||||
if( m_ppServerProcessList[dwProcessIndex] != NULL )
|
|
||||||
{
|
|
||||||
if( !m_ppServerProcessList[dwProcessIndex]->IsReady() )
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// terminate existing process that is not ready
|
|
||||||
// before creating new one.
|
|
||||||
//
|
|
||||||
|
|
||||||
ShutdownProcessNoLock( m_ppServerProcessList[dwProcessIndex] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// server is already up and ready to serve requests.
|
|
||||||
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
|
||||||
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( RapidFailsPerMinuteExceeded(pConfig->QueryRapidFailsPerMinute()) )
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// rapid fails per minute exceeded, do not create new process.
|
|
||||||
//
|
|
||||||
|
|
||||||
if( SUCCEEDED( strEventMsg.SafeSnwprintf(
|
|
||||||
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG,
|
|
||||||
pConfig->QueryRapidFailsPerMinute() ) ) )
|
|
||||||
{
|
|
||||||
apsz[0] = strEventMsg.QueryStr();
|
|
||||||
|
|
||||||
//
|
|
||||||
// not checking return code because if ReportEvent
|
|
||||||
// fails, we cannot do anything.
|
|
||||||
//
|
|
||||||
if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
|
||||||
{
|
|
||||||
ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
|
||||||
EVENTLOG_INFORMATION_TYPE,
|
|
||||||
0,
|
|
||||||
ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED,
|
|
||||||
NULL,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
apsz,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_ppServerProcessList[dwProcessIndex] == NULL )
|
|
||||||
{
|
|
||||||
m_ppServerProcessList[dwProcessIndex] = new SERVER_PROCESS();
|
|
||||||
if( m_ppServerProcessList[dwProcessIndex] == NULL )
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = m_ppServerProcessList[dwProcessIndex]->Initialize(
|
|
||||||
this,
|
|
||||||
pConfig->QueryProcessPath(),
|
|
||||||
pConfig->QueryArguments(),
|
|
||||||
pConfig->QueryStartupTimeLimitInMS(),
|
|
||||||
pConfig->QueryShutdownTimeLimitInMS(),
|
|
||||||
pConfig->QueryWindowsAuthEnabled(),
|
|
||||||
pConfig->QueryBasicAuthEnabled(),
|
|
||||||
pConfig->QueryAnonymousAuthEnabled(),
|
|
||||||
pConfig->QueryEnvironmentVariables(),
|
|
||||||
pConfig->QueryStdoutLogEnabled(),
|
|
||||||
pConfig->QueryStdoutLogFile()
|
|
||||||
);
|
|
||||||
if( FAILED( hr ) )
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = m_ppServerProcessList[dwProcessIndex]->StartProcess(context);
|
|
||||||
if( FAILED( hr ) )
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !m_ppServerProcessList[dwProcessIndex]->IsReady() )
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32( ERROR_CREATE_FAILED );
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
|
||||||
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
|
|
||||||
if( FAILED(hr) )
|
|
||||||
{
|
|
||||||
if(m_ppServerProcessList[dwProcessIndex] != NULL )
|
|
||||||
{
|
|
||||||
m_ppServerProcessList[dwProcessIndex]->DereferenceServerProcess();
|
|
||||||
m_ppServerProcessList[dwProcessIndex] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fSharedLock )
|
|
||||||
{
|
|
||||||
ReleaseSRWLockShared( &m_srwLock );
|
|
||||||
fSharedLock = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fExclusiveLock )
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive( &m_srwLock );
|
|
||||||
fExclusiveLock = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
@ -5,12 +5,12 @@
|
||||||
|
|
||||||
__override
|
__override
|
||||||
HRESULT
|
HRESULT
|
||||||
CProxyModuleFactory::GetHttpModule(
|
ASPNET_CORE_PROXY_MODULE_FACTORY::GetHttpModule(
|
||||||
CHttpModule ** ppModule,
|
CHttpModule ** ppModule,
|
||||||
IModuleAllocator * pAllocator
|
IModuleAllocator * pAllocator
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CProxyModule *pModule = new (pAllocator) CProxyModule();
|
ASPNET_CORE_PROXY_MODULE *pModule = new (pAllocator) ASPNET_CORE_PROXY_MODULE();
|
||||||
if (pModule == NULL)
|
if (pModule == NULL)
|
||||||
{
|
{
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
@ -22,7 +22,7 @@ CProxyModuleFactory::GetHttpModule(
|
||||||
|
|
||||||
__override
|
__override
|
||||||
VOID
|
VOID
|
||||||
CProxyModuleFactory::Terminate(
|
ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
@ -41,39 +41,38 @@ Return value:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
FORWARDING_HANDLER::StaticTerminate();
|
/* FORWARDING_HANDLER::StaticTerminate();
|
||||||
|
|
||||||
WEBSOCKET_HANDLER::StaticTerminate();
|
WEBSOCKET_HANDLER::StaticTerminate();*/
|
||||||
|
|
||||||
if (g_pResponseHeaderHash != NULL)
|
|
||||||
{
|
|
||||||
g_pResponseHeaderHash->Clear();
|
|
||||||
delete g_pResponseHeaderHash;
|
|
||||||
g_pResponseHeaderHash = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALLOC_CACHE_HANDLER::StaticTerminate();
|
ALLOC_CACHE_HANDLER::StaticTerminate();
|
||||||
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CProxyModule::CProxyModule(
|
ASPNET_CORE_PROXY_MODULE::ASPNET_CORE_PROXY_MODULE(
|
||||||
) : m_pHandler(NULL)
|
) : m_pApplicationInfo(NULL), m_pHandler(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CProxyModule::~CProxyModule()
|
ASPNET_CORE_PROXY_MODULE::~ASPNET_CORE_PROXY_MODULE()
|
||||||
{
|
{
|
||||||
|
if (m_pApplicationInfo != NULL)
|
||||||
|
{
|
||||||
|
m_pApplicationInfo->DereferenceApplicationInfo();
|
||||||
|
m_pApplicationInfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_pHandler != NULL)
|
if (m_pHandler != NULL)
|
||||||
{
|
{
|
||||||
m_pHandler->DereferenceForwardingHandler();
|
m_pHandler->DereferenceRequestHandler();
|
||||||
m_pHandler = NULL;
|
m_pHandler = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__override
|
__override
|
||||||
REQUEST_NOTIFICATION_STATUS
|
REQUEST_NOTIFICATION_STATUS
|
||||||
CProxyModule::OnExecuteRequestHandler(
|
ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
|
||||||
IHttpContext * pHttpContext,
|
IHttpContext * pHttpContext,
|
||||||
IHttpEventProvider *
|
IHttpEventProvider *
|
||||||
)
|
)
|
||||||
|
|
@ -81,47 +80,105 @@ CProxyModule::OnExecuteRequestHandler(
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
ASPNETCORE_CONFIG *pConfig = NULL;
|
ASPNETCORE_CONFIG *pConfig = NULL;
|
||||||
APPLICATION_MANAGER *pApplicationManager = NULL;
|
APPLICATION_MANAGER *pApplicationManager = NULL;
|
||||||
APPLICATION *pApplication = NULL;
|
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
|
||||||
hr = ASPNETCORE_CONFIG::GetConfig(pHttpContext, &pConfig);
|
APPLICATION* pApplication = NULL;
|
||||||
|
STACK_STRU(struFileName, 256);
|
||||||
|
|
||||||
|
hr = ASPNETCORE_CONFIG::GetConfig(g_pHttpServer, g_pModuleId, pHttpContext, &pConfig);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Failed;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
pApplicationManager = APPLICATION_MANAGER::GetInstance();
|
pApplicationManager = APPLICATION_MANAGER::GetInstance();
|
||||||
if (pApplicationManager == NULL)
|
if (pApplicationManager == NULL)
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto Failed;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pApplicationManager->GetApplication(
|
hr = pApplicationManager->GetApplicationInfo(
|
||||||
pHttpContext,
|
g_pHttpServer,
|
||||||
pConfig,
|
pConfig,
|
||||||
&pApplication);
|
&m_pApplicationInfo);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Failed;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pHandler = new FORWARDING_HANDLER(pHttpContext, pApplication);
|
// app_offline check to avoid loading aspnetcorerh.dll unnecessarily
|
||||||
|
if (m_pApplicationInfo->AppOfflineFound())
|
||||||
if (m_pHandler == NULL)
|
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
// servicing app_offline
|
||||||
goto Failed;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_pHandler->OnExecuteRequestHandler();
|
// make sure assmebly is loaded and application is created
|
||||||
|
|
||||||
Failed:
|
hr = m_pApplicationInfo->EnsureApplicationCreated();
|
||||||
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
|
if (FAILED(hr))
|
||||||
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
pApplication = m_pApplicationInfo->QueryApplication();
|
||||||
|
DBG_ASSERT(pApplication);
|
||||||
|
|
||||||
|
// make sure application is in running state
|
||||||
|
// cannot recreate the application as we cannot reload clr for inprocess
|
||||||
|
if (pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
|
||||||
|
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
__override
|
__override
|
||||||
REQUEST_NOTIFICATION_STATUS
|
REQUEST_NOTIFICATION_STATUS
|
||||||
CProxyModule::OnAsyncCompletion(
|
ASPNET_CORE_PROXY_MODULE::OnAsyncCompletion(
|
||||||
IHttpContext *,
|
IHttpContext *,
|
||||||
DWORD,
|
DWORD,
|
||||||
BOOL,
|
BOOL,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
<?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>
|
||||||
|
</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="environmentvariablehash.h" />
|
||||||
|
<ClInclude Include="fx_ver.h" />
|
||||||
|
<ClInclude Include="hostfxr_utility.h" />
|
||||||
|
<ClInclude Include="requesthandler.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="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>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// 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_pHttpServer(pHttpServer),
|
||||||
|
m_pConfig(pConfig),
|
||||||
|
m_status(APPLICATION_STATUS::UNKNOWN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// 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,
|
||||||
|
RUNNING,
|
||||||
|
FAUL
|
||||||
|
};
|
||||||
|
|
||||||
|
class ASPNETCORE_CONFIG;
|
||||||
|
|
||||||
|
class APPLICATION
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
APPLICATION(
|
||||||
|
_In_ IHttpServer* pHttpServer,
|
||||||
|
_In_ ASPNETCORE_CONFIG* pConfig);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
VOID
|
||||||
|
ShutDown() = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~APPLICATION();
|
||||||
|
|
||||||
|
APPLICATION_STATUS
|
||||||
|
QueryStatus();
|
||||||
|
|
||||||
|
ASPNETCORE_CONFIG*
|
||||||
|
QueryConfig();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceApplication()
|
||||||
|
const;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceApplication()
|
||||||
|
const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
APPLICATION_STATUS m_status;
|
||||||
|
IHttpServer* m_pHttpServer;
|
||||||
|
ASPNETCORE_CONFIG* m_pConfig;
|
||||||
|
};
|
||||||
|
|
@ -1,56 +1,47 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include "stdafx.h"
|
||||||
|
#include "aspnetcoreconfig.h"
|
||||||
|
|
||||||
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
|
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
|
||||||
{
|
{
|
||||||
if (QueryHostingModel() == HOSTING_IN_PROCESS &&
|
|
||||||
!g_fRecycleProcessCalled &&
|
|
||||||
(g_pHttpServer->GetAdminManager() != NULL))
|
|
||||||
{
|
|
||||||
// There is a bug in IHttpServer::RecycleProcess. It will hit AV when worker process
|
|
||||||
// has already been in recycling state.
|
|
||||||
// To workaround, do null check on GetAdminManager(). If it is NULL, worker process is in recycling
|
|
||||||
// Do not call RecycleProcess again
|
|
||||||
|
|
||||||
// RecycleProcess can olny be called once
|
|
||||||
// In case of configuration change for in-process app
|
|
||||||
// We want notify IIS first to let new request routed to new worker process
|
|
||||||
|
|
||||||
g_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Configuration Change");
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's safe for us to set this g_fRecycleProcessCalled
|
|
||||||
// as in_process scenario will always recycle the worker process for configuration change
|
|
||||||
g_fRecycleProcessCalled = TRUE;
|
|
||||||
|
|
||||||
m_struApplicationFullPath.Reset();
|
|
||||||
if (m_pEnvironmentVariables != NULL)
|
if (m_pEnvironmentVariables != NULL)
|
||||||
{
|
{
|
||||||
m_pEnvironmentVariables->Clear();
|
m_pEnvironmentVariables->Clear();
|
||||||
delete m_pEnvironmentVariables;
|
delete m_pEnvironmentVariables;
|
||||||
m_pEnvironmentVariables = NULL;
|
m_pEnvironmentVariables = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_struApplication.IsEmpty())
|
VOID
|
||||||
{
|
ASPNETCORE_CONFIG::ReferenceConfiguration(
|
||||||
APPLICATION_MANAGER::GetInstance()->RecycleApplication(m_struApplication.QueryStr());
|
VOID
|
||||||
}
|
) const
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_cRefs);
|
||||||
|
}
|
||||||
|
|
||||||
if (QueryHostingModel() == HOSTING_IN_PROCESS &&
|
|
||||||
g_pHttpServer->IsCommandLineLaunch())
|
VOID
|
||||||
|
ASPNETCORE_CONFIG::DereferenceConfiguration(
|
||||||
|
VOID
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
DBG_ASSERT(m_cRefs != 0);
|
||||||
|
LONG cRefs = 0;
|
||||||
|
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
|
||||||
{
|
{
|
||||||
// IISExpress scenario, only option is to call exit in case configuration change
|
delete this;
|
||||||
// as CLR or application may change
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
ASPNETCORE_CONFIG::GetConfig(
|
ASPNETCORE_CONFIG::GetConfig(
|
||||||
|
_In_ IHttpServer *pHttpServer,
|
||||||
|
_In_ HTTP_MODULE_ID pModuleId,
|
||||||
_In_ IHttpContext *pHttpContext,
|
_In_ IHttpContext *pHttpContext,
|
||||||
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
@ -67,7 +58,7 @@ ASPNETCORE_CONFIG::GetConfig(
|
||||||
|
|
||||||
// potential bug if user sepcific config at virtual dir level
|
// potential bug if user sepcific config at virtual dir level
|
||||||
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
|
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
|
||||||
pHttpApplication->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
|
pHttpApplication->GetModuleContextContainer()->GetModuleContext(pModuleId);
|
||||||
|
|
||||||
if (pAspNetCoreConfig != NULL)
|
if (pAspNetCoreConfig != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -83,14 +74,14 @@ ASPNETCORE_CONFIG::GetConfig(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pAspNetCoreConfig->Populate(pHttpContext);
|
hr = pAspNetCoreConfig->Populate(pHttpServer, pHttpContext);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pHttpApplication->GetModuleContextContainer()->
|
hr = pHttpApplication->GetModuleContextContainer()->
|
||||||
SetModuleContext(pAspNetCoreConfig, g_pModuleId);
|
SetModuleContext(pAspNetCoreConfig, pModuleId);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
|
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
|
||||||
|
|
@ -99,7 +90,7 @@ ASPNETCORE_CONFIG::GetConfig(
|
||||||
|
|
||||||
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
|
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
|
||||||
GetModuleContextContainer()->
|
GetModuleContextContainer()->
|
||||||
GetModuleContext(g_pModuleId);
|
GetModuleContext(pModuleId);
|
||||||
|
|
||||||
_ASSERT(pAspNetCoreConfig != NULL);
|
_ASSERT(pAspNetCoreConfig != NULL);
|
||||||
|
|
||||||
|
|
@ -137,11 +128,11 @@ Finished:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
ASPNETCORE_CONFIG::Populate(
|
ASPNETCORE_CONFIG::Populate(
|
||||||
|
IHttpServer *pHttpServer,
|
||||||
IHttpContext *pHttpContext
|
IHttpContext *pHttpContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
STACK_STRU(strSiteConfigPath, 256);
|
|
||||||
STRU strEnvName;
|
STRU strEnvName;
|
||||||
STRU strEnvValue;
|
STRU strEnvValue;
|
||||||
STRU strExpandedEnvValue;
|
STRU strExpandedEnvValue;
|
||||||
|
|
@ -160,6 +151,10 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
DWORD dwCounter = 0;
|
DWORD dwCounter = 0;
|
||||||
DWORD dwPosition = 0;
|
DWORD dwPosition = 0;
|
||||||
WCHAR* pszPath = NULL;
|
WCHAR* pszPath = NULL;
|
||||||
|
BSTR bstrWindowAuthSection = NULL;
|
||||||
|
BSTR bstrBasicAuthSection = NULL;
|
||||||
|
BSTR bstrAnonymousAuthSection = NULL;
|
||||||
|
BSTR bstrAspNetCoreSection = NULL;
|
||||||
|
|
||||||
m_pEnvironmentVariables = new ENVIRONMENT_VAR_HASH();
|
m_pEnvironmentVariables = new ENVIRONMENT_VAR_HASH();
|
||||||
if (m_pEnvironmentVariables == NULL)
|
if (m_pEnvironmentVariables == NULL)
|
||||||
|
|
@ -174,20 +169,20 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
pAdminManager = g_pHttpServer->GetAdminManager();
|
pAdminManager = pHttpServer->GetAdminManager();
|
||||||
hr = strSiteConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
|
hr = m_struConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_struApplicationFullPath.Copy(pHttpContext->GetApplication()->GetApplicationPhysicalPath());
|
hr = m_struApplicationPhysicalPath.Copy(pHttpContext->GetApplication()->GetApplicationPhysicalPath());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
pszPath = strSiteConfigPath.QueryStr();
|
pszPath = m_struConfigPath.QueryStr();
|
||||||
while (pszPath[dwPosition] != NULL)
|
while (pszPath[dwPosition] != NULL)
|
||||||
{
|
{
|
||||||
if (pszPath[dwPosition] == '/')
|
if (pszPath[dwPosition] == '/')
|
||||||
|
|
@ -214,8 +209,15 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pAdminManager->GetAdminSection(CS_WINDOWS_AUTHENTICATION_SECTION,
|
bstrWindowAuthSection = SysAllocString(CS_WINDOWS_AUTHENTICATION_SECTION);
|
||||||
strSiteConfigPath.QueryStr(),
|
if (bstrWindowAuthSection == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAdminManager->GetAdminSection(bstrWindowAuthSection,
|
||||||
|
m_struConfigPath.QueryStr(),
|
||||||
&pWindowsAuthenticationElement);
|
&pWindowsAuthenticationElement);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -235,8 +237,14 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pAdminManager->GetAdminSection(CS_BASIC_AUTHENTICATION_SECTION,
|
bstrBasicAuthSection = SysAllocString(CS_BASIC_AUTHENTICATION_SECTION);
|
||||||
strSiteConfigPath.QueryStr(),
|
if (bstrBasicAuthSection == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
hr = pAdminManager->GetAdminSection(bstrBasicAuthSection,
|
||||||
|
m_struConfigPath.QueryStr(),
|
||||||
&pBasicAuthenticationElement);
|
&pBasicAuthenticationElement);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -252,9 +260,14 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bstrAnonymousAuthSection = SysAllocString(CS_ANONYMOUS_AUTHENTICATION_SECTION);
|
||||||
hr = pAdminManager->GetAdminSection(CS_ANONYMOUS_AUTHENTICATION_SECTION,
|
if (bstrAnonymousAuthSection == NULL)
|
||||||
strSiteConfigPath.QueryStr(),
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
hr = pAdminManager->GetAdminSection(bstrAnonymousAuthSection,
|
||||||
|
m_struConfigPath.QueryStr(),
|
||||||
&pAnonymousAuthenticationElement);
|
&pAnonymousAuthenticationElement);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -271,8 +284,14 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pAdminManager->GetAdminSection(CS_ASPNETCORE_SECTION,
|
bstrAspNetCoreSection = SysAllocString(CS_ASPNETCORE_SECTION);
|
||||||
strSiteConfigPath.QueryStr(),
|
if (bstrAspNetCoreSection == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
hr = pAdminManager->GetAdminSection(bstrAspNetCoreSection,
|
||||||
|
m_struConfigPath.QueryStr(),
|
||||||
&pAspNetCoreElement);
|
&pAspNetCoreElement);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -402,13 +421,13 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
hr = GetElementStringProperty(pAspNetCoreElement,
|
hr = GetElementStringProperty(pAspNetCoreElement,
|
||||||
CS_ASPNETCORE_STDOUT_LOG_FILE,
|
CS_ASPNETCORE_STDOUT_LOG_FILE,
|
||||||
&m_struStdoutLogFile);
|
&m_struStdoutLogFile);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = GetElementChildByName(pAspNetCoreElement,
|
hr = GetElementChildByName(pAspNetCoreElement,
|
||||||
CS_ASPNETCORE_ENVIRONMENT_VARIABLES,
|
CS_ASPNETCORE_ENVIRONMENT_VARIABLES,
|
||||||
|
|
@ -34,11 +34,13 @@
|
||||||
#define MIN_PORT 1025
|
#define MIN_PORT 1025
|
||||||
#define MAX_PORT 48000
|
#define MAX_PORT 48000
|
||||||
|
|
||||||
#define HEX_TO_ASCII(c) ((CHAR)(((c) < 10) ? ((c) + '0') : ((c) + 'a' - 10)))
|
#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)))
|
||||||
|
|
||||||
extern HTTP_MODULE_ID g_pModuleId;
|
//#define HEX_TO_ASCII(c) ((CHAR)(((c) < 10) ? ((c) + '0') : ((c) + 'a' - 10)))
|
||||||
extern IHttpServer * g_pHttpServer;
|
|
||||||
extern BOOL g_fRecycleProcessCalled;
|
#include "stdafx.h"
|
||||||
|
|
||||||
enum APP_HOSTING_MODEL
|
enum APP_HOSTING_MODEL
|
||||||
{
|
{
|
||||||
|
|
@ -57,14 +59,16 @@ public:
|
||||||
VOID
|
VOID
|
||||||
CleanupStoredContext()
|
CleanupStoredContext()
|
||||||
{
|
{
|
||||||
delete this;
|
DereferenceConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
HRESULT
|
HRESULT
|
||||||
GetConfig(
|
GetConfig(
|
||||||
_In_ IHttpContext *pHttpContext,
|
_In_ IHttpServer *pHttpServer,
|
||||||
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
_In_ HTTP_MODULE_ID pModuleId,
|
||||||
|
_In_ IHttpContext *pHttpContext,
|
||||||
|
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
ENVIRONMENT_VAR_HASH*
|
ENVIRONMENT_VAR_HASH*
|
||||||
|
|
@ -132,11 +136,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
STRU*
|
STRU*
|
||||||
QueryApplicationFullPath(
|
QueryApplicationPhysicalPath(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return &m_struApplicationFullPath;
|
return &m_struApplicationPhysicalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
STRU*
|
STRU*
|
||||||
|
|
@ -149,30 +153,22 @@ public:
|
||||||
|
|
||||||
STRU*
|
STRU*
|
||||||
QueryProcessPath(
|
QueryProcessPath(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return &m_struProcessPath;
|
return &m_struProcessPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
APP_HOSTING_MODEL
|
APP_HOSTING_MODEL
|
||||||
QueryHostingModel(
|
QueryHostingModel(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return m_hostingModel;
|
return m_hostingModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
STRU*
|
|
||||||
QueryHostingModelStr(
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return &m_strHostingModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
QueryStdoutLogEnabled()
|
QueryStdoutLogEnabled()
|
||||||
{
|
{
|
||||||
return m_fStdoutLogEnabled;
|
return m_fStdoutLogEnabled;
|
||||||
}
|
}
|
||||||
|
|
@ -213,6 +209,36 @@ public:
|
||||||
return &m_struStdoutLogFile;
|
return &m_struStdoutLogFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STRU*
|
||||||
|
QueryConfigPath()
|
||||||
|
{
|
||||||
|
return &m_struConfigPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRU*
|
||||||
|
QueryHostfxrPath()
|
||||||
|
{
|
||||||
|
return &m_struHostFxrPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryIsStandAloneApplication(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_fIsStandAloneApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ReferenceConfiguration(
|
||||||
|
VOID
|
||||||
|
) const;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DereferenceConfiguration(
|
||||||
|
VOID
|
||||||
|
) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -221,33 +247,40 @@ private:
|
||||||
ASPNETCORE_CONFIG():
|
ASPNETCORE_CONFIG():
|
||||||
m_fStdoutLogEnabled( FALSE ),
|
m_fStdoutLogEnabled( FALSE ),
|
||||||
m_pEnvironmentVariables( NULL ),
|
m_pEnvironmentVariables( NULL ),
|
||||||
|
m_cRefs( 1 ),
|
||||||
m_hostingModel( HOSTING_UNKNOWN )
|
m_hostingModel( HOSTING_UNKNOWN )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
Populate(
|
Populate(
|
||||||
|
IHttpServer *pHttpServer,
|
||||||
IHttpContext *pHttpContext
|
IHttpContext *pHttpContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
mutable LONG m_cRefs;
|
||||||
|
|
||||||
DWORD m_dwRequestTimeoutInMS;
|
DWORD m_dwRequestTimeoutInMS;
|
||||||
DWORD m_dwStartupTimeLimitInMS;
|
DWORD m_dwStartupTimeLimitInMS;
|
||||||
DWORD m_dwShutdownTimeLimitInMS;
|
DWORD m_dwShutdownTimeLimitInMS;
|
||||||
DWORD m_dwRapidFailsPerMinute;
|
DWORD m_dwRapidFailsPerMinute;
|
||||||
DWORD m_dwProcessesPerApplication;
|
DWORD m_dwProcessesPerApplication;
|
||||||
STRU m_struApplication;
|
|
||||||
STRU m_struArguments;
|
STRU m_struArguments;
|
||||||
STRU m_struProcessPath;
|
STRU m_struProcessPath;
|
||||||
STRU m_struStdoutLogFile;
|
STRU m_struStdoutLogFile;
|
||||||
STRU m_struApplicationFullPath;
|
STRU m_struApplication;
|
||||||
STRU m_strHostingModel;
|
STRU m_struApplicationPhysicalPath;
|
||||||
STRU m_struApplicationVirtualPath;
|
STRU m_struApplicationVirtualPath;
|
||||||
|
STRU m_struConfigPath;
|
||||||
|
STRU m_strHostingModel;
|
||||||
|
STRU m_struHostFxrPath;
|
||||||
BOOL m_fStdoutLogEnabled;
|
BOOL m_fStdoutLogEnabled;
|
||||||
BOOL m_fForwardWindowsAuthToken;
|
BOOL m_fForwardWindowsAuthToken;
|
||||||
BOOL m_fDisableStartUpErrorPage;
|
BOOL m_fDisableStartUpErrorPage;
|
||||||
BOOL m_fWindowsAuthEnabled;
|
BOOL m_fWindowsAuthEnabled;
|
||||||
BOOL m_fBasicAuthEnabled;
|
BOOL m_fBasicAuthEnabled;
|
||||||
BOOL m_fAnonymousAuthEnabled;
|
BOOL m_fAnonymousAuthEnabled;
|
||||||
|
BOOL m_fIsStandAloneApplication;
|
||||||
APP_HOSTING_MODEL m_hostingModel;
|
APP_HOSTING_MODEL m_hostingModel;
|
||||||
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
|
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
|
||||||
};
|
};
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ASPNETCORE_DEBUG_FLAG_INFO 0x00000001
|
#define ASPNETCORE_DEBUG_FLAG_INFO 0x00000001
|
||||||
#define ASPNETCORE_DEBUG_FLAG_WARNING 0x00000002
|
#define ASPNETCORE_DEBUG_FLAG_WARNING 0x00000002
|
||||||
#define ASPNETCORE_DEBUG_FLAG_ERROR 0x00000004
|
#define ASPNETCORE_DEBUG_FLAG_ERROR 0x00000004
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
// 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,259 @@
|
||||||
|
// 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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
HOSTFXR_UTILITY::FindHostFxrDll(
|
||||||
|
ASPNETCORE_CONFIG *pConfig,
|
||||||
|
STRU* struHostFxrDllLocation,
|
||||||
|
BOOL* fStandAlone
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
// If the process path isn't dotnet, assume we are a standalone appliction.
|
||||||
|
// TODO: this should be a path equivalent check
|
||||||
|
if (!(pConfig->QueryProcessPath()->Equals(L".\\dotnet")
|
||||||
|
|| pConfig->QueryProcessPath()->Equals(L"dotnet")
|
||||||
|
|| pConfig->QueryProcessPath()->Equals(L".\\dotnet.exe")
|
||||||
|
|| pConfig->QueryProcessPath()->Equals(L"dotnet.exe")))
|
||||||
|
{
|
||||||
|
// hostfxr is in the same folder, parse and use it.
|
||||||
|
hr = GetStandaloneHostfxrLocation(struHostFxrDllLocation, pConfig);
|
||||||
|
*fStandAlone = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = GetPortableHostfxrLocation(struHostFxrDllLocation);
|
||||||
|
fStandAlone = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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::GetStandaloneHostfxrLocation(
|
||||||
|
STRU* struHostfxrPath,
|
||||||
|
ASPNETCORE_CONFIG *pConfig
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
|
||||||
|
// Get the full path to the exe and check if it exists
|
||||||
|
if (FAILED(hr = UTILITY::ConvertPathToFullPath(L"\\hostfxr.dll",
|
||||||
|
pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
|
struHostfxrPath)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
hFileHandle = CreateFile(struHostfxrPath->QueryStr(),
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
&saAttr,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
if (hFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
// Treat access isseu as File not found
|
||||||
|
hr = ERROR_FILE_NOT_FOUND;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle(hFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
HOSTFXR_UTILITY::GetPortableHostfxrLocation(
|
||||||
|
STRU* struHostfxrPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
STRU struSystemPathVariable;
|
||||||
|
STRU strDotnetExeLocation;
|
||||||
|
STRU strHostFxrSearchExpression;
|
||||||
|
STRU strHighestDotnetVersion;
|
||||||
|
PWSTR pwzDelimeterContext = NULL;
|
||||||
|
PCWSTR pszDotnetLocation = NULL;
|
||||||
|
PCWSTR pszDotnetExeString(L"dotnet.exe");
|
||||||
|
DWORD dwCopyLength;
|
||||||
|
BOOL fFound = FALSE;
|
||||||
|
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
std::vector<std::wstring> vVersionFolders;
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the System PATH value.
|
||||||
|
if (!UTILITY::GetSystemPathVariable(L"PATH", &struSystemPathVariable))
|
||||||
|
{
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split on ';', checking to see if dotnet.exe exists in any folders.
|
||||||
|
pszDotnetLocation = wcstok_s(struSystemPathVariable.QueryStr(), L";", &pwzDelimeterContext);
|
||||||
|
while (pszDotnetLocation != NULL)
|
||||||
|
{
|
||||||
|
dwCopyLength = (DWORD) wcsnlen_s(pszDotnetLocation, 260);
|
||||||
|
|
||||||
|
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
|
||||||
|
// which doesn't need the dotnet.exe portion of the string
|
||||||
|
hr = strDotnetExeLocation.Copy(pszDotnetLocation, dwCopyLength);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwCopyLength > 0 && pszDotnetLocation[dwCopyLength - 1] != L'\\')
|
||||||
|
{
|
||||||
|
hr = strDotnetExeLocation.Append(L"\\");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = struHostfxrPath->Copy(strDotnetExeLocation);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strDotnetExeLocation.Append(pszDotnetExeString);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
hFileHandle = CreateFile(strDotnetExeLocation.QueryStr(),
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
&saAttr,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
if (hFileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
// means we found the folder with a dotnet.exe inside of it.
|
||||||
|
fFound = TRUE;
|
||||||
|
CloseHandle(hFileHandle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pszDotnetLocation = wcstok_s(NULL, L";", &pwzDelimeterContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fFound)
|
||||||
|
{
|
||||||
|
// could not find dotnet.exe, error out
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = struHostfxrPath->Append(L"host\\fxr");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UTILITY::DirectoryExists(struHostfxrPath))
|
||||||
|
{
|
||||||
|
// error, not found the folder
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all folders under host\\fxr\\ for version numbers.
|
||||||
|
hr = strHostFxrSearchExpression.Copy(struHostfxrPath);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strHostFxrSearchExpression.Append(L"\\*");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As we use the logic from core-setup, we are opting to use std here.
|
||||||
|
// TODO remove all uses of std?
|
||||||
|
UTILITY::FindDotNetFolders(strHostFxrSearchExpression.QueryStr(), &vVersionFolders);
|
||||||
|
|
||||||
|
if (vVersionFolders.size() == 0)
|
||||||
|
{
|
||||||
|
// no core framework was found
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = UTILITY::FindHighestDotNetVersion(vVersionFolders, &strHighestDotnetVersion);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
hr = struHostfxrPath->Append(L"\\");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = struHostfxrPath->Append(strHighestDotnetVersion.QueryStr());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = struHostfxrPath->Append(L"\\hostfxr.dll");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
// 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 HOSTFXR_UTILITY
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HOSTFXR_UTILITY();
|
||||||
|
~HOSTFXR_UTILITY();
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
FindHostFxrDll(
|
||||||
|
ASPNETCORE_CONFIG *pConfig,
|
||||||
|
STRU* struHostFxrDllLocation,
|
||||||
|
BOOL* fStandAlone
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
GetStandaloneHostfxrLocation(
|
||||||
|
STRU* struHostfxrPath,
|
||||||
|
ASPNETCORE_CONFIG *pConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
GetPortableHostfxrLocation(
|
||||||
|
STRU* struHostfxrPath
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,11 +1,11 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include"stdafx.h"
|
||||||
|
|
||||||
// static
|
// static
|
||||||
HRESULT
|
HRESULT
|
||||||
PATH::SplitUrl(
|
UTILITY::SplitUrl(
|
||||||
PCWSTR pszDestinationUrl,
|
PCWSTR pszDestinationUrl,
|
||||||
BOOL *pfSecure,
|
BOOL *pfSecure,
|
||||||
STRU *pstrDestination,
|
STRU *pstrDestination,
|
||||||
|
|
@ -95,7 +95,7 @@ Return Value:
|
||||||
|
|
||||||
// static
|
// static
|
||||||
HRESULT
|
HRESULT
|
||||||
PATH::UnEscapeUrl(
|
UTILITY::UnEscapeUrl(
|
||||||
PCWSTR pszUrl,
|
PCWSTR pszUrl,
|
||||||
DWORD cchUrl,
|
DWORD cchUrl,
|
||||||
bool fCopyQuery,
|
bool fCopyQuery,
|
||||||
|
|
@ -151,7 +151,7 @@ PATH::UnEscapeUrl(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
HRESULT
|
HRESULT
|
||||||
PATH::UnEscapeUrl(
|
UTILITY::UnEscapeUrl(
|
||||||
PCWSTR pszUrl,
|
PCWSTR pszUrl,
|
||||||
DWORD cchUrl,
|
DWORD cchUrl,
|
||||||
STRU * pstrResult
|
STRU * pstrResult
|
||||||
|
|
@ -231,7 +231,7 @@ PATH::UnEscapeUrl(
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
PATH::EscapeAbsPath(
|
UTILITY::EscapeAbsPath(
|
||||||
IHttpRequest * pRequest,
|
IHttpRequest * pRequest,
|
||||||
STRU * strEscapedUrl
|
STRU * strEscapedUrl
|
||||||
)
|
)
|
||||||
|
|
@ -269,7 +269,7 @@ Finished:
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
PATH::IsValidAttributeNameChar(
|
UTILITY::IsValidAttributeNameChar(
|
||||||
WCHAR ch
|
WCHAR ch
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -282,7 +282,7 @@ PATH::IsValidAttributeNameChar(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
PATH::FindInMultiString(
|
UTILITY::FindInMultiString(
|
||||||
PCWSTR pszMultiString,
|
PCWSTR pszMultiString,
|
||||||
PCWSTR pszStringToFind
|
PCWSTR pszStringToFind
|
||||||
)
|
)
|
||||||
|
|
@ -301,7 +301,7 @@ PATH::FindInMultiString(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
PATH::IsValidQueryStringName(
|
UTILITY::IsValidQueryStringName(
|
||||||
PCWSTR pszName
|
PCWSTR pszName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -322,7 +322,7 @@ PATH::IsValidQueryStringName(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
PATH::IsValidHeaderName(
|
UTILITY::IsValidHeaderName(
|
||||||
PCWSTR pszName
|
PCWSTR pszName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -342,7 +342,7 @@ PATH::IsValidHeaderName(
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
PATH::IsPathUnc(
|
UTILITY::IsPathUnc(
|
||||||
__in LPCWSTR pszPath,
|
__in LPCWSTR pszPath,
|
||||||
__out BOOL * pfIsUnc
|
__out BOOL * pfIsUnc
|
||||||
)
|
)
|
||||||
|
|
@ -373,7 +373,7 @@ Finished:
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
PATH::ConvertPathToFullPath(
|
UTILITY::ConvertPathToFullPath(
|
||||||
_In_ LPCWSTR pszPath,
|
_In_ LPCWSTR pszPath,
|
||||||
_In_ LPCWSTR pszRootPath,
|
_In_ LPCWSTR pszRootPath,
|
||||||
_Out_ STRU* pStruFullPath
|
_Out_ STRU* pStruFullPath
|
||||||
|
|
@ -384,7 +384,7 @@ PATH::ConvertPathToFullPath(
|
||||||
LPWSTR pszFullPath = NULL;
|
LPWSTR pszFullPath = NULL;
|
||||||
|
|
||||||
// if relative path, prefix with root path and then convert to absolute path.
|
// if relative path, prefix with root path and then convert to absolute path.
|
||||||
if( pszPath[0] == L'.' )
|
if ( pszPath[0] == L'.' )
|
||||||
{
|
{
|
||||||
hr = strFileFullPath.Copy(pszRootPath);
|
hr = strFileFullPath.Copy(pszRootPath);
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
|
|
@ -403,13 +403,13 @@ PATH::ConvertPathToFullPath(
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = strFileFullPath.Append( pszPath );
|
hr = strFileFullPath.Append( pszPath );
|
||||||
if(FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
pszFullPath = new WCHAR[ strFileFullPath.QueryCCH() + 1];
|
pszFullPath = new WCHAR[ strFileFullPath.QueryCCH() + 1];
|
||||||
if( pszFullPath == NULL )
|
if ( pszFullPath == NULL )
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -425,14 +425,14 @@ PATH::ConvertPathToFullPath(
|
||||||
|
|
||||||
// convert to canonical path
|
// convert to canonical path
|
||||||
hr = MakePathCanonicalizationProof( pszFullPath, pStruFullPath );
|
hr = MakePathCanonicalizationProof( pszFullPath, pStruFullPath );
|
||||||
if(FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
||||||
if( pszFullPath != NULL )
|
if ( pszFullPath != NULL )
|
||||||
{
|
{
|
||||||
delete[] pszFullPath;
|
delete[] pszFullPath;
|
||||||
pszFullPath = NULL;
|
pszFullPath = NULL;
|
||||||
|
|
@ -440,3 +440,170 @@ Finished:
|
||||||
|
|
||||||
return hr;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
UTILITY::GetSystemPathVariable(
|
||||||
|
_In_ PCWSTR pszEnvironmentVariable,
|
||||||
|
_Out_ STRU *pstrResult
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DWORD dwLength;
|
||||||
|
PWSTR pszBuffer = NULL;
|
||||||
|
BOOL fSucceeded = FALSE;
|
||||||
|
|
||||||
|
if (pszEnvironmentVariable == NULL)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
pstrResult->Reset();
|
||||||
|
dwLength = GetEnvironmentVariableW(pszEnvironmentVariable, NULL, 0);
|
||||||
|
|
||||||
|
if (dwLength == 0)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszBuffer = new WCHAR[dwLength];
|
||||||
|
if (GetEnvironmentVariableW(pszEnvironmentVariable, pszBuffer, dwLength) == 0)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pstrResult->Copy(pszBuffer);
|
||||||
|
|
||||||
|
fSucceeded = TRUE;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (pszBuffer != NULL) {
|
||||||
|
delete[] pszBuffer;
|
||||||
|
}
|
||||||
|
return fSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class PATH
|
class UTILITY
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -79,17 +79,41 @@ public:
|
||||||
_Out_ STRU* pStrFullPath
|
_Out_ STRU* pStrFullPath
|
||||||
);
|
);
|
||||||
|
|
||||||
private:
|
static
|
||||||
|
HRESULT
|
||||||
PATH() {}
|
EnsureDirectoryPathExist(
|
||||||
~PATH() {}
|
_In_ LPCWSTR pszPath
|
||||||
|
);
|
||||||
|
|
||||||
static
|
static
|
||||||
CHAR
|
BOOL
|
||||||
ToHexDigit(
|
DirectoryExists(
|
||||||
UINT nDigit
|
_In_ STRU *pstrPath
|
||||||
)
|
);
|
||||||
{
|
|
||||||
return static_cast<CHAR>(nDigit > 9 ? nDigit - 10 + 'A' : nDigit + '0');
|
static
|
||||||
}
|
BOOL
|
||||||
|
GetSystemPathVariable(
|
||||||
|
_In_ PCWSTR pszEnvironmentVariable,
|
||||||
|
_Out_ STRU *pstrResult
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
FindDotNetFolders(
|
||||||
|
_In_ PCWSTR pszPath,
|
||||||
|
_Out_ std::vector<std::wstring> *pvFolders
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
FindHighestDotNetVersion(
|
||||||
|
_In_ std::vector<std::wstring> vFolders,
|
||||||
|
_Out_ STRU *pstrResult
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
UTILITY() {}
|
||||||
|
~UTILITY() {}
|
||||||
};
|
};
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>IISLib</RootNamespace>
|
<RootNamespace>IISLib</RootNamespace>
|
||||||
<ProjectName>IISLib</ProjectName>
|
<ProjectName>IISLib</ProjectName>
|
||||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
|
@ -78,6 +78,8 @@
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -94,6 +96,7 @@
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -111,6 +114,7 @@
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
@ -130,6 +134,7 @@
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<ShowIncludes>false</ShowIncludes>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ahadmin.h>
|
#include <ahadmin.h>
|
||||||
#pragma warning( disable:4127 )
|
#pragma warning( disable:4127 )
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <atlcomcli.h>
|
#include <atlcomcli.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
#include <intsafe.h>
|
#include <intsafe.h>
|
||||||
|
|
@ -16,3 +19,4 @@
|
||||||
#include "ahutil.h"
|
#include "ahutil.h"
|
||||||
#include "acache.h"
|
#include "acache.h"
|
||||||
//#include "base64.hxx"
|
//#include "base64.hxx"
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,287 @@
|
||||||
|
<?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="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>{D57EA297-6DC2-4BC0-8C91-334863327863}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>RequestHandler</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>RequestHandler</ProjectName>
|
||||||
|
</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)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<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|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="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>
|
||||||
|
<TargetName>aspnetcorerh</TargetName>
|
||||||
|
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<TargetName>aspnetcorerh</TargetName>
|
||||||
|
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>aspnetcorerh</TargetName>
|
||||||
|
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>aspnetcorerh</TargetName>
|
||||||
|
<OutDir>$(SolutionDir)artifacts\build\AspNetCore\bin\$(Configuration)\$(Platform)</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
|
||||||
|
<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>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
|
||||||
|
<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>
|
||||||
|
</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;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
|
||||||
|
<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>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PrecompiledHeaderFile>precomp.hxx</PrecompiledHeaderFile>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>..\IISLib;..\CommonLib;.\Inc</AdditionalIncludeDirectories>
|
||||||
|
<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>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="aspnetcore_event.h" />
|
||||||
|
<ClInclude Include="aspnetcore_msg.h" />
|
||||||
|
<ClInclude Include="disconnectcontext.h" />
|
||||||
|
<ClInclude Include="sttimer.h" />
|
||||||
|
<ClInclude Include="outofprocess\forwarderconnection.h" />
|
||||||
|
<ClInclude Include="outofprocess\processmanager.h" />
|
||||||
|
<ClInclude Include="outofprocess\protocolconfig.h" />
|
||||||
|
<ClInclude Include="outofprocess\responseheaderhash.h" />
|
||||||
|
<ClInclude Include="outofprocess\serverprocess.h" />
|
||||||
|
<ClInclude Include="outofprocess\websockethandler.h" />
|
||||||
|
<ClInclude Include="outofprocess\winhttphelper.h" />
|
||||||
|
<ClInclude Include="precomp.hxx" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include=".\inprocess\inprocessapplication.h" />
|
||||||
|
<ClInclude Include=".\inprocess\inprocesshandler.h" />
|
||||||
|
<ClInclude Include=".\outofprocess\forwardinghandler.h" />
|
||||||
|
<ClInclude Include=".\outofprocess\outprocessapplication.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="dllmain.cxx" />
|
||||||
|
<ClCompile Include=".\inprocess\inprocessapplication.cpp" />
|
||||||
|
<ClCompile Include=".\inprocess\inprocesshandler.cpp" />
|
||||||
|
<ClCompile Include=".\outofprocess\forwardinghandler.cpp" />
|
||||||
|
<ClCompile Include=".\outofprocess\outprocessapplication.cpp" />
|
||||||
|
<ClCompile Include="managedexports.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\forwarderconnection.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\processmanager.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\protocolconfig.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\responseheaderhash.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\serverprocess.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\websockethandler.cxx" />
|
||||||
|
<ClCompile Include="outofprocess\winhttphelper.cxx" />
|
||||||
|
</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>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\CommonLib\CommonLib.vcxproj">
|
||||||
|
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\IISLib\IISLib.vcxproj">
|
||||||
|
<Project>{4787a64f-9a3e-4867-a55a-70cb4b2b2ffe}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="RequestHandler.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Source.def" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="dllmain.cxx" />
|
||||||
|
<ClCompile Include=".\inprocess\inprocessapplication.cpp">
|
||||||
|
<Filter>InProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include=".\inprocess\inprocesshandler.cpp">
|
||||||
|
<Filter>InProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="managedexports.cxx">
|
||||||
|
<Filter>InProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include=".\outofprocess\forwardinghandler.cpp">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include=".\outofprocess\outprocessapplication.cpp">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\processmanager.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\protocolconfig.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\serverprocess.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\forwarderconnection.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\responseheaderhash.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\websockethandler.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="outofprocess\winhttphelper.cxx">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="precomp.hxx" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include=".\inprocess\inprocessapplication.h">
|
||||||
|
<Filter>InProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include=".\inprocess\inprocesshandler.h">
|
||||||
|
<Filter>InProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include=".\outofprocess\forwardinghandler.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\forwarderconnection.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\responseheaderhash.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include=".\outofprocess\outprocessapplication.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\processmanager.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\protocolconfig.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\serverprocess.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\responseheaderhash.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\websockethandler.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="outofprocess\winhttphelper.h">
|
||||||
|
<Filter>OutOfProcess</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="disconnectcontext.h" />
|
||||||
|
<ClInclude Include="aspnetcore_event.h" />
|
||||||
|
<ClInclude Include="sttimer.h" />
|
||||||
|
<ClInclude Include="aspnetcore_msg.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="RequestHandler.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Source.def" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="RequestHandler.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Source.def" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="InProcess">
|
||||||
|
<UniqueIdentifier>{e567abb5-bac5-4f05-a320-5e25dcfc0000}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="OutOfProcess">
|
||||||
|
<UniqueIdentifier>{5568209f-269e-4d0a-bbb7-ba14f874ccb7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CustomBuild Include="aspnetcore_msg.mc" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
||||||
|
LIBRARY aspnetcorerh
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
CreateApplication
|
||||||
|
CreateRequestHandler
|
||||||
|
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*++
|
||||||
|
|
||||||
|
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_
|
||||||
|
|
||||||
|
//
|
||||||
|
// Values are 32 bit values laid out as follows:
|
||||||
|
//
|
||||||
|
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||||
|
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||||
|
// +---+-+-+-----------------------+-------------------------------+
|
||||||
|
// |Sev|C|R| Facility | Code |
|
||||||
|
// +---+-+-+-----------------------+-------------------------------+
|
||||||
|
//
|
||||||
|
// where
|
||||||
|
//
|
||||||
|
// Sev - is the severity code
|
||||||
|
//
|
||||||
|
// 00 - Success
|
||||||
|
// 01 - Informational
|
||||||
|
// 10 - Warning
|
||||||
|
// 11 - Error
|
||||||
|
//
|
||||||
|
// C - is the Customer code flag
|
||||||
|
//
|
||||||
|
// R - is a reserved bit
|
||||||
|
//
|
||||||
|
// Facility - is the facility code
|
||||||
|
//
|
||||||
|
// Code - is the facility's status code
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Define the facility codes
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the severity codes
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_PROCESS_START_ERROR
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_ERROR ((DWORD)0x000003E8L)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_PROCESS_START_SUCCESS
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS ((DWORD)0x000003E9L)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_PROCESS_CRASH
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_CRASH ((DWORD)0x000003EAL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED ((DWORD)0x000003EBL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_CONFIG_ERROR
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_CONFIG_ERROR ((DWORD)0x000003ECL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE ((DWORD)0x000003EDL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST ((DWORD)0x000003EEL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_LOAD_CLR_FALIURE
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_LOAD_CLR_FALIURE ((DWORD)0x000003EFL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP ((DWORD)0x000003F0L)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR ((DWORD)0x000003F1L)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_ADD_APPLICATION_ERROR
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR ((DWORD)0x000003F2L)
|
||||||
|
|
||||||
|
//
|
||||||
|
// MessageId: ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT
|
||||||
|
//
|
||||||
|
// MessageText:
|
||||||
|
//
|
||||||
|
// %1
|
||||||
|
//
|
||||||
|
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT ((DWORD)0x000003F3L)
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _ASPNETCORE_MODULE_MSG_H_
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
LANGUAGE 0x9,0x1
|
||||||
|
1 11 "MSG00001.bin"
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
// 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 ASYNC_DISCONNECT_CONTEXT : public IHttpConnectionStoredContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ASYNC_DISCONNECT_CONTEXT()
|
||||||
|
{
|
||||||
|
m_pHandler = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanupStoredContext()
|
||||||
|
{
|
||||||
|
DBG_ASSERT(m_pHandler == NULL);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NotifyDisconnect()
|
||||||
|
{
|
||||||
|
REQUEST_HANDLER *pInitialValue = (REQUEST_HANDLER*)
|
||||||
|
InterlockedExchangePointer((PVOID*)&m_pHandler, NULL);
|
||||||
|
|
||||||
|
if (pInitialValue != NULL)
|
||||||
|
{
|
||||||
|
pInitialValue->TerminateRequest(TRUE);
|
||||||
|
pInitialValue->DereferenceRequestHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetHandler(
|
||||||
|
REQUEST_HANDLER *pHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Take a reference on the forwarding handler.
|
||||||
|
// This reference will be released on either of two conditions:
|
||||||
|
//
|
||||||
|
// 1. When the request processing ends, in which case a ResetHandler()
|
||||||
|
// is called.
|
||||||
|
//
|
||||||
|
// 2. When a disconnect notification arrives.
|
||||||
|
//
|
||||||
|
// We need to make sure that only one of them ends up dereferencing
|
||||||
|
// the object.
|
||||||
|
//
|
||||||
|
|
||||||
|
DBG_ASSERT(pHandler != NULL);
|
||||||
|
DBG_ASSERT(m_pHandler == NULL);
|
||||||
|
|
||||||
|
pHandler->ReferenceRequestHandler();
|
||||||
|
InterlockedExchangePointer((PVOID*)&m_pHandler, pHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ResetHandler(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
REQUEST_HANDLER *pInitialValue = (REQUEST_HANDLER*)
|
||||||
|
InterlockedExchangePointer((PVOID*)&m_pHandler, NULL);
|
||||||
|
|
||||||
|
if (pInitialValue != NULL)
|
||||||
|
{
|
||||||
|
pInitialValue->DereferenceRequestHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~ASYNC_DISCONNECT_CONTEXT()
|
||||||
|
{}
|
||||||
|
|
||||||
|
REQUEST_HANDLER * m_pHandler;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,340 @@
|
||||||
|
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||||
|
#include "precomp.hxx"
|
||||||
|
#include <IPHlpApi.h>
|
||||||
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
|
BOOL g_fNsiApiNotSupported = FALSE;
|
||||||
|
BOOL g_fWebSocketSupported = FALSE;
|
||||||
|
BOOL g_fEnableReferenceCountTracing = FALSE;
|
||||||
|
BOOL g_fOutOfProcessInitialize = FALSE;
|
||||||
|
BOOL g_fOutOfProcessInitializeError = FALSE;
|
||||||
|
BOOL g_fWinHttpNonBlockingCallbackAvailable = FALSE;
|
||||||
|
DWORD g_OptionalWinHttpFlags = 0;
|
||||||
|
DWORD g_dwAspNetCoreDebugFlags = 0;
|
||||||
|
DWORD g_dwDebugFlags = 0;
|
||||||
|
DWORD g_dwTlsIndex = TLS_OUT_OF_INDEXES;
|
||||||
|
SRWLOCK g_srwLockRH;
|
||||||
|
HINTERNET g_hWinhttpSession = NULL;
|
||||||
|
IHttpServer * g_pHttpServer = NULL;
|
||||||
|
HINSTANCE g_hWinHttpModule;
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InitializeGlobalConfiguration(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||||
|
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
|
||||||
|
0,
|
||||||
|
KEY_READ,
|
||||||
|
&hKey) == NO_ERROR)
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwData;
|
||||||
|
DWORD cbData;
|
||||||
|
|
||||||
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"OptionalWinHttpFlags",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD))
|
||||||
|
{
|
||||||
|
g_OptionalWinHttpFlags = dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"EnableReferenceCountTracing",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD) && (dwData == 1 || dwData == 0))
|
||||||
|
{
|
||||||
|
g_fEnableReferenceCountTracing = !!dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbData = sizeof(dwData);
|
||||||
|
if ((RegQueryValueEx(hKey,
|
||||||
|
L"DebugFlags",
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(LPBYTE)&dwData,
|
||||||
|
&cbData) == NO_ERROR) &&
|
||||||
|
(dwType == REG_DWORD))
|
||||||
|
{
|
||||||
|
g_dwAspNetCoreDebugFlags = dwData;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwSize = 0;
|
||||||
|
DWORD dwResult = GetExtendedTcpTable(NULL,
|
||||||
|
&dwSize,
|
||||||
|
FALSE,
|
||||||
|
AF_INET,
|
||||||
|
TCP_TABLE_OWNER_PID_LISTENER,
|
||||||
|
0);
|
||||||
|
if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
g_fNsiApiNotSupported = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebSocket is supported on Win8 and above only
|
||||||
|
// todo: test on win7
|
||||||
|
g_fWebSocketSupported = IsWindows8OrGreater();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global initialization routine for OutOfProcess
|
||||||
|
//
|
||||||
|
HRESULT
|
||||||
|
EnsureOutOfProcessInitializtion( IHttpServer* pServer)
|
||||||
|
{
|
||||||
|
|
||||||
|
DBG_ASSERT(pServer);
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
|
||||||
|
g_pHttpServer = pServer;
|
||||||
|
|
||||||
|
if (g_fOutOfProcessInitializeError)
|
||||||
|
{
|
||||||
|
hr = E_NOT_VALID_STATE;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
if (!g_fOutOfProcessInitialize)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&g_srwLockRH);
|
||||||
|
fLocked = TRUE;
|
||||||
|
if (g_fOutOfProcessInitializeError)
|
||||||
|
{
|
||||||
|
hr = E_NOT_VALID_STATE;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_fOutOfProcessInitialize)
|
||||||
|
{
|
||||||
|
// Done by another thread
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialze some global variables here
|
||||||
|
InitializeGlobalConfiguration();
|
||||||
|
|
||||||
|
g_hWinHttpModule = GetModuleHandle(TEXT("winhttp.dll"));
|
||||||
|
|
||||||
|
hr = WINHTTP_HELPER::StaticInitialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND))
|
||||||
|
{
|
||||||
|
g_fWebSocketSupported = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hWinhttpSession = WinHttpOpen(L"",
|
||||||
|
WINHTTP_ACCESS_TYPE_NO_PROXY,
|
||||||
|
WINHTTP_NO_PROXY_NAME,
|
||||||
|
WINHTTP_NO_PROXY_BYPASS,
|
||||||
|
WINHTTP_FLAG_ASYNC);
|
||||||
|
if (g_hWinhttpSession == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't set non-blocking callbacks WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS,
|
||||||
|
// as we will call WinHttpQueryDataAvailable to get response on the same thread
|
||||||
|
// that we received callback from Winhttp on completing sending/forwarding the request
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup the callback function
|
||||||
|
//
|
||||||
|
if (WinHttpSetStatusCallback(g_hWinhttpSession,
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
(WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS |
|
||||||
|
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST),
|
||||||
|
NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure we see the redirects (rather than winhttp doing it
|
||||||
|
// automatically)
|
||||||
|
//
|
||||||
|
DWORD dwRedirectOption = WINHTTP_OPTION_REDIRECT_POLICY_NEVER;
|
||||||
|
if (!WinHttpSetOption(g_hWinhttpSession,
|
||||||
|
WINHTTP_OPTION_REDIRECT_POLICY,
|
||||||
|
&dwRedirectOption,
|
||||||
|
sizeof(dwRedirectOption)))
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dwTlsIndex = TlsAlloc();
|
||||||
|
if (g_dwTlsIndex == TLS_OUT_OF_INDEXES)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hr = FORWARDING_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = WEBSOCKET_HANDLER::StaticInitialize(g_fEnableReferenceCountTracing);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
g_fOutOfProcessInitializeError = TRUE;
|
||||||
|
}
|
||||||
|
if (fLocked)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&g_srwLockRH);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
|
DWORD ul_reason_for_call,
|
||||||
|
LPVOID lpReserved
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(lpReserved);
|
||||||
|
|
||||||
|
switch (ul_reason_for_call)
|
||||||
|
{
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
InitializeSRWLock(&g_srwLockRH);
|
||||||
|
// Initialze some global variables here
|
||||||
|
InitializeGlobalConfiguration();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
__stdcall
|
||||||
|
CreateApplication(
|
||||||
|
_In_ IHttpServer *pServer,
|
||||||
|
_In_ ASPNETCORE_CONFIG *pConfig,
|
||||||
|
_Out_ APPLICATION **ppApplication
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
APPLICATION *pApplication = NULL;
|
||||||
|
|
||||||
|
//REQUEST_HANDLER::StaticInitialize(pServer);
|
||||||
|
|
||||||
|
if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
|
||||||
|
{
|
||||||
|
pApplication = new IN_PROCESS_APPLICATION(pServer, pConfig);
|
||||||
|
if (pApplication == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_OUT_PROCESS)
|
||||||
|
{
|
||||||
|
hr = EnsureOutOfProcessInitializtion(pServer);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pApplication = new OUT_OF_PROCESS_APPLICATION(pServer, pConfig);
|
||||||
|
if (pApplication == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = ((OUT_OF_PROCESS_APPLICATION*)pApplication)->Initialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
delete pApplication;
|
||||||
|
pApplication = NULL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppApplication = pApplication;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
__stdcall
|
||||||
|
CreateRequestHandler(
|
||||||
|
_In_ IHttpContext *pHttpContext,
|
||||||
|
_In_ HTTP_MODULE_ID *pModuleId,
|
||||||
|
_In_ APPLICATION *pApplication,
|
||||||
|
_Out_ REQUEST_HANDLER **pRequestHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
REQUEST_HANDLER* pHandler = NULL;
|
||||||
|
ASPNETCORE_CONFIG* pConfig = pApplication->QueryConfig();
|
||||||
|
DBG_ASSERT(pConfig);
|
||||||
|
|
||||||
|
if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
|
||||||
|
{
|
||||||
|
pHandler = new IN_PROCESS_HANDLER(pHttpContext, pModuleId, pApplication);
|
||||||
|
}
|
||||||
|
else if (pConfig->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_OUT_PROCESS)
|
||||||
|
{
|
||||||
|
pHandler = new FORWARDING_HANDLER(pHttpContext, pModuleId, pApplication);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pHandler == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pRequestHandler = pHandler;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,889 @@
|
||||||
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
|
typedef DWORD(*hostfxr_main_fn) (CONST DWORD argc, CONST WCHAR* argv[]);
|
||||||
|
|
||||||
|
IN_PROCESS_APPLICATION* IN_PROCESS_APPLICATION::s_Application = NULL;
|
||||||
|
|
||||||
|
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
|
||||||
|
IHttpServer* pHttpServer,
|
||||||
|
ASPNETCORE_CONFIG* pConfig) :
|
||||||
|
APPLICATION(pHttpServer, pConfig),
|
||||||
|
m_ProcessExitCode(0),
|
||||||
|
m_fManagedAppLoaded(FALSE),
|
||||||
|
m_fLoadManagedAppError(FALSE),
|
||||||
|
m_fInitialized(FALSE),
|
||||||
|
m_fRecycleProcessCalled(FALSE),
|
||||||
|
m_hLogFileHandle(INVALID_HANDLE_VALUE),
|
||||||
|
m_fDoneStdRedirect(FALSE)
|
||||||
|
{
|
||||||
|
// is it guaranteed that we have already checked app offline at this point?
|
||||||
|
// If so, I don't think there is much to do here.
|
||||||
|
DBG_ASSERT(pHttpServer != NULL);
|
||||||
|
DBG_ASSERT(pConfig != NULL);
|
||||||
|
InitializeSRWLock(&m_srwLock);
|
||||||
|
|
||||||
|
// TODO we can probably initialized as I believe we are the only ones calling recycle.
|
||||||
|
m_fInitialized = TRUE;
|
||||||
|
m_status = APPLICATION_STATUS::RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
|
||||||
|
{
|
||||||
|
Recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_APPLICATION::ShutDown()
|
||||||
|
{
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the same function as before, TODO configrm if we need to change anything for configuration.
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_APPLICATION::Recycle(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (m_fInitialized)
|
||||||
|
{
|
||||||
|
DWORD dwThreadStatus = 0;
|
||||||
|
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
||||||
|
HANDLE handle = NULL;
|
||||||
|
WIN32_FIND_DATA fileData;
|
||||||
|
|
||||||
|
if (m_pStdFile != NULL)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
|
fclose(m_pStdFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_hLogFileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
m_Timer.CancelTimer();
|
||||||
|
CloseHandle(m_hLogFileHandle);
|
||||||
|
m_hLogFileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete empty log file, if logging is not enabled
|
||||||
|
handle = FindFirstFile(m_struLogFilePath.QueryStr(), &fileData);
|
||||||
|
if (handle != INVALID_HANDLE_VALUE &&
|
||||||
|
fileData.nFileSizeHigh &&
|
||||||
|
fileData.nFileSizeLow == 0) // skip check of nFileSizeHigh
|
||||||
|
{
|
||||||
|
FindClose(handle);
|
||||||
|
// no need to check whether the deletion succeeds
|
||||||
|
// as nothing can be done
|
||||||
|
DeleteFile(m_struLogFilePath.QueryStr());
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
|
||||||
|
if (!m_pHttpServer->IsCommandLineLaunch() &&
|
||||||
|
!m_fRecycleProcessCalled &&
|
||||||
|
(m_pHttpServer->GetAdminManager() != NULL))
|
||||||
|
{
|
||||||
|
// IIS scenario.
|
||||||
|
// notify IIS first so that new request will be routed to new worker process
|
||||||
|
m_pHttpServer->RecycleProcess(L"AspNetCore Recycle Process on Demand");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fRecycleProcessCalled = TRUE;
|
||||||
|
|
||||||
|
// First call into the managed server and shutdown
|
||||||
|
if (m_ShutdownHandler != NULL)
|
||||||
|
{
|
||||||
|
m_ShutdownHandler(m_ShutdownHandlerContext);
|
||||||
|
m_ShutdownHandler = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_hThread != NULL &&
|
||||||
|
GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 &&
|
||||||
|
dwThreadStatus == STILL_ACTIVE)
|
||||||
|
{
|
||||||
|
// wait for gracefullshut down, i.e., the exit of the background thread or timeout
|
||||||
|
if (WaitForSingleObject(m_hThread, dwTimeout) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
// if the thread is still running, we need kill it first before exit to avoid AV
|
||||||
|
if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE)
|
||||||
|
{
|
||||||
|
TerminateThread(m_hThread, STATUS_CONTROL_C_EXIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(m_hThread);
|
||||||
|
m_hThread = NULL;
|
||||||
|
s_Application = NULL;
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
if (m_pHttpServer && m_pHttpServer->IsCommandLineLaunch())
|
||||||
|
{
|
||||||
|
// IISExpress scenario
|
||||||
|
// Can only call exit to terminate current process
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
IN_PROCESS_APPLICATION::OnAsyncCompletion(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus,
|
||||||
|
IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS dwRequestNotificationStatus = RQ_NOTIFICATION_CONTINUE;
|
||||||
|
|
||||||
|
if (pInProcessHandler->QueryIsManagedRequestComplete())
|
||||||
|
{
|
||||||
|
// means PostCompletion has been called and this is the associated callback.
|
||||||
|
dwRequestNotificationStatus = pInProcessHandler->QueryAsyncCompletionStatus();
|
||||||
|
// TODO cleanup whatever disconnect listener there is
|
||||||
|
return dwRequestNotificationStatus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Call the managed handler for async completion.
|
||||||
|
return m_AsyncCompletionHandler(pInProcessHandler->QueryManagedHttpContext(), hrCompletionStatus, cbCompletion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
IN_PROCESS_APPLICATION::OnExecuteRequest(
|
||||||
|
_In_ IHttpContext* pHttpContext,
|
||||||
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (m_RequestHandler != NULL)
|
||||||
|
{
|
||||||
|
return m_RequestHandler(pInProcessHandler, m_RequestHandlerContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// return error as the application did not register callback
|
||||||
|
//
|
||||||
|
if (ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::IsEnabled(pHttpContext->GetTraceContext()))
|
||||||
|
{
|
||||||
|
ANCMEvents::ANCM_EXECUTE_REQUEST_FAIL::RaiseEvent(pHttpContext->GetTraceContext(),
|
||||||
|
NULL,
|
||||||
|
(ULONG)E_APPLICATION_ACTIVATION_EXEC_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pHttpContext->GetResponse()->SetStatus(500,
|
||||||
|
"Internal Server Error",
|
||||||
|
0,
|
||||||
|
(ULONG)E_APPLICATION_ACTIVATION_EXEC_FAILURE);
|
||||||
|
|
||||||
|
return RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IN_PROCESS_APPLICATION::DirectoryExists(
|
||||||
|
_In_ STRU *pstrPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||||
|
|
||||||
|
if (pstrPath->IsEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IN_PROCESS_APPLICATION::GetEnv(
|
||||||
|
_In_ PCWSTR pszEnvironmentVariable,
|
||||||
|
_Out_ STRU *pstrResult
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DWORD dwLength;
|
||||||
|
PWSTR pszBuffer = NULL;
|
||||||
|
BOOL fSucceeded = FALSE;
|
||||||
|
|
||||||
|
if (pszEnvironmentVariable == NULL)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
pstrResult->Reset();
|
||||||
|
dwLength = GetEnvironmentVariableW(pszEnvironmentVariable, NULL, 0);
|
||||||
|
|
||||||
|
if (dwLength == 0)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszBuffer = new WCHAR[dwLength];
|
||||||
|
if (GetEnvironmentVariableW(pszEnvironmentVariable, pszBuffer, dwLength) == 0)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pstrResult->Copy(pszBuffer);
|
||||||
|
|
||||||
|
fSucceeded = TRUE;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (pszBuffer != NULL) {
|
||||||
|
delete[] pszBuffer;
|
||||||
|
}
|
||||||
|
return fSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_APPLICATION::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);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_APPLICATION::SetCallbackHandles(
|
||||||
|
_In_ PFN_REQUEST_HANDLER request_handler,
|
||||||
|
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
||||||
|
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
|
||||||
|
_In_ VOID* pvRequstHandlerContext,
|
||||||
|
_In_ VOID* pvShutdownHandlerContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_RequestHandler = request_handler;
|
||||||
|
m_RequestHandlerContext = pvRequstHandlerContext;
|
||||||
|
m_ShutdownHandler = shutdown_handler;
|
||||||
|
m_ShutdownHandlerContext = pvShutdownHandlerContext;
|
||||||
|
m_AsyncCompletionHandler = async_completion_handler;
|
||||||
|
|
||||||
|
// Initialization complete
|
||||||
|
SetEvent(m_pInitalizeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
IN_PROCESS_APPLICATION::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_APPLICATION::SetStdOut(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
STRU struPath;
|
||||||
|
|
||||||
|
SYSTEMTIME systemTime;
|
||||||
|
SECURITY_ATTRIBUTES saAttr = { 0 };
|
||||||
|
|
||||||
|
if (!m_fDoneStdRedirect)
|
||||||
|
{
|
||||||
|
// Have not set stdout yet, redirect stdout to log file
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fLocked = TRUE;
|
||||||
|
if (!m_fDoneStdRedirect)
|
||||||
|
{
|
||||||
|
hr = UTILITY::ConvertPathToFullPath(
|
||||||
|
m_pConfig->QueryStdoutLogFile()->QueryStr(),
|
||||||
|
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
|
&struPath);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = UTILITY::EnsureDirectoryPathExist(struPath.QueryStr());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSystemTime(&systemTime);
|
||||||
|
hr = m_struLogFilePath.SafeSnwprintf(L"%s_%d%02d%02d%02d%02d%02d_%d.log",
|
||||||
|
struPath.QueryStr(),
|
||||||
|
systemTime.wYear,
|
||||||
|
systemTime.wMonth,
|
||||||
|
systemTime.wDay,
|
||||||
|
systemTime.wHour,
|
||||||
|
systemTime.wMinute,
|
||||||
|
systemTime.wSecond,
|
||||||
|
GetCurrentProcessId());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
m_hLogFileHandle = CreateFileW(m_struLogFilePath.QueryStr(),
|
||||||
|
FILE_WRITE_DATA,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
&saAttr,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (m_hLogFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// best effort
|
||||||
|
// no need to capture the error code as nothing we can do here
|
||||||
|
// in case mamanged layer exits abnormally, may not be able to capture the log content as it is buffered.
|
||||||
|
//
|
||||||
|
if (!GetConsoleWindow())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// SetStdHandle works as w3wp does not have Console
|
||||||
|
// Current process does not have a console
|
||||||
|
//
|
||||||
|
SetStdHandle(STD_ERROR_HANDLE, m_hLogFileHandle);
|
||||||
|
if (m_pConfig->QueryStdoutLogEnabled())
|
||||||
|
{
|
||||||
|
SetStdHandle(STD_OUTPUT_HANDLE, m_hLogFileHandle);
|
||||||
|
// not work
|
||||||
|
// AllocConsole() does not help
|
||||||
|
// *stdout = *m_pStdFile;
|
||||||
|
// *stderr = *m_pStdFile;
|
||||||
|
// _dup2(_fileno(m_pStdFile), _fileno(stdout));
|
||||||
|
// _dup2(_fileno(m_pStdFile), _fileno(stderr));
|
||||||
|
// this one cannot capture the process start failure
|
||||||
|
// _wfreopen_s(&m_pStdFile, struLogFileName.QueryStr(), L"w", stdout);
|
||||||
|
|
||||||
|
// Periodically flush the log content to file
|
||||||
|
m_Timer.InitializeTimer(STTIMER::TimerCallback, &m_struLogFilePath, 3000, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The process has console, e.g., IIS Express scenario
|
||||||
|
CloseHandle(m_hLogFileHandle);
|
||||||
|
m_hLogFileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
if (m_pConfig->QueryStdoutLogEnabled())
|
||||||
|
{
|
||||||
|
if (_wfopen_s(&m_pStdFile, m_struLogFilePath.QueryStr(), L"w") == 0)
|
||||||
|
{
|
||||||
|
// known issue: error info may not be capture when process crashes during buffering
|
||||||
|
// even we disabled FILE buffering
|
||||||
|
setvbuf(m_pStdFile, NULL, _IONBF, 0);
|
||||||
|
_dup2(_fileno(m_pStdFile), _fileno(stdout));
|
||||||
|
_dup2(_fileno(m_pStdFile), _fileno(stderr));
|
||||||
|
}
|
||||||
|
// not work for console scenario
|
||||||
|
// close and AllocConsole does not help
|
||||||
|
//_wfreopen_s(&m_pStdFile, struLogFileName.QueryStr(), L"w", stdout);
|
||||||
|
// SetStdHandle(STD_ERROR_HANDLE, m_hLogFileHandle);
|
||||||
|
// SetStdHandle(STD_OUTPUT_HANDLE, m_hLogFileHandle);
|
||||||
|
//*stdout = *m_pStdFile;
|
||||||
|
//*stderr = *m_pStdFile;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// delete the file as log is disabled
|
||||||
|
WIN32_FIND_DATA fileData;
|
||||||
|
HANDLE handle = FindFirstFile(m_struLogFilePath.QueryStr(), &fileData);
|
||||||
|
if (handle != INVALID_HANDLE_VALUE &&
|
||||||
|
fileData.nFileSizeHigh == 0 &&
|
||||||
|
fileData.nFileSizeLow == 0)
|
||||||
|
{
|
||||||
|
FindClose(handle);
|
||||||
|
// no need to check whether the deletion succeeds
|
||||||
|
// as nothing can be done
|
||||||
|
DeleteFile(m_struLogFilePath.QueryStr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
m_fDoneStdRedirect = TRUE;
|
||||||
|
if (fLocked)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
}
|
||||||
|
if (FAILED(hr) && m_pConfig->QueryStdoutLogEnabled())
|
||||||
|
{
|
||||||
|
//todo log an warning
|
||||||
|
//STRU strEventMsg;
|
||||||
|
//LPCWSTR apsz[1];
|
||||||
|
|
||||||
|
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
|
// ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG,
|
||||||
|
// m_struLogFilePath.QueryStr(),
|
||||||
|
// HRESULT_FROM_GETLASTERROR())))
|
||||||
|
//{
|
||||||
|
// apsz[0] = strEventMsg.QueryStr();
|
||||||
|
// //
|
||||||
|
// // not checking return code because if ReportEvent
|
||||||
|
// // fails, we cannot do anything.
|
||||||
|
// //
|
||||||
|
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
|
// {
|
||||||
|
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
// EVENTLOG_WARNING_TYPE,
|
||||||
|
// 0,
|
||||||
|
// ASPNETCORE_EVENT_CONFIG_ERROR,
|
||||||
|
// NULL,
|
||||||
|
// 1,
|
||||||
|
// 0,
|
||||||
|
// apsz,
|
||||||
|
// NULL);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will be called by the inprocesshandler
|
||||||
|
HRESULT
|
||||||
|
IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
|
(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD dwTimeout;
|
||||||
|
DWORD dwResult;
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
//PCWSTR apsz[1];
|
||||||
|
//STACK_STRU(strEventMsg, 256);
|
||||||
|
|
||||||
|
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
||||||
|
{
|
||||||
|
// Core CLR has already been loaded.
|
||||||
|
// Cannot load more than once even there was a failure
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up stdout redirect
|
||||||
|
SetStdOut();
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fLocked = TRUE;
|
||||||
|
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hThread = CreateThread(
|
||||||
|
NULL, // default security attributes
|
||||||
|
0, // default stack size
|
||||||
|
(LPTHREAD_START_ROUTINE)ExecuteAspNetCoreProcess,
|
||||||
|
this, // thread function arguments
|
||||||
|
0, // default creation flags
|
||||||
|
NULL); // receive thread identifier
|
||||||
|
|
||||||
|
if (m_hThread == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pInitalizeEvent = CreateEvent(
|
||||||
|
NULL, // default security attributes
|
||||||
|
TRUE, // manual reset event
|
||||||
|
FALSE, // not set
|
||||||
|
NULL); // name
|
||||||
|
|
||||||
|
if (m_pInitalizeEvent == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the debugger is attached, never timeout
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
{
|
||||||
|
dwTimeout = INFINITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwTimeout = m_pConfig->QueryStartupTimeLimitInMS();
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE pHandles[2]{ m_hThread, m_pInitalizeEvent };
|
||||||
|
|
||||||
|
// Wait on either the thread to complete or the event to be set
|
||||||
|
dwResult = WaitForMultipleObjects(2, pHandles, FALSE, dwTimeout);
|
||||||
|
|
||||||
|
// It all timed out
|
||||||
|
if (dwResult == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
// kill the backend thread as loading dotnet timedout
|
||||||
|
TerminateThread(m_hThread, 0);
|
||||||
|
hr = HRESULT_FROM_WIN32(dwResult);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
else if (dwResult == WAIT_FAILED)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The thread ended it means that something failed
|
||||||
|
if (dwResult == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fManagedAppLoaded = TRUE;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (fLocked)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// Question: in case of application loading failure, should we allow retry on
|
||||||
|
// following request or block the activation at all
|
||||||
|
m_fLoadManagedAppError = FALSE; // m_hThread != NULL ?
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
|
// ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG,
|
||||||
|
// m_pConfiguration->QueryApplicationPath()->QueryStr(),
|
||||||
|
// m_pConfiguration->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
|
// hr)))
|
||||||
|
//{
|
||||||
|
// apsz[0] = strEventMsg.QueryStr();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // not checking return code because if ReportEvent
|
||||||
|
// // fails, we cannot do anything.
|
||||||
|
// //
|
||||||
|
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
|
// {
|
||||||
|
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
// EVENTLOG_ERROR_TYPE,
|
||||||
|
// 0,
|
||||||
|
// ASPNETCORE_EVENT_LOAD_CLR_FALIURE,
|
||||||
|
// NULL,
|
||||||
|
// 1,
|
||||||
|
// 0,
|
||||||
|
// apsz,
|
||||||
|
// NULL);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_APPLICATION::ExecuteAspNetCoreProcess(
|
||||||
|
_In_ LPVOID pContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
IN_PROCESS_APPLICATION *pApplication = (IN_PROCESS_APPLICATION*)pContext;
|
||||||
|
DBG_ASSERT(pApplication != NULL);
|
||||||
|
pApplication->ExecuteApplication();
|
||||||
|
//
|
||||||
|
// no need to log the error here as if error happened, the thread will exit
|
||||||
|
// the error will ba catched by caller LoadManagedApplication which will log an error
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
STRU strFullPath;
|
||||||
|
STRU strDotnetExeLocation;
|
||||||
|
STRU strHostFxrSearchExpression;
|
||||||
|
STRU strDotnetFolderLocation;
|
||||||
|
STRU strHighestDotnetVersion;
|
||||||
|
STRU strApplicationFullPath;
|
||||||
|
PWSTR strDelimeterContext = NULL;
|
||||||
|
PCWSTR pszDotnetExeLocation = NULL;
|
||||||
|
PCWSTR pszDotnetExeString(L"dotnet.exe");
|
||||||
|
DWORD dwCopyLength;
|
||||||
|
HMODULE hModule;
|
||||||
|
PCWSTR argv[2];
|
||||||
|
hostfxr_main_fn pProc;
|
||||||
|
std::vector<std::wstring> vVersionFolders;
|
||||||
|
bool fFound = FALSE;
|
||||||
|
|
||||||
|
// Get the System PATH value.
|
||||||
|
if (!GetEnv(L"PATH", &strFullPath))
|
||||||
|
{
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split on ';', checking to see if dotnet.exe exists in any folders.
|
||||||
|
pszDotnetExeLocation = wcstok_s(strFullPath.QueryStr(), L";", &strDelimeterContext);
|
||||||
|
|
||||||
|
while (pszDotnetExeLocation != NULL)
|
||||||
|
{
|
||||||
|
dwCopyLength = (DWORD) wcsnlen_s(pszDotnetExeLocation, 260);
|
||||||
|
if (dwCopyLength == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
|
||||||
|
// which doesn't need the dotnet.exe portion of the string
|
||||||
|
// TODO consider reducing allocations.
|
||||||
|
strDotnetExeLocation.Reset();
|
||||||
|
strDotnetFolderLocation.Reset();
|
||||||
|
hr = strDotnetExeLocation.Copy(pszDotnetExeLocation, dwCopyLength);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strDotnetFolderLocation.Copy(pszDotnetExeLocation, dwCopyLength);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwCopyLength > 0 && pszDotnetExeLocation[dwCopyLength - 1] != L'\\')
|
||||||
|
{
|
||||||
|
hr = strDotnetExeLocation.Append(L"\\");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strDotnetExeLocation.Append(pszDotnetExeString);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PathFileExists(strDotnetExeLocation.QueryStr()))
|
||||||
|
{
|
||||||
|
// means we found the folder with a dotnet.exe inside of it.
|
||||||
|
fFound = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pszDotnetExeLocation = wcstok_s(NULL, L";", &strDelimeterContext);
|
||||||
|
}
|
||||||
|
if (!fFound)
|
||||||
|
{
|
||||||
|
// could not find dotnet.exe, error out
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strDotnetFolderLocation.Append(L"\\host\\fxr");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DirectoryExists(&strDotnetFolderLocation))
|
||||||
|
{
|
||||||
|
// error, not found the folder
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all folders under host\\fxr\\ for version numbers.
|
||||||
|
hr = strHostFxrSearchExpression.Copy(strDotnetFolderLocation);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strHostFxrSearchExpression.Append(L"\\*");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As we use the logic from core-setup, we are opting to use std here.
|
||||||
|
// TODO remove all uses of std?
|
||||||
|
FindDotNetFolders(strHostFxrSearchExpression.QueryStr(), &vVersionFolders);
|
||||||
|
|
||||||
|
if (vVersionFolders.size() == 0)
|
||||||
|
{
|
||||||
|
// no core framework was found
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = FindHighestDotNetVersion(vVersionFolders, &strHighestDotnetVersion);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
hr = strDotnetFolderLocation.Append(L"\\");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strDotnetFolderLocation.Append(strHighestDotnetVersion.QueryStr());
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = strDotnetFolderLocation.Append(L"\\hostfxr.dll");
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hModule = LoadLibraryW(strDotnetFolderLocation.QueryStr());
|
||||||
|
|
||||||
|
if (hModule == NULL)
|
||||||
|
{
|
||||||
|
// .NET Core not installed (we can log a more detailed error message here)
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the entry point for main
|
||||||
|
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
|
||||||
|
if (pProc == NULL)
|
||||||
|
{
|
||||||
|
hr = ERROR_BAD_ENVIRONMENT; // better hrresult?
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first argument is mostly ignored
|
||||||
|
argv[0] = strDotnetExeLocation.QueryStr();
|
||||||
|
UTILITY::ConvertPathToFullPath(m_pConfig->QueryArguments()->QueryStr(),
|
||||||
|
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
|
&strApplicationFullPath);
|
||||||
|
argv[1] = strApplicationFullPath.QueryStr();
|
||||||
|
|
||||||
|
// There can only ever be a single instance of .NET Core
|
||||||
|
// loaded in the process but we need to get config information to boot it up in the
|
||||||
|
// first place. This is happening in an execute request handler and everyone waits
|
||||||
|
// until this initialization is done.
|
||||||
|
|
||||||
|
// We set a static so that managed code can call back into this instance and
|
||||||
|
// set the callbacks
|
||||||
|
s_Application = this;
|
||||||
|
|
||||||
|
RunDotnetApplication(argv, pProc);
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
//
|
||||||
|
// this method is called by the background thread and should never exit unless shutdown
|
||||||
|
//
|
||||||
|
if (!m_fRecycleProcessCalled)
|
||||||
|
{
|
||||||
|
//STRU strEventMsg;
|
||||||
|
//LPCWSTR apsz[1];
|
||||||
|
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
|
// ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT_MSG,
|
||||||
|
// m_pConfig->QueryApplicationPath()->QueryStr(),
|
||||||
|
// m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
|
// m_ProcessExitCode
|
||||||
|
//)))
|
||||||
|
//{
|
||||||
|
// apsz[0] = strEventMsg.QueryStr();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // not checking return code because if ReportEvent
|
||||||
|
// // fails, we cannot do anything.
|
||||||
|
// //
|
||||||
|
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
|
// {
|
||||||
|
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
// EVENTLOG_ERROR_TYPE,
|
||||||
|
// 0,
|
||||||
|
// ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT,
|
||||||
|
// NULL,
|
||||||
|
// 1,
|
||||||
|
// 0,
|
||||||
|
// apsz,
|
||||||
|
// NULL);
|
||||||
|
// }
|
||||||
|
// // error. the thread exits after application started
|
||||||
|
// // Question: should we shutdown current worker process or keep the application in failure state?
|
||||||
|
// // for now, we reccylce to keep the same behavior as that of out-of-process
|
||||||
|
//}
|
||||||
|
if (m_fManagedAppLoaded)
|
||||||
|
{
|
||||||
|
Recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calls hostfxr_main with the hostfxr and application as arguments.
|
||||||
|
// Method should be called with only
|
||||||
|
// Need to have __try / __except in methods that require unwinding.
|
||||||
|
//
|
||||||
|
HRESULT
|
||||||
|
IN_PROCESS_APPLICATION::RunDotnetApplication(PCWSTR* argv, hostfxr_main_fn pProc)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
m_ProcessExitCode = pProc(2, argv);
|
||||||
|
}
|
||||||
|
__except (FilterException(GetExceptionCode(), GetExceptionInformation()))
|
||||||
|
{
|
||||||
|
// TODO Log error message here.
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
INT
|
||||||
|
IN_PROCESS_APPLICATION::FilterException(unsigned int, struct _EXCEPTION_POINTERS*)
|
||||||
|
{
|
||||||
|
// We assume that any exception is a failure as the applicaiton didn't start or there was a startup error.
|
||||||
|
// TODO, log error based on exception code.
|
||||||
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
}
|
||||||
|
|
@ -4,37 +4,21 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef void(*request_handler_cb) (int error, IHttpContext* pHttpContext, void* pvCompletionContext);
|
typedef void(*request_handler_cb) (int error, IHttpContext* pHttpContext, void* pvCompletionContext);
|
||||||
typedef REQUEST_NOTIFICATION_STATUS(*PFN_REQUEST_HANDLER) (IHttpContext* pHttpContext, void* pvRequstHandlerContext);
|
typedef REQUEST_NOTIFICATION_STATUS(*PFN_REQUEST_HANDLER) (IN_PROCESS_HANDLER* pInProcessHandler, void* pvRequestHandlerContext);
|
||||||
typedef BOOL(*PFN_SHUTDOWN_HANDLER) (void* pvShutdownHandlerContext);
|
typedef BOOL(*PFN_SHUTDOWN_HANDLER) (void* pvShutdownHandlerContext);
|
||||||
typedef REQUEST_NOTIFICATION_STATUS(*PFN_MANAGED_CONTEXT_HANDLER)(void *pvManagedHttpContext, HRESULT hrCompletionStatus, DWORD cbCompletion);
|
typedef REQUEST_NOTIFICATION_STATUS(*PFN_MANAGED_CONTEXT_HANDLER)(void *pvManagedHttpContext, HRESULT hrCompletionStatus, DWORD cbCompletion);
|
||||||
|
typedef DWORD(*hostfxr_main_fn) (CONST DWORD argc, CONST WCHAR* argv[]);
|
||||||
#include "application.h"
|
|
||||||
|
|
||||||
class IN_PROCESS_APPLICATION : public APPLICATION
|
class IN_PROCESS_APPLICATION : public APPLICATION
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IN_PROCESS_APPLICATION();
|
IN_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG *pConfig);
|
||||||
|
|
||||||
~IN_PROCESS_APPLICATION();
|
~IN_PROCESS_APPLICATION();
|
||||||
|
|
||||||
__override
|
__override
|
||||||
HRESULT
|
|
||||||
Initialize(_In_ APPLICATION_MANAGER* pApplicationManager,
|
|
||||||
_In_ ASPNETCORE_CONFIG* pConfiguration);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
Recycle(
|
ShutDown();
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
__override
|
|
||||||
VOID OnAppOfflineHandleChange();
|
|
||||||
|
|
||||||
__override
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
|
||||||
ExecuteRequest(
|
|
||||||
_In_ IHttpContext* pHttpContext
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SetCallbackHandles(
|
SetCallbackHandles(
|
||||||
|
|
@ -45,6 +29,11 @@ public:
|
||||||
_In_ VOID* pvShutdownHandlerContext
|
_In_ VOID* pvShutdownHandlerContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Recycle(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
// Executes the .NET Core process
|
// Executes the .NET Core process
|
||||||
HRESULT
|
HRESULT
|
||||||
ExecuteApplication(
|
ExecuteApplication(
|
||||||
|
|
@ -53,14 +42,31 @@ public:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
LoadManagedApplication(
|
LoadManagedApplication(
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
REQUEST_NOTIFICATION_STATUS
|
||||||
OnAsyncCompletion(
|
OnAsyncCompletion(
|
||||||
IHttpContext* pHttpContext,
|
|
||||||
DWORD cbCompletion,
|
DWORD cbCompletion,
|
||||||
HRESULT hrCompletionStatus
|
HRESULT hrCompletionStatus,
|
||||||
|
IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnExecuteRequest
|
||||||
|
(
|
||||||
|
IHttpContext* pHttpContext,
|
||||||
|
IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
INT
|
||||||
|
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
RunDotnetApplication(
|
||||||
|
PCWSTR* argv,
|
||||||
|
hostfxr_main_fn pProc
|
||||||
);
|
);
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -72,14 +78,13 @@ public:
|
||||||
return s_Application;
|
return s_Application;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Thread executing the .NET Core process
|
// Thread executing the .NET Core process
|
||||||
HANDLE m_hThread;
|
HANDLE m_hThread;
|
||||||
|
|
||||||
// The request handler callback from managed code
|
// The request handler callback from managed code
|
||||||
PFN_REQUEST_HANDLER m_RequestHandler;
|
PFN_REQUEST_HANDLER m_RequestHandler;
|
||||||
VOID* m_RequstHandlerContext;
|
VOID* m_RequestHandlerContext;
|
||||||
|
|
||||||
// The shutdown handler callback from managed code
|
// The shutdown handler callback from managed code
|
||||||
PFN_SHUTDOWN_HANDLER m_ShutdownHandler;
|
PFN_SHUTDOWN_HANDLER m_ShutdownHandler;
|
||||||
|
|
@ -90,6 +95,10 @@ private:
|
||||||
// The event that gets triggered when managed initialization is complete
|
// The event that gets triggered when managed initialization is complete
|
||||||
HANDLE m_pInitalizeEvent;
|
HANDLE m_pInitalizeEvent;
|
||||||
|
|
||||||
|
// The std log file handle
|
||||||
|
HANDLE m_hLogFileHandle;
|
||||||
|
STRU m_struLogFilePath;
|
||||||
|
|
||||||
// The exit code of the .NET Core process
|
// The exit code of the .NET Core process
|
||||||
INT m_ProcessExitCode;
|
INT m_ProcessExitCode;
|
||||||
|
|
||||||
|
|
@ -97,9 +106,20 @@ private:
|
||||||
BOOL m_fLoadManagedAppError;
|
BOOL m_fLoadManagedAppError;
|
||||||
BOOL m_fInitialized;
|
BOOL m_fInitialized;
|
||||||
BOOL m_fIsWebSocketsConnection;
|
BOOL m_fIsWebSocketsConnection;
|
||||||
|
BOOL m_fDoneStdRedirect;
|
||||||
|
BOOL m_fRecycleProcessCalled;
|
||||||
|
|
||||||
|
FILE* m_pStdFile;
|
||||||
|
STTIMER m_Timer;
|
||||||
|
SRWLOCK m_srwLock;
|
||||||
|
|
||||||
static IN_PROCESS_APPLICATION* s_Application;
|
static IN_PROCESS_APPLICATION* s_Application;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetStdOut(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
static
|
static
|
||||||
VOID
|
VOID
|
||||||
FindDotNetFolders(
|
FindDotNetFolders(
|
||||||
|
|
@ -117,7 +137,7 @@ private:
|
||||||
static
|
static
|
||||||
BOOL
|
BOOL
|
||||||
DirectoryExists(
|
DirectoryExists(
|
||||||
_In_ STRU *pstrPath //todo: this does not need to be stru, can be PCWSTR
|
_In_ STRU *pstrPath //todo: this does not need to be stru, can be PCWSTR
|
||||||
);
|
);
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
|
|
@ -131,5 +151,4 @@ private:
|
||||||
ExecuteAspNetCoreProcess(
|
ExecuteAspNetCoreProcess(
|
||||||
_In_ LPVOID pContext
|
_In_ LPVOID pContext
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
|
IN_PROCESS_HANDLER::IN_PROCESS_HANDLER(
|
||||||
|
_In_ IHttpContext *pW3Context,
|
||||||
|
_In_ HTTP_MODULE_ID *pModuleId,
|
||||||
|
_In_ APPLICATION *pApplication
|
||||||
|
): REQUEST_HANDLER(pW3Context, pModuleId, pApplication)
|
||||||
|
{
|
||||||
|
m_fManagedRequestComplete = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IN_PROCESS_HANDLER::~IN_PROCESS_HANDLER()
|
||||||
|
{
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
IN_PROCESS_HANDLER::OnExecuteRequestHandler()
|
||||||
|
{
|
||||||
|
// First get the in process Application
|
||||||
|
HRESULT hr;
|
||||||
|
hr = ((IN_PROCESS_APPLICATION*)m_pApplication)->LoadManagedApplication();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// TODO remove com_error?
|
||||||
|
/*_com_error err(hr);
|
||||||
|
if (ANCMEvents::ANCM_START_APPLICATION_FAIL::IsEnabled(m_pW3Context->GetTraceContext()))
|
||||||
|
{
|
||||||
|
ANCMEvents::ANCM_START_APPLICATION_FAIL::RaiseEvent(
|
||||||
|
m_pW3Context->GetTraceContext(),
|
||||||
|
NULL,
|
||||||
|
err.ErrorMessage());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//fInternalError = TRUE;
|
||||||
|
m_pW3Context->GetResponse()->SetStatus(500, "Internal Server Error", 0, hr);
|
||||||
|
return REQUEST_NOTIFICATION_STATUS::RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FREB log
|
||||||
|
|
||||||
|
if (ANCMEvents::ANCM_START_APPLICATION_SUCCESS::IsEnabled(m_pW3Context->GetTraceContext()))
|
||||||
|
{
|
||||||
|
ANCMEvents::ANCM_START_APPLICATION_SUCCESS::RaiseEvent(
|
||||||
|
m_pW3Context->GetTraceContext(),
|
||||||
|
NULL,
|
||||||
|
L"InProcess Application");
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetHttpSysDisconnectCallback();
|
||||||
|
return ((IN_PROCESS_APPLICATION*)m_pApplication)->OnExecuteRequest(m_pW3Context, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
IN_PROCESS_HANDLER::OnAsyncCompletion(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
if (FAILED(hrCompletionStatus))
|
||||||
|
{
|
||||||
|
return RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For now we are assuming we are in our own self contained box.
|
||||||
|
// TODO refactor Finished and Failure sections to handle in process and out of process failure.
|
||||||
|
// TODO verify that websocket's OnAsyncCompletion is not calling this.
|
||||||
|
IN_PROCESS_APPLICATION* application = (IN_PROCESS_APPLICATION*)m_pApplication;
|
||||||
|
if (application == NULL)
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
return RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return application->OnAsyncCompletion(cbCompletion, hrCompletionStatus, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_HANDLER::TerminateRequest(
|
||||||
|
bool fClientInitiated
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(fClientInitiated);
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
IN_PROCESS_HANDLER::QueryManagedHttpContext(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pManagedHttpContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IN_PROCESS_HANDLER::QueryIsManagedRequestComplete(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_fManagedRequestComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
IHttpContext*
|
||||||
|
IN_PROCESS_HANDLER::QueryHttpContext(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pW3Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_HANDLER::IndicateManagedRequestComplete(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_fManagedRequestComplete = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
IN_PROCESS_HANDLER::QueryAsyncCompletionStatus(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_requestNotificationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_HANDLER::SetAsyncCompletionStatus(
|
||||||
|
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_requestNotificationStatus = requestNotificationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IN_PROCESS_HANDLER::SetManangedHttpContext(
|
||||||
|
PVOID pManagedHttpContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_pManagedHttpContext = pManagedHttpContext;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class IN_PROCESS_HANDLER : public REQUEST_HANDLER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IN_PROCESS_HANDLER(
|
||||||
|
|
||||||
|
_In_ IHttpContext *pW3Context,
|
||||||
|
_In_ HTTP_MODULE_ID *pModuleId,
|
||||||
|
_In_ APPLICATION *pApplication);
|
||||||
|
|
||||||
|
~IN_PROCESS_HANDLER();
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnExecuteRequestHandler();
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnAsyncCompletion(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
__override
|
||||||
|
VOID
|
||||||
|
TerminateRequest(
|
||||||
|
bool fClientInitiated
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
QueryManagedHttpContext(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetManangedHttpContext(
|
||||||
|
PVOID pManagedHttpContext
|
||||||
|
);
|
||||||
|
|
||||||
|
IHttpContext*
|
||||||
|
QueryHttpContext(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
QueryIsManagedRequestComplete(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IndicateManagedRequestComplete(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
QueryAsyncCompletionStatus(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetAsyncCompletionStatus(
|
||||||
|
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PVOID m_pManagedHttpContext;
|
||||||
|
IHttpContext* m_pHttpContext;
|
||||||
|
BOOL m_fManagedRequestComplete;
|
||||||
|
REQUEST_NOTIFICATION_STATUS m_requestNotificationStatus;
|
||||||
|
};
|
||||||
|
|
@ -28,83 +28,64 @@ register_callbacks(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HTTP_REQUEST*
|
HTTP_REQUEST*
|
||||||
http_get_raw_request(
|
http_get_raw_request(
|
||||||
_In_ IHttpContext* pHttpContext
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pHttpContext->GetRequest()->GetRawHttpRequest();
|
return pInProcessHandler->QueryHttpContext()->GetRequest()->GetRawHttpRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HTTP_RESPONSE*
|
HTTP_RESPONSE*
|
||||||
http_get_raw_response(
|
http_get_raw_response(
|
||||||
_In_ IHttpContext* pHttpContext
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pHttpContext->GetResponse()->GetRawHttpResponse();
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->GetRawHttpResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT VOID http_set_response_status_code(
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT VOID http_set_response_status_code(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ USHORT statusCode,
|
_In_ USHORT statusCode,
|
||||||
_In_ PCSTR pszReason
|
_In_ PCSTR pszReason
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
pHttpContext->GetResponse()->SetStatus(statusCode, pszReason);
|
pInProcessHandler->QueryHttpContext()->GetResponse()->SetStatus(statusCode, pszReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_post_completion(
|
http_post_completion(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
DWORD cbBytes
|
DWORD cbBytes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pHttpContext->PostCompletion(cbBytes);
|
return pInProcessHandler->QueryHttpContext()->PostCompletion(cbBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_set_completion_status(
|
http_set_completion_status(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
_In_ REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext = NULL;
|
|
||||||
|
|
||||||
hr = IN_PROCESS_STORED_CONTEXT::GetInProcessStoredContext(
|
pInProcessHandler->IndicateManagedRequestComplete();
|
||||||
pHttpContext,
|
pInProcessHandler->SetAsyncCompletionStatus(requestNotificationStatus);
|
||||||
&pInProcessStoredContext
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
pInProcessStoredContext->IndicateManagedRequestComplete();
|
|
||||||
pInProcessStoredContext->SetAsyncCompletionStatus(requestNotificationStatus);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_set_managed_context(
|
http_set_managed_context(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ PVOID pvManagedContext
|
_In_ PVOID pvManagedContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
// todo: should we consider changing the signature
|
||||||
IN_PROCESS_STORED_CONTEXT* pInProcessStoredContext = new IN_PROCESS_STORED_CONTEXT(pHttpContext, pvManagedContext);
|
HRESULT hr = S_OK;
|
||||||
if (pInProcessStoredContext == NULL)
|
pInProcessHandler->SetManangedHttpContext(pvManagedContext);
|
||||||
{
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = IN_PROCESS_STORED_CONTEXT::SetInProcessStoredContext(pHttpContext, pInProcessStoredContext);
|
|
||||||
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
|
|
||||||
{
|
|
||||||
hr = S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
@ -112,11 +93,11 @@ http_set_managed_context(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
VOID
|
VOID
|
||||||
http_indicate_completion(
|
http_indicate_completion(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ REQUEST_NOTIFICATION_STATUS notificationStatus
|
_In_ REQUEST_NOTIFICATION_STATUS notificationStatus
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
pHttpContext->IndicateCompletion(notificationStatus);
|
pInProcessHandler->QueryHttpContext()->IndicateCompletion(notificationStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
|
|
@ -161,7 +142,7 @@ http_get_application_properties(
|
||||||
|
|
||||||
pConfiguration = pApplication->QueryConfig();
|
pConfiguration = pApplication->QueryConfig();
|
||||||
|
|
||||||
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationFullPath()->QueryStr());
|
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationPhysicalPath()->QueryStr());
|
||||||
pIISCofigurationData->pwzVirtualApplicationPath = SysAllocString(pConfiguration->QueryApplicationVirtualPath()->QueryStr());
|
pIISCofigurationData->pwzVirtualApplicationPath = SysAllocString(pConfiguration->QueryApplicationVirtualPath()->QueryStr());
|
||||||
pIISCofigurationData->fWindowsAuthEnabled = pConfiguration->QueryWindowsAuthEnabled();
|
pIISCofigurationData->fWindowsAuthEnabled = pConfiguration->QueryWindowsAuthEnabled();
|
||||||
pIISCofigurationData->fBasicAuthEnabled = pConfiguration->QueryBasicAuthEnabled();
|
pIISCofigurationData->fBasicAuthEnabled = pConfiguration->QueryBasicAuthEnabled();
|
||||||
|
|
@ -173,7 +154,7 @@ http_get_application_properties(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_read_request_bytes(
|
http_read_request_bytes(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_Out_ CHAR* pvBuffer,
|
_Out_ CHAR* pvBuffer,
|
||||||
_In_ DWORD dwCbBuffer,
|
_In_ DWORD dwCbBuffer,
|
||||||
_Out_ DWORD* pdwBytesReceived,
|
_Out_ DWORD* pdwBytesReceived,
|
||||||
|
|
@ -182,7 +163,7 @@ http_read_request_bytes(
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (pHttpContext == NULL)
|
if (pInProcessHandler == NULL)
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +171,7 @@ http_read_request_bytes(
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
IHttpRequest *pHttpRequest = (IHttpRequest*)pHttpContext->GetRequest();
|
IHttpRequest *pHttpRequest = (IHttpRequest*)pInProcessHandler->QueryHttpContext()->GetRequest();
|
||||||
|
|
||||||
BOOL fAsync = TRUE;
|
BOOL fAsync = TRUE;
|
||||||
|
|
||||||
|
|
@ -213,13 +194,13 @@ http_read_request_bytes(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_write_response_bytes(
|
http_write_response_bytes(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ HTTP_DATA_CHUNK* pDataChunks,
|
_In_ HTTP_DATA_CHUNK* pDataChunks,
|
||||||
_In_ DWORD dwChunks,
|
_In_ DWORD dwChunks,
|
||||||
_In_ BOOL* pfCompletionExpected
|
_In_ BOOL* pfCompletionExpected
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHttpResponse *pHttpResponse = (IHttpResponse*)pHttpContext->GetResponse();
|
IHttpResponse *pHttpResponse = (IHttpResponse*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
||||||
BOOL fAsync = TRUE;
|
BOOL fAsync = TRUE;
|
||||||
BOOL fMoreData = TRUE;
|
BOOL fMoreData = TRUE;
|
||||||
DWORD dwBytesSent = 0;
|
DWORD dwBytesSent = 0;
|
||||||
|
|
@ -238,11 +219,11 @@ http_write_response_bytes(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_flush_response_bytes(
|
http_flush_response_bytes(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_Out_ BOOL* pfCompletionExpected
|
_Out_ BOOL* pfCompletionExpected
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHttpResponse *pHttpResponse = (IHttpResponse*)pHttpContext->GetResponse();
|
IHttpResponse *pHttpResponse = (IHttpResponse*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
||||||
|
|
||||||
BOOL fAsync = TRUE;
|
BOOL fAsync = TRUE;
|
||||||
BOOL fMoreData = TRUE;
|
BOOL fMoreData = TRUE;
|
||||||
|
|
@ -259,7 +240,7 @@ http_flush_response_bytes(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_websockets_read_bytes(
|
http_websockets_read_bytes(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ CHAR* pvBuffer,
|
_In_ CHAR* pvBuffer,
|
||||||
_In_ DWORD cbBuffer,
|
_In_ DWORD cbBuffer,
|
||||||
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
||||||
|
|
@ -268,7 +249,7 @@ http_websockets_read_bytes(
|
||||||
_In_ BOOL* pfCompletionPending
|
_In_ BOOL* pfCompletionPending
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHttpRequest3 *pHttpRequest = (IHttpRequest3*)pHttpContext->GetRequest();
|
IHttpRequest3 *pHttpRequest = (IHttpRequest3*)pInProcessHandler->QueryHttpContext()->GetRequest();
|
||||||
|
|
||||||
BOOL fAsync = TRUE;
|
BOOL fAsync = TRUE;
|
||||||
|
|
||||||
|
|
@ -293,7 +274,7 @@ http_websockets_read_bytes(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_websockets_write_bytes(
|
http_websockets_write_bytes(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ HTTP_DATA_CHUNK* pDataChunks,
|
_In_ HTTP_DATA_CHUNK* pDataChunks,
|
||||||
_In_ DWORD dwChunks,
|
_In_ DWORD dwChunks,
|
||||||
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
||||||
|
|
@ -301,7 +282,7 @@ http_websockets_write_bytes(
|
||||||
_In_ BOOL* pfCompletionExpected
|
_In_ BOOL* pfCompletionExpected
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pHttpContext->GetResponse();
|
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
||||||
|
|
||||||
BOOL fAsync = TRUE;
|
BOOL fAsync = TRUE;
|
||||||
BOOL fMoreData = TRUE;
|
BOOL fMoreData = TRUE;
|
||||||
|
|
@ -323,13 +304,13 @@ http_websockets_write_bytes(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_websockets_flush_bytes(
|
http_websockets_flush_bytes(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
||||||
_In_ VOID* pvCompletionContext,
|
_In_ VOID* pvCompletionContext,
|
||||||
_In_ BOOL* pfCompletionExpected
|
_In_ BOOL* pfCompletionExpected
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pHttpContext->GetResponse();
|
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
||||||
|
|
||||||
BOOL fAsync = TRUE;
|
BOOL fAsync = TRUE;
|
||||||
BOOL fMoreData = TRUE;
|
BOOL fMoreData = TRUE;
|
||||||
|
|
@ -348,16 +329,16 @@ http_websockets_flush_bytes(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_enable_websockets(
|
http_enable_websockets(
|
||||||
_In_ IHttpContext* pHttpContext
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!g_fWebSocketSupported)
|
//if (!g_fWebSocketSupported)
|
||||||
{
|
//{
|
||||||
return E_FAIL;
|
// return E_FAIL;
|
||||||
}
|
//}
|
||||||
|
|
||||||
((IHttpContext3*)pHttpContext)->EnableFullDuplex();
|
((IHttpContext3*)pInProcessHandler->QueryHttpContext())->EnableFullDuplex();
|
||||||
((IHttpResponse2*)pHttpContext->GetResponse())->DisableBuffering();
|
((IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse())->DisableBuffering();
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -365,51 +346,50 @@ http_enable_websockets(
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_cancel_io(
|
http_cancel_io(
|
||||||
_In_ IHttpContext* pHttpContext
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pHttpContext->CancelIo();
|
return pInProcessHandler->QueryHttpContext()->CancelIo();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_response_set_unknown_header(
|
http_response_set_unknown_header(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ PCSTR pszHeaderName,
|
_In_ PCSTR pszHeaderName,
|
||||||
_In_ PCSTR pszHeaderValue,
|
_In_ PCSTR pszHeaderValue,
|
||||||
_In_ USHORT usHeaderValueLength,
|
_In_ USHORT usHeaderValueLength,
|
||||||
_In_ BOOL fReplace
|
_In_ BOOL fReplace
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pHttpContext->GetResponse()->SetHeader( pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace );
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetHeader(pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_response_set_known_header(
|
http_response_set_known_header(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_In_ HTTP_HEADER_ID dwHeaderId,
|
_In_ HTTP_HEADER_ID dwHeaderId,
|
||||||
_In_ PCSTR pszHeaderValue,
|
_In_ PCSTR pszHeaderValue,
|
||||||
_In_ USHORT usHeaderValueLength,
|
_In_ USHORT usHeaderValueLength,
|
||||||
_In_ BOOL fReplace
|
_In_ BOOL fReplace
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pHttpContext->GetResponse()->SetHeader( dwHeaderId, pszHeaderValue, usHeaderValueLength, fReplace );
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetHeader(dwHeaderId, pszHeaderValue, usHeaderValueLength, fReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT
|
HRESULT
|
||||||
http_get_authentication_information(
|
http_get_authentication_information(
|
||||||
_In_ IHttpContext* pHttpContext,
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
||||||
_Out_ BSTR* pstrAuthType,
|
_Out_ BSTR* pstrAuthType,
|
||||||
_Out_ VOID** pvToken
|
_Out_ VOID** pvToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
*pstrAuthType = SysAllocString(pHttpContext->GetUser()->GetAuthenticationType());
|
*pstrAuthType = SysAllocString(pInProcessHandler->QueryHttpContext()->GetUser()->GetAuthenticationType());
|
||||||
*pvToken = pHttpContext->GetUser()->GetPrimaryToken();
|
*pvToken = pInProcessHandler->QueryHttpContext()->GetUser()->GetPrimaryToken();
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// End of export
|
// End of export
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
FORWARDER_CONNECTION::FORWARDER_CONNECTION(
|
FORWARDER_CONNECTION::FORWARDER_CONNECTION(
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -23,7 +23,7 @@ FORWARDER_CONNECTION::Initialize(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hConnection = WinHttpConnect(FORWARDING_HANDLER::sm_hSession,
|
m_hConnection = WinHttpConnect(g_hWinhttpSession,
|
||||||
L"127.0.0.1",
|
L"127.0.0.1",
|
||||||
(USHORT) dwPort,
|
(USHORT) dwPort,
|
||||||
0);
|
0);
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,199 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern DWORD g_OptionalWinHttpFlags;
|
||||||
|
|
||||||
|
|
||||||
|
enum FORWARDING_REQUEST_STATUS
|
||||||
|
{
|
||||||
|
FORWARDER_START,
|
||||||
|
FORWARDER_SENDING_REQUEST,
|
||||||
|
FORWARDER_RECEIVING_RESPONSE,
|
||||||
|
FORWARDER_RECEIVED_WEBSOCKET_RESPONSE,
|
||||||
|
FORWARDER_DONE,
|
||||||
|
FORWARDER_FINISH_REQUEST
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FORWARDING_HANDLER : public REQUEST_HANDLER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FORWARDING_HANDLER(
|
||||||
|
|
||||||
|
_In_ IHttpContext *pW3Context,
|
||||||
|
_In_ HTTP_MODULE_ID *pModuleId,
|
||||||
|
_In_ APPLICATION *pApplication);
|
||||||
|
|
||||||
|
~FORWARDING_HANDLER();
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnExecuteRequestHandler();
|
||||||
|
|
||||||
|
__override
|
||||||
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
OnAsyncCompletion(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetStatus(
|
||||||
|
FORWARDING_REQUEST_STATUS status
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_RequestStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CALLBACK
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD_PTR dwContext,
|
||||||
|
DWORD dwInternetStatus,
|
||||||
|
LPVOID lpvStatusInformation,
|
||||||
|
DWORD dwStatusInformationLength
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
StaticInitialize(
|
||||||
|
BOOL fEnableReferenceCountTracing
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
StaticTerminate();
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TerminateRequest(
|
||||||
|
bool fClientInitiated
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HRESULT
|
||||||
|
CreateWinHttpRequest(
|
||||||
|
_In_ const IHttpRequest * pRequest,
|
||||||
|
_In_ const PROTOCOL_CONFIG * pProtocol,
|
||||||
|
_In_ HINTERNET hConnect,
|
||||||
|
_Inout_ STRU * pstrUrl,
|
||||||
|
// _In_ ASPNETCORE_CONFIG* pAspNetCoreConfig,
|
||||||
|
_In_ SERVER_PROCESS* pServerProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletionInternal(
|
||||||
|
_In_ HINTERNET hRequest,
|
||||||
|
_In_ DWORD dwInternetStatus,
|
||||||
|
_In_ LPVOID lpvStatusInformation,
|
||||||
|
_In_ DWORD dwStatusInformationLength
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionSendRequestOrWriteComplete(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD dwInternetStatus,
|
||||||
|
_Out_ bool * pfClientError,
|
||||||
|
_Out_ bool * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionStatusHeadersAvailable(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
_Out_ bool * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionStatusDataAvailable(
|
||||||
|
HINTERNET hRequest,
|
||||||
|
DWORD dwBytes,
|
||||||
|
_Out_ bool * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnWinHttpCompletionStatusReadComplete(
|
||||||
|
_In_ IHttpResponse * pResponse,
|
||||||
|
DWORD dwStatusInformationLength,
|
||||||
|
_Out_ bool * pfAnotherCompletionExpected
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnSendingRequest(
|
||||||
|
DWORD cbCompletion,
|
||||||
|
HRESULT hrCompletionStatus,
|
||||||
|
_Out_ bool * pfClientError
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OnReceivingResponse();
|
||||||
|
|
||||||
|
BYTE *
|
||||||
|
GetNewResponseBuffer(
|
||||||
|
DWORD dwBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FreeResponseBuffers();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetStatusAndHeaders(
|
||||||
|
PCSTR pszHeaders,
|
||||||
|
DWORD cchHeaders
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
DoReverseRewrite(
|
||||||
|
_In_ IHttpResponse *pResponse
|
||||||
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetHeaders(
|
||||||
|
_In_ const PROTOCOL_CONFIG * pProtocol,
|
||||||
|
_In_ bool fForwardWindowsAuthToken,
|
||||||
|
_In_ SERVER_PROCESS* pServerProcess,
|
||||||
|
_Out_ PCWSTR * ppszHeaders,
|
||||||
|
_Inout_ DWORD * pcchHeaders
|
||||||
|
);
|
||||||
|
|
||||||
|
DWORD m_Signature;
|
||||||
|
//
|
||||||
|
// WinHTTP request handle is protected using a read-write lock.
|
||||||
|
//
|
||||||
|
SRWLOCK m_RequestLock;
|
||||||
|
HINTERNET m_hRequest;
|
||||||
|
FORWARDING_REQUEST_STATUS m_RequestStatus;
|
||||||
|
|
||||||
|
bool m_fWebSocketEnabled;
|
||||||
|
bool m_fResponseHeadersReceivedAndSet;
|
||||||
|
bool m_fResetConnection;
|
||||||
|
bool m_fHandleClosedDueToClient;
|
||||||
|
bool m_fFinishRequest;
|
||||||
|
bool m_fHasError;
|
||||||
|
BOOL m_fDoReverseRewriteHeaders;
|
||||||
|
PCSTR m_pszOriginalHostHeader;
|
||||||
|
PCWSTR m_pszHeaders;
|
||||||
|
DWORD m_cchHeaders;
|
||||||
|
DWORD m_BytesToReceive;
|
||||||
|
DWORD m_BytesToSend;
|
||||||
|
DWORD m_cchLastSend;
|
||||||
|
DWORD m_cEntityBuffers;
|
||||||
|
DWORD m_cBytesBuffered;
|
||||||
|
DWORD m_cMinBufferLimit;
|
||||||
|
ULONGLONG m_cContentLength;
|
||||||
|
WEBSOCKET_HANDLER * m_pWebSocket;
|
||||||
|
ASYNC_DISCONNECT_CONTEXT * m_pDisconnect;
|
||||||
|
|
||||||
|
BYTE * m_pEntityBuffer;
|
||||||
|
static const SIZE_T INLINE_ENTITY_BUFFERS = 8;
|
||||||
|
BUFFER_T<BYTE*, INLINE_ENTITY_BUFFERS> m_buffEntityBuffers;
|
||||||
|
|
||||||
|
static ALLOC_CACHE_HANDLER * sm_pAlloc;
|
||||||
|
static PROTOCOL_CONFIG sm_ProtocolConfig;
|
||||||
|
static RESPONSE_HEADER_HASH * sm_pResponseHeaderHash;
|
||||||
|
//
|
||||||
|
// Reference cout tracing for debugging purposes.
|
||||||
|
//
|
||||||
|
static TRACE_LOG * sm_pTraceLog;
|
||||||
|
|
||||||
|
static STRA sm_pStra502ErrorMsg;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
|
OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION(
|
||||||
|
IHttpServer* pHttpServer,
|
||||||
|
ASPNETCORE_CONFIG* pConfig) :
|
||||||
|
APPLICATION(pHttpServer, pConfig)
|
||||||
|
{
|
||||||
|
m_status = APPLICATION_STATUS::RUNNING;
|
||||||
|
m_pProcessManager = NULL;
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
|
||||||
|
OUT_OF_PROCESS_APPLICATION::~OUT_OF_PROCESS_APPLICATION()
|
||||||
|
{
|
||||||
|
if (m_pProcessManager != NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager->ShutdownAllProcesses();
|
||||||
|
m_pProcessManager->DereferenceProcessManager();
|
||||||
|
m_pProcessManager = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OUT_OF_PROCESS_APPLICATION::Initialize(
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
if (m_pProcessManager == NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager = new PROCESS_MANAGER;
|
||||||
|
if (m_pProcessManager == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_pProcessManager->Initialize();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
OUT_OF_PROCESS_APPLICATION::GetProcess(
|
||||||
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_pProcessManager->GetProcess(m_pConfig, ppServerProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
|
VOID
|
||||||
|
OUT_OF_PROCESS_APPLICATION::ShutDown()
|
||||||
|
{
|
||||||
|
if (m_pProcessManager != NULL)
|
||||||
|
{
|
||||||
|
m_pProcessManager->ShutdownAllProcesses();
|
||||||
|
m_pProcessManager->DereferenceProcessManager();
|
||||||
|
m_pProcessManager = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class OUT_OF_PROCESS_APPLICATION : public APPLICATION
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
OUT_OF_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG *pConfig);
|
||||||
|
|
||||||
|
~OUT_OF_PROCESS_APPLICATION();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
GetProcess(
|
||||||
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
|
);
|
||||||
|
|
||||||
|
__override
|
||||||
|
VOID
|
||||||
|
ShutDown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
PROCESS_MANAGER * m_pProcessManager;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,296 @@
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PROCESS_MANAGER::Initialize(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
WSADATA wsaData;
|
||||||
|
int result;
|
||||||
|
BOOL fLocked = FALSE;
|
||||||
|
|
||||||
|
if( !sm_fWSAStartupDone )
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive( &m_srwLock );
|
||||||
|
fLocked = TRUE;
|
||||||
|
|
||||||
|
if( !sm_fWSAStartupDone )
|
||||||
|
{
|
||||||
|
if( (result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32( result );
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
sm_fWSAStartupDone = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
fLocked = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dwRapidFailTickStart = GetTickCount();
|
||||||
|
|
||||||
|
if( m_hNULHandle == NULL )
|
||||||
|
{
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
m_hNULHandle = CreateFileW( L"NUL",
|
||||||
|
FILE_WRITE_DATA,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
&saAttr,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL );
|
||||||
|
if( m_hNULHandle == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if(fLocked)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive( &m_srwLock );
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_MANAGER::~PROCESS_MANAGER()
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
|
||||||
|
//if( m_ppServerProcessList != NULL )
|
||||||
|
//{
|
||||||
|
// for( DWORD i = 0; i < m_dwProcessesPerApplication; ++i )
|
||||||
|
// {
|
||||||
|
// if( m_ppServerProcessList[i] != NULL )
|
||||||
|
// {
|
||||||
|
// m_ppServerProcessList[i]->DereferenceServerProcess();
|
||||||
|
// m_ppServerProcessList[i] = NULL;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// delete[] m_ppServerProcessList;
|
||||||
|
// m_ppServerProcessList = NULL;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if( m_hNULHandle != NULL )
|
||||||
|
//{
|
||||||
|
// CloseHandle( m_hNULHandle );
|
||||||
|
// m_hNULHandle = NULL;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if( sm_fWSAStartupDone )
|
||||||
|
//{
|
||||||
|
// WSACleanup();
|
||||||
|
// sm_fWSAStartupDone = FALSE;
|
||||||
|
//}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
PROCESS_MANAGER::GetProcess(
|
||||||
|
_In_ ASPNETCORE_CONFIG *pConfig,
|
||||||
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fSharedLock = FALSE;
|
||||||
|
BOOL fExclusiveLock = FALSE;
|
||||||
|
//PCWSTR apsz[1];
|
||||||
|
STACK_STRU(strEventMsg, 256);
|
||||||
|
DWORD dwProcessIndex = 0;
|
||||||
|
SERVER_PROCESS *pSelectedServerProcess = NULL;
|
||||||
|
|
||||||
|
if (!m_fServerProcessListReady)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = TRUE;
|
||||||
|
|
||||||
|
if (!m_fServerProcessListReady)
|
||||||
|
{
|
||||||
|
m_dwProcessesPerApplication = pConfig->QueryProcessesPerApplication();
|
||||||
|
m_ppServerProcessList = new SERVER_PROCESS*[m_dwProcessesPerApplication];
|
||||||
|
if (m_ppServerProcessList == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < m_dwProcessesPerApplication; ++i)
|
||||||
|
{
|
||||||
|
m_ppServerProcessList[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_fServerProcessListReady = TRUE;
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&m_srwLock);
|
||||||
|
fSharedLock = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// round robin through to the next available process.
|
||||||
|
//
|
||||||
|
dwProcessIndex = (DWORD)InterlockedIncrement64((LONGLONG*)&m_dwRouteToProcessIndex);
|
||||||
|
dwProcessIndex = dwProcessIndex % m_dwProcessesPerApplication;
|
||||||
|
|
||||||
|
if (m_ppServerProcessList[dwProcessIndex] != NULL &&
|
||||||
|
m_ppServerProcessList[dwProcessIndex]->IsReady())
|
||||||
|
{
|
||||||
|
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockShared(&m_srwLock);
|
||||||
|
fSharedLock = FALSE;
|
||||||
|
|
||||||
|
// should make the lock per process so that we can start processes simultaneously ?
|
||||||
|
if (m_ppServerProcessList[dwProcessIndex] == NULL ||
|
||||||
|
!m_ppServerProcessList[dwProcessIndex]->IsReady())
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = TRUE;
|
||||||
|
|
||||||
|
if (m_ppServerProcessList[dwProcessIndex] != NULL)
|
||||||
|
{
|
||||||
|
if (!m_ppServerProcessList[dwProcessIndex]->IsReady())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// terminate existing process that is not ready
|
||||||
|
// before creating new one.
|
||||||
|
//
|
||||||
|
|
||||||
|
//todo:
|
||||||
|
//ShutdownProcessNoLock( m_ppServerProcessList[dwProcessIndex] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// server is already up and ready to serve requests.
|
||||||
|
//m_ppServerProcessList[dwProcessIndex]->ReferenceServerProcess();
|
||||||
|
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RapidFailsPerMinuteExceeded(pConfig->QueryRapidFailsPerMinute()))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// rapid fails per minute exceeded, do not create new process.
|
||||||
|
//
|
||||||
|
|
||||||
|
//if( SUCCEEDED( strEventMsg.SafeSnwprintf(
|
||||||
|
// ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG,
|
||||||
|
// pConfig->QueryRapidFailsPerMinute() ) ) )
|
||||||
|
//{
|
||||||
|
// apsz[0] = strEventMsg.QueryStr();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // not checking return code because if ReportEvent
|
||||||
|
// // fails, we cannot do anything.
|
||||||
|
// //
|
||||||
|
// if (FORWARDING_HANDLER::QueryEventLog() != NULL)
|
||||||
|
// {
|
||||||
|
// ReportEventW(FORWARDING_HANDLER::QueryEventLog(),
|
||||||
|
// EVENTLOG_INFORMATION_TYPE,
|
||||||
|
// 0,
|
||||||
|
// ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED,
|
||||||
|
// NULL,
|
||||||
|
// 1,
|
||||||
|
// 0,
|
||||||
|
// apsz,
|
||||||
|
// NULL);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ppServerProcessList[dwProcessIndex] == NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
pSelectedServerProcess = new SERVER_PROCESS();
|
||||||
|
if (pSelectedServerProcess == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hr = pSelectedServerProcess->Initialize(
|
||||||
|
this, //ProcessManager
|
||||||
|
pConfig->QueryProcessPath(), //
|
||||||
|
pConfig->QueryArguments(), //
|
||||||
|
pConfig->QueryStartupTimeLimitInMS(),
|
||||||
|
pConfig->QueryShutdownTimeLimitInMS(),
|
||||||
|
pConfig->QueryWindowsAuthEnabled(),
|
||||||
|
pConfig->QueryBasicAuthEnabled(),
|
||||||
|
pConfig->QueryAnonymousAuthEnabled(),
|
||||||
|
pConfig->QueryEnvironmentVariables(),
|
||||||
|
pConfig->QueryStdoutLogEnabled(),
|
||||||
|
pConfig->QueryStdoutLogFile(),
|
||||||
|
pConfig->QueryApplicationPhysicalPath(), // physical path
|
||||||
|
pConfig->QueryApplicationPath(), // app path
|
||||||
|
pConfig->QueryApplicationVirtualPath() // App relative virtual path
|
||||||
|
);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pSelectedServerProcess->StartProcess();
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pSelectedServerProcess->IsReady())
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_CREATE_FAILED);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ppServerProcessList[dwProcessIndex] = pSelectedServerProcess;
|
||||||
|
pSelectedServerProcess = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
*ppServerProcess = m_ppServerProcessList[dwProcessIndex];
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
if (fSharedLock)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockShared(&m_srwLock);
|
||||||
|
fSharedLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fExclusiveLock)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
fExclusiveLock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSelectedServerProcess != NULL)
|
||||||
|
{
|
||||||
|
delete pSelectedServerProcess;
|
||||||
|
pSelectedServerProcess = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ONE_MINUTE_IN_MILLISECONDS 60000
|
#define ONE_MINUTE_IN_MILLISECONDS 60000
|
||||||
|
class SERVER_PROCESS;
|
||||||
|
|
||||||
class PROCESS_MANAGER
|
class PROCESS_MANAGER
|
||||||
{
|
{
|
||||||
|
|
@ -29,7 +30,6 @@ public:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
GetProcess(
|
GetProcess(
|
||||||
_In_ IHttpContext *context,
|
|
||||||
_In_ ASPNETCORE_CONFIG *pConfig,
|
_In_ ASPNETCORE_CONFIG *pConfig,
|
||||||
_Out_ SERVER_PROCESS **ppServerProcess
|
_Out_ SERVER_PROCESS **ppServerProcess
|
||||||
);
|
);
|
||||||
|
|
@ -104,6 +104,8 @@ public:
|
||||||
m_fServerProcessListReady(FALSE),
|
m_fServerProcessListReady(FALSE),
|
||||||
m_cRefs( 1 )
|
m_cRefs( 1 )
|
||||||
{
|
{
|
||||||
|
m_ppServerProcessList = NULL;
|
||||||
|
m_fServerProcessListReady = FALSE;
|
||||||
InitializeSRWLock( &m_srwLock );
|
InitializeSRWLock( &m_srwLock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
PROTOCOL_CONFIG::Initialize()
|
PROTOCOL_CONFIG::Initialize()
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "aspnetcoreconfig.h"
|
|
||||||
|
|
||||||
class PROTOCOL_CONFIG
|
class PROTOCOL_CONFIG
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
RESPONSE_HEADER_HASH * g_pResponseHeaderHash = NULL;
|
|
||||||
|
|
||||||
HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] =
|
HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] =
|
||||||
{
|
{
|
||||||
|
|
@ -106,5 +106,3 @@ private:
|
||||||
RESPONSE_HEADER_HASH(const RESPONSE_HEADER_HASH &);
|
RESPONSE_HEADER_HASH(const RESPONSE_HEADER_HASH &);
|
||||||
void operator=(const RESPONSE_HEADER_HASH &);
|
void operator=(const RESPONSE_HEADER_HASH &);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RESPONSE_HEADER_HASH * g_pResponseHeaderHash;
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -23,7 +23,6 @@
|
||||||
#define ASPNETCORE_IIS_AUTH_NONE L"none"
|
#define ASPNETCORE_IIS_AUTH_NONE L"none"
|
||||||
|
|
||||||
class PROCESS_MANAGER;
|
class PROCESS_MANAGER;
|
||||||
class FORWARDER_CONNECTION;
|
|
||||||
|
|
||||||
class SERVER_PROCESS
|
class SERVER_PROCESS
|
||||||
{
|
{
|
||||||
|
|
@ -42,14 +41,14 @@ public:
|
||||||
_In_ BOOL fAnonymousAuthEnabled,
|
_In_ BOOL fAnonymousAuthEnabled,
|
||||||
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
|
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
|
||||||
_In_ BOOL fStdoutLogEnabled,
|
_In_ BOOL fStdoutLogEnabled,
|
||||||
_In_ STRU *pstruStdoutLogFile
|
_In_ STRU *pstruStdoutLogFile,
|
||||||
|
_In_ STRU *pszAppPhysicalPath,
|
||||||
|
_In_ STRU *pszAppPath,
|
||||||
|
_In_ STRU *pszAppVirtualPath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
StartProcess(
|
StartProcess( VOID );
|
||||||
_In_ IHttpContext *context
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
SetWindowsAuthToken(
|
SetWindowsAuthToken(
|
||||||
|
|
@ -90,7 +89,6 @@ public:
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_ASSERT(m_cRefs != 0 );
|
_ASSERT(m_cRefs != 0 );
|
||||||
|
|
||||||
if (InterlockedDecrement(&m_cRefs) == 0)
|
if (InterlockedDecrement(&m_cRefs) == 0)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
|
|
@ -100,6 +98,14 @@ public:
|
||||||
virtual
|
virtual
|
||||||
~SERVER_PROCESS();
|
~SERVER_PROCESS();
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CALLBACK
|
||||||
|
ProcessHandleCallback(
|
||||||
|
_In_ PVOID pContext,
|
||||||
|
_In_ BOOL
|
||||||
|
);
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
HandleProcessExit(
|
HandleProcessExit(
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -113,38 +119,11 @@ public:
|
||||||
return m_pForwarderConnection;
|
return m_pForwarderConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
VOID
|
|
||||||
CALLBACK
|
|
||||||
TimerCallback(
|
|
||||||
_In_ PTP_CALLBACK_INSTANCE Instance,
|
|
||||||
_In_ PVOID Context,
|
|
||||||
_In_ PTP_TIMER Timer
|
|
||||||
);
|
|
||||||
|
|
||||||
LPCWSTR
|
|
||||||
QueryPortStr()
|
|
||||||
{
|
|
||||||
return m_struPort.QueryStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
LPCWSTR
|
|
||||||
QueryFullLogPath()
|
|
||||||
{
|
|
||||||
return m_struFullLogFile.QueryStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
LPCSTR
|
LPCSTR
|
||||||
QueryGuid()
|
QueryGuid()
|
||||||
{
|
{
|
||||||
return m_straGuid.QueryStr();
|
return m_straGuid.QueryStr();
|
||||||
}
|
};
|
||||||
|
|
||||||
DWORD
|
|
||||||
QueryProcessGroupId()
|
|
||||||
{
|
|
||||||
return m_dwProcessId;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SendSignal(
|
SendSignal(
|
||||||
|
|
@ -165,8 +144,7 @@ private:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
SetupStdHandles(
|
SetupStdHandles(
|
||||||
_In_ IHttpContext *context,
|
_Inout_ LPSTARTUPINFOW pStartupInfo
|
||||||
_In_ LPSTARTUPINFOW pStartupInfo
|
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
@ -184,6 +162,7 @@ private:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
GetChildProcessHandles(
|
GetChildProcessHandles(
|
||||||
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
@ -193,7 +172,6 @@ private:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
SetupAppPath(
|
SetupAppPath(
|
||||||
IHttpContext* pContext,
|
|
||||||
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -220,8 +198,7 @@ private:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
PostStartCheck(
|
PostStartCheck(
|
||||||
const STRU* const pStruCommandline,
|
VOID
|
||||||
STRU* pStruErrorMessage
|
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
@ -230,28 +207,6 @@ private:
|
||||||
DWORD dwExcludedPort
|
DWORD dwExcludedPort
|
||||||
);
|
);
|
||||||
|
|
||||||
DWORD
|
|
||||||
GetNumberOfDigits(
|
|
||||||
_In_ DWORD dwNumber
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DWORD digits = 0;
|
|
||||||
|
|
||||||
if( dwNumber == 0 )
|
|
||||||
{
|
|
||||||
digits = 1;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( dwNumber > 0)
|
|
||||||
{
|
|
||||||
dwNumber = dwNumber / 10;
|
|
||||||
digits ++;
|
|
||||||
}
|
|
||||||
Finished:
|
|
||||||
return digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
VOID
|
VOID
|
||||||
SendShutDownSignal(
|
SendShutDownSignal(
|
||||||
|
|
@ -286,10 +241,12 @@ private:
|
||||||
STRU m_struFullLogFile;
|
STRU m_struFullLogFile;
|
||||||
STRU m_ProcessPath;
|
STRU m_ProcessPath;
|
||||||
STRU m_Arguments;
|
STRU m_Arguments;
|
||||||
STRU m_struAppPath;
|
STRU m_struAppVirtualPath; // e.g., '/' for site
|
||||||
STRU m_struAppFullPath;
|
STRU m_struAppFullPath; // e.g., /LM/W3SVC/4/ROOT/Inproc
|
||||||
|
STRU m_struPhysicalPath; // e.g., c:/test/mysite
|
||||||
STRU m_struPort;
|
STRU m_struPort;
|
||||||
STRU m_pszRootApplicationPath;
|
STRU m_struCommandLine;
|
||||||
|
|
||||||
volatile LONG m_lStopping;
|
volatile LONG m_lStopping;
|
||||||
volatile BOOL m_fReady;
|
volatile BOOL m_fReady;
|
||||||
mutable LONG m_cRefs;
|
mutable LONG m_cRefs;
|
||||||
|
|
@ -27,7 +27,7 @@ This prevents the need for data buffering at the Asp.Net Core Module level.
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
SRWLOCK WEBSOCKET_HANDLER::sm_RequestsListLock;
|
SRWLOCK WEBSOCKET_HANDLER::sm_RequestsListLock;
|
||||||
|
|
||||||
|
|
@ -48,7 +48,6 @@ WEBSOCKET_HANDLER::WEBSOCKET_HANDLER() :
|
||||||
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO, "WEBSOCKET_HANDLER::WEBSOCKET_HANDLER");
|
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO, "WEBSOCKET_HANDLER::WEBSOCKET_HANDLER");
|
||||||
|
|
||||||
InitializeCriticalSectionAndSpinCount(&_RequestLock, 1000);
|
InitializeCriticalSectionAndSpinCount(&_RequestLock, 1000);
|
||||||
|
|
||||||
InsertRequest();
|
InsertRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +102,6 @@ WEBSOCKET_HANDLER::StaticInitialize(
|
||||||
// If tracing is enabled, keep track of all websocket requests
|
// If tracing is enabled, keep track of all websocket requests
|
||||||
// for debugging purposes.
|
// for debugging purposes.
|
||||||
//
|
//
|
||||||
|
|
||||||
InitializeListHead (&sm_RequestsListHead);
|
InitializeListHead (&sm_RequestsListHead);
|
||||||
sm_pTraceLog = CreateRefTraceLog( 10000, 0 );
|
sm_pTraceLog = CreateRefTraceLog( 10000, 0 );
|
||||||
}
|
}
|
||||||
|
|
@ -137,9 +135,7 @@ WEBSOCKET_HANDLER::InsertRequest(
|
||||||
if (g_fEnableReferenceCountTracing)
|
if (g_fEnableReferenceCountTracing)
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(&sm_RequestsListLock);
|
AcquireSRWLockExclusive(&sm_RequestsListLock);
|
||||||
|
|
||||||
InsertTailList(&sm_RequestsListHead, &_listEntry);
|
InsertTailList(&sm_RequestsListHead, &_listEntry);
|
||||||
|
|
||||||
ReleaseSRWLockExclusive( &sm_RequestsListLock);
|
ReleaseSRWLockExclusive( &sm_RequestsListLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,9 +149,7 @@ WEBSOCKET_HANDLER::RemoveRequest(
|
||||||
if (g_fEnableReferenceCountTracing)
|
if (g_fEnableReferenceCountTracing)
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(&sm_RequestsListLock);
|
AcquireSRWLockExclusive(&sm_RequestsListLock);
|
||||||
|
|
||||||
RemoveEntryList(&_listEntry);
|
RemoveEntryList(&_listEntry);
|
||||||
|
|
||||||
ReleaseSRWLockExclusive( &sm_RequestsListLock);
|
ReleaseSRWLockExclusive( &sm_RequestsListLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +160,6 @@ WEBSOCKET_HANDLER::IncrementOutstandingIo(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&_dwOutstandingIo);
|
InterlockedIncrement(&_dwOutstandingIo);
|
||||||
|
|
||||||
if (sm_pTraceLog)
|
if (sm_pTraceLog)
|
||||||
{
|
{
|
||||||
WriteRefTraceLog(sm_pTraceLog, _dwOutstandingIo, this);
|
WriteRefTraceLog(sm_pTraceLog, _dwOutstandingIo, this);
|
||||||
|
|
@ -213,8 +206,8 @@ WEBSOCKET_HANDLER::IndicateCompletionToIIS(
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO,
|
/*DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO,
|
||||||
"WEBSOCKET_HANDLER::IndicateCompletionToIIS");
|
"WEBSOCKET_HANDLER::IndicateCompletionToIIS");*/
|
||||||
|
|
||||||
_pHandler->SetStatus(FORWARDER_DONE);
|
_pHandler->SetStatus(FORWARDER_DONE);
|
||||||
|
|
||||||
|
|
@ -254,14 +247,12 @@ Routine Description:
|
||||||
_pHandler = pHandler;
|
_pHandler = pHandler;
|
||||||
|
|
||||||
EnterCriticalSection(&_RequestLock);
|
EnterCriticalSection(&_RequestLock);
|
||||||
|
|
||||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
||||||
"WEBSOCKET_HANDLER::ProcessRequest");
|
"WEBSOCKET_HANDLER::ProcessRequest");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cache the points to IHttpContext3
|
// Cache the points to IHttpContext3
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = HttpGetExtendedInterface(g_pHttpServer,
|
hr = HttpGetExtendedInterface(g_pHttpServer,
|
||||||
pHttpContext,
|
pHttpContext,
|
||||||
&_pHttpContext);
|
&_pHttpContext);
|
||||||
|
|
@ -285,7 +276,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Get Handle to Winhttp's websocket context.
|
// Get Handle to Winhttp's websocket context.
|
||||||
//
|
//
|
||||||
|
|
||||||
_hWebSocketRequest = WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade(
|
_hWebSocketRequest = WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade(
|
||||||
hRequest,
|
hRequest,
|
||||||
(DWORD_PTR) pHandler);
|
(DWORD_PTR) pHandler);
|
||||||
|
|
@ -331,7 +321,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Initiate Read on IIS
|
// Initiate Read on IIS
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = DoIisWebSocketReceive();
|
hr = DoIisWebSocketReceive();
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -374,7 +363,6 @@ Routine Description:
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
DWORD dwBufferSize = RECEIVE_BUFFER_SIZE;
|
DWORD dwBufferSize = RECEIVE_BUFFER_SIZE;
|
||||||
BOOL fUtf8Encoded;
|
BOOL fUtf8Encoded;
|
||||||
BOOL fFinalFragment;
|
BOOL fFinalFragment;
|
||||||
|
|
@ -398,10 +386,8 @@ Routine Description:
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
DecrementOutstandingIo();
|
DecrementOutstandingIo();
|
||||||
|
|
||||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR,
|
DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR,
|
||||||
"WEBSOCKET_HANDLER::DoIisWebSocketSend failed with %08x", hr);
|
"WEBSOCKET_HANDLER::DoIisWebSocketSend failed with %08x", hr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
@ -438,12 +424,9 @@ Routine Description:
|
||||||
if (dwError != NO_ERROR)
|
if (dwError != NO_ERROR)
|
||||||
{
|
{
|
||||||
DecrementOutstandingIo();
|
DecrementOutstandingIo();
|
||||||
|
|
||||||
hr = HRESULT_FROM_WIN32(dwError);
|
hr = HRESULT_FROM_WIN32(dwError);
|
||||||
|
|
||||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR,
|
DebugPrintf(ASPNETCORE_DEBUG_FLAG_ERROR,
|
||||||
"WEBSOCKET_HANDLER::DoWinHttpWebSocketReceive failed with %08x", hr);
|
"WEBSOCKET_HANDLER::DoWinHttpWebSocketReceive failed with %08x", hr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
@ -463,7 +446,6 @@ Routine Description:
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
BOOL fUtf8Encoded = FALSE;
|
BOOL fUtf8Encoded = FALSE;
|
||||||
BOOL fFinalFragment = FALSE;
|
BOOL fFinalFragment = FALSE;
|
||||||
BOOL fClose = FALSE;
|
BOOL fClose = FALSE;
|
||||||
|
|
@ -498,7 +480,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Convert close reason to WCHAR
|
// Convert close reason to WCHAR
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = strCloseReason.CopyA((PCSTR)&_WinHttpReceiveBuffer,
|
hr = strCloseReason.CopyA((PCSTR)&_WinHttpReceiveBuffer,
|
||||||
dwReceived);
|
dwReceived);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -517,7 +498,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Send close to IIS.
|
// Send close to IIS.
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = _pWebSocketContext->SendConnectionClose(
|
hr = _pWebSocketContext->SendConnectionClose(
|
||||||
TRUE,
|
TRUE,
|
||||||
uStatus,
|
uStatus,
|
||||||
|
|
@ -542,7 +522,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Do the Send.
|
// Do the Send.
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = _pWebSocketContext->WriteFragment(
|
hr = _pWebSocketContext->WriteFragment(
|
||||||
&_WinHttpReceiveBuffer,
|
&_WinHttpReceiveBuffer,
|
||||||
&cbData,
|
&cbData,
|
||||||
|
|
@ -552,7 +531,6 @@ Routine Description:
|
||||||
OnWriteIoCompletion,
|
OnWriteIoCompletion,
|
||||||
this,
|
this,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -598,7 +576,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Get Close status from IIS.
|
// Get Close status from IIS.
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = _pWebSocketContext->GetCloseStatus(&uStatus,
|
hr = _pWebSocketContext->GetCloseStatus(&uStatus,
|
||||||
&pszReason);
|
&pszReason);
|
||||||
|
|
||||||
|
|
@ -610,7 +587,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Convert status to UTF8
|
// Convert status to UTF8
|
||||||
//
|
//
|
||||||
|
|
||||||
hr = strCloseReason.CopyWToUTF8Unescaped(pszReason);
|
hr = strCloseReason.CopyWToUTF8Unescaped(pszReason);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -622,7 +598,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Send Close.
|
// Send Close.
|
||||||
//
|
//
|
||||||
|
|
||||||
dwError = WINHTTP_HELPER::sm_pfnWinHttpWebSocketShutdown(
|
dwError = WINHTTP_HELPER::sm_pfnWinHttpWebSocketShutdown(
|
||||||
_hWebSocketRequest,
|
_hWebSocketRequest,
|
||||||
uStatus,
|
uStatus,
|
||||||
|
|
@ -635,7 +610,6 @@ Routine Description:
|
||||||
// Call will complete asynchronously, return.
|
// Call will complete asynchronously, return.
|
||||||
// ignore error.
|
// ignore error.
|
||||||
//
|
//
|
||||||
|
|
||||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
||||||
"WEBSOCKET_HANDLER::DoWinhttpWebSocketSend IO_PENDING");
|
"WEBSOCKET_HANDLER::DoWinhttpWebSocketSend IO_PENDING");
|
||||||
|
|
||||||
|
|
@ -648,7 +622,6 @@ Routine Description:
|
||||||
//
|
//
|
||||||
// Call completed synchronously.
|
// Call completed synchronously.
|
||||||
//
|
//
|
||||||
|
|
||||||
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
||||||
"WEBSOCKET_HANDLER::DoWinhttpWebSocketSend Shutdown successful.");
|
"WEBSOCKET_HANDLER::DoWinhttpWebSocketSend Shutdown successful.");
|
||||||
}
|
}
|
||||||
|
|
@ -810,7 +783,6 @@ Finished:
|
||||||
// The handler object can be gone after this call.
|
// The handler object can be gone after this call.
|
||||||
// do not reference it after this statement.
|
// do not reference it after this statement.
|
||||||
//
|
//
|
||||||
|
|
||||||
DecrementOutstandingIo();
|
DecrementOutstandingIo();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
@ -841,7 +813,6 @@ WEBSOCKET_HANDLER::OnWinHttpIoError(
|
||||||
hr, pCompletionStatus->AsyncResult.dwResult);
|
hr, pCompletionStatus->AsyncResult.dwResult);
|
||||||
|
|
||||||
Cleanup(ServerDisconnect);
|
Cleanup(ServerDisconnect);
|
||||||
|
|
||||||
DecrementOutstandingIo();
|
DecrementOutstandingIo();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
extern IHttpServer * g_pHttpServer;
|
||||||
class FORWARDING_HANDLER;
|
class FORWARDING_HANDLER;
|
||||||
|
|
||||||
class WEBSOCKET_HANDLER
|
class WEBSOCKET_HANDLER
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include "precomp.hxx"
|
#include "..\precomp.hxx"
|
||||||
|
|
||||||
PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE
|
PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE
|
||||||
WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade;
|
WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade;
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
// 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 <vector>
|
||||||
|
#include <Shlobj.h>
|
||||||
|
#include <httpserv.h>
|
||||||
|
#include <winhttp.h>
|
||||||
|
#include <httptrace.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <reftrace.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <stdio.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 "..\IISLib\acache.h"
|
||||||
|
#include "..\IISLib\multisz.h"
|
||||||
|
#include "..\IISLib\multisza.h"
|
||||||
|
#include "..\IISLib\base64.h"
|
||||||
|
#include "..\IISLib\listentry.h"
|
||||||
|
#include "..\CommonLib\fx_ver.h"
|
||||||
|
#include "..\CommonLib\debugutil.h"
|
||||||
|
#include "..\CommonLib\requesthandler.h"
|
||||||
|
#include "..\CommonLib\aspnetcoreconfig.h"
|
||||||
|
#include "..\CommonLib\utility.h"
|
||||||
|
#include "..\CommonLib\application.h"
|
||||||
|
#include "aspnetcore_event.h"
|
||||||
|
#include "aspnetcore_msg.h"
|
||||||
|
#include "disconnectcontext.h"
|
||||||
|
#include "sttimer.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include ".\inprocess\InProcessHandler.h"
|
||||||
|
#include ".\inprocess\inprocessapplication.h"
|
||||||
|
#include ".\outofprocess\responseheaderhash.h"
|
||||||
|
#include ".\outofprocess\protocolconfig.h"
|
||||||
|
#include ".\outofprocess\forwarderconnection.h"
|
||||||
|
#include ".\outofprocess\serverprocess.h"
|
||||||
|
#include ".\outofprocess\processmanager.h"
|
||||||
|
#include ".\outofprocess\websockethandler.h"
|
||||||
|
#include ".\outofprocess\forwardinghandler.h"
|
||||||
|
#include ".\outofprocess\outprocessapplication.h"
|
||||||
|
#include ".\outofprocess\winhttphelper.h"
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#define ASPNETCORE_EVENT_PROVIDER L"IIS AspNetCore Module"
|
||||||
|
#define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern BOOL g_fAsyncDisconnectAvailable;
|
||||||
|
extern BOOL g_fWinHttpNonBlockingCallbackAvailable;
|
||||||
|
extern BOOL g_fWebSocketSupported;
|
||||||
|
extern BOOL g_fNsiApiNotSupported;
|
||||||
|
extern BOOL g_fEnableReferenceCountTracing;
|
||||||
|
extern DWORD g_dwActiveServerProcesses;
|
||||||
|
extern DWORD g_OptionalWinHttpFlags;
|
||||||
|
extern SRWLOCK g_srwLockRH;
|
||||||
|
extern HINTERNET g_hWinhttpSession;
|
||||||
|
extern DWORD g_dwTlsIndex;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// 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_MSG_BUFFER_SIZE 256
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'."
|
||||||
|
#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_INTERNAL_ERROR_MSG L"Application '%s' failed to parse processPath and arguments due to internal error, ErrorCode = '0x%x'."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_POSTCREATE_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s'but failed to get its status, ErrorCode = '0x%x'."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s', ErrorCode = '0x%x' processStatus code '%x'."
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_WRONGPORT_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but failed to listen on the given port '%d'"
|
||||||
|
#define ASPNETCORE_EVENT_PROCESS_START_NOTREADY_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but either crashed or did not reponse or did not listen on the given port '%d', ErrorCode = '0x%x'"
|
||||||
|
#define ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG L"Warning: Could not create stdoutLogFile %s, ErrorCode = %d."
|
||||||
|
#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE_MSG L"Failed to gracefully shutdown process '%d'."
|
||||||
|
#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST_MSG L"Sent shutdown HTTP message to process '%d' and received http status '%d'."
|
||||||
|
#define ASPNETCORE_EVENT_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 '%s' 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_MSG L"Application '%s' with physical root '%s' hit unexpected managed background thread exit, ErrorCode = '0x%x."
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef _STTIMER_H
|
#ifndef _STTIMER_H
|
||||||
#define _STTIMER_H
|
#define _STTIMER_H
|
||||||
|
|
||||||
|
|
@ -111,6 +113,41 @@ public:
|
||||||
fInCanel = FALSE;
|
fInCanel = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
CALLBACK
|
||||||
|
TimerCallback(
|
||||||
|
_In_ PTP_CALLBACK_INSTANCE Instance,
|
||||||
|
_In_ PVOID Context,
|
||||||
|
_In_ PTP_TIMER Timer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Instance;
|
||||||
|
Timer;
|
||||||
|
STRU* pstruLogFilePath = (STRU*)Context;
|
||||||
|
HANDLE hStdoutHandle = NULL;
|
||||||
|
SECURITY_ATTRIBUTES saAttr = { 0 };
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
hStdoutHandle = CreateFileW(pstruLogFilePath->QueryStr(),
|
||||||
|
FILE_READ_DATA,
|
||||||
|
FILE_SHARE_WRITE,
|
||||||
|
&saAttr,
|
||||||
|
OPEN_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
if (hStdoutHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hStdoutHandle);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue