mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 04:36:39 +00:00
Merge pull request #1414 from PowerShell/mirichmo/add-pwrshplugin-to-build
Mirichmo/add pwrshplugin to build
This commit is contained in:
commit
4c9a44de8b
25 files changed
+1474
-727
No files matched your search
+33
-13
@@ -59,10 +59,10 @@ function Start-PSBuild {
|
||||
[switch]$XamlGen,
|
||||
|
||||
[Parameter(ParameterSetName='FullCLR')]
|
||||
[ValidateSet('x86', 'x64')]
|
||||
[ValidateSet('x86', 'x64')] # TODO: At some point, we need to add ARM support to match CoreCLR
|
||||
[string]$NativeHostArch = "x64",
|
||||
|
||||
[ValidateSet('Linux', 'Debug', 'Release', '')]
|
||||
[ValidateSet('Linux', 'Debug', 'Release', '')] # We might need "Checked" as well
|
||||
[string]$Configuration
|
||||
)
|
||||
|
||||
@@ -99,12 +99,16 @@ function Start-PSBuild {
|
||||
Use-MSBuild
|
||||
|
||||
#mc.exe is Message Compiler for native resources
|
||||
<# This currently doesn't work reliably and clean systems. Removing for now since mc.exe is not being used yet.
|
||||
$mcexe = Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\" -Recurse -Filter 'mc.exe' | ? {$_.FullName -match 'x64'} | select -First 1 | % {$_.FullName}
|
||||
if (-not $mcexe) {
|
||||
throw 'mc.exe not found. Install Microsoft Windows SDK.'
|
||||
}
|
||||
#>
|
||||
|
||||
$vcVarsPath = (Get-Item(Join-Path -Path "$env:VS140COMNTOOLS" -ChildPath '../../vc')).FullName
|
||||
if ((Test-Path -Path $vcVarsPath\vcvarsall.bat) -eq $false)
|
||||
{
|
||||
throw "Could not find Visual Studio vcvarsall.bat at" + $vcVarsPath
|
||||
}
|
||||
|
||||
# setup msbuild configuration
|
||||
if ($Configuration -eq 'Debug' -or $Configuration -eq 'Release')
|
||||
@@ -221,18 +225,35 @@ function Start-PSBuild {
|
||||
@("nativemsh/pwrshplugin") | % {
|
||||
$nativeResourcesFolder = $_
|
||||
Get-ChildItem $nativeResourcesFolder -Filter "*.mc" | % {
|
||||
# & $mcexe -c -U $_.FullName -h $nativeResourcesFolder -r $nativeResourcesFolder
|
||||
Start-NativeExecution { & $mcexe -o -d -c -U $_.FullName -h "$nativeResourcesFolder" -r "$nativeResourcesFolder" }
|
||||
}
|
||||
}
|
||||
|
||||
# Disabling until I figure out if it is necessary
|
||||
# $overrideFlags = "-DCMAKE_USER_MAKE_RULES_OVERRIDE=$PSScriptRoot\src\powershell-native\windows-compiler-override.txt"
|
||||
$overrideFlags = ""
|
||||
$location = Get-Location
|
||||
#
|
||||
# BUILD_ONECORE
|
||||
#
|
||||
|
||||
if ($cmakeGenerator) {
|
||||
Start-NativeExecution { cmake -G $cmakeGenerator . }
|
||||
} else {
|
||||
Start-NativeExecution { cmake . }
|
||||
$BuildOneCoreValues = @("ON","OFF")
|
||||
foreach ($oneCoreValue in $BuildOneCoreValues)
|
||||
{
|
||||
$command = @"
|
||||
cmd.exe /C cd /d "$location" "&" "$($vcVarsPath)\vcvarsall.bat" "$NativeHostArch" "&" cmake "$overrideFlags" -DBUILD_ONECORE=$oneCoreValue -G "$cmakeGenerator" . "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$msbuildConfiguration"
|
||||
"@
|
||||
log " Executing Build Command: $command"
|
||||
Start-NativeExecution { Invoke-Expression -Command:$command }
|
||||
}
|
||||
|
||||
Start-NativeExecution { msbuild powershell.vcxproj /p:Configuration=$msbuildConfiguration }
|
||||
|
||||
# Copy the executable binary from the local build directory to the expected destination to enable Start-DevPowerShell to work
|
||||
#
|
||||
# TODO: This should be updated to handle per-architecture builds gracefully.
|
||||
$srcPath = Join-Path (Join-Path (Join-Path (Get-Location) "bin") $msbuildConfiguration) "FullCLR/powershell.exe"
|
||||
$dstPath = ($script:Options).Top
|
||||
log " Copying $srcPath to $dstPath"
|
||||
Copy-Item $srcPath $dstPath
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
@@ -254,7 +275,6 @@ function Start-PSBuild {
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1312,7 +1332,7 @@ function script:Start-NativeExecution([scriptblock]$sb)
|
||||
try
|
||||
{
|
||||
& $sb
|
||||
# note, if $sb doens't have a native invokation, $LASTEXITCODE will
|
||||
# note, if $sb doens't have a native invocation, $LASTEXITCODE will
|
||||
# point to the obsolete value
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
{
|
||||
|
||||
@@ -1,63 +1,81 @@
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
project(PowerShell)
|
||||
|
||||
add_compile_options()
|
||||
project(PowerShellNative)
|
||||
|
||||
#
|
||||
# Verify prerequisites
|
||||
#
|
||||
if (NOT $ENV{${WindowsSDKVersion}})
|
||||
message (FATAL_ERROR "WindowsSDKVersion environment variable not found")
|
||||
endif ()
|
||||
|
||||
if (NOT $ENV{${Platform}})
|
||||
message(FATAL_ERROR "Platform environment variable not found")
|
||||
else ()
|
||||
SET(WindowsSDKPlatform "$ENV{Platform}")
|
||||
endif ()
|
||||
|
||||
#
|
||||
# Normalize the platform name
|
||||
#
|
||||
# TODO: Only x64 and x86 are supported right now. This needs to be expanded to arm as well
|
||||
#
|
||||
if (WindowsSDKPlatform STREQUAL "x64" OR WindowsSDKPlatform STREQUAL "X64" OR WindowsSDKPlatform STREQUAL "amd64" OR WindowsSDKPlatform STREQUAL "AMD64")
|
||||
SET(WindowsSDKPlatform "x64")
|
||||
elseif (WindowsSDKPlatform STREQUAL "x86" OR WindowsSDKPlatform STREQUAL "X86")
|
||||
SET(WindowsSDKPlatform "x86")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported WindowsSDKPlatform ${WindowsSDKPlatform}")
|
||||
endif ()
|
||||
|
||||
#
|
||||
# set the output path for all binaries
|
||||
#
|
||||
if (BUILD_ONECORE)
|
||||
set(PWRSH_NATIVE_OUTPUT_DIRECTORY "CoreClr")
|
||||
else ()
|
||||
set(PWRSH_NATIVE_OUTPUT_DIRECTORY "FullClr")
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
# set the output path for `powershell.exe`
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/../Microsoft.PowerShell.ConsoleHost")
|
||||
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${PROJECT_SOURCE_DIR}/Bin/${OUTPUTCONFIG}/${PWRSH_NATIVE_OUTPUT_DIRECTORY}")
|
||||
message(" Setting output directory for ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG}}")
|
||||
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
|
||||
|
||||
# set these flags, so build does static linking for msvcr120.dll
|
||||
# otherwise this dll need to be present on the system
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
#
|
||||
# Definitions for ease of reading
|
||||
#
|
||||
SET (WIN_VERSION_WIN10_RS1 0x0A000002)
|
||||
SET (WIN_VERSION_WIN10_TH2 0x0A000001)
|
||||
SET (WIN_VERSION_WIN10 0x0A00)
|
||||
SET (WIN_VERSION_WINTHRESHOLD 0x0A00)
|
||||
SET (WIN_VERSION_WINBLUE 0x0603)
|
||||
SET (WIN_VERSION_WIN8 0x0602)
|
||||
SET (WIN_VERSION_WIN7 0x0601)
|
||||
SET (NTDDI_VERSION_WIN7 0x06010000)
|
||||
SET (NTDDI_VERSION_WIN10 0x0A000002)
|
||||
SET (WIN_VERSION_VISTA 0x0600)
|
||||
SET (WIN_VERSION_LONGHORN 0x0600)
|
||||
SET (WIN_VERSION_WS03 0x0502)
|
||||
SET (WIN_VERSION_WINXP 0x0501)
|
||||
|
||||
include_directories(
|
||||
nativemsh/pwrshcommon
|
||||
nativemsh/pwrshplugin)
|
||||
#include(dsc_defs.cmake)
|
||||
if (BUILD_ONECORE)
|
||||
include(nano_defs.cmake)
|
||||
else ()
|
||||
include(coreclr_defs.cmake)
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
link_directories(
|
||||
nativemsh/pwrshcommon)
|
||||
# Default of BUILD_ONECORE should be ON once it is supported
|
||||
option(BUILD_ONECORE "Compile the OneCore version of the binaries" ON)
|
||||
option(BUILD_DOWNLEVEL "Compile the downlevel version of the binaries" OFF)
|
||||
|
||||
add_executable(powershell WIN32
|
||||
nativemsh/pwrshcommon/pwrshcommon.cpp
|
||||
nativemsh/pwrshcommon/WinSystemCallFacade.cpp
|
||||
nativemsh/pwrshexe/MainEntry.cpp)
|
||||
# Build the common library that powershell.exe and pwrshplugin.dll depend on
|
||||
add_subdirectory(nativemsh/pwrshcommon)
|
||||
|
||||
add_library(pwrshplugin
|
||||
nativemsh/pwrshplugin/entrypoints.cpp
|
||||
nativemsh/pwrshplugin/pwrshclrhost.cpp
|
||||
#nativemsh/pwrshplugin/pwrshpluginerrorcodes.mc
|
||||
#nativemsh/pwrshplugin/pwrshpluginerrorcodes.rc
|
||||
nativemsh/pwrshplugin/pwrshplugin.def)
|
||||
|
||||
|
||||
SET(powershell_definitions
|
||||
_CONSOLE
|
||||
UNICODE
|
||||
_UNICODE)
|
||||
|
||||
set_target_properties(powershell PROPERTIES COMPILE_DEFINITIONS "${powershell_definitions}")
|
||||
set_target_properties(powershell PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(powershell PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(powershell PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(powershell PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE")
|
||||
|
||||
SET(pwrshplugin_definitions
|
||||
UNICODE
|
||||
_UNICODE)
|
||||
|
||||
set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "${pwrshplugin_definitions}")
|
||||
|
||||
target_link_libraries(powershell
|
||||
mscoree.lib
|
||||
MUILoad.lib
|
||||
kernel32.lib
|
||||
msxml6.lib
|
||||
legacy_stdio_definitions.lib)
|
||||
|
||||
target_link_libraries(pwrshplugin)
|
||||
# Build pwrshplugin.dll
|
||||
add_subdirectory(nativemsh/pwrshplugin)
|
||||
|
||||
# Build powershell.exe
|
||||
add_subdirectory(nativemsh/pwrshexe)
|
||||
@@ -0,0 +1,195 @@
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "") # do not link against standard win32 libs i.e. kernel32, uuid, user32, etc.
|
||||
|
||||
#if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:cf")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /guard:cf")
|
||||
#endif (NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
|
||||
|
||||
# Incremental linking with CFG is broken until next VS release.
|
||||
# This needs to be appended to the last for each build type to override the default flag.
|
||||
set(NO_INCREMENTAL_LINKER_FLAGS "/INCREMENTAL:NO")
|
||||
|
||||
# Linker flags
|
||||
#
|
||||
# Disable the following line for UNIX altjit on Windows
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO") #Do not create Side-by-Side Assembly Manifest
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.00") #windows subsystem
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LARGEADDRESSAWARE") # can handle addresses larger than 2 gigabytes
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /RELEASE") #sets the checksum in the header
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NXCOMPAT") #Compatible with Data Execution Prevention
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DYNAMICBASE") #Use address space layout randomization
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUGTYPE:cv,fixup") #debugging format
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /PDBCOMPRESS") #shrink pdb size
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG")
|
||||
|
||||
#
|
||||
# TODO: Should these be ignored????
|
||||
#
|
||||
#set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4197,4013,4254,4070,4221")
|
||||
#set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG /PDBCOMPRESS")
|
||||
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1572864")
|
||||
|
||||
# Debug build specific flags
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "/NOVCFEATURE ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
|
||||
# Checked build specific flags
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "${CMAKE_SHARED_LINKER_FLAGS_CHECKED} /OPT:REF /OPT:NOICF /NOVCFEATURE ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_CHECKED "${CMAKE_STATIC_LINKER_FLAGS_CHECKED}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_CHECKED "${CMAKE_EXE_LINKER_FLAGS_CHECKED} /OPT:REF /OPT:NOICF ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
|
||||
# Release build specific flags
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG /OPT:REF /OPT:ICF ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG /OPT:REF /OPT:ICF ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
|
||||
# ReleaseWithDebugInfo build specific flags
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG /OPT:REF /OPT:ICF ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG /OPT:REF /OPT:ICF ${NO_INCREMENTAL_LINKER_FLAGS}")
|
||||
|
||||
# Temporary until cmake has VS generators for arm64
|
||||
#if(CLR_CMAKE_PLATFORM_ARCH_ARM64)
|
||||
# set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /machine:arm64")
|
||||
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /machine:arm64")
|
||||
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /machine:arm64")
|
||||
#endif(CLR_CMAKE_PLATFORM_ARCH_ARM64)
|
||||
|
||||
# Force uCRT to be dynamically linked for Release build
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")
|
||||
|
||||
#------------------------------------
|
||||
# Definitions (for platform)
|
||||
#-----------------------------------
|
||||
#if (CLR_CMAKE_PLATFORM_ARCH_AMD64)
|
||||
add_definitions(-D_AMD64_)
|
||||
add_definitions(-D_WIN64)
|
||||
add_definitions(-DAMD64)
|
||||
add_definitions(-DBIT64=1)
|
||||
#elseif (CLR_CMAKE_PLATFORM_ARCH_I386)
|
||||
# add_definitions(-D_X86_)
|
||||
#elseif (CLR_CMAKE_PLATFORM_ARCH_ARM)
|
||||
# add_definitions(-D_ARM_)
|
||||
# add_definitions(-DARM)
|
||||
#elseif (CLR_CMAKE_PLATFORM_ARCH_ARM64)
|
||||
# add_definitions(-D_ARM64_)
|
||||
# add_definitions(-DARM64)
|
||||
# add_definitions(-D_WIN64)
|
||||
# add_definitions(-DBIT64=1)
|
||||
#else ()
|
||||
# clr_unknown_arch()
|
||||
#endif ()
|
||||
|
||||
# Define the CRT lib references that link into Desktop imports
|
||||
set(STATIC_MT_CRT_LIB "libcmt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
|
||||
set(STATIC_MT_VCRT_LIB "libvcruntime$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
|
||||
set(STATIC_MT_CPP_LIB "libcpmt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
|
||||
|
||||
# Define the uCRT lib reference
|
||||
set(STATIC_UCRT_LIB "libucrt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
|
||||
set(DYNAMIC_UCRT_LIB "ucrt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
|
||||
|
||||
#------------------------------------
|
||||
# Definitions for compile
|
||||
#-----------------------------------
|
||||
|
||||
add_compile_options(/Zl) # omit default library name in .OBJ
|
||||
|
||||
# The following options are set by the razzle build
|
||||
add_compile_options(/TP) # compile all files as C++
|
||||
add_compile_options(/d2Zi+) # make optimized builds debugging easier
|
||||
add_compile_options(/nologo) # Suppress Startup Banner
|
||||
add_compile_options(/W3) # set warning level to 3
|
||||
#add_compile_options(/WX) # treat warnings as errors
|
||||
add_compile_options(/Oi) # enable intrinsics
|
||||
add_compile_options(/Oy-) # disable suppressing of the creation of frame pointers on the call stack for quicker function calls
|
||||
#add_compile_options(/U_MT) # undefine the predefined _MT macro
|
||||
add_compile_options(/GF) # enable read-only string pooling
|
||||
add_compile_options(/Gm-) # disable minimal rebuild
|
||||
add_compile_options(/EHa) # enable C++ EH (w/ SEH exceptions)
|
||||
add_compile_options(/Zp8) # pack structs on 8-byte boundary
|
||||
add_compile_options(/Gy) # separate functions for linker
|
||||
add_compile_options(/Zc:wchar_t-) # C++ language conformance: wchar_t is NOT the native type, but a typedef
|
||||
add_compile_options(/Zc:forScope) # C++ language conformance: enforce Standard C++ for scoping rules
|
||||
add_compile_options(/GR-) # disable C++ RTTI
|
||||
add_compile_options(/FC) # use full pathnames in diagnostics
|
||||
#add_compile_options(/MP) # Build with Multiple Processes (number of processes equal to the number of processors)
|
||||
add_compile_options(/GS) # Buffer Security Check
|
||||
add_compile_options(/Zm200) # Specify Precompiled Header Memory Allocation Limit of 150MB
|
||||
add_compile_options(/wd4960 /wd4961 /wd4603 /wd4627 /wd4838 /wd4456 /wd4457 /wd4458 /wd4459 /wd4091 /we4640)
|
||||
add_compile_options(/Zi) # enable debugging information
|
||||
add_compile_options(/ZH:SHA_256) # use SHA256 for generating hashes of compiler processed source files.
|
||||
|
||||
#if (CLR_CMAKE_PLATFORM_ARCH_I386)
|
||||
# add_compile_options(/Gz)
|
||||
#endif (CLR_CMAKE_PLATFORM_ARCH_I386)
|
||||
|
||||
add_compile_options($<$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>:/GL>)
|
||||
add_compile_options($<$<OR:$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>,$<CONFIG:Checked>>:/O1>)
|
||||
|
||||
#if (CLR_CMAKE_PLATFORM_ARCH_AMD64)
|
||||
# The generator expression in the following command means that the /homeparams option is added only for debug builds
|
||||
add_compile_options($<$<CONFIG:Debug>:/homeparams>) # Force parameters passed in registers to be written to the stack
|
||||
#endif (CLR_CMAKE_PLATFORM_ARCH_AMD64)
|
||||
|
||||
# enable control-flow-guard support for native components for non-Arm64 builds
|
||||
add_compile_options(/guard:cf)
|
||||
|
||||
# Statically linked CRT (libcmt[d].lib, libvcruntime[d].lib and libucrt[d].lib) by default. This is done to avoid
|
||||
# linking in VCRUNTIME140.DLL for a simplified xcopy experience by reducing the dependency on VC REDIST.
|
||||
#
|
||||
# For Release builds, we shall dynamically link into uCRT [ucrtbase.dll] (which is pushed down as a Windows Update on downlevel OS) but
|
||||
# wont do the same for debug/checked builds since ucrtbased.dll is not redistributable and Debug/Checked builds are not
|
||||
# production-time scenarios.
|
||||
add_compile_options($<$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>:/MT>)
|
||||
add_compile_options($<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:/MTd>)
|
||||
|
||||
#set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /ZH:SHA_256")
|
||||
|
||||
#if (CLR_CMAKE_TARGET_ARCH_AMD64)
|
||||
add_definitions(-D_TARGET_AMD64_=1)
|
||||
add_definitions(-DDBG_TARGET_64BIT=1)
|
||||
add_definitions(-DDBG_TARGET_AMD64=1)
|
||||
add_definitions(-DDBG_TARGET_WIN64=1)
|
||||
#elseif (CLR_CMAKE_TARGET_ARCH_ARM)
|
||||
# add_definitions(-D_TARGET_ARM_=1)
|
||||
# add_definitions(-DDBG_TARGET_32BIT=1)
|
||||
# add_definitions(-DDBG_TARGET_ARM=1)
|
||||
#elseif (CLR_CMAKE_TARGET_ARCH_I386)
|
||||
# add_definitions(-D_TARGET_X86_=1)
|
||||
# add_definitions(-DDBG_TARGET_32BIT=1)
|
||||
# add_definitions(-DDBG_TARGET_X86=1)
|
||||
#else ()
|
||||
# clr_unknown_arch()
|
||||
#endif (CLR_CMAKE_TARGET_ARCH_AMD64)
|
||||
|
||||
#
|
||||
# TODO: Are these needed???????????
|
||||
#
|
||||
#add_definitions(-D_BLD_CLR)
|
||||
#add_definitions(-DDEBUGGING_SUPPORTED)
|
||||
#add_definitions(-DPROFILING_SUPPORTED)
|
||||
|
||||
add_definitions(-DWIN32)
|
||||
add_definitions(-D_WIN32)
|
||||
add_definitions(-DWINVER=${WIN_VERSION_WIN8})# 0x0601 for Win7, was 0x0602
|
||||
add_definitions(-D_WIN32_WINNT=${WIN_VERSION_WIN8}) # 0x0601 for Win7
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN=1)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
#if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
|
||||
# Only enable edit and continue on windows x86 and x64
|
||||
# exclude Linux, arm & arm64
|
||||
add_definitions(-DEnC_SUPPORTED)
|
||||
#endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
|
||||
|
||||
add_definitions(-DUNICODE)
|
||||
add_definitions(-D_UNICODE)
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
SET (WindowsSdkDir $ENV{WindowsSdkDir})
|
||||
SET (WindowsSDKVersion $ENV{WindowsSDKVersion})
|
||||
SET (NETFXSdkDir $ENV{NETFXSDKDir})
|
||||
#SET (FrameWorkLibPath $ENV{FrameworkDir}/$ENV{FrameworkVersion})
|
||||
|
||||
#
|
||||
# Configure include directories
|
||||
#
|
||||
SET (WindowsSDKIncludeBase "${WindowsSdkDir}/Include/${WindowsSDKVersion}")
|
||||
|
||||
SET (IncludePath)
|
||||
#list (APPEND IncludePath "${INTERNAL_HEADER_DIR}")
|
||||
#list (APPEND IncludePath "${PUBLIC_HEADER_DIR}")
|
||||
list (APPEND IncludePath "${WindowsSDKIncludeBase}winrt")
|
||||
# Don't include due to incompatible instance.h
|
||||
# list (APPEND IncludePath "${WindowsSDKIncludeBase}um")
|
||||
list (APPEND IncludePath "${WindowsSDKIncludeBase}shared")
|
||||
list (APPEND IncludePath "${NETFXSdkDir}/Include/um")
|
||||
list (APPEND IncludePath "${WindowsSDKIncludeBase}ucrt")
|
||||
include_directories(BEFORE ${IncludePath})
|
||||
|
||||
#
|
||||
# Configure lib directories
|
||||
#
|
||||
SET (WindowsSDKLibBase "${WindowsSdkDir}/Lib/${WindowsSDKVersion}")
|
||||
SET (OneCoreLibBase "$ENV{VCInstallDir}lib/onecore/amd64")
|
||||
|
||||
SET (LibraryPath)
|
||||
if (BUILD_ONECORE)
|
||||
list (APPEND LibraryPath "${OneCoreLibBase}")
|
||||
endif (BUILD_ONECORE)
|
||||
list (APPEND LibraryPath "${WindowsSDKLibBase}ucrt/${WindowsSDKPlatform}")
|
||||
list (APPEND LibraryPath "${NETFXSdkDir}lib/um/${WindowsSDKPlatform}")
|
||||
list (APPEND LibraryPath "${WindowsSDKLibBase}um/${WindowsSDKPlatform}" )
|
||||
list (APPEND LibraryPath "${INTERNAL_LIBRARY_DIR}")
|
||||
list (APPEND LibraryPath "${PUBLIC_LIBRARY_DIR}")
|
||||
#list (APPEND LibraryPath ${FrameWorkLibPath})
|
||||
SET (WindowsSDKLibBase "${WindowsSdkDir}/Lib/${WindowsSDKVersion}")
|
||||
link_directories(${LibraryPath})
|
||||
|
||||
if (${WindowsSDKPlatform} STREQUAL "x64")
|
||||
add_definitions (
|
||||
-D_WIN64
|
||||
-D_AMD64_
|
||||
-DAMD64
|
||||
-DBUILD_WOW64_ENABLED=1
|
||||
-DBUILD_UMS_ENABLED=1
|
||||
)
|
||||
else()
|
||||
add_definitions (
|
||||
-DBUILD_WOW64_ENABLED=1
|
||||
-DBUILD_UMS_ENABLED=0
|
||||
)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Common defines.
|
||||
#
|
||||
add_definitions (
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-DCONDITION_HANDLING=1
|
||||
-DNT_UP=1
|
||||
-DNT_INST=0
|
||||
-D_NT1X_=100
|
||||
-DWINNT=1
|
||||
-DWIN32_LEAN_AND_MEAN=1
|
||||
-DDEVL=1
|
||||
#-D_MT=1
|
||||
-DMD
|
||||
-D_STL70_
|
||||
-DMI_INTERNAL
|
||||
-DWINBUILD
|
||||
-DHOOK_BUILD # TODO: should be target specific
|
||||
-DCONFIG_ENABLE_WCHAR
|
||||
-D_INTLSTR_NOTAPPEND_NULL
|
||||
-DMSC_NOOPT
|
||||
-DBUILD_WINDOWS
|
||||
-D_USE_DECLSPECS_FOR_SAL=1
|
||||
-DUNICODE
|
||||
-D_UNICODE
|
||||
-D_USE_DEV11_CRT
|
||||
)
|
||||
|
||||
#
|
||||
# platform specific defines
|
||||
#
|
||||
add_definitions(
|
||||
#-DNTDDI_VERSION=${NTDDI_VERSION_WIN7}
|
||||
-DNTDDI_VERSION=${NTDDI_VERSION_WIN10}
|
||||
-DWINBLUE_KBSPRING14
|
||||
#-D_APISET_WINDOWS_VERSION=${WIN_VERSION_WIN7}
|
||||
-D_APISET_WINDOWS_VERSION=${WIN_VERSION_WIN10}
|
||||
#-D_APISET_MINWIN_VERSION=0x0100
|
||||
-D_APISET_MINWIN_VERSION=0x0106
|
||||
#-D_APISET_MINCORE_VERSION=0x0100
|
||||
-D_APISET_MINCORE_VERSION=0x0105
|
||||
-D_WIN32_IE=0x0800
|
||||
#-D_WIN32_WINNT=${WIN_VERSION_WIN7}
|
||||
-D_WIN32_WINNT=${WIN_VERSION_WIN10}
|
||||
#-DWINVER=${WIN_VERSION_WIN7}
|
||||
-DWINVER=${WIN_VERSION_WIN10}
|
||||
)
|
||||
|
||||
# if not DEBUG for DSC
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
|
||||
#set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF /NODEFAULTLIB")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF /NODEFAULTLIB")
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
SET (WindowsSdkDir $ENV{WindowsSdkDir})
|
||||
SET (WindowsSDKVersion $ENV{WindowsSDKVersion})
|
||||
SET (NETFXSdkDir $ENV{NETFXSDKDir})
|
||||
|
||||
#
|
||||
# Configure include directories
|
||||
#
|
||||
SET (WindowsSDKIncludeBase "${WindowsSdkDir}/Include/${WindowsSDKVersion}")
|
||||
|
||||
SET (IncludePath)
|
||||
list (APPEND IncludePath "${WindowsSDKIncludeBase}winrt")
|
||||
list (APPEND IncludePath "${WindowsSDKIncludeBase}shared")
|
||||
#list (APPEND IncludePath "${NETFXSdkDir}/Include/um")
|
||||
list (APPEND IncludePath "${WindowsSDKIncludeBase}ucrt")
|
||||
include_directories(BEFORE ${IncludePath})
|
||||
|
||||
#
|
||||
# Configure lib directories
|
||||
#
|
||||
SET (WindowsSDKLibBase "${WindowsSdkDir}/Lib/${WindowsSDKVersion}")
|
||||
SET (OneCoreLibBase "$ENV{VCInstallDir}lib/onecore/amd64")
|
||||
|
||||
SET (LibraryPath)
|
||||
list (APPEND LibraryPath "${OneCoreLibBase}")
|
||||
list (APPEND LibraryPath "${WindowsSDKLibBase}ucrt/${WindowsSDKPlatform}")
|
||||
list (APPEND LibraryPath "${WindowsSDKLibBase}um/${WindowsSDKPlatform}" )
|
||||
###list (APPEND LibraryPath "${NETFXSdkDir}lib/um/${WindowsSDKPlatform}")
|
||||
link_directories(${LibraryPath})
|
||||
|
||||
#
|
||||
# Tell CMake to set the platform toolset. Nano Server requires the Win10 SDK and updated onecore.lib
|
||||
#
|
||||
set(CMAKE_VS_PLATFORM_TOOLSET "v140") # Use VS 2015 with Win 10 SDK
|
||||
set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0.10586.0") # Targets Windows 10. Alt is ${WindowsSDKVersion}
|
||||
|
||||
if (BUILD_ONECORE)
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "") # do not link against standard win32 libs i.e. kernel32, uuid, user32, etc.
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
add_compile_options(/Zl) # omit default library name in .OBJ
|
||||
add_compile_options(/Zi) # enable debugging information
|
||||
add_compile_options(/nologo) # Suppress Startup Banner
|
||||
add_compile_options(/W3) # set warning level to 3
|
||||
#add_compile_options(/WX-) # treat warnings as errors
|
||||
add_compile_options(/wd4996) # Ignore deprecation warnings
|
||||
add_compile_options(/Od) # enable intrinsics
|
||||
add_compile_options(/sdl)
|
||||
|
||||
add_compile_options(/Gm) # minimal rebuild
|
||||
add_compile_options(/EHsc) # enable C++ EH (w/ SEH exceptions)
|
||||
add_compile_options(/RTC1)
|
||||
#add_compile_options(/MDd)
|
||||
add_compile_options(/MD)
|
||||
add_compile_options(/GS) # Buffer Security Check
|
||||
add_compile_options(/fp:precise)
|
||||
add_compile_options(/Zp8) # pack structs on 8-byte boundary
|
||||
add_compile_options(/Zc:wchar_t) # C++ language conformance: wchar_t is NOT the native type, but a typedef
|
||||
#add_compile_options(/U_WINDOWS)
|
||||
|
||||
add_definitions(
|
||||
-D_WIN64
|
||||
-D_AMD64_
|
||||
-DAMD64
|
||||
-D_APISET_WINDOWS_VERSION=0x601
|
||||
-D_APISET_MINWIN_VERSION=0x0101
|
||||
-D_APISET_MINCORE_VERSION=0x0100
|
||||
-DNTDDI_VERSION=0x0A000002
|
||||
# -DWIN32=100
|
||||
-D_DEBUG
|
||||
-D_UNICODE
|
||||
-DUNICODE
|
||||
-DWIN32_LEAN_AND_MEAN=1
|
||||
#-DNDEBUG
|
||||
)
|
||||
|
||||
set(CMAKE_ENABLE_EXPORTS ON)
|
||||
|
||||
set(MY_COMMON_LINK_FLAGS "/NOLOGO /MANIFEST:NO /NXCOMPAT /DYNAMICBASE /TLBID:1 /MACHINE:x64 /guard:cf /OPT:REF /OPT:ICF /NODEFAULTLIB")
|
||||
set(MY_COMMON_LINK_FLAGS "${MY_COMMON_LINK_FLAGS} /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:advapi32.lib") # Explicitly exclude kernel32 and advapi32 since CMake is including them and they block execution on Nano Server
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MY_COMMON_LINK_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.00 /INCREMENTAL:NO") #windows subsystem
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MY_COMMON_LINK_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE /INCREMENTAL:NO") #windows subsystem
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# CMake Instructions for producing pwrshcommon.lib for consumption by powershell.exe and
|
||||
# pwrshplugin.dll. It is a library that is statically compiled into each binary.
|
||||
#
|
||||
add_library(pwrshcommon
|
||||
pwrshcommon.cpp
|
||||
WinSystemCallFacade.cpp
|
||||
ConfigFileReader.cpp
|
||||
)
|
||||
|
||||
target_include_directories(pwrshcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if (BUILD_ONECORE)
|
||||
message("Building OneCore version of pwrshcommon.lib")
|
||||
# Libraries to use when creating this binary for Windows on OneCore-based SKUs
|
||||
set(PWRSHCOMMON_WINDOWS_LIBS
|
||||
# onecore.lib
|
||||
)
|
||||
set_target_properties(pwrshcommon PROPERTIES COMPILE_DEFINITIONS "CORECLR")
|
||||
else () # NOT BUILD_ONECORE
|
||||
message("Building Full version of pwrshcommon.lib")
|
||||
# Libraries to use when creating this binary for Windows on full SKUs
|
||||
# Note: The appropriate libs get added automatically by VS
|
||||
set(PWRSHCOMMON_WINDOWS_LIBS
|
||||
# CoreCLR libs
|
||||
### ${STATIC_MT_CRT_LIB}
|
||||
### ${STATIC_MT_VCRT_LIB}
|
||||
### ${STATIC_UCRT_LIB}
|
||||
#
|
||||
# ole32.lib
|
||||
# oleaut32.lib
|
||||
# uuid.lib
|
||||
# user32.lib
|
||||
# MUILoad.lib
|
||||
# msxml6.lib
|
||||
# mscoree.lib)
|
||||
)
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
target_link_libraries(pwrshcommon
|
||||
${PWRSHCOMMON_WINDOWS_LIBS})
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mscoree.h>
|
||||
#include "NativeMshConstants.h"
|
||||
|
||||
namespace NativeMsh
|
||||
@@ -32,322 +31,413 @@ namespace NativeMsh
|
||||
|
||||
virtual bool IsInitialized() { return false; }
|
||||
|
||||
// For setting a host ptr since it is not known at container creation time.
|
||||
// TODO: Can I make it immutable?
|
||||
virtual void SetClrHost(
|
||||
void* hostPtr) = 0;
|
||||
|
||||
// Graceful clean up of the object to prevent leaks
|
||||
virtual unsigned int CleanUpHostWrapper() = 0;
|
||||
|
||||
void SetAppDomainId(DWORD id)
|
||||
{
|
||||
m_appDomainId = id;
|
||||
}
|
||||
|
||||
DWORD GetAppDomainId()
|
||||
{
|
||||
return m_appDomainId;
|
||||
}
|
||||
|
||||
//
|
||||
// The following methods are direct thin wrappers for the host calls.
|
||||
//
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateAppDomainWithManager(
|
||||
/* [in] */ LPCWSTR wszFriendlyName,
|
||||
/* [in] */ DWORD dwFlags,
|
||||
/* [in] */ LPCWSTR wszAppDomainManagerAssemblyName,
|
||||
/* [in] */ LPCWSTR wszAppDomainManagerTypeName,
|
||||
/* [in] */ int nProperties,
|
||||
/* [in] */ LPCWSTR *pPropertyNames,
|
||||
/* [in] */ LPCWSTR *pPropertyValues,
|
||||
/* [out] */ DWORD *pAppDomainID) = 0;
|
||||
virtual unsigned int SetupWrapper(LPCSTR coreClrPathPtr) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE UnloadAppDomain(
|
||||
/* [in] */ DWORD dwAppDomainId,
|
||||
/* [in] */ BOOL fWaitUntilDone) = 0;
|
||||
virtual int InitializeClr(
|
||||
const char* exePath,
|
||||
const char* appDomainFriendlyName,
|
||||
int propertyCount,
|
||||
const char** propertyKeys,
|
||||
const char** propertyValues) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateDelegate(
|
||||
/* [in] */ DWORD appDomainID,
|
||||
/* [in] */ LPCWSTR wszAssemblyName,
|
||||
/* [in] */ LPCWSTR wszClassName,
|
||||
/* [in] */ LPCWSTR wszMethodName,
|
||||
/* [out] */ INT_PTR *fnPtr) = 0;
|
||||
virtual int CreateDelegate(
|
||||
const char* entryPointAssemblyName,
|
||||
const char* entryPointTypeName,
|
||||
const char* entryPointMethodName,
|
||||
void** delegate) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Authenticate(
|
||||
/* [in] */ ULONGLONG authKey) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetStartupFlags(
|
||||
/* [in] */ STARTUP_FLAGS dwFlags) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Start() = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Stop() = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Release() = 0;
|
||||
// TODO: This probably isn't needed
|
||||
virtual int ShutdownClr() = 0;
|
||||
};
|
||||
|
||||
#if CORECLR
|
||||
//
|
||||
// Concrete implementation of the wrapper for the ICLRRuntimeHost2 interface.
|
||||
// Concrete implementation of the wrapper for CoreClr.dll's
|
||||
// Platform-Agnostic hosting interface.
|
||||
//
|
||||
class ICLRRuntimeHost2Wrapper : public ClrHostWrapper
|
||||
class CoreClrHostingApiWrapper : public ClrHostWrapper
|
||||
{
|
||||
private:
|
||||
ICLRRuntimeHost2* pHost;
|
||||
// Handle of CoreClr.dll
|
||||
HMODULE coreClrHandle;
|
||||
HMODULE pinnedModuleHandle;
|
||||
|
||||
// CoreCLR.dll API values that are hidden from the user and kept internal.
|
||||
void* hostHandle;
|
||||
unsigned int domainId;
|
||||
|
||||
// The name of the CoreCLR native runtime DLL.
|
||||
PCSTR coreClrDllName = "CoreCLR.dll";
|
||||
|
||||
//
|
||||
// Function Pointer Definitions for the function pointers to load from CoreCLR.dll
|
||||
//
|
||||
typedef int (STDMETHODCALLTYPE *coreclr_initialize_ptr)(
|
||||
const char* exePath,
|
||||
const char* appDomainFriendlyName,
|
||||
int propertyCount,
|
||||
const char** propertyKeys,
|
||||
const char** propertyValues,
|
||||
void** hostHandle,
|
||||
unsigned int* domainId);
|
||||
|
||||
typedef int (STDMETHODCALLTYPE *coreclr_shutdown_ptr)(
|
||||
void* hostHandle,
|
||||
unsigned int domainId);
|
||||
|
||||
typedef int (STDMETHODCALLTYPE *coreclr_create_delegate_ptr)(
|
||||
void* hostHandle,
|
||||
unsigned int domainId,
|
||||
const char* entryPointAssemblyName,
|
||||
const char* entryPointTypeName,
|
||||
const char* entryPointMethodName,
|
||||
void** delegate);
|
||||
|
||||
// Pointers to exported functions of CoreClr.dll
|
||||
coreclr_initialize_ptr initPtr;
|
||||
coreclr_shutdown_ptr shutdownPtr;
|
||||
coreclr_create_delegate_ptr createDelegatePtr;
|
||||
|
||||
public:
|
||||
ICLRRuntimeHost2Wrapper() : pHost(NULL) {}
|
||||
virtual ~ICLRRuntimeHost2Wrapper()
|
||||
CoreClrHostingApiWrapper()
|
||||
: coreClrHandle(NULL),
|
||||
pinnedModuleHandle(NULL),
|
||||
hostHandle(NULL),
|
||||
domainId(0),
|
||||
initPtr(NULL),
|
||||
shutdownPtr(NULL),
|
||||
createDelegatePtr(NULL)
|
||||
{}
|
||||
|
||||
virtual ~CoreClrHostingApiWrapper()
|
||||
{
|
||||
CleanUpHostWrapper();
|
||||
this->CleanUpHostWrapper();
|
||||
}
|
||||
|
||||
virtual bool IsInitialized() { return (pHost != NULL); }
|
||||
|
||||
// For setting a host ptr since it is not known at container creation time.
|
||||
virtual void SetClrHost(void* hostPtr)
|
||||
virtual bool IsInitialized()
|
||||
{
|
||||
return (NULL != coreClrHandle);
|
||||
}
|
||||
|
||||
//
|
||||
// Attempts to load CoreCLR.dll from the specified directory.
|
||||
// On success pins the dll, sets coreCLRDirectoryPath and returns the HMODULE.
|
||||
// On failure returns NULL.
|
||||
//
|
||||
virtual unsigned int SetupWrapper(LPCSTR coreClrPathPtr)
|
||||
{
|
||||
pHost = (ICLRRuntimeHost2*)hostPtr;
|
||||
std::string coreClrPath(coreClrPathPtr);
|
||||
coreClrPath += coreClrDllName;
|
||||
|
||||
HMODULE result = LoadLibraryExA(coreClrPath.c_str(), NULL, 0);
|
||||
if (!result)
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
// Pin the module - CoreCLR.dll does not support being unloaded.
|
||||
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, coreClrPath.c_str(), &pinnedModuleHandle))
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
initPtr = (coreclr_initialize_ptr)GetProcAddress(result, "coreclr_initialize");
|
||||
shutdownPtr = (coreclr_shutdown_ptr)GetProcAddress(result, "coreclr_shutdown");
|
||||
createDelegatePtr = (coreclr_create_delegate_ptr)GetProcAddress(result, "coreclr_create_delegate");
|
||||
|
||||
if (NULL == initPtr ||
|
||||
NULL == shutdownPtr ||
|
||||
NULL == createDelegatePtr)
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
// Initialization succeeded. Save the handle and return success;
|
||||
coreClrHandle = result;
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
virtual unsigned int CleanUpHostWrapper()
|
||||
{
|
||||
if (this->IsInitialized())
|
||||
{
|
||||
if (FAILED(this->UnloadAppDomain(this->GetAppDomainId(), true)))
|
||||
{
|
||||
return g_UNLOAD_APPDOMAIN_FAILED;
|
||||
}
|
||||
|
||||
if (FAILED(this->Stop()))
|
||||
HRESULT status = this->ShutdownClr();
|
||||
if (FAILED(status))
|
||||
{
|
||||
return g_STOP_CLR_HOST_FAILED;
|
||||
}
|
||||
|
||||
// Release the reference to the host
|
||||
if (FAILED(this->Release()))
|
||||
|
||||
if (this->coreClrHandle)
|
||||
{
|
||||
return g_RELEASE_CLR_HOST_FAILED;
|
||||
// TODO: Is this comment still relevant with the new hosting API?
|
||||
//
|
||||
// Free the module. This is done for completeness, but in fact CoreCLR.dll
|
||||
// was pinned earlier so this call won't actually free it. The pinning is
|
||||
// done because CoreCLR does not support unloading.
|
||||
::FreeLibrary(this->coreClrHandle);
|
||||
this->coreClrHandle = NULL;
|
||||
}
|
||||
this->SetClrHost(NULL);
|
||||
}
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateAppDomainWithManager(
|
||||
/* [in] */ LPCWSTR wszFriendlyName,
|
||||
/* [in] */ DWORD dwFlags,
|
||||
/* [in] */ LPCWSTR wszAppDomainManagerAssemblyName,
|
||||
/* [in] */ LPCWSTR wszAppDomainManagerTypeName,
|
||||
/* [in] */ int nProperties,
|
||||
/* [in] */ LPCWSTR *pPropertyNames,
|
||||
/* [in] */ LPCWSTR *pPropertyValues,
|
||||
/* [out] */ DWORD *pAppDomainID)
|
||||
virtual int InitializeClr(
|
||||
const char* exePath,
|
||||
const char* appDomainFriendlyName,
|
||||
int propertyCount,
|
||||
const char** propertyKeys,
|
||||
const char** propertyValues)
|
||||
{
|
||||
if (pHost)
|
||||
if (initPtr)
|
||||
{
|
||||
return pHost->CreateAppDomainWithManager(
|
||||
wszFriendlyName,
|
||||
dwFlags,
|
||||
wszAppDomainManagerAssemblyName,
|
||||
wszAppDomainManagerTypeName,
|
||||
nProperties,
|
||||
pPropertyNames,
|
||||
pPropertyValues,
|
||||
pAppDomainID);
|
||||
return initPtr(
|
||||
exePath,
|
||||
appDomainFriendlyName,
|
||||
propertyCount,
|
||||
propertyKeys,
|
||||
propertyValues,
|
||||
&(this->hostHandle),
|
||||
&(this->domainId));
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE UnloadAppDomain(
|
||||
/* [in] */ DWORD dwAppDomainId,
|
||||
/* [in] */ BOOL fWaitUntilDone)
|
||||
virtual int CreateDelegate(
|
||||
const char* entryPointAssemblyName,
|
||||
const char* entryPointTypeName,
|
||||
const char* entryPointMethodName,
|
||||
void** delegate)
|
||||
{
|
||||
if (pHost)
|
||||
if (createDelegatePtr)
|
||||
{
|
||||
return pHost->UnloadAppDomain(
|
||||
dwAppDomainId,
|
||||
fWaitUntilDone);
|
||||
return createDelegatePtr(
|
||||
this->hostHandle,
|
||||
this->domainId,
|
||||
entryPointAssemblyName,
|
||||
entryPointTypeName,
|
||||
entryPointMethodName,
|
||||
delegate);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateDelegate(
|
||||
/* [in] */ DWORD appDomainID,
|
||||
/* [in] */ LPCWSTR wszAssemblyName,
|
||||
/* [in] */ LPCWSTR wszClassName,
|
||||
/* [in] */ LPCWSTR wszMethodName,
|
||||
/* [out] */ INT_PTR *fnPtr)
|
||||
virtual int ShutdownClr()
|
||||
{
|
||||
if (pHost)
|
||||
if (shutdownPtr)
|
||||
{
|
||||
return pHost->CreateDelegate(
|
||||
appDomainID,
|
||||
wszAssemblyName,
|
||||
wszClassName,
|
||||
wszMethodName,
|
||||
fnPtr);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Authenticate(
|
||||
/* [in] */ ULONGLONG authKey)
|
||||
{
|
||||
if (pHost)
|
||||
{
|
||||
return pHost->Authenticate(
|
||||
authKey);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetStartupFlags(
|
||||
/* [in] */ STARTUP_FLAGS dwFlags)
|
||||
{
|
||||
if (pHost)
|
||||
{
|
||||
return pHost->SetStartupFlags(
|
||||
dwFlags);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Start()
|
||||
{
|
||||
if (pHost)
|
||||
{
|
||||
return pHost->Start();
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Stop()
|
||||
{
|
||||
if (pHost)
|
||||
{
|
||||
return pHost->Stop();
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Release()
|
||||
{
|
||||
if (pHost)
|
||||
{
|
||||
return pHost->Release();
|
||||
return shutdownPtr(
|
||||
this->hostHandle,
|
||||
this->domainId);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Encapsulates the environment that CoreCLR will run in, including the TPALIST
|
||||
class HostEnvironment
|
||||
{
|
||||
private:
|
||||
// The path to this module
|
||||
wchar_t m_hostPath[MAX_PATH];
|
||||
char m_hostPath[MAX_PATH];
|
||||
wchar_t m_hostPathW[MAX_PATH];
|
||||
|
||||
// The path to the directory containing this module
|
||||
wchar_t m_hostDirectoryPath[MAX_PATH];
|
||||
char m_hostDirectoryPath[MAX_PATH];
|
||||
wchar_t m_hostDirectoryPathW[MAX_PATH];
|
||||
|
||||
// The name of this module, without the path
|
||||
std::wstring m_hostBinaryName;
|
||||
std::string m_hostBinaryName;
|
||||
std::wstring m_hostBinaryNameW;
|
||||
|
||||
// The path to the directory that CoreCLR is in
|
||||
wchar_t m_coreCLRDirectoryPath[MAX_PATH];
|
||||
char m_coreCLRDirectoryPath[MAX_PATH];
|
||||
wchar_t m_coreCLRDirectoryPathW[MAX_PATH];
|
||||
|
||||
HMODULE m_coreCLRModule;
|
||||
void convertAnsiToWide(char* ansiArray, wchar_t* wideArray)
|
||||
{
|
||||
// Generate the wide version of the string and save its value;
|
||||
//
|
||||
// This is a two call function. The first call is to get the necessary length.
|
||||
// The second call is to perform the actual operation.
|
||||
int length = ::MultiByteToWideChar(CP_UTF8, 0, ansiArray, -1, NULL, 0);
|
||||
if (0 < length)
|
||||
{
|
||||
LPWSTR result = new wchar_t[length];
|
||||
if (NULL != result)
|
||||
{
|
||||
length = ::MultiByteToWideChar(CP_UTF8, 0, ansiArray, -1, result, length);
|
||||
if (0 < length)
|
||||
{
|
||||
wcscpy_s(wideArray, MAX_PATH, result);
|
||||
}
|
||||
delete[] result; // Free the allocated string to avoid a memory leak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void convertWideToAnsi(wchar_t* wideArray, char* ansiArray)
|
||||
{
|
||||
// Generate the ansi version of the string and save its value;
|
||||
//
|
||||
// This is a two call function. The first call is to get the necessary length.
|
||||
// The second call is to perform the actual operation.
|
||||
int length = ::WideCharToMultiByte(CP_ACP, 0, wideArray, -1, NULL, 0, NULL, NULL);
|
||||
if (0 < length)
|
||||
{
|
||||
LPSTR result = new char[length];
|
||||
if (NULL != result)
|
||||
{
|
||||
length = ::WideCharToMultiByte(CP_ACP, 0, wideArray, -1, result, length, NULL, NULL);
|
||||
if (0 < length)
|
||||
{
|
||||
strcpy_s(ansiArray, MAX_PATH, result);
|
||||
}
|
||||
delete[] result; // Free the allocated string to avoid a memory leak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
HostEnvironment()
|
||||
: m_coreCLRModule(0)
|
||||
{
|
||||
memset(m_hostPath, 0, sizeof(m_hostPath));
|
||||
memset(m_hostDirectoryPath, 0, sizeof(m_hostDirectoryPath));
|
||||
memset(m_coreCLRDirectoryPath, 0, sizeof(m_coreCLRDirectoryPath));
|
||||
}
|
||||
|
||||
~HostEnvironment()
|
||||
{
|
||||
if (m_coreCLRModule)
|
||||
{
|
||||
// Free the module. This is done for completeness, but in fact CoreCLR.dll
|
||||
// was pinned earlier so this call won't actually free it. The pinning is
|
||||
// done because CoreCLR does not support unloading.
|
||||
::FreeLibrary(m_coreCLRModule);
|
||||
}
|
||||
}
|
||||
~HostEnvironment() {}
|
||||
|
||||
// Safely copies in a host path
|
||||
void SetHostPath(PCWSTR hostPath)
|
||||
void SetHostPath(PCSTR hostPath)
|
||||
{
|
||||
if (hostPath)
|
||||
{
|
||||
::ExpandEnvironmentStringsW(hostPath, m_hostPath, MAX_PATH);
|
||||
//::wcsncpy_s(m_hostPath, hostPath, _TRUNCATE);
|
||||
::ExpandEnvironmentStringsA(hostPath, m_hostPath, MAX_PATH);
|
||||
|
||||
convertAnsiToWide(m_hostPath, m_hostPathW);
|
||||
}
|
||||
}
|
||||
void SetHostPathW(PCWSTR hostPath)
|
||||
{
|
||||
if (hostPath)
|
||||
{
|
||||
::ExpandEnvironmentStringsW(hostPath, m_hostPathW, MAX_PATH);
|
||||
|
||||
convertWideToAnsi(m_hostPathW, m_hostPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the path to the host module
|
||||
PCWSTR GetHostPath()
|
||||
PCSTR GetHostPath()
|
||||
{
|
||||
return m_hostPath;
|
||||
}
|
||||
|
||||
PCWSTR GetHostPathW()
|
||||
{
|
||||
return m_hostPathW;
|
||||
}
|
||||
|
||||
// Safely copies in a host binary name
|
||||
void SetHostBinaryName(PCWSTR hostBinaryName)
|
||||
void SetHostBinaryName(PCSTR hostBinaryName)
|
||||
{
|
||||
if (hostBinaryName)
|
||||
{
|
||||
m_hostBinaryName = std::wstring(hostBinaryName);
|
||||
m_hostBinaryName = std::string(hostBinaryName);
|
||||
}
|
||||
}
|
||||
|
||||
void SetHostBinaryNameW(PCWSTR hostBinaryName)
|
||||
{
|
||||
if (hostBinaryName)
|
||||
{
|
||||
m_hostBinaryNameW = std::wstring(hostBinaryName);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the name of the host module
|
||||
PCWSTR GetHostBinaryName()
|
||||
PCSTR GetHostBinaryName()
|
||||
{
|
||||
return m_hostBinaryName.c_str();
|
||||
}
|
||||
|
||||
PCWSTR GetHostBinaryNameW()
|
||||
{
|
||||
return m_hostBinaryNameW.c_str();
|
||||
}
|
||||
|
||||
// Safely copies in a host directory path
|
||||
void SetHostDirectoryPath(PCWSTR hostDirPath)
|
||||
void SetHostDirectoryPath(PCSTR hostDirPath)
|
||||
{
|
||||
if (hostDirPath)
|
||||
{
|
||||
::ExpandEnvironmentStringsW(hostDirPath, m_hostDirectoryPath, MAX_PATH);
|
||||
//::wcsncpy_s(m_hostDirectoryPath, hostDirPath, _TRUNCATE);
|
||||
::ExpandEnvironmentStringsA(hostDirPath, m_hostDirectoryPath, MAX_PATH);
|
||||
|
||||
convertAnsiToWide(m_hostDirectoryPath, m_hostDirectoryPathW);
|
||||
}
|
||||
}
|
||||
|
||||
void SetHostDirectoryPathW(PCWSTR hostDirPath)
|
||||
{
|
||||
if (hostDirPath)
|
||||
{
|
||||
::ExpandEnvironmentStringsW(hostDirPath, m_hostDirectoryPathW, MAX_PATH);
|
||||
|
||||
convertWideToAnsi(m_hostDirectoryPathW, m_hostDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the directory path of the host module
|
||||
PCWSTR GetHostDirectoryPath()
|
||||
PCSTR GetHostDirectoryPath()
|
||||
{
|
||||
return m_hostDirectoryPath;
|
||||
}
|
||||
|
||||
// Returns the directory path of the host module as a wide char string
|
||||
PCWSTR GetHostDirectoryPathW()
|
||||
{
|
||||
return m_hostDirectoryPathW;
|
||||
}
|
||||
|
||||
// Safely copies in a core clr directory path
|
||||
void SetCoreCLRDirectoryPath(PCWSTR hostClrPath)
|
||||
void SetCoreCLRDirectoryPath(PCSTR hostClrPath)
|
||||
{
|
||||
if (hostClrPath)
|
||||
{
|
||||
::ExpandEnvironmentStringsW(hostClrPath, m_coreCLRDirectoryPath, MAX_PATH);
|
||||
//::wcsncpy_s(m_coreCLRDirectoryPath, hostClrPath, _TRUNCATE);
|
||||
::ExpandEnvironmentStringsA(hostClrPath, m_coreCLRDirectoryPath, MAX_PATH);
|
||||
|
||||
convertAnsiToWide(m_coreCLRDirectoryPath, m_coreCLRDirectoryPathW);
|
||||
}
|
||||
}
|
||||
|
||||
void SetCoreCLRDirectoryPathW(PCWSTR hostClrPath)
|
||||
{
|
||||
if (hostClrPath)
|
||||
{
|
||||
::ExpandEnvironmentStringsW(hostClrPath, m_coreCLRDirectoryPathW, MAX_PATH);
|
||||
|
||||
convertWideToAnsi(m_coreCLRDirectoryPathW, m_coreCLRDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the directory path of the host module
|
||||
PCWSTR GetCoreCLRDirectoryPath()
|
||||
PCSTR GetCoreCLRDirectoryPath()
|
||||
{
|
||||
return m_coreCLRDirectoryPath;
|
||||
}
|
||||
|
||||
void SetCoreCLRModule(HMODULE module)
|
||||
// Returns the directory path of the host module
|
||||
PCWSTR GetCoreCLRDirectoryPathW()
|
||||
{
|
||||
m_coreCLRModule = module;
|
||||
return m_coreCLRDirectoryPathW;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
} // namespace NativeMsh
|
||||
} // namespace NativeMsh
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <windef.h>
|
||||
|
||||
#include "NativeMsh.h"
|
||||
#include "ConfigFileReader.h"
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
// The name of the PowerShell config file that identifies the PowerShell install location.
|
||||
// We use a config file to avoid writing to the registry during install
|
||||
// or hard coding paths into the binary.
|
||||
static PCWSTR powerShellConfigFileName = L"RemotePowerShellConfig.txt";
|
||||
|
||||
ConfigFileReader::ConfigFileReader()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int ConfigFileReader::Read(
|
||||
std::wstring pathToConfig)
|
||||
{
|
||||
std::wstring absolutePathToConfigFile(pathToConfig);
|
||||
absolutePathToConfigFile += powerShellConfigFileName;
|
||||
std::wfstream psConfigFile(absolutePathToConfigFile.c_str());
|
||||
|
||||
if (!psConfigFile.is_open())
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
std::wstring line;
|
||||
std::wstring psHomeDirTag(L"PSHOMEDIR=");
|
||||
std::wstring coreClrDirTag(L"CORECLRDIR=");
|
||||
while (std::getline(psConfigFile, line))
|
||||
{
|
||||
;
|
||||
|
||||
// Search for the first actionable character in the line to
|
||||
// limit the number of passes that are made iterating through the line.
|
||||
for(std::wstring::const_iterator iter = line.begin(); iter != line.end(); iter++)
|
||||
{
|
||||
if (*iter == L'#')
|
||||
{
|
||||
// Stop parsing the line because the rest of it is a comment
|
||||
continue;
|
||||
}
|
||||
else if (*iter == L'p' || *iter == L'P')
|
||||
{
|
||||
this->pathToPowerShellAssemblies = this->getValueFromLine(line, psHomeDirTag);
|
||||
if (this->pathToPowerShellAssemblies.size() > 0) // Found a match
|
||||
{
|
||||
std::wstring::const_iterator slashIter = this->pathToPowerShellAssemblies.end();
|
||||
slashIter--;
|
||||
if (*slashIter != L'\\')
|
||||
{
|
||||
// Guarantee that there is a '\' at the end of the path
|
||||
this->pathToPowerShellAssemblies.append(L"\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*iter == L'c' || *iter == L'C')
|
||||
{
|
||||
this->coreClrDirectory = this->getValueFromLine(line, coreClrDirTag);
|
||||
if (this->coreClrDirectory.size() > 0) // Found a match
|
||||
{
|
||||
std::wstring::const_iterator slashIter = this->coreClrDirectory.end();
|
||||
slashIter--;
|
||||
if (*slashIter != L'\\')
|
||||
{
|
||||
// Guarantee that there is a '\' at the end of the path
|
||||
this->coreClrDirectory.append(L"\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Else: Do nothing to ignore unmatched characters (whitespace, etc.)
|
||||
}
|
||||
}
|
||||
if (0 == this->pathToPowerShellAssemblies.size() ||
|
||||
0 == this->coreClrDirectory.size())
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// This trim function removes beginning and ending whitespace. It does not
|
||||
// remove internal whitespace because that is valid within paths.
|
||||
std::wstring ConfigFileReader::trim(
|
||||
const std::wstring& toTrim)
|
||||
{
|
||||
static PCWSTR WHITESPACE_CHARS = L" \n\r\t";
|
||||
std::wstring copyToTrim = toTrim;
|
||||
std::size_t first = copyToTrim.find_first_not_of(WHITESPACE_CHARS);
|
||||
|
||||
if (first == std::wstring::npos)
|
||||
{
|
||||
// No non-whitespace found
|
||||
return std::wstring(L"");
|
||||
}
|
||||
|
||||
// Result not checked for std::wstring::npos because it is guaranteed to have a value if the first pass succeeded.
|
||||
copyToTrim.erase(copyToTrim.find_last_not_of(WHITESPACE_CHARS)+1);
|
||||
|
||||
return copyToTrim.substr(first);
|
||||
}
|
||||
|
||||
// Parses the specified line for the given tag. Tags are assumed to include
|
||||
// the "=" separator character.
|
||||
std::wstring ConfigFileReader::getValueFromLine(
|
||||
const std::wstring& line, // Passed by value to preserve the original line.
|
||||
std::wstring& tagToFind)
|
||||
{
|
||||
std::wstring trimmedLine = this->trim(line);
|
||||
std::size_t index = trimmedLine.find(tagToFind);
|
||||
if (std::string::npos != index)
|
||||
{
|
||||
std::wstring value = trimmedLine.substr(index + tagToFind.size()); // Everything else after the tag
|
||||
return this->trim(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::wstring(L"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// Microsoft Windows NT
|
||||
// Copyright (C) Microsoft Corporation, 2014.
|
||||
//
|
||||
// Contents: A class that extracts the path to $PSHOME and the path to its
|
||||
// CoreCLR from a configuration file.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
class ConfigFileReader
|
||||
{
|
||||
private:
|
||||
std::wstring pathToPowerShellAssemblies;
|
||||
std::wstring coreClrDirectory;
|
||||
|
||||
std::wstring trim(const std::wstring& toTrim);
|
||||
std::wstring getValueFromLine(const std::wstring& line, std::wstring& tagToFind);
|
||||
|
||||
public:
|
||||
ConfigFileReader();
|
||||
|
||||
// Initiates a Read operation of the specified configuration file.
|
||||
unsigned int Read(std::wstring pathToConfig);
|
||||
|
||||
// Information Getters
|
||||
std::wstring GetPathToPowerShell() { return pathToPowerShellAssemblies; }
|
||||
std::wstring GetPathToCoreClr() { return coreClrDirectory; }
|
||||
};
|
||||
} // namespace NativeMsh
|
||||
|
||||
@@ -17,14 +17,20 @@
|
||||
#include "NativeMshConstants.h"
|
||||
#include "ClrHostWrapper.h"
|
||||
#include "SystemCallFacade.h"
|
||||
#include "ConfigFileReader.h"
|
||||
#include "IPwrshCommonOutput.h"
|
||||
|
||||
#if !CORECLR
|
||||
#include <mscoree.h>
|
||||
#endif
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
class PwrshCommon
|
||||
{
|
||||
private:
|
||||
IPwrshCommonOutput* output;
|
||||
ConfigFileReader* reader;
|
||||
SystemCallFacade* sysCalls;
|
||||
|
||||
public:
|
||||
@@ -37,6 +43,7 @@ namespace NativeMsh
|
||||
// allocate them with "new".
|
||||
PwrshCommon(
|
||||
IPwrshCommonOutput* outObj, // Enables clients to specify how error messages are displayed or suppressed
|
||||
ConfigFileReader* rdr, // Enables specification of how the config file is read.
|
||||
SystemCallFacade* systemCalls); // Wraps all calls to Windows APIs to allow for dependency injection via unit test
|
||||
|
||||
~PwrshCommon();
|
||||
@@ -91,17 +98,12 @@ namespace NativeMsh
|
||||
__deref_out_opt PWSTR * pwszRuntimeVersion,
|
||||
__deref_out_opt PWSTR * pwszConsoleHostAssemblyName);
|
||||
|
||||
#if CORECLR
|
||||
unsigned int LaunchCoreCLR(
|
||||
ClrHostWrapper* hostWrapper,
|
||||
HostEnvironment& hostEnvironment);
|
||||
HostEnvironment& hostEnvironment,
|
||||
PCSTR friendlyName);
|
||||
|
||||
unsigned int CreateAppDomain(
|
||||
ClrHostWrapper* hostWrapper,
|
||||
PCWSTR friendlyName,
|
||||
HostEnvironment& hostEnvironment);
|
||||
|
||||
#else // !CORECLR
|
||||
#if !CORECLR
|
||||
// NOTE:
|
||||
// This must be ifdef'd out of the CoreCLR build because it uses .NET 1.0
|
||||
// types that have been deprecated and removed from mscoree.h.
|
||||
@@ -113,7 +115,6 @@ namespace NativeMsh
|
||||
LPCWSTR wszMonadVersion,
|
||||
LPCWSTR wszRuntimeVersion,
|
||||
__in_ecount(1) ICorRuntimeHost** pCLR);
|
||||
|
||||
#endif // !CORECLR
|
||||
|
||||
protected:
|
||||
@@ -170,28 +171,21 @@ namespace NativeMsh
|
||||
__out_ecount(1) int * lpMinorVersion);
|
||||
|
||||
virtual bool DoesAssemblyExist(
|
||||
std::wstring& fileToTest);
|
||||
std::string& fileToTest);
|
||||
|
||||
virtual void ProbeAssembly(
|
||||
_In_z_ PCWSTR directoryPath,
|
||||
_In_z_ PCWSTR assemblyName,
|
||||
std::wstring& result);
|
||||
_In_z_ PCSTR directoryPath,
|
||||
_In_z_ PCSTR assemblyName,
|
||||
std::string& result);
|
||||
|
||||
virtual void GetTrustedAssemblyList(
|
||||
PCWSTR coreCLRDirectoryPath,
|
||||
std::wstringstream& assemblyList,
|
||||
PCSTR coreCLRDirectoryPath,
|
||||
std::stringstream& assemblyList,
|
||||
bool& listEmpty);
|
||||
|
||||
virtual unsigned int IdentifyHostDirectory(
|
||||
HostEnvironment& hostEnvironment);
|
||||
|
||||
virtual HMODULE TryLoadCoreCLR(
|
||||
_In_ PCWSTR directoryPath);
|
||||
|
||||
virtual unsigned int InitializeClr(
|
||||
_In_ ClrHostWrapper* hostWrapper,
|
||||
_In_ HMODULE coreClrModule);
|
||||
|
||||
private:
|
||||
// Explicitly disallow copy construction and assignment
|
||||
PwrshCommon(const PwrshCommon&);
|
||||
|
||||
@@ -32,18 +32,13 @@ namespace NativeMsh
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags) = 0;
|
||||
|
||||
virtual DWORD WINAPI GetModuleFileNameW(
|
||||
virtual DWORD WINAPI GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ PWSTR lpFilename,
|
||||
_Out_ LPSTR lpFilename,
|
||||
_In_ DWORD nSize) = 0;
|
||||
|
||||
virtual HMODULE WINAPI GetModuleHandleW(
|
||||
_In_opt_ PCWSTR lpModuleName) = 0;
|
||||
|
||||
virtual BOOL WINAPI GetModuleHandleExW(
|
||||
_In_ DWORD dwFlags,
|
||||
_In_opt_ PCWSTR lpModuleName,
|
||||
_Out_ HMODULE *phModule) = 0;
|
||||
virtual HMODULE WINAPI GetModuleHandleA(
|
||||
_In_opt_ PCSTR lpModuleName) = 0;
|
||||
|
||||
virtual FARPROC WINAPI GetProcAddress(
|
||||
_In_ HMODULE hModule,
|
||||
@@ -53,12 +48,13 @@ namespace NativeMsh
|
||||
_In_ HMODULE hModule) = 0;
|
||||
|
||||
// File Manipulation Wrappers
|
||||
virtual FILE* _wfopen(
|
||||
const wchar_t *filename,
|
||||
const wchar_t *mode) = 0;
|
||||
virtual errno_t fopen_s(
|
||||
FILE** file,
|
||||
const char *filename,
|
||||
const char *mode) = 0;
|
||||
|
||||
virtual int fclose(
|
||||
FILE *stream) = 0;
|
||||
};
|
||||
|
||||
} // namespace NativeMsh
|
||||
} // namespace NativeMsh
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace NativeMsh
|
||||
{
|
||||
HMODULE WINAPI WinSystemCallFacade::LoadLibraryExW(
|
||||
_In_ LPCTSTR lpFileName,
|
||||
_In_ LPCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags)
|
||||
{
|
||||
@@ -24,28 +24,20 @@ namespace NativeMsh
|
||||
#pragma prefast(push)
|
||||
#pragma prefast (disable: 26006) // Possibly incorrect single element annotation on string buffer - This is a thin wrapper around a system call, so it's behavior is not controllable.
|
||||
|
||||
DWORD WINAPI WinSystemCallFacade::GetModuleFileNameW(
|
||||
DWORD WINAPI WinSystemCallFacade::GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ LPTSTR lpFilename, // _Out_writes_to_(nSize, return +1) OR __out_ecount_part(nSize, return + 1)? __out_ecount(nSize)
|
||||
_Out_ LPSTR lpFilename, // _Out_writes_to_(nSize, return +1) OR __out_ecount_part(nSize, return + 1)? __out_ecount(nSize)
|
||||
_In_ DWORD nSize)
|
||||
{
|
||||
return ::GetModuleFileNameW(hModule, lpFilename, nSize);
|
||||
return ::GetModuleFileNameA(hModule, lpFilename, nSize);
|
||||
}
|
||||
|
||||
#pragma prefast(pop)
|
||||
|
||||
HMODULE WINAPI WinSystemCallFacade::GetModuleHandleW(
|
||||
_In_opt_ LPCTSTR lpModuleName)
|
||||
HMODULE WINAPI WinSystemCallFacade::GetModuleHandleA(
|
||||
_In_opt_ LPCSTR lpModuleName)
|
||||
{
|
||||
return ::GetModuleHandleW(lpModuleName);
|
||||
}
|
||||
|
||||
BOOL WINAPI WinSystemCallFacade::GetModuleHandleExW(
|
||||
_In_ DWORD dwFlags,
|
||||
_In_opt_ LPCTSTR lpModuleName,
|
||||
_Out_ HMODULE *phModule)
|
||||
{
|
||||
return ::GetModuleHandleExW(dwFlags, lpModuleName, phModule);
|
||||
return ::GetModuleHandleA(lpModuleName);
|
||||
}
|
||||
|
||||
FARPROC WINAPI WinSystemCallFacade::GetProcAddress(
|
||||
@@ -61,11 +53,12 @@ namespace NativeMsh
|
||||
return ::FreeLibrary(hModule);
|
||||
}
|
||||
|
||||
FILE* WinSystemCallFacade::_wfopen(
|
||||
const wchar_t *filename,
|
||||
const wchar_t *mode)
|
||||
errno_t WinSystemCallFacade::fopen_s(
|
||||
FILE** file,
|
||||
const char *filename,
|
||||
const char *mode)
|
||||
{
|
||||
return ::_wfopen(filename, mode);
|
||||
return ::fopen_s(file, filename, mode);
|
||||
}
|
||||
|
||||
int WinSystemCallFacade::fclose(
|
||||
@@ -74,4 +67,4 @@ namespace NativeMsh
|
||||
return ::fclose(stream);
|
||||
}
|
||||
|
||||
} // namespace NativeMsh
|
||||
} // namespace NativeMsh
|
||||
@@ -30,18 +30,13 @@ namespace NativeMsh
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags);
|
||||
|
||||
virtual DWORD WINAPI GetModuleFileNameW(
|
||||
virtual DWORD WINAPI GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ PWSTR lpFilename,
|
||||
_Out_ LPSTR lpFilename,
|
||||
_In_ DWORD nSize);
|
||||
|
||||
virtual HMODULE WINAPI GetModuleHandleW(
|
||||
_In_opt_ PCWSTR lpModuleName);
|
||||
|
||||
virtual BOOL WINAPI GetModuleHandleExW(
|
||||
_In_ DWORD dwFlags,
|
||||
_In_opt_ PCWSTR lpModuleName,
|
||||
_Out_ HMODULE *phModule);
|
||||
virtual HMODULE WINAPI GetModuleHandleA(
|
||||
_In_opt_ LPCSTR lpModuleName);
|
||||
|
||||
virtual FARPROC WINAPI GetProcAddress(
|
||||
_In_ HMODULE hModule,
|
||||
@@ -51,12 +46,13 @@ namespace NativeMsh
|
||||
_In_ HMODULE hModule);
|
||||
|
||||
// File Manipulation Wrappers
|
||||
virtual FILE* _wfopen(
|
||||
const wchar_t *filename,
|
||||
const wchar_t *mode);
|
||||
virtual errno_t fopen_s(
|
||||
FILE** file,
|
||||
const char *filename,
|
||||
const char *mode);
|
||||
|
||||
virtual int fclose(
|
||||
FILE *stream);
|
||||
};
|
||||
|
||||
} // namespace NativeMsh
|
||||
} // namespace NativeMsh
|
||||
@@ -667,182 +667,193 @@ namespace NativeMsh
|
||||
// System.Management.Automation must not be listed here. I should exist on the APP_PATH.
|
||||
//
|
||||
// NOTE: The names must not include the .dll extension because it will be added programmatically.
|
||||
static PCWSTR trustedAssemblies[] =
|
||||
static PCSTR trustedAssemblies[] =
|
||||
{
|
||||
L"Microsoft.CSharp",
|
||||
L"Microsoft.VisualBasic",
|
||||
L"Microsoft.Win32.Primitives",
|
||||
L"Microsoft.Win32.Registry.AccessControl",
|
||||
L"Microsoft.Win32.Registry",
|
||||
L"mscorlib",
|
||||
L"System.AppContext",
|
||||
L"System.Buffers",
|
||||
L"System.Collections.Concurrent",
|
||||
L"System.Collections",
|
||||
L"System.Collections.Immutable",
|
||||
L"System.Collections.NonGeneric",
|
||||
L"System.Collections.Specialized",
|
||||
L"System.ComponentModel.Annotations",
|
||||
L"System.ComponentModel.DataAnnotations",
|
||||
L"System.ComponentModel",
|
||||
L"System.ComponentModel.EventBasedAsync",
|
||||
L"System.ComponentModel.Primitives",
|
||||
L"System.ComponentModel.TypeConverter",
|
||||
L"System.Console",
|
||||
L"System.Core",
|
||||
L"System.Data.Common",
|
||||
L"System.Diagnostics.Contracts",
|
||||
L"System.Diagnostics.Debug",
|
||||
L"System.Diagnostics.DiagnosticSource",
|
||||
L"System.Diagnostics.FileVersionInfo",
|
||||
L"System.Diagnostics.Process",
|
||||
L"System.Diagnostics.StackTrace",
|
||||
L"System.Diagnostics.TextWriterTraceListener",
|
||||
L"System.Diagnostics.Tools",
|
||||
L"System.Diagnostics.TraceSource",
|
||||
L"System.Diagnostics.Tracing",
|
||||
L"System",
|
||||
L"System.Dynamic.Runtime",
|
||||
L"System.Globalization.Calendars",
|
||||
L"System.Globalization",
|
||||
L"System.Globalization.Extensions",
|
||||
L"System.IO.Compression",
|
||||
L"System.IO.Compression.ZipFile",
|
||||
L"System.IO",
|
||||
L"System.IO.FileSystem.AccessControl",
|
||||
L"System.IO.FileSystem",
|
||||
L"System.IO.FileSystem.DriveInfo",
|
||||
L"System.IO.FileSystem.Primitives",
|
||||
L"System.IO.FileSystem.Watcher",
|
||||
L"System.IO.MemoryMappedFiles",
|
||||
L"System.IO.Packaging",
|
||||
L"System.IO.Pipes",
|
||||
L"System.IO.UnmanagedMemoryStream",
|
||||
L"System.Linq",
|
||||
L"System.Linq.Expressions",
|
||||
L"System.Linq.Parallel",
|
||||
L"System.Linq.Queryable",
|
||||
L"System.Net",
|
||||
L"System.Net.Http",
|
||||
L"System.Net.Http.WinHttpHandler",
|
||||
L"System.Net.NameResolution",
|
||||
L"System.Net.NetworkInformation",
|
||||
L"System.Net.Ping",
|
||||
L"System.Net.Primitives",
|
||||
L"System.Net.Requests",
|
||||
L"System.Net.Security",
|
||||
L"System.Net.Sockets",
|
||||
L"System.Net.WebHeaderCollection",
|
||||
L"System.Net.WebSockets.Client",
|
||||
L"System.Net.WebSockets",
|
||||
L"System.Numerics",
|
||||
L"System.Numerics.Vectors",
|
||||
L"System.ObjectModel",
|
||||
L"System.Private.DataContractSerialization",
|
||||
L"System.Private.ServiceModel",
|
||||
L"System.Private.Uri",
|
||||
L"System.Reflection.DispatchProxy",
|
||||
L"System.Reflection",
|
||||
L"System.Reflection.Emit",
|
||||
L"System.Reflection.Emit.ILGeneration",
|
||||
L"System.Reflection.Emit.Lightweight",
|
||||
L"System.Reflection.Extensions",
|
||||
L"System.Reflection.Metadata",
|
||||
L"System.Reflection.Primitives",
|
||||
L"System.Reflection.TypeExtensions",
|
||||
L"System.Resources.ReaderWriter",
|
||||
L"System.Resources.ResourceManager",
|
||||
L"System.Runtime.CompilerServices.VisualC",
|
||||
L"System.Runtime",
|
||||
L"System.Runtime.Extensions",
|
||||
L"System.Runtime.Handles",
|
||||
L"System.Runtime.InteropServices",
|
||||
L"System.Runtime.InteropServices.PInvoke",
|
||||
L"System.Runtime.InteropServices.RuntimeInformation",
|
||||
L"System.Runtime.Loader",
|
||||
L"System.Runtime.Numerics",
|
||||
L"System.Runtime.Serialization",
|
||||
L"System.Runtime.Serialization.Json",
|
||||
L"System.Runtime.Serialization.Primitives",
|
||||
L"System.Runtime.Serialization.Xml",
|
||||
L"System.Security.AccessControl",
|
||||
L"System.Security.Claims",
|
||||
L"System.Security.Cryptography.Algorithms",
|
||||
L"System.Security.Cryptography.Cng",
|
||||
L"System.Security.Cryptography.Csp",
|
||||
L"System.Security.Cryptography.Encoding",
|
||||
L"System.Security.Cryptography.OpenSsl",
|
||||
L"System.Security.Cryptography.Primitives",
|
||||
L"System.Security.Cryptography.X509Certificates",
|
||||
L"System.Security.Principal",
|
||||
L"System.Security.Principal.Windows",
|
||||
L"System.Security.SecureString",
|
||||
L"System.ServiceModel",
|
||||
L"System.ServiceModel.Duplex",
|
||||
L"System.ServiceModel.Http",
|
||||
L"System.ServiceModel.NetTcp",
|
||||
L"System.ServiceModel.Primitives",
|
||||
L"System.ServiceModel.Security",
|
||||
L"System.ServiceModel.Web",
|
||||
L"System.ServiceProcess.ServiceController",
|
||||
L"System.Text.Encoding.CodePages",
|
||||
L"System.Text.Encoding",
|
||||
L"System.Text.Encoding.Extensions",
|
||||
L"System.Text.Encodings.Web",
|
||||
L"System.Text.RegularExpressions",
|
||||
L"System.Threading.AccessControl",
|
||||
L"System.Threading",
|
||||
L"System.Threading.Overlapped",
|
||||
L"System.Threading.Tasks.Dataflow",
|
||||
L"System.Threading.Tasks",
|
||||
L"System.Threading.Tasks.Extensions",
|
||||
L"System.Threading.Tasks.Parallel",
|
||||
L"System.Threading.Thread",
|
||||
L"System.Threading.ThreadPool",
|
||||
L"System.Threading.Timer",
|
||||
L"System.Windows",
|
||||
L"System.Xml",
|
||||
L"System.Xml.Linq",
|
||||
L"System.Xml.ReaderWriter",
|
||||
L"System.Xml.Serialization",
|
||||
L"System.Xml.XDocument",
|
||||
L"System.Xml.XmlDocument",
|
||||
L"System.Xml.XmlSerializer",
|
||||
L"System.Xml.XPath",
|
||||
L"System.Xml.XPath.XDocument",
|
||||
L"System.Xml.XPath.XmlDocument",
|
||||
L"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext"
|
||||
"Microsoft.CSharp",
|
||||
"Microsoft.VisualBasic",
|
||||
"Microsoft.Win32.Primitives",
|
||||
"Microsoft.Win32.Registry.AccessControl",
|
||||
"Microsoft.Win32.Registry",
|
||||
"mscorlib",
|
||||
"System.AppContext",
|
||||
"System.Buffers",
|
||||
"System.Collections.Concurrent",
|
||||
"System.Collections",
|
||||
"System.Collections.Immutable",
|
||||
"System.Collections.NonGeneric",
|
||||
"System.Collections.Specialized",
|
||||
"System.ComponentModel.Annotations",
|
||||
"System.ComponentModel.DataAnnotations",
|
||||
"System.ComponentModel",
|
||||
"System.ComponentModel.EventBasedAsync",
|
||||
"System.ComponentModel.Primitives",
|
||||
"System.ComponentModel.TypeConverter",
|
||||
"System.Console",
|
||||
"System.Core",
|
||||
"System.Data.Common",
|
||||
"System.Diagnostics.Contracts",
|
||||
"System.Diagnostics.Debug",
|
||||
"System.Diagnostics.DiagnosticSource",
|
||||
"System.Diagnostics.FileVersionInfo",
|
||||
"System.Diagnostics.Process",
|
||||
"System.Diagnostics.StackTrace",
|
||||
"System.Diagnostics.TextWriterTraceListener",
|
||||
"System.Diagnostics.Tools",
|
||||
"System.Diagnostics.TraceSource",
|
||||
"System.Diagnostics.Tracing",
|
||||
"System",
|
||||
"System.Dynamic.Runtime",
|
||||
"System.Globalization.Calendars",
|
||||
"System.Globalization",
|
||||
"System.Globalization.Extensions",
|
||||
"System.IO.Compression",
|
||||
"System.IO.Compression.ZipFile",
|
||||
"System.IO",
|
||||
"System.IO.FileSystem.AccessControl",
|
||||
"System.IO.FileSystem",
|
||||
"System.IO.FileSystem.DriveInfo",
|
||||
"System.IO.FileSystem.Primitives",
|
||||
"System.IO.FileSystem.Watcher",
|
||||
"System.IO.MemoryMappedFiles",
|
||||
"System.IO.Packaging",
|
||||
"System.IO.Pipes",
|
||||
"System.IO.UnmanagedMemoryStream",
|
||||
"System.Linq",
|
||||
"System.Linq.Expressions",
|
||||
"System.Linq.Parallel",
|
||||
"System.Linq.Queryable",
|
||||
"System.Net",
|
||||
"System.Net.Http",
|
||||
"System.Net.Http.WinHttpHandler",
|
||||
"System.Net.NameResolution",
|
||||
"System.Net.NetworkInformation",
|
||||
"System.Net.Ping",
|
||||
"System.Net.Primitives",
|
||||
"System.Net.Requests",
|
||||
"System.Net.Security",
|
||||
"System.Net.Sockets",
|
||||
"System.Net.WebHeaderCollection",
|
||||
"System.Net.WebSockets.Client",
|
||||
"System.Net.WebSockets",
|
||||
"System.Numerics",
|
||||
"System.Numerics.Vectors",
|
||||
"System.ObjectModel",
|
||||
"System.Private.DataContractSerialization",
|
||||
"System.Private.ServiceModel",
|
||||
"System.Private.Uri",
|
||||
"System.Reflection.DispatchProxy",
|
||||
"System.Reflection",
|
||||
"System.Reflection.Emit",
|
||||
"System.Reflection.Emit.ILGeneration",
|
||||
"System.Reflection.Emit.Lightweight",
|
||||
"System.Reflection.Extensions",
|
||||
"System.Reflection.Metadata",
|
||||
"System.Reflection.Primitives",
|
||||
"System.Reflection.TypeExtensions",
|
||||
"System.Resources.ReaderWriter",
|
||||
"System.Resources.ResourceManager",
|
||||
"System.Runtime.CompilerServices.VisualC",
|
||||
"System.Runtime",
|
||||
"System.Runtime.Extensions",
|
||||
"System.Runtime.Handles",
|
||||
"System.Runtime.InteropServices",
|
||||
"System.Runtime.InteropServices.PInvoke",
|
||||
"System.Runtime.InteropServices.RuntimeInformation",
|
||||
"System.Runtime.Loader",
|
||||
"System.Runtime.Numerics",
|
||||
"System.Runtime.Serialization",
|
||||
"System.Runtime.Serialization.Json",
|
||||
"System.Runtime.Serialization.Primitives",
|
||||
"System.Runtime.Serialization.Xml",
|
||||
"System.Security.AccessControl",
|
||||
"System.Security.Claims",
|
||||
"System.Security.Cryptography.Algorithms",
|
||||
"System.Security.Cryptography.Cng",
|
||||
"System.Security.Cryptography.Csp",
|
||||
"System.Security.Cryptography.Encoding",
|
||||
"System.Security.Cryptography.OpenSsl",
|
||||
"System.Security.Cryptography.Primitives",
|
||||
"System.Security.Cryptography.X509Certificates",
|
||||
"System.Security.Principal",
|
||||
"System.Security.Principal.Windows",
|
||||
"System.Security.SecureString",
|
||||
"System.ServiceModel",
|
||||
"System.ServiceModel.Duplex",
|
||||
"System.ServiceModel.Http",
|
||||
"System.ServiceModel.NetTcp",
|
||||
"System.ServiceModel.Primitives",
|
||||
"System.ServiceModel.Security",
|
||||
"System.ServiceModel.Web",
|
||||
"System.ServiceProcess.ServiceController",
|
||||
"System.Text.Encoding.CodePages",
|
||||
"System.Text.Encoding",
|
||||
"System.Text.Encoding.Extensions",
|
||||
"System.Text.Encodings.Web",
|
||||
"System.Text.RegularExpressions",
|
||||
"System.Threading.AccessControl",
|
||||
"System.Threading",
|
||||
"System.Threading.Overlapped",
|
||||
"System.Threading.Tasks.Dataflow",
|
||||
"System.Threading.Tasks",
|
||||
"System.Threading.Tasks.Extensions",
|
||||
"System.Threading.Tasks.Parallel",
|
||||
"System.Threading.Thread",
|
||||
"System.Threading.ThreadPool",
|
||||
"System.Threading.Timer",
|
||||
"System.Windows",
|
||||
"System.Xml",
|
||||
"System.Xml.Linq",
|
||||
"System.Xml.ReaderWriter",
|
||||
"System.Xml.Serialization",
|
||||
"System.Xml.XDocument",
|
||||
"System.Xml.XmlDocument",
|
||||
"System.Xml.XmlSerializer",
|
||||
"System.Xml.XPath",
|
||||
"System.Xml.XPath.XDocument",
|
||||
"System.Xml.XPath.XmlDocument",
|
||||
"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext"
|
||||
};
|
||||
|
||||
// Define the function pointer for the CLR entry point
|
||||
typedef HRESULT(STDAPICALLTYPE *GetCLRRuntimeHostFp)(REFIID riid, IUnknown** pUnk);
|
||||
|
||||
// The name of the CoreCLR native runtime DLL.
|
||||
static PCWSTR coreClrDll = L"CoreCLR.dll";
|
||||
static PCSTR coreClrDll = "CoreCLR.dll";
|
||||
|
||||
// The location where CoreCLR is expected to be installed. If CoreCLR.dll isn't
|
||||
// The location where CoreCLR is expected to be installed for inbox PowerShell. If CoreCLR.dll isn't
|
||||
// found in the same directory as the host, it will be looked for here.
|
||||
static PCWSTR coreCLRInstallDirectory = L"%windir%\\system32\\DotNetCore\\v1.0\\";
|
||||
static PCSTR coreCLRInstallDirectory = "%windir%\\system32\\DotNetCore\\v1.0\\";
|
||||
|
||||
// The location where CoreCLR PowerShell Ext binaries are expected to be installed.
|
||||
static PCWSTR coreCLRPowerShellExtInstallDirectory = L"%windir%\\system32\\CoreClrPowerShellExt\\v1.0\\";
|
||||
// The location where CoreCLR PowerShell Ext binaries are expected to be installed for inbox PowerShell.
|
||||
static PCSTR coreCLRPowerShellExtInstallDirectory = "%windir%\\system32\\CoreClrPowerShellExt\\v1.0\\";
|
||||
|
||||
// The default PowerShell install directory. This location may be overridden through a config file in %windir%\System32.
|
||||
static PCWSTR powerShellInstallPath = L"%windir%\\System32\\WindowsPowerShell\\v1.0\\";
|
||||
// The default PowerShell install directory for inbox PowerShell.
|
||||
// This location may be overridden by placing a config file in the same directory as the PowerShell host.
|
||||
static PCSTR powerShellInstallPath = "%windir%\\System32\\WindowsPowerShell\\v1.0\\";
|
||||
|
||||
unsigned int PwrshCommon::IdentifyHostDirectory(
|
||||
HostEnvironment& hostEnvironment)
|
||||
{
|
||||
// Discover the path to the exe's module (powershell.exe or wsmprovhost.exe).
|
||||
// For remoting, this is expected to be %windir%\system32 since that is the location of wsmprovhost.exe.
|
||||
// Discover the path to the plugin or the executable (pwrshplugin.dll or powershell.exe).
|
||||
// For PowerShell Core, the plugin no longer resides in %windir%\\system32 (it is in a sub-directory).
|
||||
// If pwrshplugin.dll is not loaded, it means that this is running via powershell.exe.
|
||||
wchar_t hostPath[MAX_PATH];
|
||||
DWORD thisModuleLength = sysCalls->GetModuleFileNameW(sysCalls->GetModuleHandleW(NULL), hostPath, MAX_PATH);
|
||||
DWORD thisModuleLength;
|
||||
|
||||
if (0 == thisModuleLength)
|
||||
if (GetModuleHandleW(L"pwrshplugin.dll"))
|
||||
{
|
||||
thisModuleLength = GetModuleFileNameW(GetModuleHandleW(L"pwrshplugin.dll"), hostPath, MAX_PATH);
|
||||
}
|
||||
else
|
||||
{
|
||||
thisModuleLength = GetModuleFileNameW(GetModuleHandleW(NULL), hostPath, MAX_PATH);
|
||||
}
|
||||
if (0 == thisModuleLength) // Greater than zero means it is the length of the fully qualified path (without the NULL character)
|
||||
{
|
||||
// TODO: Use GetLastError() to find the specific error #
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
// Search for the last backslash in the host path.
|
||||
int lastBackslashIndex;
|
||||
for (lastBackslashIndex = thisModuleLength - 1; lastBackslashIndex >= 0; lastBackslashIndex--)
|
||||
@@ -854,106 +865,62 @@ namespace NativeMsh
|
||||
}
|
||||
|
||||
// The remaining part of the path after the last '\' is the binary name.
|
||||
hostEnvironment.SetHostBinaryName(hostPath + lastBackslashIndex + 1);
|
||||
hostEnvironment.SetHostBinaryNameW(hostPath + lastBackslashIndex + 1);
|
||||
|
||||
// Copy the directory path portion of the path
|
||||
hostPath[lastBackslashIndex + 1] = '\0';
|
||||
hostEnvironment.SetHostPath(hostPath);
|
||||
hostEnvironment.SetHostPathW(hostPath);
|
||||
|
||||
hostEnvironment.SetHostDirectoryPath(powerShellInstallPath);
|
||||
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// Attempts to load CoreCLR.dll from the specified directory.
|
||||
// On success pins the dll, sets coreCLRDirectoryPath and returns the HMODULE.
|
||||
// On failure returns NULL.
|
||||
HMODULE PwrshCommon::TryLoadCoreCLR(
|
||||
_In_ PCWSTR directoryPath)
|
||||
{
|
||||
std::wstring coreCLRPath(directoryPath);
|
||||
coreCLRPath += coreClrDll;
|
||||
|
||||
HMODULE result = sysCalls->LoadLibraryExW(coreCLRPath.c_str(), NULL, 0);
|
||||
if (!result)
|
||||
// Read the config file to determine the appropriate host path and CoreCLR path to use.
|
||||
unsigned int result = reader->Read(hostPath);
|
||||
if (EXIT_CODE_SUCCESS == result)
|
||||
{
|
||||
return NULL;
|
||||
// The config file was successfully parsed. Use those directories.
|
||||
hostEnvironment.SetHostDirectoryPathW(reader->GetPathToPowerShell().c_str());
|
||||
hostEnvironment.SetCoreCLRDirectoryPathW(reader->GetPathToCoreClr().c_str());
|
||||
}
|
||||
|
||||
// Pin the module - CoreCLR.dll does not support being unloaded.
|
||||
HMODULE dummy_coreCLRModule;
|
||||
if (!sysCalls->GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, coreCLRPath.c_str(), &dummy_coreCLRModule))
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
// There was an issue accessing or parsing the config file OR
|
||||
// we are working for the EXE.
|
||||
//
|
||||
// TODO: This should not be the fallback for inbox PowerShell.exe.
|
||||
// It should use coreCLRInstallDirectory and coreCLRPowerShellExtInstallDirectory.
|
||||
//
|
||||
// Use the directory detected via GetModuleFileName + GetModuleHandle
|
||||
hostEnvironment.SetHostDirectoryPathW(hostPath);
|
||||
// At the moment, CoreCLR is in the same directory as PowerShell Core.
|
||||
// This path must be modified if we decide to use a different directory.
|
||||
hostEnvironment.SetCoreCLRDirectoryPathW(hostPath);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int PwrshCommon::InitializeClr(
|
||||
_In_ ClrHostWrapper* hostWrapper,
|
||||
_In_ HMODULE coreClrModule)
|
||||
{
|
||||
#if CORECLR
|
||||
// Get the function pointer for "GetCLRRuntimeHost"
|
||||
GetCLRRuntimeHostFp getCLRRuntimeHostfp = (GetCLRRuntimeHostFp)sysCalls->GetProcAddress(coreClrModule, "GetCLRRuntimeHost");
|
||||
if (getCLRRuntimeHostfp == NULL)
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
// Get the CLR runtime host
|
||||
ICLRRuntimeHost2* pHost = NULL;
|
||||
HRESULT hResult = getCLRRuntimeHostfp(IID_ICLRRuntimeHost2, (IUnknown**)&pHost);
|
||||
if (FAILED(hResult))
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
hostWrapper->SetClrHost(pHost);
|
||||
// Authenticate with either
|
||||
// CORECLR_HOST_AUTHENTICATION_KEY or
|
||||
// CORECLR_HOST_AUTHENTICATION_KEY_NONGEN
|
||||
hResult = hostWrapper->Authenticate(CORECLR_HOST_AUTHENTICATION_KEY);
|
||||
if (FAILED(hResult))
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
hostWrapper->SetStartupFlags((STARTUP_FLAGS)(STARTUP_SINGLE_APPDOMAIN | STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN));
|
||||
|
||||
hResult = hostWrapper->Start();
|
||||
if (FAILED(hResult))
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool PwrshCommon::DoesAssemblyExist(
|
||||
std::wstring& fileToTest)
|
||||
std::string& fileToTest)
|
||||
{
|
||||
FILE *file = sysCalls->_wfopen(fileToTest.c_str(), L"r");
|
||||
//FILE *file = sysCalls->fopen(fileToTest.c_str(), "r"); // TODO: Use fopen_s?
|
||||
FILE *file = NULL;
|
||||
errno_t status = sysCalls->fopen_s(&file, fileToTest.c_str(), "r");
|
||||
|
||||
if (file != NULL) {
|
||||
sysCalls->fclose(file);
|
||||
return true;
|
||||
return (status == 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This assumes that directoryPath already includes a trailing "\\"
|
||||
void PwrshCommon::ProbeAssembly(
|
||||
_In_z_ PCWSTR directoryPath,
|
||||
_In_z_ PCWSTR assemblyName,
|
||||
std::wstring& result)
|
||||
_In_z_ PCSTR directoryPath,
|
||||
_In_z_ PCSTR assemblyName,
|
||||
std::string& result)
|
||||
{
|
||||
PCWSTR niExtension = L".ni.dll";
|
||||
PCWSTR ilExtension = L".dll";
|
||||
PCSTR niExtension = ".ni.dll";
|
||||
PCSTR ilExtension = ".dll";
|
||||
|
||||
// Test NI extension first because it is preferable to IL
|
||||
std::wstring fileToTest(directoryPath);
|
||||
std::string fileToTest(directoryPath);
|
||||
fileToTest += assemblyName;
|
||||
fileToTest += niExtension;
|
||||
if (DoesAssemblyExist(fileToTest)) {
|
||||
@@ -973,13 +940,13 @@ namespace NativeMsh
|
||||
// Returns the semicolon-separated list of paths to runtime dlls that are considered trusted.
|
||||
// Do not put powershell assemblies in the TPA list as it will cause 'Security Transparent V.S. Security Critical' error.
|
||||
void PwrshCommon::GetTrustedAssemblyList(
|
||||
PCWSTR coreCLRDirectoryPath,
|
||||
std::wstringstream& assemblyList,
|
||||
PCSTR coreCLRDirectoryPath,
|
||||
std::stringstream& assemblyList,
|
||||
bool& listEmpty)
|
||||
{
|
||||
for (const wchar_t * &assembly : trustedAssemblies)
|
||||
for (const char* &assembly : trustedAssemblies)
|
||||
{
|
||||
std::wstring assemblyPath;
|
||||
std::string assemblyPath;
|
||||
ProbeAssembly(coreCLRDirectoryPath, assembly, assemblyPath);
|
||||
|
||||
if (assemblyPath.length() > 0)
|
||||
@@ -987,7 +954,7 @@ namespace NativeMsh
|
||||
if (listEmpty)
|
||||
listEmpty = false;
|
||||
else
|
||||
assemblyList << L";";
|
||||
assemblyList << ";";
|
||||
assemblyList << assemblyPath;
|
||||
}
|
||||
}
|
||||
@@ -1023,20 +990,26 @@ namespace NativeMsh
|
||||
//
|
||||
|
||||
PwrshCommon::PwrshCommon()
|
||||
: output(new PwrshCommonOutputDefault()), sysCalls(new WinSystemCallFacade())
|
||||
: output(new PwrshCommonOutputDefault()), reader(new ConfigFileReader()), sysCalls(new WinSystemCallFacade())
|
||||
{
|
||||
}
|
||||
|
||||
PwrshCommon::PwrshCommon(
|
||||
IPwrshCommonOutput* outObj,
|
||||
ConfigFileReader* rdr,
|
||||
SystemCallFacade* systemCalls)
|
||||
: output(outObj), sysCalls(systemCalls)
|
||||
: output(outObj), reader(rdr), sysCalls(systemCalls)
|
||||
{
|
||||
if (NULL == output)
|
||||
{
|
||||
output = new PwrshCommonOutputDefault();
|
||||
}
|
||||
|
||||
if (NULL == reader)
|
||||
{
|
||||
reader = new ConfigFileReader();
|
||||
}
|
||||
|
||||
if (NULL == sysCalls)
|
||||
{
|
||||
sysCalls = new WinSystemCallFacade();
|
||||
@@ -1051,6 +1024,12 @@ namespace NativeMsh
|
||||
output = NULL;
|
||||
}
|
||||
|
||||
if (reader)
|
||||
{
|
||||
delete reader;
|
||||
reader = NULL;
|
||||
}
|
||||
|
||||
if (sysCalls)
|
||||
{
|
||||
delete sysCalls;
|
||||
@@ -1351,10 +1330,10 @@ namespace NativeMsh
|
||||
pwszRuntimeVersion, L"ConsoleHostAssemblyName", pwszConsoleHostAssemblyName);
|
||||
}
|
||||
|
||||
#if CORECLR
|
||||
unsigned int PwrshCommon::LaunchCoreCLR(
|
||||
ClrHostWrapper* hostWrapper,
|
||||
HostEnvironment& hostEnvironment)
|
||||
HostEnvironment& hostEnvironment,
|
||||
PCSTR friendlyName)
|
||||
{
|
||||
unsigned int exitCode = this->IdentifyHostDirectory(hostEnvironment);
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
@@ -1363,131 +1342,57 @@ namespace NativeMsh
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
// Try to load from the well-known location.
|
||||
wchar_t coreCLRInstallPath[MAX_PATH];
|
||||
exitCode = ::ExpandEnvironmentStringsW(coreCLRInstallDirectory, coreCLRInstallPath, MAX_PATH);
|
||||
if (0 == exitCode || _countof(coreCLRInstallPath) <= exitCode)
|
||||
{
|
||||
this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError());
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
HMODULE coreClrModule = this->TryLoadCoreCLR(coreCLRInstallPath);
|
||||
|
||||
if (coreClrModule)
|
||||
{
|
||||
// Save the directory that CoreCLR was found in
|
||||
WCHAR coreCLRDirectoryPath[MAX_PATH];
|
||||
DWORD modulePathLength = sysCalls->GetModuleFileNameW(coreClrModule, coreCLRDirectoryPath, MAX_PATH);
|
||||
|
||||
// Search for the last backslash and terminate it there to keep just the directory path with trailing slash
|
||||
for (int lastBackslashIndex = modulePathLength - 1; lastBackslashIndex >= 0; lastBackslashIndex--)
|
||||
{
|
||||
if (coreCLRDirectoryPath[lastBackslashIndex] == L'\\')
|
||||
{
|
||||
coreCLRDirectoryPath[lastBackslashIndex + 1] = L'\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
hostEnvironment.SetCoreCLRDirectoryPath(coreCLRDirectoryPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError());
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
exitCode = this->InitializeClr(hostWrapper, coreClrModule);
|
||||
exitCode = hostWrapper->SetupWrapper(hostEnvironment.GetCoreCLRDirectoryPath());
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
{
|
||||
this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError());
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
hostEnvironment.SetCoreCLRModule(coreClrModule);
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
unsigned int PwrshCommon::CreateAppDomain(
|
||||
ClrHostWrapper* hostWrapper,
|
||||
PCWSTR friendlyName,
|
||||
HostEnvironment& hostEnvironment)
|
||||
{
|
||||
const int nMaxProps = 8;
|
||||
LPCWSTR props[nMaxProps];
|
||||
LPCWSTR vals[nMaxProps];
|
||||
|
||||
if (!hostWrapper->IsInitialized())
|
||||
{
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
|
||||
//PAL_LeaveHolder holder;
|
||||
DWORD dwDomainFlags = 0;
|
||||
dwDomainFlags = APPDOMAIN_SECURITY_DEFAULT;
|
||||
dwDomainFlags |= APPDOMAIN_ENABLE_ASSEMBLY_LOADFILE;
|
||||
dwDomainFlags |= APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT;
|
||||
|
||||
// By default CoreCLR only allows platform neutral assembly to be run. To allow
|
||||
// assemblies marked as platform specific, include this flag
|
||||
dwDomainFlags |= APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS;
|
||||
// Enable PInvoke
|
||||
dwDomainFlags |= APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP;
|
||||
// This will not tear down an application if a managed exception goes unhandled
|
||||
dwDomainFlags |= APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS;
|
||||
|
||||
|
||||
const int nMaxProps = 8;
|
||||
LPCSTR props[nMaxProps];
|
||||
LPCSTR vals[nMaxProps];
|
||||
int nProps = 0;
|
||||
props[nProps] = L"APPBASE";
|
||||
vals[nProps] = hostEnvironment.GetHostDirectoryPath();
|
||||
nProps++;
|
||||
|
||||
// If I do not include my managed enload point dll in this list, I get a security error.
|
||||
std::wstringstream assemblyList;
|
||||
std::stringstream assemblyList;
|
||||
bool listEmpty = true;
|
||||
this->GetTrustedAssemblyList(hostEnvironment.GetCoreCLRDirectoryPath(), assemblyList, listEmpty);
|
||||
|
||||
wchar_t coreCLRPowerShellExtInstallPath[MAX_PATH];
|
||||
::ExpandEnvironmentStringsW(coreCLRPowerShellExtInstallDirectory, coreCLRPowerShellExtInstallPath, MAX_PATH);
|
||||
char coreCLRPowerShellExtInstallPath[MAX_PATH];
|
||||
::ExpandEnvironmentStringsA(coreCLRPowerShellExtInstallDirectory, coreCLRPowerShellExtInstallPath, MAX_PATH);
|
||||
this->GetTrustedAssemblyList(coreCLRPowerShellExtInstallPath, assemblyList, listEmpty);
|
||||
|
||||
props[nProps] = L"TRUSTED_PLATFORM_ASSEMBLIES";
|
||||
std::wstring tempStr = assemblyList.str();
|
||||
props[nProps] = "TRUSTED_PLATFORM_ASSEMBLIES";
|
||||
std::string tempStr = assemblyList.str();
|
||||
vals[nProps] = tempStr.c_str();
|
||||
nProps++;
|
||||
|
||||
props[nProps] = L"APP_PATHS";
|
||||
vals[nProps] = L"";
|
||||
props[nProps] = "APP_PATHS";
|
||||
vals[nProps] = ""; // Used to be hostEnvironment.GetHostDirectoryPath()
|
||||
nProps++;
|
||||
|
||||
props[nProps] = L"APP_NI_PATHS";
|
||||
vals[nProps] = L"";
|
||||
props[nProps] = "APP_NI_PATHS";
|
||||
vals[nProps] = ""; // Used to be hostEnvironment.GetHostDirectoryPath()
|
||||
nProps++;
|
||||
|
||||
// Create the customized AppDomainManager out of the SandboxHelper class
|
||||
DWORD appDomainId = INVALID_APPDOMAIN_ID;
|
||||
HRESULT hr = hostWrapper->CreateAppDomainWithManager(
|
||||
friendlyName,
|
||||
dwDomainFlags,
|
||||
NULL, // AppDomainManager is no longer required now that we can use AssemblyLoadContext to access arbitrary assemblies from within SMA.dll
|
||||
NULL,
|
||||
nProps,
|
||||
props,
|
||||
vals,
|
||||
&appDomainId);
|
||||
int hr = hostWrapper->InitializeClr(
|
||||
hostEnvironment.GetHostDirectoryPath(),
|
||||
friendlyName,
|
||||
nProps,
|
||||
props,
|
||||
vals);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
//LONG systemErrorCode = GetLastError();
|
||||
this->output->DisplayMessage(false, g_GETTING_DEFAULT_DOMAIN_FAILED, hr);
|
||||
|
||||
this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError());
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
}
|
||||
hostWrapper->SetAppDomainId(appDomainId);
|
||||
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#else // !CORECLR
|
||||
|
||||
#if !CORECLR
|
||||
// NOTE:
|
||||
// This must be ifdef'd out of the CoreCLR build because it uses .NET 1.0
|
||||
// types that have been deprecated and removed from mscoree.h.
|
||||
@@ -1550,7 +1455,7 @@ namespace NativeMsh
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
#endif // !CORECLR
|
||||
#endif // !CORECLR
|
||||
|
||||
#pragma prefast(pop)
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Builds PowerShell.exe, the native host for PowerShell.
|
||||
#
|
||||
|
||||
if (BUILD_ONECORE)
|
||||
# Settings to use when creating PowerShell.exe for Windows on OneCore-based SKUs
|
||||
set(PWRSHEXE_WINDOWS_SOURCES
|
||||
CssMainEntry.cpp
|
||||
)
|
||||
set(PWRSHEXE_WINDOWS_LIBS
|
||||
### ${STATIC_MT_CRT_LIB}
|
||||
### ${STATIC_MT_VCRT_LIB}
|
||||
### ${STATIC_UCRT_LIB}
|
||||
onecore.lib
|
||||
vcruntime.lib
|
||||
ucrtd.lib
|
||||
msvcrt.lib
|
||||
msvcrt.lib
|
||||
msvcprtd.lib
|
||||
user32.lib
|
||||
atls.lib
|
||||
)
|
||||
set(powershell_definitions
|
||||
_CONSOLE
|
||||
CORECLR
|
||||
)
|
||||
else ()
|
||||
# Settings to use when creating PowerShell.exe for Windows on full SKUs or downlevel platforms
|
||||
set(PWRSHEXE_WINDOWS_SOURCES
|
||||
MainEntry.cpp
|
||||
)
|
||||
# Most libs are automatically added by VS
|
||||
set(PWRSHEXE_WINDOWS_LIBS
|
||||
# CoreCLR libs
|
||||
${STATIC_MT_CRT_LIB}
|
||||
${STATIC_MT_VCRT_LIB}
|
||||
# ${STATIC_UCRT_LIB}
|
||||
# ole32.lib
|
||||
# oleaut32.lib
|
||||
# uuid.lib
|
||||
# user32.lib
|
||||
MUILoad.lib
|
||||
msxml6.lib
|
||||
mscoree.lib
|
||||
legacy_stdio_definitions.lib # Resolves: LNK2019: unresolved external symbol _vsnwprintf
|
||||
)
|
||||
set(powershell_definitions
|
||||
_CONSOLE
|
||||
)
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
add_executable(powershell
|
||||
${PWRSHEXE_WINDOWS_SOURCES})
|
||||
|
||||
set_target_properties(powershell PROPERTIES COMPILE_DEFINITIONS "${powershell_definitions}")
|
||||
|
||||
target_link_libraries(powershell ${PWRSHEXE_WINDOWS_LIBS})
|
||||
target_link_libraries(powershell pwrshcommon)
|
||||
@@ -12,10 +12,13 @@
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include "mscoree.h"
|
||||
#if !CORECLR
|
||||
#include "mscoree.h"
|
||||
#endif
|
||||
#include "NativeMsh.h"
|
||||
#include "ClrHostWrapper.h"
|
||||
#include "OutputWriter.h"
|
||||
#include "ConfigFileReader.h"
|
||||
#include "WinSystemCallFacade.h"
|
||||
|
||||
namespace NativeMsh
|
||||
@@ -33,10 +36,10 @@ namespace NativeMsh
|
||||
|
||||
// All these objects will be destroyed when commonFuncs goes out of scope.
|
||||
PwrshExeOutput* output = new PwrshExeOutput();
|
||||
PwrshCommon commonFuncs(output, new WinSystemCallFacade());
|
||||
ICLRRuntimeHost2Wrapper hostWrapper;
|
||||
PwrshCommon commonFuncs(output, new ConfigFileReader(), new WinSystemCallFacade());
|
||||
CoreClrHostingApiWrapper hostWrapper;
|
||||
|
||||
exitCode = commonFuncs.LaunchCoreCLR(&hostWrapper, hostEnvironment);
|
||||
exitCode = commonFuncs.LaunchCoreCLR(&hostWrapper, hostEnvironment, "powershell");
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
{
|
||||
if (verbose)
|
||||
@@ -51,23 +54,14 @@ namespace NativeMsh
|
||||
return false;
|
||||
}
|
||||
|
||||
exitCode = commonFuncs.CreateAppDomain(&hostWrapper, hostEnvironment.GetHostBinaryName(), hostEnvironment);
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
{
|
||||
if (verbose)
|
||||
::wprintf(L"Unable to create app domain\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Set the powershell custom assembly loader to be the default
|
||||
LoaderRunHelperFp initDelegate = NULL;
|
||||
HRESULT hr = hostWrapper.CreateDelegate(
|
||||
hostWrapper.GetAppDomainId(),
|
||||
L"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
L"System.Management.Automation.PowerShellAssemblyLoadContextInitializer",
|
||||
L"SetPowerShellAssemblyLoadContext",
|
||||
(INT_PTR*)&initDelegate);
|
||||
"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
"System.Management.Automation.PowerShellAssemblyLoadContextInitializer",
|
||||
"SetPowerShellAssemblyLoadContext",
|
||||
(void**)&initDelegate);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@@ -75,18 +69,17 @@ namespace NativeMsh
|
||||
}
|
||||
else
|
||||
{
|
||||
initDelegate(hostEnvironment.GetHostDirectoryPath());
|
||||
initDelegate(hostEnvironment.GetHostDirectoryPathW());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Start the assembly
|
||||
MonadRunHelperFp pfnDelegate = NULL;
|
||||
hr = hostWrapper.CreateDelegate(
|
||||
hostWrapper.GetAppDomainId(),
|
||||
L"Microsoft.PowerShell.ConsoleHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
L"Microsoft.PowerShell.UnmanagedPSEntry",
|
||||
L"Start",
|
||||
(INT_PTR*)&pfnDelegate);
|
||||
"Microsoft.PowerShell.ConsoleHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
"Microsoft.PowerShell.UnmanagedPSEntry",
|
||||
"Start",
|
||||
(void**)&pfnDelegate);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <msxml6.h>
|
||||
#include <VersionHelpers.h>
|
||||
#include "OutputWriter.h"
|
||||
#include "ConfigFileReader.h"
|
||||
#include "WinSystemCallFacade.h"
|
||||
|
||||
// include the tlb for mscorlib for access to the default AppDomain through COM Interop
|
||||
@@ -49,7 +50,7 @@ WCHAR g_IconApp[MAX_PATH+1];
|
||||
|
||||
// All these objects will be destroyed when pwrshCommon goes out of scope.
|
||||
PwrshExeOutput* pwrshExeOutput = new PwrshExeOutput();
|
||||
PwrshCommon pwrshCommon(pwrshExeOutput, new WinSystemCallFacade());
|
||||
PwrshCommon pwrshCommon(pwrshExeOutput, new ConfigFileReader(), new WinSystemCallFacade());
|
||||
|
||||
bool ConvertArgvToSafeArray(
|
||||
IN int argc,
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Builds pwrshplugin.dll, the WinRM plugin for PowerShell remote hosting.
|
||||
#
|
||||
add_library(pwrshplugin SHARED
|
||||
entrypoints.cpp
|
||||
pwrshclrhost.cpp
|
||||
pwrshpluginerrorcodes.mc
|
||||
#pwrshpluginerrorcodes.rc
|
||||
pwrshpluginResources.rc
|
||||
pwrshplugin.def
|
||||
)
|
||||
|
||||
if (BUILD_ONECORE)
|
||||
# Libraries to use when creating this binary for Windows on OneCore-based SKUs
|
||||
set(PWRSHPLUGIN_WINDOWS_LIBS
|
||||
### ${STATIC_MT_CRT_LIB}
|
||||
### ${STATIC_MT_VCRT_LIB}
|
||||
### ${STATIC_UCRT_LIB}
|
||||
onecore.lib
|
||||
vcruntime.lib
|
||||
ucrtd.lib
|
||||
msvcrt.lib
|
||||
msvcprtd.lib
|
||||
user32.lib
|
||||
atls.lib
|
||||
wsmsvc.lib
|
||||
)
|
||||
set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "CORECLR")
|
||||
else ()
|
||||
# Libraries to use when creating this binary for Windows on full SKUs
|
||||
set(PWRSHPLUGIN_WINDOWS_LIBS
|
||||
# ntdll.lib
|
||||
# kernel32.lib
|
||||
# advapi32.lib
|
||||
# ole32.lib
|
||||
# oleaut32.lib
|
||||
# uuid.lib
|
||||
MUILoad.lib
|
||||
mscoree.lib
|
||||
wsmsvc.lib
|
||||
# CoreCLR lib
|
||||
${STATIC_MT_CRT_LIB}
|
||||
${STATIC_MT_VCRT_LIB}
|
||||
# ${STATIC_UCRT_LIB}
|
||||
legacy_stdio_definitions.lib # Resolves: LNK2019: unresolved external symbol _vsnwprintf
|
||||
)
|
||||
set(pwrshplugin_definitions ${common_pwrsh_definitions})
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
target_link_libraries(pwrshplugin
|
||||
${PWRSHPLUGIN_WINDOWS_LIBS})
|
||||
|
||||
target_link_libraries(pwrshplugin pwrshcommon)
|
||||
@@ -186,6 +186,7 @@ static PwrshCommon sPwrshCommon;
|
||||
// pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion.
|
||||
// returns: 0 on success, non-zero on failure.
|
||||
_Success_(return == 0) //EXIT_CODE_SUCCESS
|
||||
extern "C"
|
||||
unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
|
||||
int iPSMinorVersion,
|
||||
size_t runtimeVersionLength,
|
||||
@@ -323,6 +324,7 @@ DWORD ReportOperationComplete(WSMAN_PLUGIN_REQUEST *requestDetails, DWORD errorC
|
||||
// initialized more than once within the same process, but only once per
|
||||
// applicationIdentification.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
DWORD WINAPI WSManPluginStartup(
|
||||
__in DWORD flags,
|
||||
__in PCWSTR applicationIdentification,
|
||||
@@ -406,6 +408,7 @@ DWORD WINAPI WSManPluginStartup(
|
||||
// reason: If this is a system shutdown this will be WSMAN_PLUGIN_SHUTDOWN_SYSTEM.
|
||||
// For WSMan service shutdown this will be WSMAN_PLUGIN_SHUTDOWN_SERVICE. For an IIS host
|
||||
//shutdown this will be WSMAN_PLUGIN_SHUTDOWN_IISHOST.
|
||||
extern "C"
|
||||
DWORD WINAPI WSManPluginShutdown(
|
||||
__in PVOID pluginContext,
|
||||
__in DWORD flags,
|
||||
@@ -453,6 +456,7 @@ DWORD WINAPI WSManPluginShutdown(
|
||||
// requestDetails the plug-in needs to call WSManPluginOperationComplete.
|
||||
// The shell is active until this time.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginShell(
|
||||
__in PVOID pluginContext,
|
||||
__in WSMAN_PLUGIN_REQUEST *requestDetails,
|
||||
@@ -528,6 +532,7 @@ VOID WINAPI WSManPluginShell(
|
||||
// corresponding release function has been called. Failure to follow the contract
|
||||
// will result in errors being generated.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginReleaseShellContext(__in PVOID shellContext)
|
||||
{
|
||||
if ((NULL == shellContext))
|
||||
@@ -560,6 +565,7 @@ VOID WINAPI WSManPluginReleaseShellContext(__in PVOID shellContext)
|
||||
// requestDetails the plug-in needs to call WSManPluginOperationComplete.
|
||||
// The command is active until this time.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginCommand(
|
||||
__in WSMAN_PLUGIN_REQUEST *requestDetails,
|
||||
__in DWORD flags,
|
||||
@@ -593,6 +599,7 @@ VOID WINAPI WSManPluginCommand(
|
||||
// corresponding release function has been called. Failure to follow the contract
|
||||
// will result in errors being generated.
|
||||
// ---------------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginReleaseCommandContext(
|
||||
__in PVOID shellContext,
|
||||
__in PVOID commandContext
|
||||
@@ -624,6 +631,7 @@ VOID WINAPI WSManPluginReleaseCommandContext(
|
||||
// For each piece of data the plug-in calls WSManPluginResultComplete to
|
||||
// acknowledge receipt and to allow the next piece of data to be delivered.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginSend(
|
||||
__in WSMAN_PLUGIN_REQUEST *requestDetails,
|
||||
__in DWORD flags,
|
||||
@@ -663,6 +671,7 @@ VOID WINAPI WSManPluginSend(
|
||||
// WSManPluginResultComplete. The operation is marked as active until this
|
||||
// time.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginReceive(
|
||||
__in WSMAN_PLUGIN_REQUEST *requestDetails,
|
||||
__in DWORD flags,
|
||||
@@ -698,6 +707,7 @@ VOID WINAPI WSManPluginReceive(
|
||||
// of this callback may be many completion calls for the Signal, Receive, Command
|
||||
// and Shell operations.
|
||||
// -----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginSignal(
|
||||
__in WSMAN_PLUGIN_REQUEST *requestDetails,
|
||||
__in DWORD flags,
|
||||
@@ -723,7 +733,7 @@ VOID WINAPI WSManPluginSignal(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
VOID WINAPI WSManPluginConnect(
|
||||
__in WSMAN_PLUGIN_REQUEST *requestDetails,
|
||||
__in DWORD flags,
|
||||
|
||||
@@ -40,9 +40,10 @@ typedef void (STDMETHODCALLTYPE *LoaderRunHelperFp)(LPCWSTR appPath);
|
||||
|
||||
unsigned int PowerShellCoreClrWorker::LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion)
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName)
|
||||
{
|
||||
return commonLib->LaunchCoreCLR(hostWrapper, hostEnvironment);
|
||||
return commonLib->LaunchCoreCLR(hostWrapper, hostEnvironment, friendlyName);
|
||||
}
|
||||
|
||||
unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs(
|
||||
@@ -50,24 +51,17 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs(
|
||||
_In_z_ wchar_t* wszMgdPlugInFileName,
|
||||
_Outptr_result_maybenull_ PlugInException** pPluginException)
|
||||
{
|
||||
unsigned int exitCode = EXIT_CODE_SUCCESS;
|
||||
|
||||
*pPluginException = NULL;
|
||||
|
||||
exitCode = commonLib->CreateAppDomain(hostWrapper, L"PwrshPlugin", hostEnvironment);
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
{
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
// Set the powershell custom assembly loader to be the default
|
||||
LoaderRunHelperFp initDelegate = NULL;
|
||||
HRESULT hr = hostWrapper->CreateDelegate(
|
||||
hostWrapper->GetAppDomainId(),
|
||||
L"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
L"System.Management.Automation.PowerShellAssemblyLoadContextInitializer",
|
||||
L"SetPowerShellAssemblyLoadContext",
|
||||
(INT_PTR*)&initDelegate);
|
||||
"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
"System.Management.Automation.PowerShellAssemblyLoadContextInitializer",
|
||||
"SetPowerShellAssemblyLoadContext",
|
||||
//(INT_PTR*)&initDelegate);
|
||||
(void**)&initDelegate);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@@ -75,7 +69,7 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs(
|
||||
}
|
||||
else
|
||||
{
|
||||
initDelegate(hostEnvironment.GetHostDirectoryPath());
|
||||
initDelegate(hostEnvironment.GetHostDirectoryPathW());
|
||||
}
|
||||
|
||||
// Call into powershell entry point
|
||||
@@ -84,14 +78,12 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs(
|
||||
// Create the function pointer for the managed entry point
|
||||
// It must be targeted at a static method in the managed code.
|
||||
hr = hostWrapper->CreateDelegate(
|
||||
hostWrapper->GetAppDomainId(),
|
||||
L"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
L"System.Management.Automation.Remoting.WSManPluginManagedEntryWrapper",
|
||||
L"InitPlugin",
|
||||
(INT_PTR*)&entryPointDelegate);
|
||||
"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
"System.Management.Automation.Remoting.WSManPluginManagedEntryWrapper",
|
||||
"InitPlugin",
|
||||
(void**)&entryPointDelegate);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
//LONG systemErrorCode = GetLastError();
|
||||
output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr);
|
||||
|
||||
return EXIT_CODE_INIT_FAILURE;
|
||||
@@ -103,7 +95,7 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs(
|
||||
|
||||
PowerShellCoreClrWorker::PowerShellCoreClrWorker()
|
||||
: systemCalls(new WinSystemCallFacade()),
|
||||
hostWrapper(new ICLRRuntimeHost2Wrapper()),
|
||||
hostWrapper(new CoreClrHostingApiWrapper()),
|
||||
output(new PwrshPluginOutputDefault()),
|
||||
commonLib(new PwrshCommon())
|
||||
{
|
||||
@@ -133,12 +125,12 @@ PowerShellCoreClrWorker::PowerShellCoreClrWorker(
|
||||
{
|
||||
// Instantiate it even if one is not provided to guarantee that it will
|
||||
// always be non-NULL during execution.
|
||||
hostWrapper = new ICLRRuntimeHost2Wrapper();
|
||||
hostWrapper = new CoreClrHostingApiWrapper();
|
||||
}
|
||||
|
||||
if (NULL == commonLib)
|
||||
{
|
||||
commonLib = new PwrshCommon(new PwrshPluginOutputDefault(), new WinSystemCallFacade());
|
||||
commonLib = new PwrshCommon(new PwrshPluginOutputDefault(), new ConfigFileReader(), new WinSystemCallFacade());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +232,8 @@ PowerShellClrWorker::~PowerShellClrWorker()
|
||||
|
||||
unsigned int PowerShellClrWorker::LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion)
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName)
|
||||
{
|
||||
return commonLib.LaunchCLR(wszMonadVersion, wszRuntimeVersion, &pHost);
|
||||
}
|
||||
@@ -310,7 +303,8 @@ unsigned int PowerShellClrWorker::LoadWorkerCallbackPtrs(
|
||||
|
||||
unsigned int PowerShellClrManagedWorker::LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion)
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName)
|
||||
{
|
||||
return commonLib.LaunchCLR(wszMonadVersion, wszRuntimeVersion, &pHost);
|
||||
}
|
||||
@@ -350,7 +344,8 @@ unsigned int PowerShellClrManagedWorker::LoadWorkerCallbackPtrs(
|
||||
|
||||
// use CreateInstance because we use the assembly strong name (as opposed to CreateInstanceFrom)
|
||||
//
|
||||
// wszMgdPlugInFileName is %systemdir%\Windows\System32\WindowsPowerShell\v1.0\system.management.automation.dll.
|
||||
// wszMgdPlugInFileName is system.management.automation.dll within the powershell install path.
|
||||
// For inbox PowerShell, this is %systemdir%\Windows\System32\WindowsPowerShell\v1.0\system.management.automation.dll (Aka $PSHOME\system.management.automation.dll)
|
||||
_bstr_t bstrConsoleHostAssemblyName = _bstr_t(L"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
|
||||
_bstr_t bstrUnmanagedMshEntryClass = _bstr_t(L"System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper");
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "pwrshplugindefs.h" // PwrshPluginWkr_Ptrs and PlugInException
|
||||
#if !CORECLR
|
||||
#include <mscoree.h>
|
||||
#endif
|
||||
#include <atlbase.h>
|
||||
#include <string>
|
||||
#include "SystemCallFacade.h"
|
||||
@@ -46,7 +48,8 @@ public:
|
||||
|
||||
virtual unsigned int LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion) = 0;
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName) = 0;
|
||||
|
||||
virtual unsigned int LoadWorkerCallbackPtrs(
|
||||
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
|
||||
@@ -88,7 +91,8 @@ public:
|
||||
//
|
||||
virtual unsigned int LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion);
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName);
|
||||
|
||||
virtual unsigned int LoadWorkerCallbackPtrs(
|
||||
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
|
||||
@@ -114,7 +118,8 @@ public:
|
||||
//
|
||||
virtual unsigned int LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion);
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName);
|
||||
|
||||
virtual unsigned int LoadWorkerCallbackPtrs(
|
||||
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
|
||||
@@ -143,15 +148,16 @@ public:
|
||||
|
||||
virtual ~PowerShellCoreClrWorker();
|
||||
|
||||
std::wstring GetHostDirectory() { return std::wstring(hostEnvironment.GetHostDirectoryPath()); }
|
||||
std::wstring GetClrDirectory() { return std::wstring(hostEnvironment.GetCoreCLRDirectoryPath()); }
|
||||
std::wstring GetHostDirectory() { return std::wstring(hostEnvironment.GetHostDirectoryPathW()); }
|
||||
std::wstring GetClrDirectory() { return std::wstring(hostEnvironment.GetCoreCLRDirectoryPathW()); }
|
||||
|
||||
//
|
||||
// IPowerShellClrHost Methods
|
||||
//
|
||||
virtual unsigned int LaunchClr(
|
||||
_In_ LPCWSTR wszMonadVersion,
|
||||
_In_ LPCWSTR wszRuntimeVersion);
|
||||
_In_ LPCWSTR wszRuntimeVersion,
|
||||
_In_ LPCSTR friendlyName);
|
||||
|
||||
virtual unsigned int LoadWorkerCallbackPtrs(
|
||||
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
// pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion.
|
||||
// returns: 0 on success, non-zero on failure.
|
||||
_Success_(return == 0) // EXIT_CODE_SUCCESS
|
||||
extern unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
|
||||
int iPSMinorVersion,
|
||||
size_t runtimeVersionLength,
|
||||
__inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion,
|
||||
__out_ecount(1) size_t* pRuntimeVersionLength);
|
||||
extern "C"
|
||||
unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
|
||||
int iPSMinorVersion,
|
||||
size_t runtimeVersionLength,
|
||||
__inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion,
|
||||
__out_ecount(1) size_t* pRuntimeVersionLength);
|
||||
@@ -15,4 +15,4 @@ WSManPluginSend
|
||||
WSManPluginSignal
|
||||
WSManPluginReceive
|
||||
WSManPluginConnect
|
||||
PerformWSManPluginReportCompletion
|
||||
PerformWSManPluginReportCompletion
|
||||
@@ -714,7 +714,7 @@ private:
|
||||
break;
|
||||
}
|
||||
|
||||
exitCode = powerShellClrHost->LaunchClr(wszMonadVersion, wszTempCLRVersion);
|
||||
exitCode = powerShellClrHost->LaunchClr(wszMonadVersion, wszTempCLRVersion, "PwrshPlugin");
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
{
|
||||
PWSTR msg = NULL;
|
||||
@@ -1091,6 +1091,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
extern "C"
|
||||
void WINAPI PerformWSManPluginReportCompletion()
|
||||
{
|
||||
// Now report the plugin completion, to indicate that plugin is ready to shutdown.
|
||||
@@ -1098,4 +1099,4 @@ void WINAPI PerformWSManPluginReportCompletion()
|
||||
// - pluginContext MUST be the same context that plugin provided to the WSManPluginStartup method
|
||||
// - flags are reserved, so 0
|
||||
WSManPluginReportCompletion(g_pPluginContext, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
SET (CMAKE_C_FLAGS_INIT "/Wall /FC")
|
||||
SET (CMAKE_C_FLAGS_DEBUG_INIT "/Od /Zi")
|
||||
SET (CLR_C_FLAGS_CHECKED_INIT "/O1 /Zi")
|
||||
SET (CMAKE_C_FLAGS_RELEASE_INIT "/Ox /Zi")
|
||||
SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/O2 /Zi")
|
||||
|
||||
SET (CMAKE_CXX_FLAGS_INIT "/Wall /FC")
|
||||
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "/Od /Zi")
|
||||
SET (CLR_CXX_FLAGS_CHECKED_INIT "/O1 /Zi")
|
||||
SET (CMAKE_CXX_FLAGS_RELEASE_INIT "/Ox /Zi")
|
||||
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/O2 /Zi")
|
||||
|
||||
SET (CLR_DEFINES_DEBUG_INIT DEBUG _DEBUG _DBG URTBLDENV_FRIENDLY=Checked BUILDENV_CHECKED=1)
|
||||
SET (CLR_DEFINES_CHECKED_INIT DEBUG _DEBUG _DBG URTBLDENV_FRIENDLY=Checked BUILDENV_CHECKED=1)
|
||||
SET (CLR_DEFINES_RELEASE_INIT NDEBUG URTBLDENV_FRIENDLY=Retail)
|
||||
SET (CLR_DEFINES_RELWITHDEBINFO_INIT NDEBUG URTBLDENV_FRIENDLY=Retail)
|
||||
Reference in new issue
Block a user