From 786e3ace86b65d58d443126779323aac40bd207a Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 24 May 2019 10:55:34 -0700 Subject: [PATCH 01/23] very light work --- .../CommonLib/HostFxrResolver.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index 45e3699fadc3..ca73e65fdf56 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -11,9 +11,12 @@ #include "Environment.h" #include "StringHelpers.h" #include "RegistryKey.h" +#include "ModuleHelpers.h" namespace fs = std::filesystem; +typedef INT(*get_hostfxr_path) (PWSTR buffer, DWORD* bufferSize, PCWSTR assemblyPath); + void HostFxrResolver::GetHostFxrParameters( const fs::path &processPath, @@ -46,7 +49,36 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(format(L"Process path '%s' doesn't have '.exe' extension.", expandedProcessPath.c_str())); } + // C:\Users\jukotali\Downloads\nethostbits + // call load dll and see what happens :) + auto moduleHandle = LoadLibrary(L"C:\\Users\\jukotali\\Downloads\\nethostbits\\nethost.dll"); + auto getHostfxrPath = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); + std::wstring test; + DWORD size = 500; + test.resize(500); + // pass in dllPath here? + std::wstring appDll; + if (expandedApplicationArguments.size() == 0) + { + // standalone + appDll = applicationPhysicalPath / fs::path(processPath).replace_extension(L"dll"); + } + else + { + // portable + appDll = applicationPhysicalPath / expandedApplicationArguments; + } + + getHostfxrPath(test.data(), &size, appDll.data()); + + test.resize(size); + // Check if the absolute path is to dotnet or not. + // Things to figure out: + // 1. what do we do with the dotnet path? Any reason for us to care? + // need to care to make sure a newer shim still has fast load times with old handler + // just create a reverse function? + // 2. Does this work with registry keys? if (IsDotnetExecutable(expandedProcessPath)) { LOG_INFOF(L"Process path '%ls' is dotnet, treating application as portable", expandedProcessPath.c_str()); From 048b870e914a919ae56bca044cc09f59dd36f0f0 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 24 May 2019 11:43:28 -0700 Subject: [PATCH 02/23] stop using dotnet.exe --- .vscode/settings.json | 62 ++++++++- .../AspNetCore/ApplicationFactory.h | 7 +- .../AspNetCore/HandlerResolver.cpp | 6 +- .../CommonLib/HostFxrResolutionResult.cpp | 13 +- .../CommonLib/HostFxrResolutionResult.h | 12 +- .../CommonLib/HostFxrResolver.cpp | 17 --- .../CommonLib/HostFxrResolver.h | 1 - .../CommonLibTests/hostfxr_utility_tests.cpp | 120 ++++++++++++++++++ .../inprocessapplication.cpp | 11 +- .../inprocessapplication.h | 8 -- 10 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json index 89a3c7cca0c7..b449516f4ac8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,66 @@ "*.*proj": "xml", "*.props": "xml", "*.targets": "xml", - "*.tasks": "xml" + "*.tasks": "xml", + "filesystem": "cpp", + "array": "cpp", + "initializer_list": "cpp", + "list": "cpp", + "random": "cpp", + "type_traits": "cpp", + "vector": "cpp", + "xhash": "cpp", + "xstring": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "algorithm": "cpp", + "atomic": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "cmath": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "fstream": "cpp", + "functional": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xtr1common": "cpp" } } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h index 23c5a67d409f..83426740f822 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h @@ -22,9 +22,8 @@ HRESULT class ApplicationFactory { public: - ApplicationFactory(HMODULE hRequestHandlerDll, std::wstring location, PFN_ASPNETCORE_CREATE_APPLICATION pfnAspNetCoreCreateApplication) noexcept: + ApplicationFactory(HMODULE hRequestHandlerDll, PFN_ASPNETCORE_CREATE_APPLICATION pfnAspNetCoreCreateApplication) noexcept: m_pfnAspNetCoreCreateApplication(pfnAspNetCoreCreateApplication), - m_location(std::move(location)), m_hRequestHandlerDll(hRequestHandlerDll) { } @@ -34,11 +33,8 @@ class ApplicationFactory _In_ IHttpContext *pHttpContext, _Outptr_ IAPPLICATION **pApplication) const { - // m_location.data() is const ptr copy to local to get mutable pointer - auto location = m_location; std::array parameters { { - {"InProcessExeLocation", location.data()}, {"TraceContext", pHttpContext->GetTraceContext()}, {"Site", pHttpContext->GetSite()} } @@ -49,6 +45,5 @@ class ApplicationFactory private: PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication; - std::wstring m_location; HandleWrapper m_hRequestHandlerDll; }; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp index bb4202398864..14e49c29f161 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp @@ -49,7 +49,6 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication pstrHandlerDllName = s_pwzAspnetcoreOutOfProcessRequestHandlerName; } HandleWrapper hRequestHandlerDll; - std::wstring location; std::wstring handlerDllPath; // Try to see if RH is already loaded, use GetModuleHandleEx to increment ref count if (!GetModuleHandleEx(0, pstrHandlerDllName, &hRequestHandlerDll)) @@ -60,15 +59,12 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication std::unique_ptr options; RETURN_IF_FAILED(HostFxrResolutionResult::Create( - L"", pConfiguration.QueryProcessPath(), pApplication.GetApplicationPhysicalPath(), pConfiguration.QueryArguments(), errorContext, options)); - location = options->GetDotnetExeLocation(); - auto redirectionOutput = std::make_shared(); hr = FindNativeAssemblyFromHostfxr(*options, pstrHandlerDllName, handlerDllPath, pApplication, pConfiguration, redirectionOutput, errorContext); @@ -120,7 +116,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication auto pfnAspNetCoreCreateApplication = ModuleHelpers::GetKnownProcAddress(hRequestHandlerDll, "CreateApplication"); RETURN_LAST_ERROR_IF_NULL(pfnAspNetCoreCreateApplication); - pApplicationFactory = std::make_unique(hRequestHandlerDll.release(), location, pfnAspNetCoreCreateApplication); + pApplicationFactory = std::make_unique(hRequestHandlerDll.release(), pfnAspNetCoreCreateApplication); return S_OK; } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp index 9a80749f2c70..c2c1e019b628 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp @@ -19,20 +19,12 @@ void HostFxrResolutionResult::GetArguments(DWORD& hostfxrArgc, std::unique_ptr

& ppWrapper) { - std::filesystem::path knownDotnetLocation; - - if (!pcwzDotnetExePath.empty()) - { - knownDotnetLocation = pcwzDotnetExePath; - } - try { std::filesystem::path hostFxrDllPath; @@ -42,16 +34,15 @@ HRESULT HostFxrResolutionResult::Create( pcwzApplicationPhysicalPath, pcwzArguments, hostFxrDllPath, - knownDotnetLocation, arguments, errorContext); - LOG_INFOF(L"Parsed hostfxr options: dotnet location: '%ls' hostfxr path: '%ls' arguments:", knownDotnetLocation.c_str(), hostFxrDllPath.c_str()); + LOG_INFOF(L"Parsed hostfxr options: hostfxr path: '%ls' arguments:", hostFxrDllPath.c_str()); for (size_t i = 0; i < arguments.size(); i++) { LOG_INFOF(L"Argument[%d] = '%ls'", i, arguments[i].c_str()); } - ppWrapper = std::make_unique(knownDotnetLocation, hostFxrDllPath, arguments); + ppWrapper = std::make_unique( hostFxrDllPath, arguments); } catch (InvalidOperationException &ex) { diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h index a0bbf1700356..849a94ec9eaa 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h @@ -16,12 +16,10 @@ class HostFxrResolutionResult { public: HostFxrResolutionResult( - std::filesystem::path dotnetExeLocation, std::filesystem::path hostFxrLocation, std::vector arguments ) noexcept - : m_dotnetExeLocation(std::move(dotnetExeLocation)), - m_hostFxrLocation(std::move(hostFxrLocation)), + : m_hostFxrLocation(std::move(hostFxrLocation)), m_arguments(std::move(arguments)) {} @@ -34,15 +32,8 @@ class HostFxrResolutionResult return m_hostFxrLocation; } - const std::filesystem::path& - GetDotnetExeLocation() const noexcept - { - return m_dotnetExeLocation; - } - static HRESULT Create( - _In_ const std::wstring& pcwzExeLocation, _In_ const std::wstring& pcwzProcessPath, _In_ const std::wstring& pcwzApplicationPhysicalPath, _In_ const std::wstring& pcwzArguments, @@ -50,7 +41,6 @@ class HostFxrResolutionResult _Out_ std::unique_ptr& ppWrapper); private: - const std::filesystem::path m_dotnetExeLocation; const std::filesystem::path m_hostFxrLocation; const std::vector m_arguments; }; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index ca73e65fdf56..fecb564bee02 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -23,7 +23,6 @@ HostFxrResolver::GetHostFxrParameters( const fs::path &applicationPhysicalPath, const std::wstring &applicationArguments, fs::path &hostFxrDllPath, - fs::path &dotnetExePath, std::vector &arguments, ErrorContext& errorContext ) @@ -37,8 +36,6 @@ HostFxrResolver::GetHostFxrParameters( fs::path expandedProcessPath = Environment::ExpandEnvironmentVariables(processPath); const auto expandedApplicationArguments = Environment::ExpandEnvironmentVariables(applicationArguments); - LOG_INFOF(L"Known dotnet.exe location: '%ls'", dotnetExePath.c_str()); - if (!expandedProcessPath.has_extension()) { // The only executable extension inprocess supports @@ -88,14 +85,6 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(L"Application arguments are empty."); } - if (dotnetExePath.empty()) - { - dotnetExePath = GetAbsolutePathToDotnet(applicationPhysicalPath, expandedProcessPath); - } - - hostFxrDllPath = GetAbsolutePathToHostFxr(dotnetExePath); - - arguments.push_back(dotnetExePath); AppendArguments( expandedApplicationArguments, applicationPhysicalPath, @@ -149,14 +138,8 @@ HostFxrResolver::GetHostFxrParameters( // passing "dotnet" here because we don't know where dotnet.exe should come from // so trying all fallbacks is appropriate - if (dotnetExePath.empty()) - { - dotnetExePath = GetAbsolutePathToDotnet(applicationPhysicalPath, L"dotnet"); - } - hostFxrDllPath = GetAbsolutePathToHostFxr(dotnetExePath); // For portable with launcher apps we need dotnet.exe to be argv[0] and .dll be argv[1] - arguments.push_back(dotnetExePath); arguments.push_back(applicationDllPath); } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h index 70f63fca6f90..183656ad3b07 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h @@ -24,7 +24,6 @@ class HostFxrResolver const std::filesystem::path &applicationPhysicalPath, const std::wstring &applicationArguments, std::filesystem::path &hostFxrDllPath, - std::filesystem::path &dotnetExePath, std::vector &arguments, ErrorContext& errorContext ); diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp new file mode 100644 index 000000000000..7614475ef6e7 --- /dev/null +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp @@ -0,0 +1,120 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +#include "stdafx.h" +#include +#include +#include +#include "HostFxrResolver.h" +#include "Environment.h" + +TEST(ParseHostFxrArguments, BasicHostFxrArguments) +{ + std::vector bstrArray; + + HostFxrResolver::AppendArguments( + L"exec \"test.dll\"", // args + L"invalid", // physical path to application + bstrArray); // args array. + + EXPECT_EQ(2, bstrArray.size()); + ASSERT_STREQ(L"exec", bstrArray[0].c_str()); + ASSERT_STREQ(L"test.dll", bstrArray[1].c_str()); +} + +TEST(ParseHostFxrArguments, NoExecProvided) +{ + std::vector bstrArray; + + HostFxrResolver::AppendArguments( + L"test.dll", // args + L"ignored", // physical path to application + bstrArray); // args array. + + EXPECT_EQ(1, bstrArray.size()); + ASSERT_STREQ(L"test.dll", bstrArray[0].c_str()); +} + +TEST(ParseHostFxrArguments, ConvertDllToAbsolutePath) +{ + std::vector bstrArray; + // we need to use existing dll so let's use ntdll that we know exists everywhere + auto system32 = Environment::ExpandEnvironmentVariables(L"%WINDIR%\\System32"); + HostFxrResolver::AppendArguments( + L"exec \"ntdll.dll\"", // args + system32, // physical path to application + bstrArray, // args array. + true); // expandDllPaths + + EXPECT_EQ(2, bstrArray.size()); + ASSERT_STREQ(L"exec", bstrArray[0].c_str()); + ASSERT_STREQ((system32 + L"\\ntdll.dll").c_str(), bstrArray[1].c_str()); +} + +TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs) +{ + std::vector bstrArray; + std::filesystem::path struHostFxrDllLocation; + + EXPECT_THROW(HostFxrResolver::GetHostFxrParameters( + L"dotnet", // processPath + L"some\\path", // application physical path, ignored. + L"", //arguments + struHostFxrDllLocation, + bstrArray), // args array. + InvalidOperationException); +} + +TEST(GetAbsolutePathToDotnetFromProgramFiles, BackupWorks) +{ + STRU struAbsolutePathToDotnet; + BOOL fDotnetInProgramFiles; + BOOL is64Bit; + BOOL fIsWow64 = FALSE; + SYSTEM_INFO systemInfo; + IsWow64Process(GetCurrentProcess(), &fIsWow64); + if (fIsWow64) + { + is64Bit = FALSE; + } + else + { + GetNativeSystemInfo(&systemInfo); + is64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; + } + + if (is64Bit) + { + fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files/dotnet/dotnet.exe"); + } + else + { + fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files (x86)/dotnet/dotnet.exe"); + } + + auto dotnetPath = HostFxrResolver::GetAbsolutePathToDotnetFromProgramFiles(); + if (fDotnetInProgramFiles) + { + EXPECT_TRUE(dotnetPath.has_value()); + } + else + { + EXPECT_FALSE(dotnetPath.has_value()); + } +} + +TEST(GetHostFxrArguments, InvalidParams) +{ + std::vector bstrArray; + std::filesystem::path struHostFxrDllLocation; + std::filesystem::path struExeLocation; + + EXPECT_THROW(HostFxrResolver::GetHostFxrParameters( + L"bogus", // processPath + L"", // application physical path, ignored. + L"ignored", //arguments + struHostFxrDllLocation, + struExeLocation, + bstrArray), // args array. + InvalidOperationException); +} diff --git a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp index 5707e4cd7728..608d9078797a 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp @@ -20,8 +20,8 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION( IHttpServer& pHttpServer, IHttpApplication& pApplication, std::unique_ptr pConfig, - APPLICATION_PARAMETER* pParameters, - DWORD nParameters) : + APPLICATION_PARAMETER* , + DWORD ) : InProcessApplicationBase(pHttpServer, pApplication), m_Initialized(false), m_blockManagedCallbacks(true), @@ -31,12 +31,6 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION( { DBG_ASSERT(m_pConfig); - const auto knownLocation = FindParameter(s_exeLocationParameterName, pParameters, nParameters); - if (knownLocation != nullptr) - { - m_dotnetExeKnownLocation = knownLocation; - } - m_stringRedirectionOutput = std::make_shared(); } @@ -200,7 +194,6 @@ IN_PROCESS_APPLICATION::ExecuteApplication() if (s_fMainCallback == nullptr) { THROW_IF_FAILED(HostFxrResolutionResult::Create( - m_dotnetExeKnownLocation, m_pConfig->QueryProcessPath(), QueryApplicationPhysicalPath(), m_pConfig->QueryArguments(), diff --git a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h index 4eda1fd7dadc..e3fd00238db2 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h @@ -88,12 +88,6 @@ class IN_PROCESS_APPLICATION : public InProcessApplicationBase return s_Application; } - const std::wstring& - QueryExeLocation() const - { - return m_dotnetExeKnownLocation; - } - const InProcessOptions& QueryConfig() const { @@ -162,8 +156,6 @@ class IN_PROCESS_APPLICATION : public InProcessApplicationBase PFN_DISCONNECT_HANDLER m_DisconnectHandler; std::atomic m_RequestsDrainedHandler; - std::wstring m_dotnetExeKnownLocation; - std::atomic_bool m_blockManagedCallbacks; bool m_Initialized; bool m_waitForShutdown; From 83ba7bc94e03e0bbc8b95af747f6e824473ac813 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 24 May 2019 12:54:09 -0700 Subject: [PATCH 03/23] nit --- .../CommonLib/HostFxrResolver.cpp | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index fecb564bee02..0475a5e8762c 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -46,29 +46,11 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(format(L"Process path '%s' doesn't have '.exe' extension.", expandedProcessPath.c_str())); } - // C:\Users\jukotali\Downloads\nethostbits // call load dll and see what happens :) + // TODO make sure we figure out a way to load this dll sxs + // TODO error handling auto moduleHandle = LoadLibrary(L"C:\\Users\\jukotali\\Downloads\\nethostbits\\nethost.dll"); auto getHostfxrPath = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); - std::wstring test; - DWORD size = 500; - test.resize(500); - // pass in dllPath here? - std::wstring appDll; - if (expandedApplicationArguments.size() == 0) - { - // standalone - appDll = applicationPhysicalPath / fs::path(processPath).replace_extension(L"dll"); - } - else - { - // portable - appDll = applicationPhysicalPath / expandedApplicationArguments; - } - - getHostfxrPath(test.data(), &size, appDll.data()); - - test.resize(size); // Check if the absolute path is to dotnet or not. // Things to figure out: @@ -85,11 +67,20 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(L"Application arguments are empty."); } + std::wstring test; + DWORD size = 500; + test.resize(size); + AppendArguments( expandedApplicationArguments, applicationPhysicalPath, arguments, true); + + getHostfxrPath(test.data(), &size, arguments[0].c_str()); + + test.resize(size); // todo maybe +1 for nullchar + hostFxrDllPath = test; } else { @@ -135,12 +126,18 @@ HostFxrResolver::GetHostFxrParameters( else { LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str()); + std::wstring test; + DWORD size = 500; + test.resize(size); // passing "dotnet" here because we don't know where dotnet.exe should come from // so trying all fallbacks is appropriate - // For portable with launcher apps we need dotnet.exe to be argv[0] and .dll be argv[1] arguments.push_back(applicationDllPath); + getHostfxrPath(test.data(), &size, applicationDllPath.c_str()); + + test.resize(size); // todo maybe +1 for nullchar + hostFxrDllPath = test; } AppendArguments( From db12f53bb5261d60e16155d9a62115e9056c62dd Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 24 May 2019 14:00:45 -0700 Subject: [PATCH 04/23] Realizing we still need dotnet path :( --- .../CommonLib/HostFxrResolver.cpp | 19 +++++++++++++++---- .../CommonLib/HostFxrResolver.h | 4 ++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index 0475a5e8762c..194079df51e4 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -15,7 +15,7 @@ namespace fs = std::filesystem; -typedef INT(*get_hostfxr_path) (PWSTR buffer, DWORD* bufferSize, PCWSTR assemblyPath); +typedef INT(*get_hostfxr_path) (PWSTR buffer, size_t* bufferSize, PCWSTR assemblyPath); void HostFxrResolver::GetHostFxrParameters( @@ -68,7 +68,7 @@ HostFxrResolver::GetHostFxrParameters( } std::wstring test; - DWORD size = 500; + size_t size = 500; test.resize(size); AppendArguments( @@ -81,6 +81,8 @@ HostFxrResolver::GetHostFxrParameters( test.resize(size); // todo maybe +1 for nullchar hostFxrDllPath = test; + + arguments.insert(arguments.begin(), GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath)); } else { @@ -127,17 +129,20 @@ HostFxrResolver::GetHostFxrParameters( { LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str()); std::wstring test; - DWORD size = 500; + size_t size = 500; test.resize(size); // passing "dotnet" here because we don't know where dotnet.exe should come from // so trying all fallbacks is appropriate // For portable with launcher apps we need dotnet.exe to be argv[0] and .dll be argv[1] - arguments.push_back(applicationDllPath); + getHostfxrPath(test.data(), &size, applicationDllPath.c_str()); test.resize(size); // todo maybe +1 for nullchar hostFxrDllPath = test; + + arguments.push_back(GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath)); + arguments.push_back(applicationDllPath); } AppendArguments( @@ -323,6 +328,12 @@ HostFxrResolver::GetAbsolutePathToDotnet( processPath.c_str())); } +fs::path +HostFxrResolver::GetAbsolutePathToDotnetFromHostfxr(const fs::path& hostfxrPath) +{ + return hostfxrPath.parent_path().parent_path().parent_path().parent_path() / "dotnet.exe"; +} + fs::path HostFxrResolver::GetAbsolutePathToHostFxr( const fs::path & dotnetPath diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h index 183656ad3b07..2010d416d32b 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h @@ -67,6 +67,10 @@ class HostFxrResolver const std::filesystem::path & dotnetPath ); + static + std::filesystem::path + GetAbsolutePathToDotnetFromHostfxr(const std::filesystem::path& hostfxrPath); + static std::optional InvokeWhereToFindDotnet(); From 2bff3a6ea9948a571a64b14bf7e3f1f091664900 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 24 May 2019 14:06:08 -0700 Subject: [PATCH 05/23] Reverting dotnet stuff --- .vscode/settings.json | 5 ++++- .../AspNetCore/ApplicationFactory.h | 7 ++++++- .../AspNetCore/HandlerResolver.cpp | 6 +++++- .../CommonLib/HostFxrResolutionResult.cpp | 13 +++++++++++-- .../CommonLib/HostFxrResolutionResult.h | 12 +++++++++++- .../CommonLib/HostFxrResolver.cpp | 10 +++++++--- .../AspNetCoreModuleV2/CommonLib/HostFxrResolver.h | 1 + .../CommonLibTests/hostfxr_utility_tests.cpp | 2 ++ .../inprocessapplication.cpp | 11 +++++++++-- .../InProcessRequestHandler/inprocessapplication.h | 8 ++++++++ 10 files changed, 64 insertions(+), 11 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index b449516f4ac8..14126dac8b89 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -64,6 +64,9 @@ "xloctime": "cpp", "xmemory": "cpp", "xstddef": "cpp", - "xtr1common": "cpp" + "xtr1common": "cpp", + "iostream": "cpp", + "set": "cpp", + "sstream": "cpp" } } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h index 83426740f822..23c5a67d409f 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h @@ -22,8 +22,9 @@ HRESULT class ApplicationFactory { public: - ApplicationFactory(HMODULE hRequestHandlerDll, PFN_ASPNETCORE_CREATE_APPLICATION pfnAspNetCoreCreateApplication) noexcept: + ApplicationFactory(HMODULE hRequestHandlerDll, std::wstring location, PFN_ASPNETCORE_CREATE_APPLICATION pfnAspNetCoreCreateApplication) noexcept: m_pfnAspNetCoreCreateApplication(pfnAspNetCoreCreateApplication), + m_location(std::move(location)), m_hRequestHandlerDll(hRequestHandlerDll) { } @@ -33,8 +34,11 @@ class ApplicationFactory _In_ IHttpContext *pHttpContext, _Outptr_ IAPPLICATION **pApplication) const { + // m_location.data() is const ptr copy to local to get mutable pointer + auto location = m_location; std::array parameters { { + {"InProcessExeLocation", location.data()}, {"TraceContext", pHttpContext->GetTraceContext()}, {"Site", pHttpContext->GetSite()} } @@ -45,5 +49,6 @@ class ApplicationFactory private: PFN_ASPNETCORE_CREATE_APPLICATION m_pfnAspNetCoreCreateApplication; + std::wstring m_location; HandleWrapper m_hRequestHandlerDll; }; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp index 14e49c29f161..bb4202398864 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp @@ -49,6 +49,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication pstrHandlerDllName = s_pwzAspnetcoreOutOfProcessRequestHandlerName; } HandleWrapper hRequestHandlerDll; + std::wstring location; std::wstring handlerDllPath; // Try to see if RH is already loaded, use GetModuleHandleEx to increment ref count if (!GetModuleHandleEx(0, pstrHandlerDllName, &hRequestHandlerDll)) @@ -59,12 +60,15 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication std::unique_ptr options; RETURN_IF_FAILED(HostFxrResolutionResult::Create( + L"", pConfiguration.QueryProcessPath(), pApplication.GetApplicationPhysicalPath(), pConfiguration.QueryArguments(), errorContext, options)); + location = options->GetDotnetExeLocation(); + auto redirectionOutput = std::make_shared(); hr = FindNativeAssemblyFromHostfxr(*options, pstrHandlerDllName, handlerDllPath, pApplication, pConfiguration, redirectionOutput, errorContext); @@ -116,7 +120,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication auto pfnAspNetCoreCreateApplication = ModuleHelpers::GetKnownProcAddress(hRequestHandlerDll, "CreateApplication"); RETURN_LAST_ERROR_IF_NULL(pfnAspNetCoreCreateApplication); - pApplicationFactory = std::make_unique(hRequestHandlerDll.release(), pfnAspNetCoreCreateApplication); + pApplicationFactory = std::make_unique(hRequestHandlerDll.release(), location, pfnAspNetCoreCreateApplication); return S_OK; } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp index c2c1e019b628..9a80749f2c70 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp @@ -19,12 +19,20 @@ void HostFxrResolutionResult::GetArguments(DWORD& hostfxrArgc, std::unique_ptr

& ppWrapper) { + std::filesystem::path knownDotnetLocation; + + if (!pcwzDotnetExePath.empty()) + { + knownDotnetLocation = pcwzDotnetExePath; + } + try { std::filesystem::path hostFxrDllPath; @@ -34,15 +42,16 @@ HRESULT HostFxrResolutionResult::Create( pcwzApplicationPhysicalPath, pcwzArguments, hostFxrDllPath, + knownDotnetLocation, arguments, errorContext); - LOG_INFOF(L"Parsed hostfxr options: hostfxr path: '%ls' arguments:", hostFxrDllPath.c_str()); + LOG_INFOF(L"Parsed hostfxr options: dotnet location: '%ls' hostfxr path: '%ls' arguments:", knownDotnetLocation.c_str(), hostFxrDllPath.c_str()); for (size_t i = 0; i < arguments.size(); i++) { LOG_INFOF(L"Argument[%d] = '%ls'", i, arguments[i].c_str()); } - ppWrapper = std::make_unique( hostFxrDllPath, arguments); + ppWrapper = std::make_unique(knownDotnetLocation, hostFxrDllPath, arguments); } catch (InvalidOperationException &ex) { diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h index 849a94ec9eaa..a0bbf1700356 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h @@ -16,10 +16,12 @@ class HostFxrResolutionResult { public: HostFxrResolutionResult( + std::filesystem::path dotnetExeLocation, std::filesystem::path hostFxrLocation, std::vector arguments ) noexcept - : m_hostFxrLocation(std::move(hostFxrLocation)), + : m_dotnetExeLocation(std::move(dotnetExeLocation)), + m_hostFxrLocation(std::move(hostFxrLocation)), m_arguments(std::move(arguments)) {} @@ -32,8 +34,15 @@ class HostFxrResolutionResult return m_hostFxrLocation; } + const std::filesystem::path& + GetDotnetExeLocation() const noexcept + { + return m_dotnetExeLocation; + } + static HRESULT Create( + _In_ const std::wstring& pcwzExeLocation, _In_ const std::wstring& pcwzProcessPath, _In_ const std::wstring& pcwzApplicationPhysicalPath, _In_ const std::wstring& pcwzArguments, @@ -41,6 +50,7 @@ class HostFxrResolutionResult _Out_ std::unique_ptr& ppWrapper); private: + const std::filesystem::path m_dotnetExeLocation; const std::filesystem::path m_hostFxrLocation; const std::vector m_arguments; }; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index 194079df51e4..c937b5c18d76 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -23,6 +23,7 @@ HostFxrResolver::GetHostFxrParameters( const fs::path &applicationPhysicalPath, const std::wstring &applicationArguments, fs::path &hostFxrDllPath, + fs::path &dotnetExePath, std::vector &arguments, ErrorContext& errorContext ) @@ -36,6 +37,8 @@ HostFxrResolver::GetHostFxrParameters( fs::path expandedProcessPath = Environment::ExpandEnvironmentVariables(processPath); const auto expandedApplicationArguments = Environment::ExpandEnvironmentVariables(applicationArguments); + LOG_INFOF(L"Known dotnet.exe location: '%ls'", dotnetExePath.c_str()); + if (!expandedProcessPath.has_extension()) { // The only executable extension inprocess supports @@ -81,8 +84,8 @@ HostFxrResolver::GetHostFxrParameters( test.resize(size); // todo maybe +1 for nullchar hostFxrDllPath = test; - - arguments.insert(arguments.begin(), GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath)); + dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); + arguments.insert(arguments.begin(), dotnetExePath); } else { @@ -141,7 +144,8 @@ HostFxrResolver::GetHostFxrParameters( test.resize(size); // todo maybe +1 for nullchar hostFxrDllPath = test; - arguments.push_back(GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath)); + dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); + arguments.push_back(dotnetExePath); arguments.push_back(applicationDllPath); } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h index 2010d416d32b..5a465fd3ba92 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h @@ -24,6 +24,7 @@ class HostFxrResolver const std::filesystem::path &applicationPhysicalPath, const std::wstring &applicationArguments, std::filesystem::path &hostFxrDllPath, + std::filesystem::path &dotnetExePath, std::vector &arguments, ErrorContext& errorContext ); diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp index 7614475ef6e7..31ddd86dc471 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp @@ -55,12 +55,14 @@ TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs) { std::vector bstrArray; std::filesystem::path struHostFxrDllLocation; + std::filesystem::path struExeLocation; EXPECT_THROW(HostFxrResolver::GetHostFxrParameters( L"dotnet", // processPath L"some\\path", // application physical path, ignored. L"", //arguments struHostFxrDllLocation, + struExeLocation, bstrArray), // args array. InvalidOperationException); } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp index 608d9078797a..5707e4cd7728 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp @@ -20,8 +20,8 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION( IHttpServer& pHttpServer, IHttpApplication& pApplication, std::unique_ptr pConfig, - APPLICATION_PARAMETER* , - DWORD ) : + APPLICATION_PARAMETER* pParameters, + DWORD nParameters) : InProcessApplicationBase(pHttpServer, pApplication), m_Initialized(false), m_blockManagedCallbacks(true), @@ -31,6 +31,12 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION( { DBG_ASSERT(m_pConfig); + const auto knownLocation = FindParameter(s_exeLocationParameterName, pParameters, nParameters); + if (knownLocation != nullptr) + { + m_dotnetExeKnownLocation = knownLocation; + } + m_stringRedirectionOutput = std::make_shared(); } @@ -194,6 +200,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication() if (s_fMainCallback == nullptr) { THROW_IF_FAILED(HostFxrResolutionResult::Create( + m_dotnetExeKnownLocation, m_pConfig->QueryProcessPath(), QueryApplicationPhysicalPath(), m_pConfig->QueryArguments(), diff --git a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h index e3fd00238db2..4eda1fd7dadc 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h @@ -88,6 +88,12 @@ class IN_PROCESS_APPLICATION : public InProcessApplicationBase return s_Application; } + const std::wstring& + QueryExeLocation() const + { + return m_dotnetExeKnownLocation; + } + const InProcessOptions& QueryConfig() const { @@ -156,6 +162,8 @@ class IN_PROCESS_APPLICATION : public InProcessApplicationBase PFN_DISCONNECT_HANDLER m_DisconnectHandler; std::atomic m_RequestsDrainedHandler; + std::wstring m_dotnetExeKnownLocation; + std::atomic_bool m_blockManagedCallbacks; bool m_Initialized; bool m_waitForShutdown; From 77aa2112a7b938254c1606dc7c17dbea95432d50 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 24 May 2019 14:15:21 -0700 Subject: [PATCH 06/23] Get things working --- .../CommonLib/HostFxrResolver.cpp | 330 +----------------- .../CommonLib/HostFxrResolver.h | 33 -- .../CommonLibTests/hostfxr_utility_tests.cpp | 38 -- 3 files changed, 5 insertions(+), 396 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index c937b5c18d76..9f67ea1e6356 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -80,6 +80,7 @@ HostFxrResolver::GetHostFxrParameters( arguments, true); + // TODO need to check if args[0] is a dll or not. getHostfxrPath(test.data(), &size, arguments[0].c_str()); test.resize(size); // todo maybe +1 for nullchar @@ -165,12 +166,6 @@ HostFxrResolver::GetHostFxrParameters( } } -BOOL -HostFxrResolver::IsDotnetExecutable(const std::filesystem::path & dotnetPath) -{ - return ends_with(dotnetPath, L"dotnet.exe", true); -} - void HostFxrResolver::AppendArguments( const std::wstring &applicationArguments, @@ -240,330 +235,15 @@ HostFxrResolver::AppendArguments( } } -// The processPath ends with dotnet.exe or dotnet -// like: C:\Program Files\dotnet\dotnet.exe, C:\Program Files\dotnet\dotnet, dotnet.exe, or dotnet. -// Get the absolute path to dotnet. If the path is already an absolute path, it will return that path -fs::path -HostFxrResolver::GetAbsolutePathToDotnet( - const fs::path & applicationPath, - const fs::path & requestedPath -) -{ - LOG_INFOF(L"Resolving absolute path to dotnet.exe from '%ls'", requestedPath.c_str()); - - auto processPath = requestedPath; - if (processPath.is_relative()) - { - processPath = applicationPath / processPath; - } - - // - // If we are given an absolute path to dotnet.exe, we are done - // - if (is_regular_file(processPath)) - { - LOG_INFOF(L"Found dotnet.exe at '%ls'", processPath.c_str()); - - return processPath; - } - - // At this point, we are calling where.exe to find dotnet. - // If we encounter any failures, try getting dotnet.exe from the - // backup location. - // Only do it if no path is specified - if (requestedPath.has_parent_path()) - { - LOG_INFOF(L"Absolute path to dotnet.exe was not found at '%ls'", requestedPath.c_str()); - - throw InvalidOperationException(format(L"Could not find dotnet.exe at '%s'", processPath.c_str())); - } - - const auto dotnetViaWhere = InvokeWhereToFindDotnet(); - if (dotnetViaWhere.has_value()) - { - LOG_INFOF(L"Found dotnet.exe via where.exe invocation at '%ls'", dotnetViaWhere.value().c_str()); - - return dotnetViaWhere.value(); - } - - auto isWow64Process = Environment::IsRunning64BitProcess(); - - std::wstring regKeySubSection; - - if (isWow64Process) - { - regKeySubSection = L"SOFTWARE\\WOW6432Node\\dotnet\\Setup\\InstalledVersions\\x64"; - } - else - { - regKeySubSection = L"SOFTWARE\\dotnet\\Setup\\InstalledVersions\\x86"; - } - - const auto installationLocation = RegistryKey::TryGetString( - HKEY_LOCAL_MACHINE, - regKeySubSection, - L"InstallLocation"); - - if (installationLocation.has_value()) - { - LOG_INFOF(L"InstallLocation registry key is set to '%ls'", installationLocation.value().c_str()); - - auto const installationLocationDotnet = fs::path(installationLocation.value()) / "dotnet.exe"; - - if (is_regular_file(installationLocationDotnet)) - { - LOG_INFOF(L"Found dotnet.exe in InstallLocation at '%ls'", installationLocationDotnet.c_str()); - return installationLocationDotnet; - } - } - - const auto programFilesLocation = GetAbsolutePathToDotnetFromProgramFiles(); - if (programFilesLocation.has_value()) - { - LOG_INFOF(L"Found dotnet.exe in Program Files at '%ls'", programFilesLocation.value().c_str()); - - return programFilesLocation.value(); - } - - LOG_INFOF(L"dotnet.exe not found"); - throw InvalidOperationException(format( - L"Could not find dotnet.exe at '%s' or using the system PATH environment variable." - " Check that a valid path to dotnet is on the PATH and the bitness of dotnet matches the bitness of the IIS worker process.", - processPath.c_str())); -} - fs::path HostFxrResolver::GetAbsolutePathToDotnetFromHostfxr(const fs::path& hostfxrPath) { return hostfxrPath.parent_path().parent_path().parent_path().parent_path() / "dotnet.exe"; } -fs::path -HostFxrResolver::GetAbsolutePathToHostFxr( - const fs::path & dotnetPath -) -{ - std::vector versionFolders; - const auto hostFxrBase = dotnetPath.parent_path() / "host" / "fxr"; - - LOG_INFOF(L"Resolving absolute path to hostfxr.dll from '%ls'", dotnetPath.c_str()); - - if (!is_directory(hostFxrBase)) - { - throw InvalidOperationException(format(L"Unable to find hostfxr directory at %s", hostFxrBase.c_str())); - } - - FindDotNetFolders(hostFxrBase, versionFolders); - - if (versionFolders.empty()) - { - throw InvalidOperationException(format(L"Hostfxr directory '%s' doesn't contain any version subdirectories", hostFxrBase.c_str())); - } - - const auto highestVersion = FindHighestDotNetVersion(versionFolders); - const auto hostFxrPath = hostFxrBase / highestVersion / "hostfxr.dll"; - - if (!is_regular_file(hostFxrPath)) - { - throw InvalidOperationException(format(L"hostfxr.dll not found at '%s'", hostFxrPath.c_str())); - } - - LOG_INFOF(L"hostfxr.dll located at '%ls'", hostFxrPath.c_str()); - return hostFxrPath; -} - -// -// Tries to call where.exe to find the location of dotnet.exe. -// Will check that the bitness of dotnet matches the current -// worker process bitness. -// Returns true if a valid dotnet was found, else false.R -// -std::optional -HostFxrResolver::InvokeWhereToFindDotnet() -{ - HRESULT hr = S_OK; - // Arguments to call where.exe - STARTUPINFOW startupInfo = { 0 }; - PROCESS_INFORMATION processInformation = { 0 }; - SECURITY_ATTRIBUTES securityAttributes; - - CHAR pzFileContents[READ_BUFFER_SIZE]; - HandleWrapper hStdOutReadPipe; - HandleWrapper hStdOutWritePipe; - HandleWrapper hProcess; - HandleWrapper hThread; - CComBSTR pwzDotnetName = NULL; - DWORD dwFilePointer; - BOOL fIsCurrentProcess64Bit; - DWORD dwExitCode; - STRU struDotnetSubstring; - STRU struDotnetLocationsString; - DWORD dwNumBytesRead; - DWORD dwBinaryType; - INT index = 0; - INT prevIndex = 0; - std::optional result; - - // Set the security attributes for the read/write pipe - securityAttributes.nLength = sizeof(securityAttributes); - securityAttributes.lpSecurityDescriptor = NULL; - securityAttributes.bInheritHandle = TRUE; - - LOG_INFO(L"Invoking where.exe to find dotnet.exe"); - - // Create a read/write pipe that will be used for reading the result of where.exe - FINISHED_LAST_ERROR_IF(!CreatePipe(&hStdOutReadPipe, &hStdOutWritePipe, &securityAttributes, 0)); - FINISHED_LAST_ERROR_IF(!SetHandleInformation(hStdOutReadPipe, HANDLE_FLAG_INHERIT, 0)); - - // Set the stdout and err pipe to the write pipes. - startupInfo.cb = sizeof(startupInfo); - startupInfo.dwFlags |= STARTF_USESTDHANDLES; - startupInfo.hStdOutput = hStdOutWritePipe; - startupInfo.hStdError = hStdOutWritePipe; - - // CreateProcess requires a mutable string to be passed to commandline - // See https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083/ - pwzDotnetName = L"\"where.exe\" dotnet.exe"; - - // Create a process to invoke where.exe - FINISHED_LAST_ERROR_IF(!CreateProcessW(NULL, - pwzDotnetName, - NULL, - NULL, - TRUE, - CREATE_NO_WINDOW, - NULL, - NULL, - &startupInfo, - &processInformation - )); - - // Store handles into wrapper so they get closed automatically - hProcess = processInformation.hProcess; - hThread = processInformation.hThread; - - // Wait for where.exe to return - WaitForSingleObject(processInformation.hProcess, INFINITE); - - // - // where.exe will return 0 on success, 1 if the file is not found - // and 2 if there was an error. Check if the exit code is 1 and set - // a new hr result saying it couldn't find dotnet.exe - // - FINISHED_LAST_ERROR_IF (!GetExitCodeProcess(processInformation.hProcess, &dwExitCode)); - - // - // In this block, if anything fails, we will goto our fallback of - // looking in C:/Program Files/ - // - if (dwExitCode != 0) - { - FINISHED_IF_FAILED(E_FAIL); - } - - // Where succeeded. - // Reset file pointer to the beginning of the file. - dwFilePointer = SetFilePointer(hStdOutReadPipe, 0, NULL, FILE_BEGIN); - if (dwFilePointer == INVALID_SET_FILE_POINTER) - { - FINISHED_IF_FAILED(E_FAIL); - } - - // - // As the call to where.exe succeeded (dotnet.exe was found), ReadFile should not hang. - // TODO consider putting ReadFile in a separate thread with a timeout to guarantee it doesn't block. - // - FINISHED_LAST_ERROR_IF (!ReadFile(hStdOutReadPipe, pzFileContents, READ_BUFFER_SIZE, &dwNumBytesRead, NULL)); - - if (dwNumBytesRead >= READ_BUFFER_SIZE) - { - // This shouldn't ever be this large. We could continue to call ReadFile in a loop, - // however if someone had this many dotnet.exes on their machine. - FINISHED_IF_FAILED(E_FAIL); - } - - FINISHED_IF_FAILED(struDotnetLocationsString.CopyA(pzFileContents, dwNumBytesRead)); - - LOG_INFOF(L"where.exe invocation returned: '%ls'", struDotnetLocationsString.QueryStr()); - - fIsCurrentProcess64Bit = Environment::IsRunning64BitProcess(); - - LOG_INFOF(L"Current process bitness type detected as isX64=%d", fIsCurrentProcess64Bit); - - while (TRUE) - { - index = struDotnetLocationsString.IndexOf(L"\r\n", prevIndex); - if (index == -1) - { - break; - } - - FINISHED_IF_FAILED(struDotnetSubstring.Copy(&struDotnetLocationsString.QueryStr()[prevIndex], index - prevIndex)); - // \r\n is two wchars, so add 2 here. - prevIndex = index + 2; - - LOG_INFOF(L"Processing entry '%ls'", struDotnetSubstring.QueryStr()); - - if (LOG_LAST_ERROR_IF(!GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType))) - { - continue; - } - - LOG_INFOF(L"Binary type %d", dwBinaryType); - - if (fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY)) - { - // The bitness of dotnet matched with the current worker process bitness. - return std::make_optional(struDotnetSubstring.QueryStr()); - } - } - - Finished: - return result; -} - -std::optional -HostFxrResolver::GetAbsolutePathToDotnetFromProgramFiles() -{ - const auto programFilesDotnet = fs::path(Environment::ExpandEnvironmentVariables(L"%ProgramFiles%")) / "dotnet" / "dotnet.exe"; - return is_regular_file(programFilesDotnet) ? std::make_optional(programFilesDotnet) : std::nullopt; -} - -std::wstring -HostFxrResolver::FindHighestDotNetVersion( - _In_ std::vector & vFolders -) -{ - 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 = max(max_ver, fx_ver); - } - } - - return max_ver.as_str(); -} - -VOID -HostFxrResolver::FindDotNetFolders( - const std::filesystem::path &path, - _Out_ std::vector &pvFolders -) +BOOL +HostFxrResolver::IsDotnetExecutable(const std::filesystem::path& dotnetPath) { - WIN32_FIND_DATAW data = {}; - const auto searchPattern = std::wstring(path) + L"\\*"; - HandleWrapper handle = FindFirstFileExW(searchPattern.c_str(), FindExInfoStandard, &data, FindExSearchNameMatch, nullptr, 0); - if (handle == INVALID_HANDLE_VALUE) - { - LOG_LAST_ERROR(); - return; - } - - do - { - pvFolders.emplace_back(data.cFileName); - } while (FindNextFileW(handle, &data)); + // TODO this probably should check the path is dotnet for program files. + return ends_with(dotnetPath, L"dotnet.exe", true); } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h index 5a465fd3ba92..ac7fe2dfd8b1 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h @@ -38,9 +38,6 @@ class HostFxrResolver bool expandDllPaths = false ); - static - std::optional - GetAbsolutePathToDotnetFromProgramFiles(); private: static @@ -49,40 +46,10 @@ class HostFxrResolver const std::filesystem::path & dotnetPath ); - static - VOID - FindDotNetFolders( - const std::filesystem::path& path, - std::vector & pvFolders - ); - - static - std::wstring - FindHighestDotNetVersion( - std::vector & vFolders - ); - - static - std::filesystem::path - GetAbsolutePathToHostFxr( - const std::filesystem::path & dotnetPath - ); - static std::filesystem::path GetAbsolutePathToDotnetFromHostfxr(const std::filesystem::path& hostfxrPath); - static - std::optional - InvokeWhereToFindDotnet(); - - static - std::filesystem::path - GetAbsolutePathToDotnet( - const std::filesystem::path & applicationPath, - const std::filesystem::path & requestedPath - ); - struct LocalFreeDeleter { void operator ()(_In_ LPWSTR* ptr) const diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp index 31ddd86dc471..6db158693b9c 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp @@ -67,44 +67,6 @@ TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs) InvalidOperationException); } -TEST(GetAbsolutePathToDotnetFromProgramFiles, BackupWorks) -{ - STRU struAbsolutePathToDotnet; - BOOL fDotnetInProgramFiles; - BOOL is64Bit; - BOOL fIsWow64 = FALSE; - SYSTEM_INFO systemInfo; - IsWow64Process(GetCurrentProcess(), &fIsWow64); - if (fIsWow64) - { - is64Bit = FALSE; - } - else - { - GetNativeSystemInfo(&systemInfo); - is64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; - } - - if (is64Bit) - { - fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files/dotnet/dotnet.exe"); - } - else - { - fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files (x86)/dotnet/dotnet.exe"); - } - - auto dotnetPath = HostFxrResolver::GetAbsolutePathToDotnetFromProgramFiles(); - if (fDotnetInProgramFiles) - { - EXPECT_TRUE(dotnetPath.has_value()); - } - else - { - EXPECT_FALSE(dotnetPath.has_value()); - } -} - TEST(GetHostFxrArguments, InvalidParams) { std::vector bstrArray; From b67ded903d17bea0159f6e1cbca32178e0706940 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 28 May 2019 13:10:20 -0700 Subject: [PATCH 07/23] fix a few tests --- .../test/Common.FunctionalTests/Inprocess/StartupTests.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs index 11467d4424bc..1f74326e3f00 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -44,8 +44,8 @@ public async Task ExpandEnvironmentVariableInWebConfig() [ConditionalTheory] [InlineData("bogus", "", @"Executable was not found at '.*?\\bogus.exe")] - [InlineData("c:\\random files\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\dotnet.exe'")] - [InlineData(".\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\.\\dotnet.exe'")] + [InlineData("c:\\random files\\dotnet.exe", "something.dll", "")] + [InlineData(".\\dotnet.exe", "something.dll", "")] [InlineData("dotnet.exe", "", @"Application arguments are empty.")] [InlineData("dotnet.zip", "", @"Process path 'dotnet.zip' doesn't have '.exe' extension.")] public async Task InvalidProcessPath_ExpectServerError(string path, string arguments, string subError) @@ -104,8 +104,6 @@ public async Task StartsWithDotnetOnThePath(string path) await deploymentResult.AssertStarts(); StopServer(); - // Verify that in this scenario where.exe was invoked only once by shim and request handler uses cached value - Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains("Invoking where.exe to find dotnet.exe"))); } [ConditionalTheory] @@ -140,7 +138,6 @@ public async Task StartsWithDotnetInstallLocation(RuntimeArchitecture runtimeArc // Verify that in this scenario dotnet.exe was found using InstallLocation lookup // I would've liked to make a copy of dotnet directory in this test and use it for verification // but dotnet roots are usually very large on dev machines so this test would take disproportionally long time and disk space - Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains($"Found dotnet.exe in InstallLocation at '{installDir}\\dotnet.exe'"))); } } } From 8731339bdb51b2b39965fd70bc4f061cfb308b47 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 29 May 2019 08:29:42 -0700 Subject: [PATCH 08/23] nits --- eng/Dependencies.props | 24 +++++++++++++++++++ eng/Versions.props | 1 + .../AspNetCore/AspNetCore.vcxproj | 1 + ...tCore.Server.IntegrationTesting.IIS.csproj | 2 ++ 4 files changed, 28 insertions(+) diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 754b192df387..5e5e057ee642 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -179,11 +179,35 @@ and are generated based on the last package release. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eng/Versions.props b/eng/Versions.props index df0077a0a312..d5b86827db95 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -206,6 +206,7 @@ 5.3.0 2.2.1 1.0.1 + 3.0.0-preview6-27727-02 3.0.1 3.0.1 11.1.0 diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index db33b281cd90..1ff32ebf3413 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -266,6 +266,7 @@ {09d9d1d6-2951-4e14-bc35-76a23cf9391a} + diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj index 424be8c5f5d6..7178ba3ac634 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj @@ -45,12 +45,14 @@ + + From 1bd5ec5a97febe7527224a4507f8b0e8b8248375 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 29 May 2019 14:07:00 -0700 Subject: [PATCH 09/23] not sure why the property isn't set --- .../IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj | 1 - .../Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj | 1 + src/Servers/IIS/build.cmd | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index 1ff32ebf3413..db33b281cd90 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -266,7 +266,6 @@ {09d9d1d6-2951-4e14-bc35-76a23cf9391a} - diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj index 7178ba3ac634..a37673073ca2 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj @@ -63,6 +63,7 @@ + diff --git a/src/Servers/IIS/build.cmd b/src/Servers/IIS/build.cmd index 4369bfd550d3..ceccd91c6eaa 100644 --- a/src/Servers/IIS/build.cmd +++ b/src/Servers/IIS/build.cmd @@ -1,3 +1,3 @@ @ECHO OFF SET RepoRoot=%~dp0..\..\.. -%RepoRoot%\build.cmd -BuildNative -projects %~dp0**\*.csproj %* +%RepoRoot%\build.cmd -BuildNative -projects %~dp0**\*.csproj %* From de73cc1e6a3c425213ebc9443aa0f61aa776b077 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 13:14:25 -0700 Subject: [PATCH 10/23] maybe --- .../IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj | 3 +++ .../Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index db33b281cd90..446200ec57fa 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -266,6 +266,9 @@ {09d9d1d6-2951-4e14-bc35-76a23cf9391a} + + all + diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj index a37673073ca2..fad8567c2efd 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj @@ -45,14 +45,13 @@ - + - @@ -63,7 +62,6 @@ - From e1b9bbae6c1d65e63db8a1bda2cfc58f7a6681ba Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 14:05:24 -0700 Subject: [PATCH 11/23] darc --- eng/Dependencies.props | 2 +- eng/Version.Details.xml | 5 +++++ eng/Versions.props | 1 - ...Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj | 5 ++++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 5e5e057ee642..5725e7041e13 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -190,7 +190,6 @@ and are generated based on the last package release. - @@ -208,6 +207,7 @@ and are generated based on the last package release. + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 69452ee23103..e9cdc61dd5d1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -405,6 +405,11 @@ https://github.com/dotnet/core-setup 2bb2dcaeffb1dfeda077354449868ddac254bc3d + + https://github.com/dotnet/core-setup + + + diff --git a/eng/Versions.props b/eng/Versions.props index d5b86827db95..df0077a0a312 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -206,7 +206,6 @@ 5.3.0 2.2.1 1.0.1 - 3.0.0-preview6-27727-02 3.0.1 3.0.1 11.1.0 diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj index fad8567c2efd..1bc403b14b5f 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj @@ -45,7 +45,8 @@ - + + @@ -62,6 +63,8 @@ + + From c007d1dc12c3d1b11d65d5142d1fae02f78ffa3f Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 15:14:19 -0700 Subject: [PATCH 12/23] Updates --- eng/Versions.props | 1 + .../AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp | 1 + .../CommonLib/HostFxrResolutionResult.cpp | 4 +++- .../CommonLib/HostFxrResolutionResult.h | 1 + .../AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp | 10 ++++++++-- .../IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h | 3 ++- .../InProcessRequestHandler/inprocessapplication.cpp | 3 ++- .../Common.FunctionalTests/Inprocess/StartupTests.cs | 2 -- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index df0077a0a312..700c7b8aae31 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -58,6 +58,7 @@ 3.0.0-preview8-27914-06 3.0.0-preview8-27914-06 2.1.0-preview8-27914-06 + 1.0.0-preview8.19364.1 4.6.0-preview8.19364.1 diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp index bb4202398864..bc82981e9c65 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp @@ -65,6 +65,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication pApplication.GetApplicationPhysicalPath(), pConfiguration.QueryArguments(), errorContext, + m_hModule, options)); location = options->GetDotnetExeLocation(); diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp index 9a80749f2c70..d2356f54c105 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.cpp @@ -24,6 +24,7 @@ HRESULT HostFxrResolutionResult::Create( _In_ const std::wstring& pcwzApplicationPhysicalPath, _In_ const std::wstring& pcwzArguments, _In_ ErrorContext& errorContext, + _In_ HMODULE aspNetCoreModule, _Out_ std::unique_ptr& ppWrapper) { std::filesystem::path knownDotnetLocation; @@ -44,7 +45,8 @@ HRESULT HostFxrResolutionResult::Create( hostFxrDllPath, knownDotnetLocation, arguments, - errorContext); + errorContext, + aspNetCoreModule); LOG_INFOF(L"Parsed hostfxr options: dotnet location: '%ls' hostfxr path: '%ls' arguments:", knownDotnetLocation.c_str(), hostFxrDllPath.c_str()); for (size_t i = 0; i < arguments.size(); i++) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h index a0bbf1700356..a4e90451fb98 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolutionResult.h @@ -47,6 +47,7 @@ class HostFxrResolutionResult _In_ const std::wstring& pcwzApplicationPhysicalPath, _In_ const std::wstring& pcwzArguments, _In_ ErrorContext& errorContext, + _In_ HMODULE aspNetCoreModule, _Out_ std::unique_ptr& ppWrapper); private: diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index 9f67ea1e6356..a8dd26fe471f 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -12,6 +12,7 @@ #include "StringHelpers.h" #include "RegistryKey.h" #include "ModuleHelpers.h" +#include "GlobalVersionUtility.h" namespace fs = std::filesystem; @@ -25,7 +26,8 @@ HostFxrResolver::GetHostFxrParameters( fs::path &hostFxrDllPath, fs::path &dotnetExePath, std::vector &arguments, - ErrorContext& errorContext + ErrorContext& errorContext, + HMODULE aspNetCoreModule ) { LOG_INFOF(L"Resolving hostfxr parameters for application: '%ls' arguments: '%ls' path: '%ls'", @@ -52,7 +54,11 @@ HostFxrResolver::GetHostFxrParameters( // call load dll and see what happens :) // TODO make sure we figure out a way to load this dll sxs // TODO error handling - auto moduleHandle = LoadLibrary(L"C:\\Users\\jukotali\\Downloads\\nethostbits\\nethost.dll"); + std::wstring modulePath = GlobalVersionUtility::GetModuleName(aspNetCoreModule); + + modulePath = GlobalVersionUtility::RemoveFileNameFromFolderPath(modulePath); + + auto moduleHandle = LoadLibrary(modulePath.append(L"\\nethost.dll").c_str()); auto getHostfxrPath = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); // Check if the absolute path is to dotnet or not. diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h index ac7fe2dfd8b1..ea67d692f17a 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h @@ -26,7 +26,8 @@ class HostFxrResolver std::filesystem::path &hostFxrDllPath, std::filesystem::path &dotnetExePath, std::vector &arguments, - ErrorContext& errorContext + ErrorContext& errorContext, + HMODULE aspNetCoreModule ); static diff --git a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp index 5707e4cd7728..dfe17f645b1f 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp @@ -195,7 +195,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication() auto context = std::make_shared(); - ErrorContext errorContext; // unused + ErrorContext errorContext; // unused if (s_fMainCallback == nullptr) { @@ -205,6 +205,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication() QueryApplicationPhysicalPath(), m_pConfig->QueryArguments(), errorContext, + GetModuleHandle(TEXT("aspnetcorev2.dll")), hostFxrResolutionResult )); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs index 1f74326e3f00..04aa679c360e 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -44,8 +44,6 @@ public async Task ExpandEnvironmentVariableInWebConfig() [ConditionalTheory] [InlineData("bogus", "", @"Executable was not found at '.*?\\bogus.exe")] - [InlineData("c:\\random files\\dotnet.exe", "something.dll", "")] - [InlineData(".\\dotnet.exe", "something.dll", "")] [InlineData("dotnet.exe", "", @"Application arguments are empty.")] [InlineData("dotnet.zip", "", @"Process path 'dotnet.zip' doesn't have '.exe' extension.")] public async Task InvalidProcessPath_ExpectServerError(string path, string arguments, string subError) From 1e94d98e164910c5a3dd9daa25853c6f7b3a5e88 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 15:32:39 -0700 Subject: [PATCH 13/23] nit --- .../IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs index 04aa679c360e..cac6bcc70d77 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -15,7 +15,6 @@ using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; -using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Win32; using Xunit; From a452e58b6aca4c7d53588d269987af4ab0d59641 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 16:19:57 -0700 Subject: [PATCH 14/23] targets --- eng/targets/Cpp.Common.targets | 3 +++ eng/targets/Wix.Common.targets | 2 ++ .../ANCMIISExpressV2/ancm_iis_expressv2.wxs | 14 ++++++++++++++ .../AspNetCoreModule-Setup/Directory.Build.props | 6 ++++++ .../AspNetCore/AspNetCore.vcxproj | 5 ++--- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/eng/targets/Cpp.Common.targets b/eng/targets/Cpp.Common.targets index f32f3f18213b..d6fdd5497e4e 100644 --- a/eng/targets/Cpp.Common.targets +++ b/eng/targets/Cpp.Common.targets @@ -9,9 +9,12 @@ + + + diff --git a/eng/targets/Wix.Common.targets b/eng/targets/Wix.Common.targets index 4c6d15a790be..4d88e87153f7 100644 --- a/eng/targets/Wix.Common.targets +++ b/eng/targets/Wix.Common.targets @@ -27,6 +27,8 @@ $(DefineConstants);Cabinet=$(Cabinet) + + en-US $(Culture) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs index fa6326578ae2..1c0ca9b10dbd 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -35,10 +35,12 @@ + + @@ -172,6 +174,12 @@ DiskId="1" Vital="yes"> + + @@ -214,6 +222,12 @@ Source="$(var.AspNetCoreV2WoW64.TargetPath)" DiskId="1" Vital="yes"> + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props index d08b147e4ae5..c562b14247d0 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props @@ -36,6 +36,8 @@ AspNetCoreSchemaPath=$(_ServerIISBasePath)AspNetCoreModuleV2\AspNetCore\aspnetcore_schema_v2.xml; AspNetCoreMofPath=$(_ServerIISBasePath)AspNetCoreModuleV2\AspNetCore\ancm.mof; + NetHost64bit=$(Pkgruntime_win-x64_Microsoft_NETCore_DotNetAppHost)\runtimes\win-x64\native\nethost.dll; + NetHost32bit=$(Pkgruntime_win-x86_Microsoft_NETCore_DotNetAppHost)\runtimes\win-x86\native\nethost.dll; $(DefineConstants) @@ -70,5 +72,9 @@ false Platform=Win32 + + + diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index 446200ec57fa..0ba0ff7d7da6 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -266,9 +266,8 @@ {09d9d1d6-2951-4e14-bc35-76a23cf9391a} - - all - + From df06edc3f56c8f06eac54107e0f5b3a72e9fe987 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 18:05:43 -0700 Subject: [PATCH 15/23] ideas --- .../ANCMIISExpressV2/ancm_iis_expressv2.wxs | 12 +++++++++--- .../ANCMV2/aspnetcoremodulev2.wxs | 2 ++ .../AspNetCoreModule-Setup/Directory.Build.props | 6 ++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs index 1c0ca9b10dbd..76dd025ec5ed 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -174,9 +174,15 @@ DiskId="1" Vital="yes"> - + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs index b04b1e21f5bd..cd332bc4bdef 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs @@ -26,9 +26,11 @@ + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props index c562b14247d0..cab788f32c8e 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props @@ -72,9 +72,7 @@ false Platform=Win32 - - - + + From 2313933fd18668060ccfe2bf9db53256ee31c4dc Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 18:05:53 -0700 Subject: [PATCH 16/23] nit --- .../IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index 0ba0ff7d7da6..8c8b40a215c9 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -266,8 +266,8 @@ {09d9d1d6-2951-4e14-bc35-76a23cf9391a} - + + From ba92949d33fc978b8aea8bcebb55eacf647bee5b Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 3 Jun 2019 22:44:56 -0700 Subject: [PATCH 17/23] Get dlls working --- .../ANCMIISExpressV2/ancm_iis_expressv2.wxs | 26 ++++++++--------- .../ANCMV2/aspnetcoremodulev2.wxs | 28 +++++++++++++++++-- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs index 76dd025ec5ed..553137c17485 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -179,17 +179,13 @@ - - + - - - - @@ -229,16 +225,18 @@ DiskId="1" Vital="yes"> - + + + + + + - - - - @@ -271,10 +269,12 @@ + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs index cd332bc4bdef..76e6b6a39ed9 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs @@ -26,12 +26,12 @@ - + - + @@ -146,7 +146,7 @@ - + + + + + + + @@ -202,6 +212,16 @@ + + + + + + + + From d6fc761c4f4505bbd891258d5895051eb70ee5d1 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 4 Jun 2019 08:19:55 -0700 Subject: [PATCH 18/23] revert --- src/Servers/IIS/build/assets.props | 314 ++++++++++++++--------------- 1 file changed, 157 insertions(+), 157 deletions(-) diff --git a/src/Servers/IIS/build/assets.props b/src/Servers/IIS/build/assets.props index e6f289883b34..bac74143d2ce 100644 --- a/src/Servers/IIS/build/assets.props +++ b/src/Servers/IIS/build/assets.props @@ -11,215 +11,215 @@ - $(ArtifactsBinDir)AspNetCoreModuleShim\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2.dll - $(ArtifactsBinDir)InProcessRequestHandler\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2_inprocess.dll + $(ArtifactsBinDir)AspNetCoreModuleShim\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2.dll + $(ArtifactsBinDir)InProcessRequestHandler\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2_inprocess.dll $(ArtifactsBinDir)OutOfProcessRequestHandler\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2_outofprocess.dll From 08c422c77b543304e0523b9adb1f02412c736855 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 4 Jun 2019 11:15:44 -0700 Subject: [PATCH 19/23] Cleanup --- eng/Version.Details.xml | 5 +- eng/targets/Cpp.Common.targets | 2 - eng/targets/Wix.Common.targets | 2 - .../ANCMIISExpressV2/ancm_iis_expressv2.wxs | 18 ++-- .../ANCMV2/aspnetcoremodulev2.wxs | 22 ++--- .../AspNetCore/AspNetCore.vcxproj | 2 - .../CommonLib/HostFxrResolver.cpp | 93 +++++++++++-------- .../CommonLib/hostfxroptions.cpp | 67 ------------- .../CommonLib/hostfxroptions.h | 61 ------------ .../CommonLibTests/hostfxr_utility_tests.cpp | 32 ------- 10 files changed, 77 insertions(+), 227 deletions(-) delete mode 100644 src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp delete mode 100644 src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.h diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e9cdc61dd5d1..d33703d0443f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -405,10 +405,9 @@ https://github.com/dotnet/core-setup 2bb2dcaeffb1dfeda077354449868ddac254bc3d - + https://github.com/dotnet/core-setup - - + 63abc77da6d99470caa5bfa0465afe244105e595 diff --git a/eng/targets/Cpp.Common.targets b/eng/targets/Cpp.Common.targets index d6fdd5497e4e..2b8733ae9f81 100644 --- a/eng/targets/Cpp.Common.targets +++ b/eng/targets/Cpp.Common.targets @@ -9,8 +9,6 @@ - - diff --git a/eng/targets/Wix.Common.targets b/eng/targets/Wix.Common.targets index 4d88e87153f7..4c6d15a790be 100644 --- a/eng/targets/Wix.Common.targets +++ b/eng/targets/Wix.Common.targets @@ -27,8 +27,6 @@ $(DefineConstants);Cabinet=$(Cabinet) - - en-US $(Culture) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs index 553137c17485..f63ef673f4d9 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -35,12 +35,12 @@ - + - + @@ -179,10 +179,10 @@ - - + @@ -230,8 +230,8 @@ - - + - + - + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs index 76e6b6a39ed9..fe294ee69302 100644 --- a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMV2/aspnetcoremodulev2.wxs @@ -27,11 +27,11 @@ - + - + @@ -160,14 +160,14 @@ - - + - + @@ -213,14 +213,14 @@ - - + - + @@ -243,13 +243,13 @@ - + - + diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index 8c8b40a215c9..db33b281cd90 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -266,8 +266,6 @@ {09d9d1d6-2951-4e14-bc35-76a23cf9391a} - - diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index a8dd26fe471f..5ffd78c3adc8 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -51,22 +51,17 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(format(L"Process path '%s' doesn't have '.exe' extension.", expandedProcessPath.c_str())); } - // call load dll and see what happens :) // TODO make sure we figure out a way to load this dll sxs - // TODO error handling std::wstring modulePath = GlobalVersionUtility::GetModuleName(aspNetCoreModule); + // If we are in the shim, load hostfxr. + // Otherwise, throw. + // I think we need to assume that hostfxr is loaded by the shim. + // but we may need a backup, which really sucks. modulePath = GlobalVersionUtility::RemoveFileNameFromFolderPath(modulePath); auto moduleHandle = LoadLibrary(modulePath.append(L"\\nethost.dll").c_str()); - auto getHostfxrPath = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); - - // Check if the absolute path is to dotnet or not. - // Things to figure out: - // 1. what do we do with the dotnet path? Any reason for us to care? - // need to care to make sure a newer shim still has fast load times with old handler - // just create a reverse function? - // 2. Does this work with registry keys? + if (IsDotnetExecutable(expandedProcessPath)) { LOG_INFOF(L"Process path '%ls' is dotnet, treating application as portable", expandedProcessPath.c_str()); @@ -76,22 +71,35 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(L"Application arguments are empty."); } - std::wstring test; - size_t size = 500; - test.resize(size); + if (dotnetExePath.empty()) + { + if (moduleHandle != nullptr) + { + auto get_host_fxr_path = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); + + std::wstring hostfxrPath; + size_t size = MAX_PATH * 2; + hostfxrPath.resize(size); - AppendArguments( - expandedApplicationArguments, - applicationPhysicalPath, - arguments, - true); + AppendArguments( + expandedApplicationArguments, + applicationPhysicalPath, + arguments, + true); - // TODO need to check if args[0] is a dll or not. - getHostfxrPath(test.data(), &size, arguments[0].c_str()); + get_host_fxr_path(hostfxrPath.data(), &size, arguments[0].c_str()); - test.resize(size); // todo maybe +1 for nullchar - hostFxrDllPath = test; - dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); + hostfxrPath.resize(size); + hostFxrDllPath = hostfxrPath; + dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); + } + else + { + // TODO need to review 2.2 code, this may need to still be allowed for handler if we shipped 2.2 without this assumption + throw InvalidOperationException(L"Must have hostfxr loaded in shim or have nethost.dll next to app."); + } + } + arguments.insert(arguments.begin(), dotnetExePath); } else @@ -137,21 +145,31 @@ HostFxrResolver::GetHostFxrParameters( } else { - LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str()); - std::wstring test; - size_t size = 500; - test.resize(size); - - // passing "dotnet" here because we don't know where dotnet.exe should come from - // so trying all fallbacks is appropriate - // For portable with launcher apps we need dotnet.exe to be argv[0] and .dll be argv[1] - - getHostfxrPath(test.data(), &size, applicationDllPath.c_str()); - - test.resize(size); // todo maybe +1 for nullchar - hostFxrDllPath = test; + if (dotnetExePath.empty()) + { + if (moduleHandle != nullptr) + { + auto getHostfxrPath = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); + + LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str()); + std::wstring test; + size_t size = 500; + test.resize(size); + + getHostfxrPath(test.data(), &size, applicationDllPath.c_str()); + + test.resize(size); // todo maybe +1 for nullchar + hostFxrDllPath = test; + + dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); + } + else + { + // TODO need to review 2.2 code, this may need to still be allowed for handler if we shipped 2.2 without this assumption + throw InvalidOperationException(L"Must have hostfxr loaded in shim or have nethost.dll next to app."); + } + } - dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); arguments.push_back(dotnetExePath); arguments.push_back(applicationDllPath); } @@ -250,6 +268,5 @@ HostFxrResolver::GetAbsolutePathToDotnetFromHostfxr(const fs::path& hostfxrPath) BOOL HostFxrResolver::IsDotnetExecutable(const std::filesystem::path& dotnetPath) { - // TODO this probably should check the path is dotnet for program files. return ends_with(dotnetPath, L"dotnet.exe", true); } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp deleted file mode 100644 index 060224c60d9b..000000000000 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp +++ /dev/null @@ -1,67 +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 "hostfxroptions.h" - -#include "hostfxr_utility.h" -#include "debugutil.h" -#include "exceptions.h" -#include "EventLog.h" - -HRESULT HOSTFXR_OPTIONS::Create( - _In_ const std::wstring& pcwzDotnetExePath, - _In_ const std::wstring& pcwzProcessPath, - _In_ const std::wstring& pcwzApplicationPhysicalPath, - _In_ const std::wstring& pcwzArguments, - _Out_ std::unique_ptr& ppWrapper) -{ - std::filesystem::path knownDotnetLocation; - - if (!pcwzDotnetExePath.empty()) - { - knownDotnetLocation = pcwzDotnetExePath; - } - - try - { - std::filesystem::path hostFxrDllPath; - std::vector arguments; - HOSTFXR_UTILITY::GetHostFxrParameters( - pcwzProcessPath, - pcwzApplicationPhysicalPath, - pcwzArguments, - hostFxrDllPath, - knownDotnetLocation, - arguments); - - LOG_INFOF(L"Parsed hostfxr options: dotnet location: '%ls' hostfxr path: '%ls' arguments:", knownDotnetLocation.c_str(), hostFxrDllPath.c_str()); - for (size_t i = 0; i < arguments.size(); i++) - { - LOG_INFOF(L"Argument[%d] = '%ls'", i, arguments[i].c_str()); - } - ppWrapper = std::make_unique(knownDotnetLocation, hostFxrDllPath, arguments); - } - catch (InvalidOperationException &ex) - { - EventLog::Error( - ASPNETCORE_EVENT_INPROCESS_START_ERROR, - ASPNETCORE_EVENT_INPROCESS_START_ERROR_MSG, - pcwzApplicationPhysicalPath.c_str(), - ex.as_wstring().c_str()); - - RETURN_CAUGHT_EXCEPTION(); - } - catch (std::runtime_error &ex) - { - EventLog::Error( - ASPNETCORE_EVENT_INPROCESS_START_ERROR, - ASPNETCORE_EVENT_INPROCESS_START_ERROR_MSG, - pcwzApplicationPhysicalPath.c_str(), - GetUnexpectedExceptionMessage(ex).c_str()); - - RETURN_CAUGHT_EXCEPTION(); - } - CATCH_RETURN(); - - return S_OK; -} diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.h deleted file mode 100644 index 243cc53ae7b8..000000000000 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/hostfxroptions.h +++ /dev/null @@ -1,61 +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 -#include -#include -#include -#include -#include - -class HOSTFXR_OPTIONS -{ -public: - HOSTFXR_OPTIONS( - std::filesystem::path dotnetExeLocation, - std::filesystem::path hostFxrLocation, - std::vector arguments - ) noexcept - : m_dotnetExeLocation(std::move(dotnetExeLocation)), - m_hostFxrLocation(std::move(hostFxrLocation)), - m_arguments(std::move(arguments)) - {} - - void - GetArguments(DWORD &hostfxrArgc, std::unique_ptr &hostfxrArgv) const - { - hostfxrArgc = static_cast(m_arguments.size()); - hostfxrArgv = std::make_unique(hostfxrArgc); - for (DWORD i = 0; i < hostfxrArgc; ++i) - { - hostfxrArgv[i] = m_arguments[i].c_str(); - } - } - - const std::filesystem::path& - GetHostFxrLocation() const noexcept - { - return m_hostFxrLocation; - } - - const std::filesystem::path& - GetDotnetExeLocation() const noexcept - { - return m_dotnetExeLocation; - } - - static - HRESULT Create( - _In_ const std::wstring& pcwzExeLocation, - _In_ const std::wstring& pcwzProcessPath, - _In_ const std::wstring& pcwzApplicationPhysicalPath, - _In_ const std::wstring& pcwzArguments, - _Out_ std::unique_ptr& ppWrapper); - -private: - const std::filesystem::path m_dotnetExeLocation; - const std::filesystem::path m_hostFxrLocation; - const std::vector m_arguments; -}; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp index 6db158693b9c..f3530e3254e8 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLibTests/hostfxr_utility_tests.cpp @@ -50,35 +50,3 @@ TEST(ParseHostFxrArguments, ConvertDllToAbsolutePath) ASSERT_STREQ(L"exec", bstrArray[0].c_str()); ASSERT_STREQ((system32 + L"\\ntdll.dll").c_str(), bstrArray[1].c_str()); } - -TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs) -{ - std::vector bstrArray; - std::filesystem::path struHostFxrDllLocation; - std::filesystem::path struExeLocation; - - EXPECT_THROW(HostFxrResolver::GetHostFxrParameters( - L"dotnet", // processPath - L"some\\path", // application physical path, ignored. - L"", //arguments - struHostFxrDllLocation, - struExeLocation, - bstrArray), // args array. - InvalidOperationException); -} - -TEST(GetHostFxrArguments, InvalidParams) -{ - std::vector bstrArray; - std::filesystem::path struHostFxrDllLocation; - std::filesystem::path struExeLocation; - - EXPECT_THROW(HostFxrResolver::GetHostFxrParameters( - L"bogus", // processPath - L"", // application physical path, ignored. - L"ignored", //arguments - struHostFxrDllLocation, - struExeLocation, - bstrArray), // args array. - InvalidOperationException); -} From f16f65a3533b9a3b581040ab8fbc32a1b7a2727e Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 4 Jun 2019 12:53:05 -0700 Subject: [PATCH 20/23] fix args --- .../CommonLib/HostFxrResolver.cpp | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index 5ffd78c3adc8..6a3629a77609 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -87,11 +87,14 @@ HostFxrResolver::GetHostFxrParameters( arguments, true); + // argument[0] will contain the dll path. get_host_fxr_path(hostfxrPath.data(), &size, arguments[0].c_str()); hostfxrPath.resize(size); hostFxrDllPath = hostfxrPath; dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); + + arguments.insert(arguments.begin(), dotnetExePath); } else { @@ -99,8 +102,15 @@ HostFxrResolver::GetHostFxrParameters( throw InvalidOperationException(L"Must have hostfxr loaded in shim or have nethost.dll next to app."); } } - - arguments.insert(arguments.begin(), dotnetExePath); + else + { + arguments.push_back(dotnetExePath); + AppendArguments( + expandedApplicationArguments, + applicationPhysicalPath, + arguments, + true); + } } else { @@ -149,17 +159,17 @@ HostFxrResolver::GetHostFxrParameters( { if (moduleHandle != nullptr) { - auto getHostfxrPath = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); + auto get_host_fxr_path = ModuleHelpers::GetKnownProcAddress(moduleHandle, "get_hostfxr_path"); LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str()); - std::wstring test; - size_t size = 500; - test.resize(size); - getHostfxrPath(test.data(), &size, applicationDllPath.c_str()); + std::wstring hostfxrPath; + size_t size = MAX_PATH * 2; + hostfxrPath.resize(size); - test.resize(size); // todo maybe +1 for nullchar - hostFxrDllPath = test; + get_host_fxr_path(hostfxrPath.data(), &size, applicationDllPath.c_str()); + hostfxrPath.resize(size); + hostFxrDllPath = hostfxrPath; dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath); } From 57a2a7c4270b04b3907dd456a51b92fa260bb5b0 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 11 Jun 2019 14:22:39 -0700 Subject: [PATCH 21/23] whoops --- eng/Version.Details.xml | 2 +- src/Servers/IIS/build/assets.props | 314 ++++++++++++++--------------- 2 files changed, 158 insertions(+), 158 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d33703d0443f..0e4ea3f32d85 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -405,7 +405,7 @@ https://github.com/dotnet/core-setup 2bb2dcaeffb1dfeda077354449868ddac254bc3d - + https://github.com/dotnet/core-setup 63abc77da6d99470caa5bfa0465afe244105e595 diff --git a/src/Servers/IIS/build/assets.props b/src/Servers/IIS/build/assets.props index bac74143d2ce..e6f289883b34 100644 --- a/src/Servers/IIS/build/assets.props +++ b/src/Servers/IIS/build/assets.props @@ -11,215 +11,215 @@ - $(ArtifactsBinDir)AspNetCoreModuleShim\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2.dll - $(ArtifactsBinDir)InProcessRequestHandler\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2_inprocess.dll + $(ArtifactsBinDir)AspNetCoreModuleShim\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2.dll + $(ArtifactsBinDir)InProcessRequestHandler\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2_inprocess.dll $(ArtifactsBinDir)OutOfProcessRequestHandler\$(NativeVCPlatform)\$(Configuration)\aspnetcorev2_outofprocess.dll From 2ed35d28e0b285ee675cfa5ca25254243f8dd490 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 11 Jun 2019 18:11:17 -0700 Subject: [PATCH 22/23] nit --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0e4ea3f32d85..6be083dfdf2d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -405,9 +405,9 @@ https://github.com/dotnet/core-setup 2bb2dcaeffb1dfeda077354449868ddac254bc3d - + https://github.com/dotnet/core-setup - 63abc77da6d99470caa5bfa0465afe244105e595 + 3f9156d5d9b5ae4b100baeaa75011aaee88a3f4b From e1975452b57e98b1819640450140ac3e38937955 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 16 Jul 2019 10:12:19 -0700 Subject: [PATCH 23/23] cleanup --- eng/Dependencies.props | 21 ------------------- eng/Versions.props | 1 + .../CommonLib/HostFxrResolver.cpp | 3 ++- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 5725e7041e13..3e35ae7b3666 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -179,33 +179,12 @@ and are generated based on the last package release. - - - - - - - - - - - - - - - - - - - - - diff --git a/eng/Versions.props b/eng/Versions.props index 700c7b8aae31..61440c281ccb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,6 +57,7 @@ 3.0.0-preview8-27914-06 3.0.0-preview8-27914-06 3.0.0-preview8-27914-06 + 3.0.0-preview8-27914-06 2.1.0-preview8-27914-06 diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp index 6a3629a77609..e972f726188c 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp @@ -87,9 +87,10 @@ HostFxrResolver::GetHostFxrParameters( arguments, true); - // argument[0] will contain the dll path. get_host_fxr_path(hostfxrPath.data(), &size, arguments[0].c_str()); + // If this fails, path probe + hostfxrPath.resize(size); hostFxrDllPath = hostfxrPath; dotnetExePath = GetAbsolutePathToDotnetFromHostfxr(hostFxrDllPath);