Adds RequestHandler dll and hostfxr changes from ANCM (#497)
This commit is contained in:
parent
8cedb4eff3
commit
c3bc6fed9c
|
|
@ -30,8 +30,15 @@
|
||||||
<PackageId>Microsoft.AspNetCore.AspNetCoreModule</PackageId>
|
<PackageId>Microsoft.AspNetCore.AspNetCoreModule</PackageId>
|
||||||
<Version>$(PackageVersion)</Version>
|
<Version>$(PackageVersion)</Version>
|
||||||
<RepositoryRoot>$(RepositoryRoot)</RepositoryRoot>
|
<RepositoryRoot>$(RepositoryRoot)</RepositoryRoot>
|
||||||
|
</ArtifactInfo>
|
||||||
|
<ArtifactInfo Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModule.RequestHandler.$(PackageVersion).nupkg">
|
||||||
|
<ArtifactType>NuGetPackage</ArtifactType>
|
||||||
|
<PackageId>Microsoft.AspNetCore.AspNetCoreModule.RequestHandler</PackageId>
|
||||||
|
<Version>$(PackageVersion)</Version>
|
||||||
|
<RepositoryRoot>$(RepositoryRoot)</RepositoryRoot>
|
||||||
</ArtifactInfo>
|
</ArtifactInfo>
|
||||||
<FilesToExcludeFromSigning Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModule.$(PackageVersion).nupkg" />
|
<FilesToExcludeFromSigning Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModule.$(PackageVersion).nupkg" />
|
||||||
|
<FilesToExcludeFromSigning Include="$(BuildDir)Microsoft.AspNetCore.AspNetCoreModule.RequestHandler.$(PackageVersion).nupkg" />
|
||||||
|
|
||||||
<ArtifactInfo Include="$(AncmZipOutputPath)">
|
<ArtifactInfo Include="$(AncmZipOutputPath)">
|
||||||
<ArtifactType>ZipArchive</ArtifactType>
|
<ArtifactType>ZipArchive</ArtifactType>
|
||||||
|
|
@ -69,6 +76,11 @@
|
||||||
Overwrite="true"
|
Overwrite="true"
|
||||||
SourceFiles="@(AncmFiles)"
|
SourceFiles="@(AncmFiles)"
|
||||||
WorkingDirectory="$(RepositoryRoot)" />
|
WorkingDirectory="$(RepositoryRoot)" />
|
||||||
|
|
||||||
|
<PackNuspec NuspecPath="$(MSBuildThisFileDirectory)..\nuget\AspNetCoreRequestHandler.nuspec"
|
||||||
|
DestinationFolder="$(BuildDir)"
|
||||||
|
Properties="version=$(PackageVersion);Configuration=$(Configuration)"
|
||||||
|
BasePath="$(RepositoryRoot)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
<licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
||||||
<copyright>© .NET Foundation. All rights reserved.</copyright>
|
<copyright>© .NET Foundation. All rights reserved.</copyright>
|
||||||
<projectUrl>http://www.asp.net/</projectUrl>
|
<projectUrl>http://www.asp.net/</projectUrl>
|
||||||
|
<iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
|
||||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||||
<description>ASP.NET Core Module</description>
|
<description>ASP.NET Core Module</description>
|
||||||
<language>en-US</language>
|
<language>en-US</language>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Microsoft.AspNetCore.AspNetCoreModule.RequestHandler</id>
|
||||||
|
<title>Microsoft ASP.NET Core Module Request Handler</title>
|
||||||
|
<version>$VERSION$</version>
|
||||||
|
<authors>Microsoft</authors>
|
||||||
|
<owners>Microsoft</owners>
|
||||||
|
<licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
||||||
|
<copyright>© .NET Foundation. All rights reserved.</copyright>
|
||||||
|
<projectUrl>http://www.asp.net/</projectUrl>
|
||||||
|
<iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
|
||||||
|
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||||
|
<description>ASP.NET Core Module Request Handler</description>
|
||||||
|
<language>en-US</language>
|
||||||
|
<tags>Microsoft.AspNetCore.AspNetCoreModule.RequestHandler</tags>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<!-- TODO make build output outside of content files. -->
|
||||||
|
<file src="src\RequestHandler\bin\$Configuration$\Win32\aspnetcorerh.dll" target="runtimes\win-x86\nativeassets\netcoreapp2.1\aspnetcorerh.dll" />
|
||||||
|
<file src="src\RequestHandler\bin\$Configuration$\x64\aspnetcorerh.dll" target="runtimes\win-x64\nativeassets\netcoreapp2.1\aspnetcorerh.dll" />
|
||||||
|
</files>
|
||||||
|
</package>
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// 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 API_BUFFER_TOO_SMALL 0x80008098
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
@ -145,8 +146,7 @@ public:
|
||||||
private:
|
private:
|
||||||
HRESULT FindRequestHandlerAssembly();
|
HRESULT FindRequestHandlerAssembly();
|
||||||
HRESULT FindNativeAssemblyFromGlobalLocation(STRU* struFilename);
|
HRESULT FindNativeAssemblyFromGlobalLocation(STRU* struFilename);
|
||||||
HRESULT FindNativeAssemblyFromLocalBin(STRU* struFilename);
|
HRESULT FindNativeAssemblyFromHostfxr(STRU* struFilename);
|
||||||
HRESULT GetRequestHandlerFromRuntimeStore(STRU* struFilename);
|
|
||||||
|
|
||||||
mutable LONG m_cRefs;
|
mutable LONG m_cRefs;
|
||||||
APPLICATION_INFO_KEY m_applicationInfoKey;
|
APPLICATION_INFO_KEY m_applicationInfoKey;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public:
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
if (HRESULT_FROM_WIN32(GetLastError()) == ERROR_FILE_NOT_FOUND)
|
||||||
{
|
{
|
||||||
fResult = FALSE;
|
fResult = FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,11 +145,11 @@ APPLICATION_INFO::UpdateAppOfflineFileHandle()
|
||||||
HRESULT
|
HRESULT
|
||||||
APPLICATION_INFO::EnsureApplicationCreated()
|
APPLICATION_INFO::EnsureApplicationCreated()
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
BOOL fLocked = FALSE;
|
BOOL fLocked = FALSE;
|
||||||
APPLICATION* pApplication = NULL;
|
APPLICATION* pApplication = NULL;
|
||||||
STACK_STRU(struFileName, 300); // >MAX_PATH
|
STACK_STRU(struFileName, 300); // >MAX_PATH
|
||||||
STRU hostFxrDllLocation;
|
STRU hostFxrDllLocation;
|
||||||
|
|
||||||
if (m_pApplication != NULL)
|
if (m_pApplication != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -184,7 +184,6 @@ APPLICATION_INFO::EnsureApplicationCreated()
|
||||||
}
|
}
|
||||||
m_pApplication = pApplication;
|
m_pApplication = pApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
if (fLocked)
|
if (fLocked)
|
||||||
{
|
{
|
||||||
|
|
@ -196,9 +195,9 @@ Finished:
|
||||||
HRESULT
|
HRESULT
|
||||||
APPLICATION_INFO::FindRequestHandlerAssembly()
|
APPLICATION_INFO::FindRequestHandlerAssembly()
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
BOOL fLocked = FALSE;
|
BOOL fLocked = FALSE;
|
||||||
STACK_STRU(struFileName, 300); // >MAX_PATH
|
STACK_STRU(struFileName, 256);
|
||||||
|
|
||||||
if (g_fAspnetcoreRHLoadedError)
|
if (g_fAspnetcoreRHLoadedError)
|
||||||
{
|
{
|
||||||
|
|
@ -219,19 +218,10 @@ APPLICATION_INFO::FindRequestHandlerAssembly()
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load assembly and create the application
|
if (FAILED(hr = HOSTFXR_UTILITY::GetHostFxrParameters(m_pConfiguration)) ||
|
||||||
if (m_pConfiguration->QueryHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
|
FAILED(hr = FindNativeAssemblyFromHostfxr(&struFileName)))
|
||||||
{
|
|
||||||
// Look at inetsvr only for now. TODO add in functionality
|
|
||||||
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// TODO eventually make this fail for in process loading.
|
||||||
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
|
hr = FindNativeAssemblyFromGlobalLocation(&struFileName);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -294,6 +284,11 @@ APPLICATION_INFO::FindNativeAssemblyFromGlobalLocation(STRU* struFilename)
|
||||||
// Though we could call LoadLibrary(L"aspnetcorerh.dll") relying the OS to solve
|
// 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)
|
// the path (the targeted dll is the same folder of w3wp.exe/iisexpress)
|
||||||
// let's still load with full path to avoid security issue
|
// let's still load with full path to avoid security issue
|
||||||
|
if (FAILED(hr = struFilename->Resize(dwSize + 20)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
while (!fDone)
|
while (!fDone)
|
||||||
{
|
{
|
||||||
DWORD dwReturnedSize = GetModuleFileNameW(g_hModule, struFilename->QueryStr(), dwSize);
|
DWORD dwReturnedSize = GetModuleFileNameW(g_hModule, struFilename->QueryStr(), dwSize);
|
||||||
|
|
@ -306,7 +301,10 @@ APPLICATION_INFO::FindNativeAssemblyFromGlobalLocation(STRU* struFilename)
|
||||||
else if ((dwReturnedSize == dwSize) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
|
else if ((dwReturnedSize == dwSize) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
|
||||||
{
|
{
|
||||||
dwSize *= 2; // smaller buffer. increase the buffer and retry
|
dwSize *= 2; // smaller buffer. increase the buffer and retry
|
||||||
struFilename->Resize(dwSize + 20); // aspnetcorerh.dll
|
if (FAILED(hr = struFilename->Resize(dwSize + 20))) // + 20 for aspnetcorerh.dll
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -322,6 +320,7 @@ APPLICATION_INFO::FindNativeAssemblyFromGlobalLocation(STRU* struFilename)
|
||||||
struFilename->QueryStr()[dwPosition] = L'\0';
|
struFilename->QueryStr()[dwPosition] = L'\0';
|
||||||
|
|
||||||
if (FAILED(hr = struFilename->SyncWithBuffer()) ||
|
if (FAILED(hr = struFilename->SyncWithBuffer()) ||
|
||||||
|
FAILED(hr = struFilename->Append(L"\\")) ||
|
||||||
FAILED(hr = struFilename->Append(g_pwzAspnetcoreRequestHandlerName)))
|
FAILED(hr = struFilename->Append(g_pwzAspnetcoreRequestHandlerName)))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -330,3 +329,137 @@ APPLICATION_INFO::FindNativeAssemblyFromGlobalLocation(STRU* struFilename)
|
||||||
Finished:
|
Finished:
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tries to find aspnetcorerh.dll from the application
|
||||||
|
// Calls into hostfxr.dll to find it.
|
||||||
|
// Will leave hostfxr.dll loaded as it will be used again to call hostfxr_main.
|
||||||
|
//
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
APPLICATION_INFO::FindNativeAssemblyFromHostfxr(
|
||||||
|
STRU* struFilename
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
STRU struApplicationFullPath;
|
||||||
|
STRU struNativeSearchPaths;
|
||||||
|
STRU struNativeDllLocation;
|
||||||
|
HMODULE hmHostFxrDll = NULL;
|
||||||
|
INT intHostFxrExitCode = 0;
|
||||||
|
INT intIndex = -1;
|
||||||
|
INT intPrevIndex = 0;
|
||||||
|
BOOL fFound = FALSE;
|
||||||
|
DWORD dwBufferSize = 1024 * 10;
|
||||||
|
|
||||||
|
DBG_ASSERT(struFileName != NULL);
|
||||||
|
|
||||||
|
hmHostFxrDll = LoadLibraryW(m_pConfiguration->QueryHostFxrFullPath());
|
||||||
|
|
||||||
|
if (hmHostFxrDll == NULL)
|
||||||
|
{
|
||||||
|
// Could not load hostfxr
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hostfxr_get_native_search_directories_fn pFnHostFxrSearchDirectories = (hostfxr_get_native_search_directories_fn)
|
||||||
|
GetProcAddress(hmHostFxrDll, "hostfxr_get_native_search_directories");
|
||||||
|
|
||||||
|
if (pFnHostFxrSearchDirectories == NULL)
|
||||||
|
{
|
||||||
|
// Host fxr version is incorrect (need a higher version).
|
||||||
|
// TODO log error
|
||||||
|
hr = E_FAIL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = struNativeSearchPaths.Resize(dwBufferSize)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
intHostFxrExitCode = pFnHostFxrSearchDirectories(
|
||||||
|
m_pConfiguration->QueryHostFxrArgCount(),
|
||||||
|
m_pConfiguration->QueryHostFxrArguments(),
|
||||||
|
struNativeSearchPaths.QueryStr(),
|
||||||
|
dwBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if (intHostFxrExitCode == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (intHostFxrExitCode == API_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
dwBufferSize *= 2; // smaller buffer. increase the buffer and retry
|
||||||
|
if (FAILED(hr = struNativeSearchPaths.Resize(dwBufferSize)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
// Log "Error finding native search directories from aspnetcore application.
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = struNativeSearchPaths.SyncWithBuffer()))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
fFound = FALSE;
|
||||||
|
|
||||||
|
// The native search directories are semicolon delimited.
|
||||||
|
// Split on semicolons, append aspnetcorerh.dll, and check if the file exists.
|
||||||
|
while ((intIndex = struNativeSearchPaths.IndexOf(L";", intPrevIndex)) != -1)
|
||||||
|
{
|
||||||
|
if (FAILED(hr = struNativeDllLocation.Copy(struNativeSearchPaths.QueryStr(), intIndex - intPrevIndex)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!struNativeDllLocation.EndsWith(L"\\"))
|
||||||
|
{
|
||||||
|
if (FAILED(hr = struNativeDllLocation.Append(L"\\")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = struNativeDllLocation.Append(g_pwzAspnetcoreRequestHandlerName)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UTILITY::CheckIfFileExists(struNativeDllLocation.QueryStr()))
|
||||||
|
{
|
||||||
|
if (FAILED(hr = struFilename->Copy(struNativeDllLocation)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
fFound = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
intPrevIndex = intIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fFound)
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (FAILED(hr) && hmHostFxrDll != NULL)
|
||||||
|
{
|
||||||
|
FreeLibrary(hmHostFxrDll);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ DWORD g_dwActiveServerProcesses = 0;
|
||||||
SRWLOCK g_srwLock;
|
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";
|
PCWSTR g_pwzAspnetcoreRequestHandlerName = L"aspnetcorerh.dll";
|
||||||
PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
|
PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
|
||||||
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
|
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ inline bool IsSpace(char ch)
|
||||||
|
|
||||||
#include "..\..\CommonLib\environmentvariablehash.h"
|
#include "..\..\CommonLib\environmentvariablehash.h"
|
||||||
#include "..\..\CommonLib\aspnetcoreconfig.h"
|
#include "..\..\CommonLib\aspnetcoreconfig.h"
|
||||||
|
#include "..\..\CommonLib\hostfxr_utility.h"
|
||||||
#include "..\..\CommonLib\application.h"
|
#include "..\..\CommonLib\application.h"
|
||||||
#include "..\..\CommonLib\utility.h"
|
#include "..\..\CommonLib\utility.h"
|
||||||
#include "..\..\CommonLib\debugutil.h"
|
#include "..\..\CommonLib\debugutil.h"
|
||||||
|
|
@ -116,6 +117,7 @@ inline bool IsSpace(char ch)
|
||||||
#include "globalmodule.h"
|
#include "globalmodule.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "proxymodule.h"
|
#include "proxymodule.h"
|
||||||
|
#include "applicationinfo.h"
|
||||||
|
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler(
|
||||||
// cannot recreate the application as we cannot reload clr for inprocess
|
// cannot recreate the application as we cannot reload clr for inprocess
|
||||||
if (pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING)
|
if (pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING)
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
|
hr = HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED);
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create RequestHandler and process the request
|
// Create RequestHandler and process the request
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,12 @@
|
||||||
|
|
||||||
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
|
ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
|
||||||
{
|
{
|
||||||
|
if (m_ppStrArguments != NULL)
|
||||||
|
{
|
||||||
|
delete[] m_ppStrArguments;
|
||||||
|
m_ppStrArguments = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_pEnvironmentVariables != NULL)
|
if (m_pEnvironmentVariables != NULL)
|
||||||
{
|
{
|
||||||
m_pEnvironmentVariables->Clear();
|
m_pEnvironmentVariables->Clear();
|
||||||
|
|
@ -22,7 +28,6 @@ ASPNETCORE_CONFIG::ReferenceConfiguration(
|
||||||
InterlockedIncrement(&m_cRefs);
|
InterlockedIncrement(&m_cRefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ASPNETCORE_CONFIG::DereferenceConfiguration(
|
ASPNETCORE_CONFIG::DereferenceConfiguration(
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -132,6 +137,7 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
IHttpContext *pHttpContext
|
IHttpContext *pHttpContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
STACK_STRU(strHostingModel, 300);
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
STRU strEnvName;
|
STRU strEnvName;
|
||||||
STRU strEnvValue;
|
STRU strEnvValue;
|
||||||
|
|
@ -308,7 +314,7 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
|
|
||||||
hr = GetElementStringProperty(pAspNetCoreElement,
|
hr = GetElementStringProperty(pAspNetCoreElement,
|
||||||
CS_ASPNETCORE_HOSTING_MODEL,
|
CS_ASPNETCORE_HOSTING_MODEL,
|
||||||
&m_strHostingModel);
|
&strHostingModel);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
// Swallow this error for backward compatability
|
// Swallow this error for backward compatability
|
||||||
|
|
@ -316,11 +322,11 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_strHostingModel.IsEmpty() || m_strHostingModel.Equals(L"outofprocess", TRUE))
|
if (strHostingModel.IsEmpty() || strHostingModel.Equals(L"outofprocess", TRUE))
|
||||||
{
|
{
|
||||||
m_hostingModel = HOSTING_OUT_PROCESS;
|
m_hostingModel = HOSTING_OUT_PROCESS;
|
||||||
}
|
}
|
||||||
else if (m_strHostingModel.Equals(L"inprocess", TRUE))
|
else if (strHostingModel.Equals(L"inprocess", TRUE))
|
||||||
{
|
{
|
||||||
m_hostingModel = HOSTING_IN_PROCESS;
|
m_hostingModel = HOSTING_IN_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ public:
|
||||||
_In_ IHttpServer *pHttpServer,
|
_In_ IHttpServer *pHttpServer,
|
||||||
_In_ HTTP_MODULE_ID pModuleId,
|
_In_ HTTP_MODULE_ID pModuleId,
|
||||||
_In_ IHttpContext *pHttpContext,
|
_In_ IHttpContext *pHttpContext,
|
||||||
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
ENVIRONMENT_VAR_HASH*
|
ENVIRONMENT_VAR_HASH*
|
||||||
|
|
@ -215,18 +215,54 @@ public:
|
||||||
return &m_struConfigPath;
|
return &m_struConfigPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
STRU*
|
CONST
|
||||||
QueryHostfxrPath()
|
PCWSTR*
|
||||||
{
|
QueryHostFxrArguments(
|
||||||
return &m_struHostFxrPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
QueryIsStandAloneApplication(
|
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return m_fIsStandAloneApplication;
|
return m_ppStrArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONST
|
||||||
|
DWORD
|
||||||
|
QueryHostFxrArgCount(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_dwArgc;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONST
|
||||||
|
PCWSTR
|
||||||
|
QueryHostFxrFullPath(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_struHostFxrLocation.QueryStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetHostFxrFullPath(
|
||||||
|
PCWSTR pStrHostFxrFullPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return m_struHostFxrLocation.Copy(pStrHostFxrFullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetHostFxrArguments(
|
||||||
|
DWORD dwArgc,
|
||||||
|
PCWSTR* ppStrArguments
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (m_ppStrArguments != NULL)
|
||||||
|
{
|
||||||
|
delete[] m_ppStrArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dwArgc = dwArgc;
|
||||||
|
m_ppStrArguments = ppStrArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -248,7 +284,8 @@ private:
|
||||||
m_fStdoutLogEnabled( FALSE ),
|
m_fStdoutLogEnabled( FALSE ),
|
||||||
m_pEnvironmentVariables( NULL ),
|
m_pEnvironmentVariables( NULL ),
|
||||||
m_cRefs( 1 ),
|
m_cRefs( 1 ),
|
||||||
m_hostingModel( HOSTING_UNKNOWN )
|
m_hostingModel( HOSTING_UNKNOWN ),
|
||||||
|
m_ppStrArguments(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,8 +309,6 @@ private:
|
||||||
STRU m_struApplicationPhysicalPath;
|
STRU m_struApplicationPhysicalPath;
|
||||||
STRU m_struApplicationVirtualPath;
|
STRU m_struApplicationVirtualPath;
|
||||||
STRU m_struConfigPath;
|
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;
|
||||||
|
|
@ -283,4 +318,7 @@ private:
|
||||||
BOOL m_fIsStandAloneApplication;
|
BOOL m_fIsStandAloneApplication;
|
||||||
APP_HOSTING_MODEL m_hostingModel;
|
APP_HOSTING_MODEL m_hostingModel;
|
||||||
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
|
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
|
||||||
|
STRU m_struHostFxrLocation;
|
||||||
|
PCWSTR* m_ppStrArguments;
|
||||||
|
DWORD m_dwArgc;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,40 +7,10 @@ HOSTFXR_UTILITY::HOSTFXR_UTILITY()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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.
|
// Runs a standalone appliction.
|
||||||
// The folder structure looks like this:
|
// The folder structure looks like this:
|
||||||
|
|
@ -54,160 +24,183 @@ HOSTFXR_UTILITY::FindHostFxrDll(
|
||||||
// Assuming we don't need Application.exe as the dll is the actual application.
|
// Assuming we don't need Application.exe as the dll is the actual application.
|
||||||
//
|
//
|
||||||
HRESULT
|
HRESULT
|
||||||
HOSTFXR_UTILITY::GetStandaloneHostfxrLocation(
|
HOSTFXR_UTILITY::GetStandaloneHostfxrParameters(
|
||||||
STRU* struHostfxrPath,
|
|
||||||
ASPNETCORE_CONFIG *pConfig
|
ASPNETCORE_CONFIG *pConfig
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
|
STRU struExePath;
|
||||||
SECURITY_ATTRIBUTES saAttr;
|
STRU struDllPath;
|
||||||
|
STRU struArguments;
|
||||||
|
DWORD dwPosition;
|
||||||
|
|
||||||
// Get the full path to the exe and check if it exists
|
hr = UTILITY::ConvertPathToFullPath(pConfig->QueryProcessPath()->QueryStr(),
|
||||||
if (FAILED(hr = UTILITY::ConvertPathToFullPath(L"\\hostfxr.dll",
|
|
||||||
pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
struHostfxrPath)))
|
&struExePath);
|
||||||
{
|
|
||||||
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))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the System PATH value.
|
if (FAILED(hr = struDllPath.Copy(struExePath)))
|
||||||
if (!UTILITY::GetSystemPathVariable(L"PATH", &struSystemPathVariable))
|
|
||||||
{
|
{
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split on ';', checking to see if dotnet.exe exists in any folders.
|
dwPosition = struDllPath.LastIndexOf(L'.', 0);
|
||||||
pszDotnetLocation = wcstok_s(struSystemPathVariable.QueryStr(), L";", &pwzDelimeterContext);
|
if (dwPosition == -1)
|
||||||
while (pszDotnetLocation != NULL)
|
|
||||||
{
|
{
|
||||||
dwCopyLength = (DWORD) wcsnlen_s(pszDotnetLocation, 260);
|
hr = E_FAIL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
// We store both the exe and folder locations as we eventually need to check inside of host\\fxr
|
struDllPath.QueryStr()[dwPosition] = L'\0';
|
||||||
// which doesn't need the dotnet.exe portion of the string
|
|
||||||
hr = strDotnetExeLocation.Copy(pszDotnetLocation, dwCopyLength);
|
if (FAILED(hr = struDllPath.SyncWithBuffer()) ||
|
||||||
|
FAILED(hr = struDllPath.Append(L".dll")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UTILITY::CheckIfFileExists(struDllPath.QueryStr()))
|
||||||
|
{
|
||||||
|
// Treat access issue as File not found
|
||||||
|
hr = ERROR_FILE_NOT_FOUND;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = struArguments.Copy(struDllPath)) ||
|
||||||
|
FAILED(hr = struArguments.Append(L" ")) ||
|
||||||
|
FAILED(hr = struArguments.Append(pConfig->QueryArguments())))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = SetHostFxrArguments(&struArguments, &struExePath, pConfig)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||||
|
ASPNETCORE_CONFIG *pConfig
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
STRU struSystemPathVariable;
|
||||||
|
STRU struHostFxrPath;
|
||||||
|
STRU strDotnetExeLocation;
|
||||||
|
STRU strHostFxrSearchExpression;
|
||||||
|
STRU strHighestDotnetVersion;
|
||||||
|
std::vector<std::wstring> vVersionFolders;
|
||||||
|
DWORD dwPosition;
|
||||||
|
DWORD dwPathLength = MAX_PATH;
|
||||||
|
DWORD dwDotnetLength = 0;
|
||||||
|
BOOL fFound = FALSE;
|
||||||
|
|
||||||
|
if (UTILITY::CheckIfFileExists(pConfig->QueryProcessPath()->QueryStr()))
|
||||||
|
{
|
||||||
|
hr = UTILITY::ConvertPathToFullPath(L"hostfxr.dll", pConfig->QueryApplicationPath()->QueryStr(), &struHostFxrPath);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwCopyLength > 0 && pszDotnetLocation[dwCopyLength - 1] != L'\\')
|
if (UTILITY::CheckIfFileExists(struHostFxrPath.QueryStr()))
|
||||||
{
|
{
|
||||||
hr = strDotnetExeLocation.Append(L"\\");
|
// Standalone application
|
||||||
|
if (FAILED(hr = pConfig->SetHostFxrFullPath(struHostFxrPath.QueryStr())))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = GetStandaloneHostfxrParameters(pConfig);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = UTILITY::ConvertPathToFullPath(
|
||||||
|
pConfig->QueryProcessPath()->QueryStr(),
|
||||||
|
pConfig->QueryApplicationPath()->QueryStr(),
|
||||||
|
&strDotnetExeLocation
|
||||||
|
);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
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)
|
if (FAILED(hr = strDotnetExeLocation.Resize(MAX_PATH)))
|
||||||
{
|
{
|
||||||
// could not find dotnet.exe, error out
|
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = struHostfxrPath->Append(L"host\\fxr");
|
while (!fFound)
|
||||||
|
{
|
||||||
|
dwDotnetLength = SearchPath(NULL, L"dotnet", L".exe", dwPathLength, strDotnetExeLocation.QueryStr(), NULL);
|
||||||
|
if (dwDotnetLength == 0)
|
||||||
|
{
|
||||||
|
hr = GetLastError();
|
||||||
|
// Could not find dotnet
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
else if (dwDotnetLength == dwPathLength)
|
||||||
|
{
|
||||||
|
// Increase size
|
||||||
|
dwPathLength *= 2;
|
||||||
|
if (FAILED(hr = strDotnetExeLocation.Resize(dwPathLength)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fFound = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = strDotnetExeLocation.SyncWithBuffer())
|
||||||
|
|| FAILED(hr = struHostFxrPath.Copy(strDotnetExeLocation)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwPosition = struHostFxrPath.LastIndexOf(L'\\', 0);
|
||||||
|
if (dwPosition == -1)
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
struHostFxrPath.QueryStr()[dwPosition] = L'\0';
|
||||||
|
|
||||||
|
if (FAILED(hr = struHostFxrPath.SyncWithBuffer())
|
||||||
|
|| FAILED(hr = struHostFxrPath.Append(L"\\")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = struHostFxrPath.Append(L"host\\fxr");
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UTILITY::DirectoryExists(struHostfxrPath))
|
if (!UTILITY::DirectoryExists(&struHostFxrPath))
|
||||||
{
|
{
|
||||||
// error, not found the folder
|
// error, not found in folder
|
||||||
hr = ERROR_BAD_ENVIRONMENT;
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all folders under host\\fxr\\ for version numbers.
|
// Find all folders under host\\fxr\\ for version numbers.
|
||||||
hr = strHostFxrSearchExpression.Copy(struHostfxrPath);
|
hr = strHostFxrSearchExpression.Copy(struHostFxrPath);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -235,25 +228,84 @@ HOSTFXR_UTILITY::GetPortableHostfxrLocation(
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
hr = struHostfxrPath->Append(L"\\");
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr = struHostFxrPath.Append(L"\\"))
|
||||||
|
|| FAILED(hr = struHostFxrPath.Append(strHighestDotnetVersion.QueryStr()))
|
||||||
|
|| FAILED(hr = struHostFxrPath.Append(L"\\hostfxr.dll")))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = struHostfxrPath->Append(strHighestDotnetVersion.QueryStr());
|
if (!UTILITY::CheckIfFileExists(struHostFxrPath.QueryStr()))
|
||||||
if (FAILED(hr))
|
{
|
||||||
|
hr = ERROR_FILE_INVALID;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = SetHostFxrArguments(pConfig->QueryArguments(), &strDotnetExeLocation, pConfig)))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = struHostfxrPath->Append(L"\\hostfxr.dll");
|
if (FAILED(hr = pConfig->SetHostFxrFullPath(struHostFxrPath.QueryStr())))
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Forms the argument list in HOSTFXR_PARAMETERS.
|
||||||
|
// Sets the ArgCount and Arguments.
|
||||||
|
// Arg structure:
|
||||||
|
// argv[0] = Path to exe activating hostfxr.
|
||||||
|
// argv[1] = L"exec"
|
||||||
|
// argv[2] = first argument specified in the arguments portion of aspnetcore config.
|
||||||
|
//
|
||||||
|
HRESULT
|
||||||
|
HOSTFXR_UTILITY::SetHostFxrArguments(
|
||||||
|
STRU* struArgumentsFromConfig,
|
||||||
|
STRU* pstruExePath,
|
||||||
|
ASPNETCORE_CONFIG* pConfig
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
INT argc = 0;
|
||||||
|
PCWSTR* argv = NULL;
|
||||||
|
LPWSTR* pwzArgs = NULL;
|
||||||
|
|
||||||
|
pwzArgs = CommandLineToArgvW(struArgumentsFromConfig->QueryStr(), &argc);
|
||||||
|
|
||||||
|
if (pwzArgs == NULL)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
argv = new PCWSTR[argc + 2];
|
||||||
|
if (argv == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
argv[0] = SysAllocString(pstruExePath->QueryStr());
|
||||||
|
argv[1] = SysAllocString(L"exec");
|
||||||
|
|
||||||
|
for (INT i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
argv[i + 2] = SysAllocString(pwzArgs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pConfig->SetHostFxrArguments(argc + 2, argv);
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (pwzArgs != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(pwzArgs);
|
||||||
|
DBG_ASSERT(pwzArgs == NULL);
|
||||||
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef INT(*hostfxr_get_native_search_directories_fn) (const int argc, const PCWSTR argv[], PCWSTR dest, size_t dest_size);
|
||||||
|
typedef INT(*hostfxr_main_fn) (CONST DWORD argc, CONST PCWSTR argv[]);
|
||||||
|
|
||||||
|
|
||||||
class HOSTFXR_UTILITY
|
class HOSTFXR_UTILITY
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -11,23 +15,23 @@ public:
|
||||||
|
|
||||||
static
|
static
|
||||||
HRESULT
|
HRESULT
|
||||||
FindHostFxrDll(
|
GetHostFxrParameters(
|
||||||
ASPNETCORE_CONFIG *pConfig,
|
ASPNETCORE_CONFIG *pConfig
|
||||||
STRU* struHostFxrDllLocation,
|
|
||||||
BOOL* fStandAlone
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
static
|
static
|
||||||
HRESULT
|
HRESULT
|
||||||
GetStandaloneHostfxrLocation(
|
GetStandaloneHostfxrParameters(
|
||||||
STRU* struHostfxrPath,
|
|
||||||
ASPNETCORE_CONFIG *pConfig
|
ASPNETCORE_CONFIG *pConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
static
|
static
|
||||||
HRESULT
|
HRESULT
|
||||||
GetPortableHostfxrLocation(
|
SetHostFxrArguments(
|
||||||
STRU* struHostfxrPath
|
STRU * struArguments,
|
||||||
|
STRU * pstruExePath,
|
||||||
|
ASPNETCORE_CONFIG *pConfig
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <httpserv.h>
|
#include <httpserv.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <shellapi.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "..\IISLib\hashtable.h"
|
#include "..\IISLib\hashtable.h"
|
||||||
#include "..\IISLib\stringu.h"
|
#include "..\IISLib\stringu.h"
|
||||||
|
|
|
||||||
|
|
@ -545,45 +545,6 @@ UTILITY::DirectoryExists(
|
||||||
return GetFileAttributesExW(pstrPath->QueryStr(), GetFileExInfoStandard, &data);
|
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
|
VOID
|
||||||
UTILITY::FindDotNetFolders(
|
UTILITY::FindDotNetFolders(
|
||||||
_In_ PCWSTR pszPath,
|
_In_ PCWSTR pszPath,
|
||||||
|
|
@ -606,4 +567,35 @@ UTILITY::FindDotNetFolders(
|
||||||
} while (FindNextFileW(handle, &data));
|
} while (FindNextFileW(handle, &data));
|
||||||
|
|
||||||
FindClose(handle);
|
FindClose(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
UTILITY::CheckIfFileExists(
|
||||||
|
_In_ PCWSTR pszFilePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HANDLE hFileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
BOOL fFileExists = FALSE;
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
hFileHandle = CreateFile(pszFilePath,
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
&saAttr,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
fFileExists = hFileHandle != INVALID_HANDLE_VALUE || GetLastError() == ERROR_SHARING_VIOLATION;
|
||||||
|
|
||||||
|
if (fFileExists)
|
||||||
|
{
|
||||||
|
CloseHandle(hFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fFileExists;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,6 @@ public:
|
||||||
_In_ STRU *pstrPath
|
_In_ STRU *pstrPath
|
||||||
);
|
);
|
||||||
|
|
||||||
static
|
|
||||||
BOOL
|
|
||||||
GetSystemPathVariable(
|
|
||||||
_In_ PCWSTR pszEnvironmentVariable,
|
|
||||||
_Out_ STRU *pstrResult
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
static
|
||||||
VOID
|
VOID
|
||||||
FindDotNetFolders(
|
FindDotNetFolders(
|
||||||
|
|
@ -112,6 +105,12 @@ public:
|
||||||
_Out_ STRU *pstrResult
|
_Out_ STRU *pstrResult
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOL
|
||||||
|
CheckIfFileExists(
|
||||||
|
PCWSTR pszFilePath
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UTILITY() {}
|
UTILITY() {}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#include "..\precomp.hxx"
|
#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::s_Application = NULL;
|
||||||
|
|
||||||
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
|
IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
|
||||||
|
|
@ -180,84 +178,6 @@ IN_PROCESS_APPLICATION::OnExecuteRequest(
|
||||||
return RQ_NOTIFICATION_FINISH_REQUEST;
|
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
|
VOID
|
||||||
IN_PROCESS_APPLICATION::SetCallbackHandles(
|
IN_PROCESS_APPLICATION::SetCallbackHandles(
|
||||||
_In_ PFN_REQUEST_HANDLER request_handler,
|
_In_ PFN_REQUEST_HANDLER request_handler,
|
||||||
|
|
@ -277,30 +197,6 @@ IN_PROCESS_APPLICATION::SetCallbackHandles(
|
||||||
SetEvent(m_pInitalizeEvent);
|
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
|
VOID
|
||||||
IN_PROCESS_APPLICATION::SetStdOut(
|
IN_PROCESS_APPLICATION::SetStdOut(
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -495,6 +391,11 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
{
|
{
|
||||||
// Core CLR has already been loaded.
|
// Core CLR has already been loaded.
|
||||||
// Cannot load more than once even there was a failure
|
// Cannot load more than once even there was a failure
|
||||||
|
if (m_fLoadManagedAppError)
|
||||||
|
{
|
||||||
|
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -505,6 +406,11 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
fLocked = TRUE;
|
fLocked = TRUE;
|
||||||
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
if (m_fManagedAppLoaded || m_fLoadManagedAppError)
|
||||||
{
|
{
|
||||||
|
if (m_fLoadManagedAppError)
|
||||||
|
{
|
||||||
|
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,16 +478,12 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
m_fManagedAppLoaded = TRUE;
|
m_fManagedAppLoaded = TRUE;
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
if (fLocked)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
// Question: in case of application loading failure, should we allow retry on
|
// Question: in case of application loading failure, should we allow retry on
|
||||||
// following request or block the activation at all
|
// following request or block the activation at all
|
||||||
m_fLoadManagedAppError = FALSE; // m_hThread != NULL ?
|
m_fLoadManagedAppError = TRUE; // m_hThread != NULL ?
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
//if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||||
|
|
@ -610,6 +512,12 @@ Finished:
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fLocked)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLock);
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -619,166 +527,29 @@ IN_PROCESS_APPLICATION::ExecuteAspNetCoreProcess(
|
||||||
_In_ LPVOID pContext
|
_In_ LPVOID pContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
IN_PROCESS_APPLICATION *pApplication = (IN_PROCESS_APPLICATION*)pContext;
|
IN_PROCESS_APPLICATION *pApplication = (IN_PROCESS_APPLICATION*)pContext;
|
||||||
DBG_ASSERT(pApplication != NULL);
|
DBG_ASSERT(pApplication != NULL);
|
||||||
pApplication->ExecuteApplication();
|
hr = pApplication->ExecuteApplication();
|
||||||
//
|
//
|
||||||
// no need to log the error here as if error happened, the thread will exit
|
// 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
|
// the error will ba catched by caller LoadManagedApplication which will log an error
|
||||||
//
|
//
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
IN_PROCESS_APPLICATION::ExecuteApplication(
|
IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
HMODULE hModule;
|
||||||
|
hostfxr_main_fn pProc;
|
||||||
|
|
||||||
STRU strFullPath;
|
// should be a redudant call here, but we will be safe and call it twice.
|
||||||
STRU strDotnetExeLocation;
|
// TODO AV here on m_pHostFxrParameters being null
|
||||||
STRU strHostFxrSearchExpression;
|
hModule = LoadLibraryW(m_pConfig->QueryHostFxrFullPath());
|
||||||
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)
|
if (hModule == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -791,17 +562,10 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||||
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
|
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
|
||||||
if (pProc == NULL)
|
if (pProc == NULL)
|
||||||
{
|
{
|
||||||
hr = ERROR_BAD_ENVIRONMENT; // better hrresult?
|
hr = ERROR_BAD_ENVIRONMENT;
|
||||||
goto Finished;
|
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
|
// 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
|
// 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
|
// first place. This is happening in an execute request handler and everyone waits
|
||||||
|
|
@ -811,7 +575,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||||
// set the callbacks
|
// set the callbacks
|
||||||
s_Application = this;
|
s_Application = this;
|
||||||
|
|
||||||
RunDotnetApplication(argv, pProc);
|
RunDotnetApplication(m_pConfig->QueryHostFxrArgCount(), m_pConfig->QueryHostFxrArguments(), pProc);
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
//
|
//
|
||||||
|
|
@ -862,19 +626,20 @@ Finished:
|
||||||
// Calls hostfxr_main with the hostfxr and application as arguments.
|
// Calls hostfxr_main with the hostfxr and application as arguments.
|
||||||
// Method should be called with only
|
// Method should be called with only
|
||||||
// Need to have __try / __except in methods that require unwinding.
|
// Need to have __try / __except in methods that require unwinding.
|
||||||
|
// Note, this will not
|
||||||
//
|
//
|
||||||
HRESULT
|
HRESULT
|
||||||
IN_PROCESS_APPLICATION::RunDotnetApplication(PCWSTR* argv, hostfxr_main_fn pProc)
|
IN_PROCESS_APPLICATION::RunDotnetApplication(DWORD argc, CONST PCWSTR* argv, hostfxr_main_fn pProc)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
m_ProcessExitCode = pProc(2, argv);
|
m_ProcessExitCode = pProc(argc, argv);
|
||||||
}
|
}
|
||||||
__except (FilterException(GetExceptionCode(), GetExceptionInformation()))
|
__except (FilterException(GetExceptionCode(), GetExceptionInformation()))
|
||||||
{
|
{
|
||||||
// TODO Log error message here.
|
// TODO Log error message here.
|
||||||
hr = E_FAIL;
|
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,11 @@ typedef void(*request_handler_cb) (int error, IHttpContext* pHttpContext, void*
|
||||||
typedef REQUEST_NOTIFICATION_STATUS(*PFN_REQUEST_HANDLER) (IN_PROCESS_HANDLER* pInProcessHandler, void* pvRequestHandlerContext);
|
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[]);
|
|
||||||
|
|
||||||
class IN_PROCESS_APPLICATION : public APPLICATION
|
class IN_PROCESS_APPLICATION : public APPLICATION
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IN_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG *pConfig);
|
IN_PROCESS_APPLICATION(IHttpServer* pHttpServer, ASPNETCORE_CONFIG* pConfig);
|
||||||
|
|
||||||
~IN_PROCESS_APPLICATION();
|
~IN_PROCESS_APPLICATION();
|
||||||
|
|
||||||
|
|
@ -59,16 +58,6 @@ public:
|
||||||
IN_PROCESS_HANDLER* pInProcessHandler
|
IN_PROCESS_HANDLER* pInProcessHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
static
|
|
||||||
INT
|
|
||||||
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
RunDotnetApplication(
|
|
||||||
PCWSTR* argv,
|
|
||||||
hostfxr_main_fn pProc
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
static
|
||||||
IN_PROCESS_APPLICATION*
|
IN_PROCESS_APPLICATION*
|
||||||
GetInstance(
|
GetInstance(
|
||||||
|
|
@ -120,35 +109,20 @@ private:
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
static
|
|
||||||
VOID
|
|
||||||
FindDotNetFolders(
|
|
||||||
_In_ PCWSTR pszPath,
|
|
||||||
_Out_ std::vector<std::wstring> *pvFolders
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
|
||||||
HRESULT
|
|
||||||
FindHighestDotNetVersion(
|
|
||||||
_In_ std::vector<std::wstring> vFolders,
|
|
||||||
_Out_ STRU *pstrResult
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
|
||||||
BOOL
|
|
||||||
DirectoryExists(
|
|
||||||
_In_ STRU *pstrPath //todo: this does not need to be stru, can be PCWSTR
|
|
||||||
);
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
GetEnv(
|
|
||||||
_In_ PCWSTR pszEnvironmentVariable,
|
|
||||||
_Out_ STRU *pstrResult
|
|
||||||
);
|
|
||||||
|
|
||||||
static
|
static
|
||||||
VOID
|
VOID
|
||||||
ExecuteAspNetCoreProcess(
|
ExecuteAspNetCoreProcess(
|
||||||
_In_ LPVOID pContext
|
_In_ LPVOID pContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
INT
|
||||||
|
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
RunDotnetApplication(
|
||||||
|
DWORD argc,
|
||||||
|
CONST PCWSTR* argv,
|
||||||
|
hostfxr_main_fn pProc
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -127,7 +127,7 @@ struct IISConfigurationData
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
||||||
HRESULT // TODO probably should make this a wide string
|
HRESULT
|
||||||
http_get_application_properties(
|
http_get_application_properties(
|
||||||
_In_ IISConfigurationData* pIISCofigurationData
|
_In_ IISConfigurationData* pIISCofigurationData
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue