Cleanup all native code from repository (#7892)
Native code for PowerShell has been moved to repository PowerShell/PowerShell-Native. Hence, removing all the native code and related build components.
This commit is contained in:
parent
2ea815756d
commit
b42c001700
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -1,4 +0,0 @@
|
|||
[submodule "src/libpsl-native/test/googletest"]
|
||||
path = src/libpsl-native/test/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
ignore = dirty
|
284
build.psm1
284
build.psm1
|
@ -177,220 +177,6 @@ if ( -not $env:PSModulePath.Contains($TestModulePath) ) {
|
|||
$env:PSModulePath = $TestModulePath+$TestModulePathSeparator+$($env:PSModulePath)
|
||||
}
|
||||
|
||||
function Test-Win10SDK {
|
||||
# The Windows 10 SDK is installed to "${env:ProgramFiles(x86)}\Windows Kits\10\bin\x64",
|
||||
# but the directory may exist even if the SDK has not been installed.
|
||||
#
|
||||
# A slightly more robust check is for the mc.exe binary within that directory.
|
||||
# It is only present if the SDK is installed.
|
||||
return (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\10\bin\x64\mc.exe")
|
||||
}
|
||||
|
||||
function Start-BuildNativeWindowsBinaries {
|
||||
param(
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string]$Configuration = 'Release',
|
||||
|
||||
# The `x64_arm` syntax is the build environment for VS2017, `x64` means the host is an x64 machine and will use
|
||||
# the x64 built tool. The `arm` refers to the target architecture when doing cross compilation.
|
||||
[ValidateSet('x64', 'x86', 'x64_arm64', 'x64_arm')]
|
||||
[string]$Arch = 'x64',
|
||||
|
||||
[switch]$Clean
|
||||
)
|
||||
|
||||
if (-not $Environment.IsWindows) {
|
||||
Write-Warning -Message "'Start-BuildNativeWindowsBinaries' is only supported on Windows platforms"
|
||||
return
|
||||
}
|
||||
|
||||
# cmake is needed to build pwsh.exe
|
||||
if (-not (precheck 'cmake' $null)) {
|
||||
throw 'cmake not found. Run "Start-PSBootstrap -BuildWindowsNative". You can also install it from https://chocolatey.org/packages/cmake'
|
||||
}
|
||||
|
||||
Use-MSBuild
|
||||
|
||||
# mc.exe is Message Compiler for native resources
|
||||
if (-Not (Test-Win10SDK)) {
|
||||
throw 'Win 10 SDK not found. Run "Start-PSBootstrap -BuildWindowsNative" or install Microsoft Windows 10 SDK from https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk'
|
||||
}
|
||||
|
||||
if ($env:VS140COMNTOOLS -ne $null) {
|
||||
$vcPath = (Get-Item(Join-Path -Path "$env:VS140COMNTOOLS" -ChildPath '../../vc')).FullName
|
||||
} else {
|
||||
$vcPath = (Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017" -Filter "VC" -Directory -Recurse | Select-Object -First 1).FullName
|
||||
}
|
||||
|
||||
$atlMfcIncludePath = Join-Path -Path $vcPath -ChildPath 'atlmfc/include'
|
||||
if (!(Test-Path $atlMfcIncludePath)) { # for VS2017, need to search for it
|
||||
$atlMfcIncludePath = (Get-ChildItem $vcPath -Filter AtlBase.h -Recurse -File | Select-Object -First 1).DirectoryName
|
||||
}
|
||||
|
||||
# atlbase.h is included in the pwrshplugin project
|
||||
if ((Test-Path -Path $atlMfcIncludePath\atlbase.h) -eq $false) {
|
||||
throw "Could not find Visual Studio include file atlbase.h at $atlMfcIncludePath. Please ensure the optional feature 'Microsoft Foundation Classes for C++' is installed."
|
||||
}
|
||||
|
||||
# vcvarsall.bat is used to setup environment variables
|
||||
$vcvarsallbatPath = "$vcPath\vcvarsall.bat"
|
||||
if (!(Test-Path -Path $vcvarsallbatPath)) { # for VS2017, need to search for it
|
||||
$vcvarsallbatPath = (Get-ChildItem $vcPath -Filter vcvarsall.bat -Recurse -File | Select-Object -First 1).FullName
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrEmpty($vcvarsallbatPath) -or (Test-Path -Path $vcvarsallbatPath) -eq $false) {
|
||||
throw "Could not find Visual Studio vcvarsall.bat at $vcvarsallbatPath. Please ensure the optional feature 'Common Tools for Visual C++' is installed."
|
||||
}
|
||||
|
||||
Write-Log "Start building native Windows binaries"
|
||||
|
||||
if ($Clean) {
|
||||
git clean -fdx
|
||||
Remove-Item $HOME\source\cmakecache.txt -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
try {
|
||||
Push-Location "$PSScriptRoot\src\powershell-native"
|
||||
|
||||
# setup cmakeGenerator
|
||||
$cmakeGeneratorPlatform = ""
|
||||
if ($Arch -eq 'x86') {
|
||||
$cmakeGenerator = 'Visual Studio 15 2017'
|
||||
$cmakeArch = 'x86'
|
||||
} elseif ($Arch -eq 'x64_arm') {
|
||||
$cmakeGenerator = 'Visual Studio 15 2017 ARM'
|
||||
$cmakeArch = 'arm'
|
||||
} elseif ($Arch -eq 'x64_arm64') {
|
||||
$cmakeGenerator = 'Visual Studio 15 2017'
|
||||
$cmakeArch = 'arm64'
|
||||
$cmakeGeneratorPlatform = "-A ARM64"
|
||||
} else {
|
||||
$cmakeGenerator = 'Visual Studio 15 2017 Win64'
|
||||
$cmakeArch = 'x64'
|
||||
}
|
||||
|
||||
# Compile native resources
|
||||
$currentLocation = Get-Location
|
||||
@("nativemsh\pwrshplugin") | ForEach-Object {
|
||||
$nativeResourcesFolder = $_
|
||||
Get-ChildItem $nativeResourcesFolder -Filter "*.mc" | ForEach-Object {
|
||||
$command = @"
|
||||
cmd.exe /C cd /d "$currentLocation" "&" "$vcvarsallbatPath" "$Arch" "&" mc.exe -o -d -c -U "$($_.FullName)" -h "$currentLocation\$nativeResourcesFolder" -r "$currentLocation\$nativeResourcesFolder"
|
||||
"@
|
||||
Write-Log " Executing mc.exe Command: $command"
|
||||
Start-NativeExecution { Invoke-Expression -Command:$command }
|
||||
}
|
||||
}
|
||||
|
||||
# make sure we use version we installed and not from VS
|
||||
$cmakePath = (Get-Command cmake).Source
|
||||
# Disabling until I figure out if it is necessary
|
||||
# $overrideFlags = "-DCMAKE_USER_MAKE_RULES_OVERRIDE=$PSScriptRoot\src\powershell-native\windows-compiler-override.txt"
|
||||
$overrideFlags = ""
|
||||
$command = @"
|
||||
cmd.exe /C cd /d "$currentLocation" "&" "$vcvarsallbatPath" "$Arch" "&" "$cmakePath" "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$cmakeArch -G "$cmakeGenerator" $cmakeGeneratorPlatform "$currentLocation" "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration"
|
||||
"@
|
||||
Write-Log " Executing Build Command: $command"
|
||||
Start-NativeExecution { Invoke-Expression -Command:$command }
|
||||
|
||||
# Copy the binaries from the local build directory to the packaging directory
|
||||
$FilesToCopy = @('pwrshplugin.dll', 'pwrshplugin.pdb')
|
||||
$dstPath = "$PSScriptRoot\src\powershell-win-core"
|
||||
$FilesToCopy | ForEach-Object {
|
||||
$srcPath = [IO.Path]::Combine($PWD.Path, "bin", $Configuration, "CoreClr/$_")
|
||||
|
||||
Write-Log " Copying $srcPath to $dstPath"
|
||||
Copy-Item $srcPath $dstPath
|
||||
}
|
||||
|
||||
#
|
||||
# Build the ETW manifest resource-only binary
|
||||
#
|
||||
$location = "$PSScriptRoot\src\PowerShell.Core.Instrumentation"
|
||||
Set-Location -Path $location
|
||||
|
||||
Remove-Item $HOME\source\cmakecache.txt -ErrorAction SilentlyContinue
|
||||
|
||||
$command = @"
|
||||
cmd.exe /C cd /d "$location" "&" "$vcvarsallbatPath" "$Arch" "&" "$cmakePath" "$overrideFlags" -DBUILD_ONECORE=ON -DBUILD_TARGET_ARCH=$cmakeArch -G "$cmakeGenerator" $cmakeGeneratorPlatform "$location" "&" msbuild ALL_BUILD.vcxproj "/p:Configuration=$Configuration"
|
||||
"@
|
||||
Write-Log " Executing Build Command for PowerShell.Core.Instrumentation: $command"
|
||||
Start-NativeExecution { Invoke-Expression -Command:$command }
|
||||
|
||||
# Copy the binary to the packaging directory
|
||||
# NOTE: No PDB file; it's a resource-only DLL.
|
||||
$srcPath = [IO.Path]::Combine($PWD.Path, $Configuration, 'PowerShell.Core.Instrumentation.dll')
|
||||
Copy-Item -Path $srcPath -Destination $dstPath
|
||||
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
function Start-BuildNativeUnixBinaries {
|
||||
param (
|
||||
[switch] $BuildLinuxArm
|
||||
)
|
||||
|
||||
if (-not $Environment.IsLinux -and -not $Environment.IsMacOS) {
|
||||
Write-Warning -Message "'Start-BuildNativeUnixBinaries' is only supported on Linux/macOS platforms"
|
||||
return
|
||||
}
|
||||
|
||||
if ($BuildLinuxArm -and -not $Environment.IsUbuntu) {
|
||||
throw "Cross compiling for linux-arm is only supported on Ubuntu environment"
|
||||
}
|
||||
|
||||
# Verify we have all tools in place to do the build
|
||||
$precheck = $true
|
||||
foreach ($Dependency in 'cmake', 'make', 'g++') {
|
||||
$precheck = $precheck -and (precheck $Dependency "Build dependency '$Dependency' not found. Run 'Start-PSBootstrap'.")
|
||||
}
|
||||
|
||||
if ($BuildLinuxArm) {
|
||||
foreach ($Dependency in 'arm-linux-gnueabihf-gcc', 'arm-linux-gnueabihf-g++') {
|
||||
$precheck = $precheck -and (precheck $Dependency "Build dependency '$Dependency' not found. Run 'Start-PSBootstrap'.")
|
||||
}
|
||||
}
|
||||
|
||||
# Abort if any precheck failed
|
||||
if (-not $precheck) {
|
||||
return
|
||||
}
|
||||
|
||||
# Build native components
|
||||
$Ext = if ($Environment.IsLinux) {
|
||||
"so"
|
||||
} elseif ($Environment.IsMacOS) {
|
||||
"dylib"
|
||||
}
|
||||
|
||||
$Native = "$PSScriptRoot/src/libpsl-native"
|
||||
$Lib = "$PSScriptRoot/src/powershell-unix/libpsl-native.$Ext"
|
||||
Write-Log "Start building $Lib"
|
||||
|
||||
git clean -qfdX $Native
|
||||
|
||||
try {
|
||||
Push-Location $Native
|
||||
if ($BuildLinuxArm) {
|
||||
Start-NativeExecution { cmake -DCMAKE_TOOLCHAIN_FILE="./arm.toolchain.cmake" . }
|
||||
Start-NativeExecution { make -j }
|
||||
}
|
||||
else {
|
||||
Start-NativeExecution { cmake -DCMAKE_BUILD_TYPE=Debug . }
|
||||
Start-NativeExecution { make -j }
|
||||
Start-NativeExecution { ctest --verbose }
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
if (-not (Test-Path $Lib)) {
|
||||
throw "Compilation of $Lib failed"
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Tests if a version is preview
|
||||
|
@ -1719,7 +1505,6 @@ function Start-PSBootstrap {
|
|||
[string]$Version = $dotnetCLIRequiredVersion,
|
||||
[switch]$Package,
|
||||
[switch]$NoSudo,
|
||||
[switch]$BuildWindowsNative,
|
||||
[switch]$BuildLinuxArm,
|
||||
[switch]$Force
|
||||
)
|
||||
|
@ -1909,75 +1694,6 @@ function Start-PSBootstrap {
|
|||
|
||||
Invoke-WebRequest -OutFile "~/.rcedit/rcedit-x64.exe" -Uri $rceditUrl
|
||||
}
|
||||
|
||||
if ($BuildWindowsNative) {
|
||||
Write-Log "Install Windows dependencies for building PSRP plugin"
|
||||
|
||||
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
|
||||
$newMachineEnvironmentPath = $machinePath
|
||||
|
||||
$cmakePresent = precheck 'cmake' $null
|
||||
$sdkPresent = Test-Win10SDK
|
||||
|
||||
# Install chocolatey
|
||||
$chocolateyPath = "$env:AllUsersProfile\chocolatey\bin"
|
||||
|
||||
if(precheck 'choco' $null) {
|
||||
Write-Log "Chocolatey is already installed. Skipping installation."
|
||||
}
|
||||
elseif(($cmakePresent -eq $false) -or ($sdkPresent -eq $false)) {
|
||||
Write-Log "Chocolatey not present. Installing chocolatey."
|
||||
if ($Force -or $PSCmdlet.ShouldProcess("Install chocolatey via https://chocolatey.org/install.ps1")) {
|
||||
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
if (-not ($machinePath.ToLower().Contains($chocolateyPath.ToLower()))) {
|
||||
Write-Log "Adding $chocolateyPath to Path environment variable"
|
||||
$env:Path += ";$chocolateyPath"
|
||||
$newMachineEnvironmentPath += ";$chocolateyPath"
|
||||
} else {
|
||||
Write-Log "$chocolateyPath already present in Path environment variable"
|
||||
}
|
||||
} else {
|
||||
Write-Error "Chocolatey is required to install missing dependencies. Please install it from https://chocolatey.org/ manually. Alternatively, install cmake and Windows 10 SDK."
|
||||
return
|
||||
}
|
||||
} else {
|
||||
Write-Log "Skipping installation of chocolatey, cause both cmake and Win 10 SDK are present."
|
||||
}
|
||||
|
||||
# Install cmake
|
||||
$cmakePath = "${env:ProgramFiles}\CMake\bin"
|
||||
if($cmakePresent -and !($force.IsPresent)) {
|
||||
Write-Log "Cmake is already installed. Skipping installation."
|
||||
} else {
|
||||
Write-Log "Cmake not present or -Force used. Installing cmake."
|
||||
Start-NativeExecution { choco install cmake -y --version 3.10.0 }
|
||||
if (-not ($machinePath.ToLower().Contains($cmakePath.ToLower()))) {
|
||||
Write-Log "Adding $cmakePath to Path environment variable"
|
||||
$env:Path += ";$cmakePath"
|
||||
$newMachineEnvironmentPath = "$cmakePath;$newMachineEnvironmentPath"
|
||||
} else {
|
||||
Write-Log "$cmakePath already present in Path environment variable"
|
||||
}
|
||||
}
|
||||
|
||||
# Install Windows 10 SDK
|
||||
$packageName = "windows-sdk-10.0"
|
||||
|
||||
if (-not $sdkPresent) {
|
||||
Write-Log "Windows 10 SDK not present. Installing $packageName."
|
||||
Start-NativeExecution { choco install windows-sdk-10.0 -y }
|
||||
} else {
|
||||
Write-Log "Windows 10 SDK present. Skipping installation."
|
||||
}
|
||||
|
||||
# Update path machine environment variable
|
||||
if ($newMachineEnvironmentPath -ne $machinePath) {
|
||||
Write-Log "Updating Path machine environment variable"
|
||||
if ($Force -or $PSCmdlet.ShouldProcess("Update Path machine environment variable to $newMachineEnvironmentPath")) {
|
||||
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
#
|
||||
# Builds PowerShell.Core.Instrumentation.dll resource-only DLL containing ETW event resources
|
||||
#
|
||||
|
||||
# The fully qualified path to the event manifest
|
||||
SET(EVENTS_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/PowerShell.Core.Instrumentation.man")
|
||||
|
||||
# User mode manifest resource-only dll
|
||||
function(add_manifest_binary)
|
||||
|
||||
add_definitions(-D_DLL=1)
|
||||
add_library(${ARGV})
|
||||
|
||||
# NOTE: EVENTS_MANIFEST must be the fully qualified path to the manifest
|
||||
SET(MC_MANIFEST_FULLNAME ${EVENTS_MANIFEST})
|
||||
|
||||
# get the ETW manifest's filename without the directory or extension
|
||||
get_filename_component(MC_MANIFEST_BASENAME ${EVENTS_MANIFEST} NAME_WE)
|
||||
|
||||
SET(MC_COMMAND "mc.exe")
|
||||
SET(GeneratedManifestFiles)
|
||||
|
||||
# The target directory for generated managed files
|
||||
SET (MC_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
# include the generated directory in the include path
|
||||
include_directories("${MC_GENERATED_DIR}")
|
||||
|
||||
SET (MC_GENERATED_FILES
|
||||
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc
|
||||
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}TEMP.BIN
|
||||
${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}_MSG00001.BIN
|
||||
)
|
||||
|
||||
SET(MC_COMMAND "mc.exe -h ${MC_GENERATED_DIR} -r ${MC_GENERATED_DIR} ${MC_MANIFEST_FULLNAME}")
|
||||
|
||||
add_custom_command(
|
||||
COMMENT "Generating native event manifest files for ${EVENTS_MANIFEST}"
|
||||
OUTPUT ${MC_GENERATED_FILES}
|
||||
DEPENDS ${MC_MANIFEST_FULLNAME}
|
||||
COMMAND cmd.exe /c ${MC_COMMAND}
|
||||
WORKING_DIRECTORY ${MC_GENERATED_DIR}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
list (APPEND GeneratedManifestFiles ${MC_GENERATED_DIR}/${MC_MANIFEST_BASENAME}.rc)
|
||||
|
||||
set_source_files_properties(${GeneratedManifestFiles} PROPERTIES GENERATED TRUE)
|
||||
add_custom_target(GeneratedManifestFiles DEPENDS ${GeneratedManifestFiles})
|
||||
|
||||
# for a resource only dll, cmake can report an error
|
||||
# if there is no linker language set.
|
||||
# CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
|
||||
# Missing variable is: CMAKE_RC_CREATE_SHARED_LIBRARY
|
||||
get_property(isSet TARGET ${ARGV0} PROPERTY LINKER_LANGUAGE SET)
|
||||
if (NOT ${isSet})
|
||||
set_target_properties(${ARGV0} PROPERTIES LINKER_LANGUAGE "CXX")
|
||||
endif()
|
||||
|
||||
set_target_properties(${ARGV0} PROPERTIES LINK_FLAGS "/NODEFAULTLIB /NOENTRY")
|
||||
|
||||
if (BUILD_ONECORE)
|
||||
set_target_properties(${ARGV0} PROPERTIES COMPILE_DEFINITIONS "CORECLR")
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
# ensure the target is dependent on the generated files.
|
||||
add_dependencies(${ARGV0} GeneratedManifestFiles)
|
||||
|
||||
endfunction()
|
||||
|
||||
file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/version.rc)
|
||||
|
||||
add_manifest_binary(PowerShell.Core.Instrumentation SHARED ${SOURCES})
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>PowerShell.Core.Instrumentation</id>
|
||||
<version>6.0.0-beta.10</version>
|
||||
<authors>Microsoft</authors>
|
||||
<owners>Microsoft</owners>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>PowerShell Core ETW resource binary</description>
|
||||
<copyright>(c) Microsoft Corporation. All rights reserved.</copyright>
|
||||
</metadata>
|
||||
</package>
|
5
src/PowerShell.Core.Instrumentation/README.md
Normal file
5
src/PowerShell.Core.Instrumentation/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# PowerShell.Core.Instrumentation
|
||||
|
||||
The code under `PowerShell.Core.Instrumentation` is being migrated to [PowerShell-native](https://github.com/PowerShell/PowerShell-native) repository.
|
||||
Please make PRs to the new repository.
|
||||
Code under here will be removed once the move is complete.
|
|
@ -1,15 +0,0 @@
|
|||
//
|
||||
// Copyright (C) Microsoft. All rights reserved.
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <ntverp.h>
|
||||
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
#define VER_FILEDESCRIPTION_STR "PowerShellCore"
|
||||
#define VER_INTERNALNAME_STR "PowerShell.Core.Instrumentation.dll"
|
||||
#define VER_ORIGINALFILENAME_STR "PowerShell.Core.Instrumentation.dll"
|
||||
|
||||
#include "common.ver"
|
||||
|
||||
#include "PowerShell.Core.Instrumentation.rc"
|
12
src/libpsl-native/.gitignore
vendored
12
src/libpsl-native/.gitignore
vendored
|
@ -1,12 +0,0 @@
|
|||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
Testing/
|
||||
test/psl-native-test
|
||||
src/libpsl-native.so
|
||||
src/libpsl-native.dylib
|
||||
test/native-tests.xml
|
|
@ -1,25 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.8.11)
|
||||
project(PSL-NATIVE)
|
||||
|
||||
# Can't use add_compile_options with 2.8.11
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror -fstack-protector-strong -fpie -DFORTIFY_SOURCE=2 -O2")
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro,-z,now")
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl")
|
||||
endif()
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/../powershell-unix")
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*")
|
||||
message(STATUS "Building for ARM, no tests")
|
||||
add_subdirectory(src)
|
||||
else ()
|
||||
# test in BUILD_DIR
|
||||
message(STATUS "Tests enabled")
|
||||
enable_testing()
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
||||
endif ()
|
|
@ -1,5 +1,5 @@
|
|||
# libpsl-native
|
||||
|
||||
The code under `powershell-native` is being migrated to [PowerShell-native](https://github.com/PowerShell/PowerShell-native) repository.
|
||||
The code under `libpsl-native` is being migrated to [PowerShell-native](https://github.com/PowerShell/PowerShell-native) repository.
|
||||
Please make PRs to the new repository.
|
||||
Code under here will be removed once the move is complete.
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
set(CMAKE_SYSTEM_PROCESSOR armv7l)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++ -fstack-protector-strong -fpie -DFORTIFY_SOURCE=2 -O2)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,relro,-z,now")
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
|
||||
# add_compile_options(-target armv7-linux-gnueabihf)
|
||||
add_compile_options(-mthumb)
|
||||
add_compile_options(-mfpu=vfpv3)
|
||||
add_compile_options(-g)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
1
src/libpsl-native/src/.gitignore
vendored
1
src/libpsl-native/src/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
pal_config.h
|
|
@ -1,37 +0,0 @@
|
|||
include(CheckIncludeFiles)
|
||||
|
||||
add_library(psl-native SHARED
|
||||
getstat.cpp
|
||||
getpwuid.cpp
|
||||
getppid.cpp
|
||||
getuserfrompid.cpp
|
||||
getfileowner.cpp
|
||||
getcurrentthreadid.cpp
|
||||
getcurrentprocessorid.cpp
|
||||
getusername.cpp
|
||||
getcomputername.cpp
|
||||
getlinkcount.cpp
|
||||
getfullyqualifiedname.cpp
|
||||
geterrorcategory.cpp
|
||||
getinodedata.cpp
|
||||
isfile.cpp
|
||||
isdirectory.cpp
|
||||
issamefilesystemitem.cpp
|
||||
issymlink.cpp
|
||||
isexecutable.cpp
|
||||
setdate.cpp
|
||||
createhardlink.cpp
|
||||
createsymlink.cpp
|
||||
followsymlink.cpp
|
||||
createprocess.cpp
|
||||
nativesyslog.cpp)
|
||||
|
||||
check_include_files(
|
||||
"sys/types.h;sys/sysctl.h"
|
||||
HAVE_SYS_SYSCTL_H)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pal_config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pal_config.h)
|
||||
|
||||
target_include_directories(psl-native PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief create new hard link
|
||||
|
||||
#include "createhardlink.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief Createhardlink create new symbolic link
|
||||
//!
|
||||
//! Createhardlink
|
||||
//!
|
||||
//! @param[in] link
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the symbolic link to create
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[in] target
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the existing file
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval 0 if successful, otherwise -1
|
||||
//!
|
||||
|
||||
int32_t CreateHardLink(const char *newlink, const char *target)
|
||||
{
|
||||
assert(newlink);
|
||||
assert(target);
|
||||
|
||||
return link(target, newlink);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t CreateHardLink(const char *link, const char *target);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,220 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "createprocess.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
enum
|
||||
{
|
||||
SUPPRESS_PROCESS_SIGINT = 0x00000001
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
READ_END_OF_PIPE = 0,
|
||||
WRITE_END_OF_PIPE = 1
|
||||
};
|
||||
|
||||
static void CloseIfOpen(int fd)
|
||||
{
|
||||
if (fd >= 0)
|
||||
{
|
||||
close(fd); // Ignoring errors from close is a deliberate choice
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the IO operation was interrupted and needs to be retried.
|
||||
// Returns true if the operation was interrupted; otherwise, false.
|
||||
template <typename TInt>
|
||||
static inline bool CheckInterrupted(TInt result)
|
||||
{
|
||||
return result < 0 && errno == EINTR;
|
||||
}
|
||||
|
||||
static int Dup2WithInterruptedRetry(int oldfd, int newfd)
|
||||
{
|
||||
int result;
|
||||
while (CheckInterrupted(result = dup2(oldfd, newfd)));
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t SystemNative_Pipe(int32_t pipeFds[2], int32_t flags)
|
||||
{
|
||||
int32_t result;
|
||||
while (CheckInterrupted(result = pipe(pipeFds)));
|
||||
|
||||
// Then, if O_CLOEXEC was specified, use fcntl to configure the file descriptors appropriately.
|
||||
if ((flags & O_CLOEXEC) != 0 && result == 0)
|
||||
{
|
||||
while (CheckInterrupted(result = fcntl(pipeFds[0], F_SETFD, FD_CLOEXEC)));
|
||||
if (result == 0)
|
||||
{
|
||||
while (CheckInterrupted(result = fcntl(pipeFds[1], F_SETFD, FD_CLOEXEC)));
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
int tmpErrno = errno;
|
||||
close(pipeFds[0]);
|
||||
close(pipeFds[1]);
|
||||
errno = tmpErrno;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t ForkAndExecProcess(
|
||||
const char* filename,
|
||||
char* const argv[],
|
||||
char* const envp[],
|
||||
const char* cwd,
|
||||
int32_t redirectStdin,
|
||||
int32_t redirectStdout,
|
||||
int32_t redirectStderr,
|
||||
int32_t creationFlags,
|
||||
int32_t* childPid,
|
||||
int32_t* stdinFd,
|
||||
int32_t* stdoutFd,
|
||||
int32_t* stderrFd)
|
||||
{
|
||||
int success = true;
|
||||
int processId = -1;
|
||||
int stdinFds[2] = { -1, -1 };
|
||||
int stdoutFds[2] = { -1, -1 };
|
||||
int stderrFds[2] = { -1, -1 };
|
||||
|
||||
// Validate arguments
|
||||
if (nullptr == filename || nullptr == argv || nullptr == envp || nullptr == stdinFd || nullptr == stdoutFd ||
|
||||
nullptr == stderrFd || nullptr == childPid)
|
||||
{
|
||||
assert(false && "null argument.");
|
||||
errno = EINVAL;
|
||||
success = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((redirectStdin & ~1) != 0 || (redirectStdout & ~1) != 0 || (redirectStderr & ~1) != 0)
|
||||
{
|
||||
assert(false && "Boolean redirect* inputs must be 0 or 1.");
|
||||
errno = EINVAL;
|
||||
success = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Make sure we can find and access the executable. exec will do this, of course, but at that point it's already
|
||||
// in the child process, at which point it'll translate to the child process' exit code rather than to failing
|
||||
// the Start itself. There's a race condition here, in that this could change prior to exec's checks, but there's
|
||||
// little we can do about that. There are also more rigorous checks exec does, such as validating the executable
|
||||
// format of the target; such errors will emerge via the child process' exit code.
|
||||
if (access(filename, X_OK) != 0)
|
||||
{
|
||||
success = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Open pipes for any requests to redirect stdin/stdout/stderr
|
||||
if ((redirectStdin && SystemNative_Pipe(stdinFds, O_CLOEXEC) != 0) ||
|
||||
(redirectStdout && SystemNative_Pipe(stdoutFds, O_CLOEXEC) != 0) ||
|
||||
(redirectStderr && SystemNative_Pipe(stderrFds, O_CLOEXEC) != 0))
|
||||
{
|
||||
success = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Fork the child process
|
||||
if ((processId = fork()) == -1)
|
||||
{
|
||||
success = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (processId == 0) // processId == 0 if this is child process
|
||||
{
|
||||
// For any redirections that should happen, dup the pipe descriptors onto stdin/out/err.
|
||||
// We don't explicitly close out the old pipe descriptors because they are set to close on execve.
|
||||
if ((redirectStdin && Dup2WithInterruptedRetry(stdinFds[READ_END_OF_PIPE], STDIN_FILENO) == -1) ||
|
||||
(redirectStdout && Dup2WithInterruptedRetry(stdoutFds[WRITE_END_OF_PIPE], STDOUT_FILENO) == -1) ||
|
||||
(redirectStderr && Dup2WithInterruptedRetry(stderrFds[WRITE_END_OF_PIPE], STDERR_FILENO) == -1))
|
||||
{
|
||||
_exit(errno != 0 ? errno : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Change to the designated working directory, if one was specified
|
||||
if (nullptr != cwd)
|
||||
{
|
||||
int result;
|
||||
while (CheckInterrupted(result = chdir(cwd)));
|
||||
if (result == -1)
|
||||
{
|
||||
_exit(errno != 0 ? errno : EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// If SUPPRESS_PROCESS_SIGINT was chosen then create a process that ignores
|
||||
// interrupt signals
|
||||
if (creationFlags & SUPPRESS_PROCESS_SIGINT)
|
||||
{
|
||||
struct sigaction sa, saOld;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
memset(&saOld, 0, sizeof(saOld));
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_handler = SIG_IGN; // Ignore the signal
|
||||
|
||||
int result = sigaction(SIGINT, &sa, &saOld);
|
||||
if (result == -1)
|
||||
{
|
||||
_exit(errno != 0 ? errno : EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, execute the new process. execve will not return if it's successful.
|
||||
execve(filename, argv, envp);
|
||||
_exit(errno != 0 ? errno : EXIT_FAILURE); // execve failed
|
||||
}
|
||||
|
||||
// This is the parent process. processId == pid of the child
|
||||
*childPid = processId;
|
||||
*stdinFd = stdinFds[WRITE_END_OF_PIPE];
|
||||
*stdoutFd = stdoutFds[READ_END_OF_PIPE];
|
||||
*stderrFd = stderrFds[READ_END_OF_PIPE];
|
||||
|
||||
done:
|
||||
int priorErrno = errno;
|
||||
|
||||
// Regardless of success or failure, close the parent's copy of the child's end of
|
||||
// any opened pipes. The parent doesn't need them anymore.
|
||||
CloseIfOpen(stdinFds[READ_END_OF_PIPE]);
|
||||
CloseIfOpen(stdoutFds[WRITE_END_OF_PIPE]);
|
||||
CloseIfOpen(stderrFds[WRITE_END_OF_PIPE]);
|
||||
|
||||
// If we failed, close everything else and give back error values in all out arguments.
|
||||
if (!success)
|
||||
{
|
||||
CloseIfOpen(stdinFds[WRITE_END_OF_PIPE]);
|
||||
CloseIfOpen(stdoutFds[READ_END_OF_PIPE]);
|
||||
CloseIfOpen(stderrFds[READ_END_OF_PIPE]);
|
||||
|
||||
*stdinFd = -1;
|
||||
*stdoutFd = -1;
|
||||
*stderrFd = -1;
|
||||
*childPid = -1;
|
||||
|
||||
errno = priorErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t ForkAndExecProcess(
|
||||
const char* filename, // filename argument to execve
|
||||
char* const argv[], // argv argument to execve
|
||||
char* const envp[], // envp argument to execve
|
||||
const char* cwd, // path passed to chdir in child process
|
||||
int32_t redirectStdin, // whether to redirect standard input from the parent
|
||||
int32_t redirectStdout, // whether to redirect standard output to the parent
|
||||
int32_t redirectStderr, // whether to redirect standard error to the parent
|
||||
int32_t creationFlags, // creation flags
|
||||
int32_t* childPid, // [out] the child process' id
|
||||
int32_t* stdinFd, // [out] if redirectStdin, the parent's fd for the child's stdin
|
||||
int32_t* stdoutFd, // [out] if redirectStdout, the parent's fd for the child's stdout
|
||||
int32_t* stderrFd); // [out] if redirectStderr, the parent's fd for the child's stderr
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief create new symbolic link
|
||||
|
||||
#include "createsymlink.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief Createsymlink create new symbolic link
|
||||
//!
|
||||
//! Createsymlink
|
||||
//!
|
||||
//! @param[in] link
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the symbolic link to create
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[in] target
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the existing file
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval 0 if successful, -1 otherwise
|
||||
//!
|
||||
|
||||
int32_t CreateSymLink(const char *link, const char *target)
|
||||
{
|
||||
assert(link);
|
||||
assert(target);
|
||||
|
||||
errno = 0;
|
||||
|
||||
return symlink(target, link);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t CreateSymLink(const char *link, const char *target);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns whether a path is a symbolic link
|
||||
|
||||
#include "followsymlink.h"
|
||||
#include "issymlink.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief FollowSymLink determines target path of a sym link
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval target path, or NULL if unsuccessful
|
||||
//!
|
||||
|
||||
char* FollowSymLink(const char* fileName)
|
||||
{
|
||||
assert(fileName);
|
||||
errno = 0;
|
||||
|
||||
// return null for non symlinks
|
||||
if (!IsSymLink(fileName))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// attempt to resolve with the absolute file path
|
||||
char buffer[PATH_MAX];
|
||||
char* realPath = realpath(fileName, buffer);
|
||||
|
||||
if (realPath)
|
||||
{
|
||||
return strndup(realPath, strnlen(realPath, PATH_MAX));
|
||||
}
|
||||
|
||||
// if the path wasn't resolved, use readlink
|
||||
ssize_t sz = readlink(fileName, buffer, PATH_MAX);
|
||||
if (sz == -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[sz] = '\0';
|
||||
return strndup(buffer, sz + 1);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* FollowSymLink(const char* fileName);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements GetComputerName Win32 API
|
||||
|
||||
#include "getcomputername.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief GetComputerName retrieves the name of the host associated with
|
||||
//! the current thread.
|
||||
//!
|
||||
//! @retval username as UTF-8 string, or null if unsuccessful
|
||||
|
||||
char* GetComputerName()
|
||||
{
|
||||
errno = 0;
|
||||
// Get computername from system, note that gethostname(2) gets the
|
||||
// nodename from uname
|
||||
std::string computername(_POSIX_HOST_NAME_MAX, 0);
|
||||
int32_t ret = gethostname(&computername[0], computername.length());
|
||||
// Map errno to Win32 Error Codes
|
||||
if (ret != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(computername.c_str());
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char *GetComputerName();
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "getcurrentprocessorid.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t GetCurrentProcessId()
|
||||
{
|
||||
return getpid();
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
pid_t GetCurrentProcessId();
|
||||
|
||||
PAL_END_EXTERNC
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "getcurrentthreadid.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <pthread.h>
|
||||
|
||||
pid_t GetCurrentThreadId()
|
||||
{
|
||||
pid_t tid = 0;
|
||||
#if defined(__linux__)
|
||||
tid = syscall(SYS_gettid);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
uint64_t tid64;
|
||||
pthread_threadid_np(NULL, &tid64);
|
||||
tid = (pid_t)tid64;
|
||||
#endif
|
||||
return tid;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
pid_t GetCurrentThreadId();
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "geterrorcategory.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Copy of PowerShell ErrorCategory enum from ErrorPackage.cs
|
||||
enum ErrorCategory {
|
||||
NotSpecified = 0,
|
||||
OpenError = 1,
|
||||
CloseError = 2,
|
||||
DeviceError = 3,
|
||||
DeadlockDetected = 4,
|
||||
InvalidArgument = 5,
|
||||
InvalidData = 6,
|
||||
InvalidOperation = 7,
|
||||
InvalidResult = 8,
|
||||
InvalidType = 9,
|
||||
MetadataError = 10,
|
||||
NotImplemented = 11,
|
||||
NotInstalled = 12,
|
||||
ObjectNotFound = 13,
|
||||
OperationStopped = 14,
|
||||
OperationTimeout = 15,
|
||||
SyntaxError = 16,
|
||||
ParserError = 17,
|
||||
PermissionDenied = 18,
|
||||
ResourceBusy = 19,
|
||||
ResourceExists = 20,
|
||||
ResourceUnavailable = 21,
|
||||
ReadError = 22,
|
||||
WriteError = 23,
|
||||
FromStdErr = 24,
|
||||
SecurityError = 25,
|
||||
ProtocolError = 26,
|
||||
ConnectionError = 27,
|
||||
AuthenticationError = 28,
|
||||
LimitsExceeded = 29,
|
||||
QuotaExceeded = 30,
|
||||
NotEnabled = 31,
|
||||
};
|
||||
|
||||
//! @brief Maps Linux errno to PowerShell ErrorCategory
|
||||
int32_t GetErrorCategory(int32_t errnum)
|
||||
{
|
||||
switch (errnum)
|
||||
{
|
||||
case EINVAL:
|
||||
return InvalidArgument;
|
||||
case ENOENT:
|
||||
case ESRCH:
|
||||
return ObjectNotFound;
|
||||
case EINTR:
|
||||
return OperationStopped;
|
||||
case EACCES:
|
||||
case EPERM:
|
||||
return PermissionDenied;
|
||||
default:
|
||||
return NotSpecified;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t GetErrorCategory(int32_t);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns the owner of a file
|
||||
|
||||
#include "getstat.h"
|
||||
#include "getpwuid.h"
|
||||
#include "getfileowner.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief GetFileOwner returns the owner of a file
|
||||
//!
|
||||
//! GetFileOwner
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval file owner, or NULL if unsuccessful
|
||||
//!
|
||||
char* GetFileOwner(const char* fileName)
|
||||
{
|
||||
assert(fileName);
|
||||
errno = 0;
|
||||
|
||||
struct stat buf;
|
||||
int32_t ret = GetStat(fileName, &buf);
|
||||
if (ret != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return GetPwUid(buf.st_uid);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* GetFileOwner(const char* fileName);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements GetFullyQualifiedName on Linux
|
||||
|
||||
#include "getcomputername.h"
|
||||
#include "getfullyqualifiedname.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
//! @brief GetFullyQualifiedName retrieves the fully qualified dns name of the host
|
||||
//!
|
||||
//! @retval username as UTF-8 string, or null if unsuccessful
|
||||
char *GetFullyQualifiedName()
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
char *computerName = GetComputerName();
|
||||
if (computerName == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct addrinfo hints, *info;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC; /*either IPV4 or IPV6*/
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
|
||||
/* There are several ways to get the domain name:
|
||||
* uname(2), gethostbyname(3), resolver(3), getdomainname(2),
|
||||
* and getaddrinfo(3). Some of these are not portable, some aren't
|
||||
* POSIX compliant, and some are being deprecated. getaddrinfo seems
|
||||
* to be the best choice.
|
||||
*/
|
||||
char *fullName = NULL;
|
||||
if (getaddrinfo(computerName, "http", &hints, &info) != 0)
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// return the first canonical name in the list
|
||||
fullName = strndup(info->ai_canonname, strnlen(info->ai_canonname, NI_MAXHOST));
|
||||
|
||||
// only free info if getaddrinfo was successful
|
||||
freeaddrinfo(info);
|
||||
exit:
|
||||
free(computerName);
|
||||
return fullName;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char *GetFullyQualifiedName();
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Retrieve the device ID and inode number of a file
|
||||
|
||||
#include "getinodedata.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief GetInodeData retrieves a file's device and inode information.
|
||||
//!
|
||||
//! GetInodeData
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file path
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[out] device
|
||||
//! @parblock
|
||||
//! Points to a uint64_t value that will contain the file's device ID.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[out] inode
|
||||
//! @parblock
|
||||
//! Points to a uint64_t value that will contain the file's inode number.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval 0 If the function succeeds, -1 otherwise.
|
||||
//!
|
||||
|
||||
int32_t GetInodeData(const char* fileName, uint64_t* device, uint64_t* inode)
|
||||
{
|
||||
assert(fileName);
|
||||
assert(device);
|
||||
assert(inode);
|
||||
errno = 0;
|
||||
|
||||
struct stat statBuf;
|
||||
int ret = stat(fileName, &statBuf);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
*device = statBuf.st_dev;
|
||||
*inode = statBuf.st_ino;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t GetInodeData(const char* fileName, uint64_t* device, uint64_t* inode);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Retrieve link count of a file
|
||||
|
||||
#include "getlinkcount.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief GetLinkCount retrieves the file link count (number of hard links)
|
||||
//! for the given file
|
||||
//!
|
||||
//! GetLinkCount
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[out] count
|
||||
//! @parblock
|
||||
//! This function returns the number of hard links associated with this file
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval 1 If the function succeeds, and the variable pointed to by buffer contains
|
||||
//! information about the files
|
||||
//! @retval 0 If the function fails, the return value is zero. To get
|
||||
//! extended error information, call GetLastError.
|
||||
//!
|
||||
|
||||
int32_t GetLinkCount(const char* fileName, int32_t *count)
|
||||
{
|
||||
assert(fileName);
|
||||
assert(count);
|
||||
errno = 0;
|
||||
|
||||
struct stat statBuf;
|
||||
|
||||
int32_t ret = lstat(fileName, &statBuf);
|
||||
|
||||
*count = statBuf.st_nlink;
|
||||
return ret;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t GetLinkCount(const char* fileName, int32_t *count);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pal_config.h"
|
||||
#include "getppid.h"
|
||||
|
||||
#include <sys/user.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
//! @brief GetPPid returns the parent process id for a process
|
||||
//!
|
||||
//! GetPPid
|
||||
//!
|
||||
//! @param[in] pid
|
||||
//! @parblock
|
||||
//! The process id to query for it's parent.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval the parent process id, or UINT_MAX if unsuccessful
|
||||
//!
|
||||
pid_t GetPPid(pid_t pid)
|
||||
{
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
const pid_t PIDUnknown = UINT_MAX;
|
||||
struct kinfo_proc info;
|
||||
size_t length = sizeof(struct kinfo_proc);
|
||||
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
|
||||
if (sysctl(mib, 4, &info, &length, NULL, 0) < 0)
|
||||
return PIDUnknown;
|
||||
if (length == 0)
|
||||
return PIDUnknown;
|
||||
|
||||
return info.kp_eproc.e_ppid;
|
||||
|
||||
#else
|
||||
|
||||
return UINT_MAX;
|
||||
|
||||
#endif
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
pid_t GetPPid(pid_t pid);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns the username for a uid
|
||||
|
||||
#include "getpwuid.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief GetPwUid returns the username for a uid
|
||||
//!
|
||||
//! GetPwUid
|
||||
//!
|
||||
//! @param[in] uid
|
||||
//! @parblock
|
||||
//! The user identifier to lookup.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval username as UTF-8 string, or NULL if unsuccessful
|
||||
//!
|
||||
char* GetPwUid(uid_t uid)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
struct passwd pwd;
|
||||
struct passwd* result = NULL;
|
||||
char* buf;
|
||||
|
||||
int buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (buflen < 1)
|
||||
{
|
||||
buflen = 2048;
|
||||
}
|
||||
|
||||
allocate:
|
||||
buf = (char*)calloc(buflen, sizeof(char));
|
||||
|
||||
errno = 0;
|
||||
ret = getpwuid_r(uid, &pwd, buf, buflen, &result);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
if (errno == ERANGE)
|
||||
{
|
||||
free(buf);
|
||||
buflen *= 2;
|
||||
goto allocate;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// no result
|
||||
if (result == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// allocate copy on heap so CLR can free it
|
||||
size_t userlen = strnlen(pwd.pw_name, buflen);
|
||||
char* username = strndup(pwd.pw_name, userlen);
|
||||
free(buf);
|
||||
return username;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* GetPwUid(uid_t uid);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns the stat of a file
|
||||
|
||||
#include "getstat.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief GetStat returns the stat of a file. This simply delegates to the
|
||||
//! stat() system call and maps errno to the expected values for GetLastError.
|
||||
//!
|
||||
//! GetStat
|
||||
//!
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[in] stat
|
||||
//! @parblock
|
||||
//! A pointer to the buffer in which to place the stat information
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval 0 if successful
|
||||
//! @retval -1 if failed
|
||||
//!
|
||||
|
||||
// DO NOT use in managed code
|
||||
// use externally defined structs in managed code has proven to be buggy
|
||||
// (memory corruption issues due to layout difference between platforms)
|
||||
// see https://github.com/dotnet/corefx/issues/29700#issuecomment-389313075
|
||||
int32_t GetStat(const char* path, struct stat* buf)
|
||||
{
|
||||
assert(path);
|
||||
errno = 0;
|
||||
|
||||
return stat(path, buf);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t GetStat(const char* path, struct stat* buf);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_config.h"
|
||||
#include "getfileowner.h"
|
||||
#include "getpwuid.h"
|
||||
#include "getuserfrompid.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <errno.h>
|
||||
|
||||
#if HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
char* GetUserFromPid(pid_t pid)
|
||||
{
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
// Get effective owner of pid from procfs
|
||||
std::stringstream ss;
|
||||
ss << "/proc/" << pid;
|
||||
std::string path;
|
||||
ss >> path;
|
||||
|
||||
return GetFileOwner(path.c_str());
|
||||
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
// Get effective owner of pid from sysctl
|
||||
struct kinfo_proc oldp;
|
||||
size_t oldlenp = sizeof(oldp);
|
||||
int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
|
||||
u_int namelen = sizeof(name)/sizeof(int);
|
||||
|
||||
// Read-only query
|
||||
int ret = sysctl(name, namelen, &oldp, &oldlenp, NULL, 0);
|
||||
if (ret != 0 || oldlenp == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return GetPwUid(oldp.kp_eproc.e_ucred.cr_uid);
|
||||
|
||||
#else
|
||||
|
||||
return NULL;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* GetUserFromPid(pid_t pid);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements GetUserName for Linux
|
||||
|
||||
#include "getpwuid.h"
|
||||
#include "getusername.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief GetUserName retrieves the name of the user associated with
|
||||
//! the current thread.
|
||||
//!
|
||||
//! @retval username as UTF-8 string, or null if unsuccessful
|
||||
char* GetUserName()
|
||||
{
|
||||
// geteuid() gets the effective user ID of the calling process, and is always successful
|
||||
return GetPwUid(geteuid());
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* GetUserName();
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,43 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns if the path is a directory
|
||||
|
||||
#include "getstat.h"
|
||||
#include "getpwuid.h"
|
||||
#include "getfileowner.h"
|
||||
#include "isdirectory.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief returns if the path is a directory; uses stat and so follows symlinks
|
||||
//!
|
||||
//! IsDirectory
|
||||
//!
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval true if directory, false otherwise
|
||||
//!
|
||||
bool IsDirectory(const char* path)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
struct stat buf;
|
||||
int32_t ret = GetStat(path, &buf);
|
||||
if (ret != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISDIR(buf.st_mode);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
bool IsDirectory(const char* path);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns whether a file is executable
|
||||
|
||||
#include "isexecutable.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief IsExecutable determines if path is executable
|
||||
//!
|
||||
//! IsExecutable
|
||||
//!
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval true if path is an executable, false otherwise
|
||||
//!
|
||||
|
||||
bool IsExecutable(const char* path)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
return access(path, X_OK) != -1;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
bool IsExecutable(const char* path);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns if the path exists
|
||||
|
||||
#include "isfile.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief returns if the path is a file or directory
|
||||
//!
|
||||
//! IsFile
|
||||
//!
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval true if path exists, false otherwise
|
||||
//!
|
||||
bool IsFile(const char* path)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
struct stat buf;
|
||||
return lstat(path, &buf) == 0;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
bool IsFile(const char* path);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Determines whether two paths ultimately point to the same filesystem object
|
||||
|
||||
#include "getstat.h"
|
||||
#include "issamefilesystemitem.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//! @brief Returns a boolean value indicating whether two paths ultimately refer to the same file or directory.
|
||||
//!
|
||||
//! IsSameFileSystemItem
|
||||
//!
|
||||
//! @param[in] path_one
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the first path.
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @param[in] path_two
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the second path.
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval true if both paths point to the same filesystem object,
|
||||
//! false otherwise
|
||||
//!
|
||||
bool IsSameFileSystemItem(const char* path_one, const char* path_two)
|
||||
{
|
||||
assert(path_one);
|
||||
assert(path_two);
|
||||
|
||||
struct stat buf_1;
|
||||
struct stat buf_2;
|
||||
|
||||
if (GetStat(path_one, &buf_1) == 0 && GetStat(path_two, &buf_2) == 0)
|
||||
{
|
||||
return buf_1.st_dev == buf_2.st_dev && buf_1.st_ino == buf_2.st_ino;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
bool IsSameFileSystemItem(const char* path_one, const char* path_two);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief returns whether a path is a symbolic link
|
||||
|
||||
#include "issymlink.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
//! @brief IsSymlink determines if path is a symbolic link
|
||||
//!
|
||||
//! IsSymlink
|
||||
//!
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @retval true if path is a symbolic link, false otherwise
|
||||
//!
|
||||
|
||||
bool IsSymLink(const char* path)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
struct stat buf;
|
||||
int32_t ret = lstat(path, &buf);
|
||||
if (ret != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISLNK(buf.st_mode);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
bool IsSymLink(const char* path);
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,93 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @file nativesyslog.cpp
|
||||
//! @brief Provides wrappers around the syslog apis to support exporting
|
||||
//! for PInvoke calls by powershell.
|
||||
//! These functions are intended only for PowerShell internal use.
|
||||
//! To view log output in real time
|
||||
//! On Linux
|
||||
//! tail -f /var/log/syslog | grep powershell
|
||||
//! On OSX
|
||||
//! sudo log stream
|
||||
//! NOTE: replace powershell with the LogIdentity value when overriding in configuration
|
||||
#include <syslog.h>
|
||||
#include <nativesyslog.h>
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
static os_log_t _log = NULL;
|
||||
|
||||
// This format string ensures the message string for the log statements
|
||||
// are visible. Using just %s marks them as private and the do not show
|
||||
// up with log stream.
|
||||
#define MESSAGE_FORMAT "%{public}s"
|
||||
|
||||
// The submodule name to pass to os_log_create.
|
||||
// The passed in ident value will be used for the category.
|
||||
// see man os_log_create
|
||||
#define SUBMODULE_NAME "com.microsoft.powershell"
|
||||
|
||||
#endif
|
||||
|
||||
//! @brief Native_SysLog is a wrapper around the syslog api.
|
||||
//! It explicitly passes the message as a parameter to a %s format
|
||||
//! string since the message may have arbitrary characters that can
|
||||
//! be misinterpreted as format specifiers.
|
||||
//!
|
||||
//! @retval none.
|
||||
extern "C" void Native_SysLog(int32_t priority, const char* message)
|
||||
{
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
switch (priority)
|
||||
{
|
||||
case LOG_EMERG:
|
||||
case LOG_ALERT:
|
||||
case LOG_CRIT:
|
||||
os_log_fault(_log, MESSAGE_FORMAT, message);
|
||||
break;
|
||||
|
||||
case LOG_ERR:
|
||||
os_log_error(_log, MESSAGE_FORMAT, message);
|
||||
break;
|
||||
|
||||
case LOG_DEBUG:
|
||||
os_log_debug(_log, MESSAGE_FORMAT, message);
|
||||
break;
|
||||
|
||||
default:
|
||||
os_log(_log, MESSAGE_FORMAT, message);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
syslog(priority, "%s", message);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! @brief Native_OpenLog is a wrapper around the openlog, syslog api.
|
||||
//! it allows passing an ident and facility but uses an explicit
|
||||
//! option value for consistent logging across powershell instances.
|
||||
//!
|
||||
//! @retval none.
|
||||
extern "C" void Native_OpenLog(const char* ident, int facility)
|
||||
{
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
_log = os_log_create(SUBMODULE_NAME, ident);
|
||||
#else
|
||||
openlog(ident, LOG_NDELAY | LOG_PID, facility);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! @brief Native_OpenLog is a wrapper around the closelog, syslog api.
|
||||
//!
|
||||
//! @retval none.
|
||||
extern "C" void Native_CloseLog()
|
||||
{
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
// Nothing to do here now, for now.
|
||||
#else
|
||||
closelog();
|
||||
#endif
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
void Native_OpenLog(const char* ident, int facility);
|
||||
void Native_SysLog(int32_t priority, const char* message);
|
||||
void Native_CloseLog();
|
||||
|
||||
PAL_END_EXTERNC
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
**==============================================================================
|
||||
**
|
||||
** PAL_BEGIN_EXTERNC
|
||||
** PAL_END_EXTERNC
|
||||
**
|
||||
**==============================================================================
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# define PAL_BEGIN_EXTERNC extern "C" {
|
||||
# define PAL_END_EXTERNC }
|
||||
#else
|
||||
# define PAL_BEGIN_EXTERNC
|
||||
# define PAL_END_EXTERNC
|
||||
#endif
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#cmakedefine01 HAVE_SYS_SYSCTL_H
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief set local/system date and time
|
||||
|
||||
#include "setdate.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
//! @brief SetDate sets the date and time on local computer.
|
||||
//! You must be super-user to set the time.
|
||||
//! See comment in setdate.h about the use of private_tm
|
||||
//!
|
||||
//! SetDate
|
||||
//!
|
||||
//! @retval 0 successfully set date
|
||||
//! @retval -1 if failure occurred.
|
||||
//!
|
||||
int32_t SetDate(struct private_tm* time)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
// Select locale from environment
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
struct timeval tv;
|
||||
int32_t result = GetTimeVal(*time,tv);
|
||||
if(result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return settimeofday(&tv, NULL);
|
||||
}
|
||||
|
||||
static int32_t GetTimeVal(struct private_tm& time, struct timeval& tv)
|
||||
{
|
||||
struct tm nativeTime = {0};
|
||||
nativeTime.tm_hour = static_cast<int>(time.Hour);
|
||||
nativeTime.tm_isdst = static_cast<int>(time.IsDst);
|
||||
nativeTime.tm_mday = static_cast<int>(time.DayOfMonth);
|
||||
nativeTime.tm_min = static_cast<int>(time.Minutes);
|
||||
nativeTime.tm_mon = static_cast<int>(time.Month);
|
||||
nativeTime.tm_sec = static_cast<int>(time.Seconds);
|
||||
nativeTime.tm_wday = static_cast<int>(time.DayOfWeek);
|
||||
nativeTime.tm_yday = static_cast<int>(time.DayInYear);
|
||||
nativeTime.tm_year = static_cast<int>(time.Year);
|
||||
|
||||
time_t newTime = mktime(&nativeTime);
|
||||
if (newTime == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
tv.tv_sec = newTime;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t SetDate(struct private_tm* time);
|
||||
|
||||
static int32_t GetTimeVal(struct private_tm& time, struct timeval& tv);
|
||||
|
||||
PAL_END_EXTERNC
|
||||
|
||||
// Using a private struct because theuse externally defined structs
|
||||
// in managed code has proven to be buggy
|
||||
// (memory corruption issues due to layout difference between platforms)
|
||||
// see https://github.com/dotnet/corefx/issues/29700#issuecomment-389313075
|
||||
#pragma pack(push, 4) // exact fit - no padding
|
||||
struct private_tm
|
||||
{
|
||||
int32_t Seconds; /* Seconds (0-60) */
|
||||
int32_t Minutes; /* Minutes (0-59) */
|
||||
int32_t Hour; /* Hours (0-23) */
|
||||
int32_t DayOfMonth;/* Day of the month (1-31) */
|
||||
int32_t Month; /* Month (0-11) */
|
||||
int32_t Year; /* Year - 1900 */
|
||||
int32_t DayOfWeek; /* Day of the week (0-6, Sunday = 0) */
|
||||
int32_t DayInYear; /* Day in the year (0-365, 1 Jan = 0) */
|
||||
int32_t IsDst; /* Daylight saving time */
|
||||
};
|
||||
#pragma pack(pop) //back to whatever the previous packing mode was
|
|
@ -1,26 +0,0 @@
|
|||
add_subdirectory(googletest)
|
||||
|
||||
add_executable(psl-native-test
|
||||
test-getfileowner.cpp
|
||||
test-locale.cpp
|
||||
test-getuserfrompid.cpp
|
||||
test-getcurrentprocessid.cpp
|
||||
test-getusername.cpp
|
||||
test-getcomputername.cpp
|
||||
test-getlinkcount.cpp
|
||||
test-getfullyqualifiedname.cpp
|
||||
test-isdirectory.cpp
|
||||
test-isfile.cpp
|
||||
test-issymlink.cpp
|
||||
test-isexecutable.cpp
|
||||
test-createsymlink.cpp
|
||||
test-createhardlink.cpp
|
||||
main.cpp)
|
||||
|
||||
# manually include gtest headers
|
||||
target_include_directories(psl-native-test PRIVATE ${gtest_SOURCE_DIR}/include)
|
||||
|
||||
target_link_libraries(psl-native-test psl-native gtest)
|
||||
|
||||
add_test(NAME psl-native-test
|
||||
COMMAND psl-native-test --gtest_output=xml:native-tests.xml)
|
|
@ -1 +0,0 @@
|
|||
Subproject commit c99458533a9b4c743ed51537e25989ea55944908
|
|
@ -1,10 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements test for CreateHardLink()
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <unistd.h>
|
||||
#include "getlinkcount.h"
|
||||
#include "createhardlink.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CreateHardLinkTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
||||
static const int bufSize = 64;
|
||||
const string fileTemplate = "/tmp/symlinktest.fXXXXXX";
|
||||
const string dirTemplate = "/tmp/symlinktest.dXXXXXX";
|
||||
const string fileHardLink = "/tmp/symlinktest.flink";
|
||||
const string dirHardLink = "/tmp/symlinktest.dlink";
|
||||
char *file, *dir;
|
||||
char fileTemplateBuf[bufSize], dirTemplateBuf[bufSize];
|
||||
|
||||
CreateHardLinkTest()
|
||||
{
|
||||
// since mkstemp and mkdtemp modifies the template string, let's give them writable buffers
|
||||
strcpy(fileTemplateBuf, fileTemplate.c_str());
|
||||
strcpy(dirTemplateBuf, dirTemplate.c_str());
|
||||
|
||||
// First create a temp file
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
|
||||
// Create a temp directory
|
||||
dir = mkdtemp(dirTemplateBuf);
|
||||
EXPECT_TRUE(dir != NULL);
|
||||
|
||||
// Create hard link to file
|
||||
int ret = CreateHardLink(fileHardLink.c_str(), file);
|
||||
EXPECT_EQ(ret, 0);
|
||||
|
||||
// Create hard link to directory - should fail
|
||||
ret = CreateHardLink(dirHardLink.c_str(), dir);
|
||||
EXPECT_EQ(ret, -1);
|
||||
}
|
||||
|
||||
~CreateHardLinkTest()
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = unlink(fileHardLink.c_str());
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
ret = unlink(file);
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
ret = rmdir(dir);
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CreateHardLinkTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/symlinktest_invalidFile";
|
||||
std::string invalidLink = "/tmp/symlinktest_invalidLink";
|
||||
|
||||
// make sure neither exists
|
||||
unlink(invalidFile.c_str());
|
||||
unlink(invalidLink.c_str());
|
||||
|
||||
int ret = CreateHardLink(invalidLink.c_str(), invalidFile.c_str());
|
||||
EXPECT_EQ(-1, ret);
|
||||
}
|
||||
|
||||
TEST_F(CreateHardLinkTest, VerifyLinkCount)
|
||||
{
|
||||
int count = 0;
|
||||
int ret = GetLinkCount(fileHardLink.c_str(), &count);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(2, count);
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements test for CreateSymLink() and FollowSymLink()
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "issymlink.h"
|
||||
#include "createsymlink.h"
|
||||
#include "followsymlink.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CreateSymLinkTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
||||
static const int bufSize = 64;
|
||||
const string fileTemplate = "/tmp/symlinktest.fXXXXXX";
|
||||
const string dirTemplate = "/tmp/symlinktest.dXXXXXX";
|
||||
const string fileSymLink = "/tmp/symlinktest.flink";
|
||||
const string dirSymLink = "/tmp/symlinktest.dlink";
|
||||
char *file, *dir;
|
||||
char fileTemplateBuf[bufSize], dirTemplateBuf[bufSize];
|
||||
|
||||
CreateSymLinkTest()
|
||||
{
|
||||
// since mkstemp and mkdtemp modifies the template string, let's give them writable buffers
|
||||
strcpy(fileTemplateBuf, fileTemplate.c_str());
|
||||
strcpy(dirTemplateBuf, dirTemplate.c_str());
|
||||
|
||||
// First create a temp file
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
|
||||
// Create a temp directory
|
||||
dir = mkdtemp(dirTemplateBuf);
|
||||
EXPECT_TRUE(dir != NULL);
|
||||
|
||||
// Create symbolic link to file
|
||||
int ret = CreateSymLink(fileSymLink.c_str(), file);
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
// Create symbolic link to directory
|
||||
ret = CreateSymLink(dirSymLink.c_str(), dir);
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
|
||||
~CreateSymLinkTest()
|
||||
{
|
||||
bool ret;
|
||||
|
||||
ret = unlink(fileSymLink.c_str());
|
||||
EXPECT_FALSE(ret);
|
||||
|
||||
ret = unlink(dirSymLink.c_str());
|
||||
EXPECT_FALSE(ret);
|
||||
|
||||
ret = unlink(file);
|
||||
EXPECT_FALSE(ret);
|
||||
|
||||
ret = rmdir(dir);
|
||||
EXPECT_FALSE(ret);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CreateSymLinkTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/symlinktest_invalidFile";
|
||||
std::string invalidLink = "/tmp/symlinktest_invalidLink";
|
||||
|
||||
// make sure neither exists
|
||||
unlink(invalidFile.c_str());
|
||||
unlink(invalidLink.c_str());
|
||||
|
||||
// Linux allows creation of symbolic link that points to an invalid file
|
||||
int ret = CreateSymLink(invalidLink.c_str(), invalidFile.c_str());
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
std::string target = FollowSymLink(invalidLink.c_str());
|
||||
EXPECT_EQ(target, invalidFile);
|
||||
|
||||
unlink(invalidLink.c_str());
|
||||
}
|
||||
|
||||
TEST_F(CreateSymLinkTest, SymLinkToFile)
|
||||
{
|
||||
bool ret = IsSymLink(fileSymLink.c_str());
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
std::string target = FollowSymLink(fileSymLink.c_str());
|
||||
char buffer[PATH_MAX];
|
||||
std::string expected = realpath(file, buffer);
|
||||
EXPECT_EQ(expected, target);
|
||||
}
|
||||
|
||||
TEST_F(CreateSymLinkTest, SymLinkToDirectory)
|
||||
{
|
||||
bool ret = IsSymLink(dirSymLink.c_str());
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
std::string target = FollowSymLink(dirSymLink.c_str());
|
||||
char buffer[PATH_MAX];
|
||||
std::string expected = realpath(dir, buffer);
|
||||
EXPECT_EQ(expected, target);
|
||||
}
|
||||
|
||||
TEST_F(CreateSymLinkTest, SymLinkAgain)
|
||||
{
|
||||
int ret = CreateSymLink(fileSymLink.c_str(), file);
|
||||
EXPECT_EQ(-1, ret);
|
||||
EXPECT_EQ(EEXIST, errno);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Unit tests for GetComputerName
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "getcomputername.h"
|
||||
|
||||
//! Test fixture for GetComputerNameTest
|
||||
class GetComputerNameTest : public ::testing::Test
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(GetComputerNameTest, Success)
|
||||
{
|
||||
char expectedComputerName[_POSIX_HOST_NAME_MAX];
|
||||
|
||||
// the gethostname system call gets the nodename from uname
|
||||
FILE *fPtr = popen("uname -n", "r");
|
||||
ASSERT_TRUE(fPtr != NULL);
|
||||
|
||||
char *linePtr = fgets(expectedComputerName, sizeof(expectedComputerName), fPtr);
|
||||
ASSERT_TRUE(linePtr != NULL);
|
||||
|
||||
// There's a tendency to have \n at end of fgets string, so remove it before compare
|
||||
size_t sz = strlen(expectedComputerName);
|
||||
if (sz > 0 && expectedComputerName[sz - 1] == '\n')
|
||||
{
|
||||
expectedComputerName[sz - 1] = '\0';
|
||||
}
|
||||
pclose(fPtr);
|
||||
|
||||
ASSERT_STREQ(GetComputerName(), expectedComputerName);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "getcurrentprocessorid.h"
|
||||
|
||||
// This is a very simple test case to show how tests can be written
|
||||
TEST(GetCurrentProcessId,simple)
|
||||
{
|
||||
const int32_t currentProcessId = GetCurrentProcessId();
|
||||
const pid_t pid = getpid();
|
||||
|
||||
// first make sure that on this platform those types are of the same size
|
||||
ASSERT_TRUE(sizeof(int32_t) >= sizeof(pid_t));
|
||||
|
||||
// now compare the actual values
|
||||
ASSERT_EQ(currentProcessId,static_cast<int32_t>(pid));
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "getcurrentthreadid.h"
|
||||
#include <pthread.h>
|
||||
|
||||
TEST(GetCurrentThreadId,simple)
|
||||
{
|
||||
const HANDLE currentThreadId = GetCurrentThreadId();
|
||||
const pid_t tid = pthread_self();
|
||||
|
||||
// first make sure that on this platform those types are of the same size
|
||||
ASSERT_TRUE(sizeof(HANDLE) >= sizeof(pid_t));
|
||||
|
||||
// now compare the actual values
|
||||
ASSERT_EQ(currentThreadId,reinterpret_cast<HANDLE>(tid));
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Tests GetFileOwner
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "getfileowner.h"
|
||||
|
||||
TEST(GetFileOwnerTest, CanGetOwnerOfRoot)
|
||||
{
|
||||
EXPECT_STREQ(GetFileOwner("/"), "root");
|
||||
}
|
||||
|
||||
TEST(GetFileOwnerTest, CannotGetOwnerOfFakeFile)
|
||||
{
|
||||
EXPECT_STREQ(GetFileOwner("SomeMadeUpFileNameThatDoesNotExist"), NULL);
|
||||
EXPECT_EQ(ENOENT, errno);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Unit tests for GetFullyQualifiedName
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "getcomputername.h"
|
||||
#include "getfullyqualifiedname.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string>
|
||||
|
||||
TEST(GetFullyQualifiedNameTest, ValidateLinuxGetFullyQualifiedDomainName)
|
||||
{
|
||||
char *hostname = GetComputerName();
|
||||
ASSERT_STRNE(NULL, hostname);
|
||||
|
||||
// this might be fail
|
||||
errno = 0;
|
||||
char *actual = GetFullyQualifiedName();
|
||||
int fqdnErrno = errno;
|
||||
|
||||
struct addrinfo hints, *info;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
errno = 0;
|
||||
if (getaddrinfo(hostname, "http", &hints, &info) != 0)
|
||||
{
|
||||
// test that getaddrinfo failed the same way
|
||||
EXPECT_EQ(fqdnErrno, errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Compare canonical name to FQDN
|
||||
EXPECT_STREQ(info->ai_canonname, actual);
|
||||
freeaddrinfo(info);
|
||||
exit:
|
||||
free(hostname);
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements test for getLinkCount()
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <pwd.h>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "getlinkcount.h"
|
||||
|
||||
class getLinkCountTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
||||
static const int bufSize = 64;
|
||||
const std::string fileTemplate = "/tmp/createFile.XXXXXX";
|
||||
char fileTemplateBuf[bufSize];
|
||||
|
||||
int32_t count;
|
||||
char *file;
|
||||
|
||||
getLinkCountTest()
|
||||
{
|
||||
// since mkstemp modifies the template string, let's give it writable buffer
|
||||
strcpy(fileTemplateBuf, fileTemplate.c_str());
|
||||
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
}
|
||||
|
||||
void createFileForTesting(const std::string &theFile)
|
||||
{
|
||||
std::ofstream ofs;
|
||||
ofs.open(theFile, std::ofstream::out);
|
||||
ofs << "hi there, ms ostc!";
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
std::string createHardLink(const std::string &origFile)
|
||||
{
|
||||
std::string newFile = origFile + "_link";
|
||||
int ret = link(origFile.c_str(), newFile.c_str());
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
return newFile;
|
||||
}
|
||||
|
||||
void removeFile(const std::string &fileName)
|
||||
{
|
||||
int ret = unlink(fileName.c_str());
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(getLinkCountTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/createFile";
|
||||
int32_t ret = GetLinkCount(invalidFile.c_str(), &count);
|
||||
ASSERT_EQ(-1, ret);
|
||||
EXPECT_EQ(ENOENT, errno);
|
||||
}
|
||||
|
||||
TEST_F(getLinkCountTest, LinkCountOfSinglyLinkedFile)
|
||||
{
|
||||
createFileForTesting(file);
|
||||
int32_t ret = GetLinkCount(file, &count);
|
||||
ASSERT_EQ(0, ret);
|
||||
EXPECT_EQ(1, count);
|
||||
|
||||
removeFile(file);
|
||||
}
|
||||
|
||||
TEST_F(getLinkCountTest, LinkCountOfMultiplyLinkedFile)
|
||||
{
|
||||
createFileForTesting(file);
|
||||
std::string newFile = createHardLink(file);
|
||||
int32_t ret = GetLinkCount(file, &count);
|
||||
ASSERT_EQ(0, ret);
|
||||
EXPECT_EQ(2, count);
|
||||
|
||||
removeFile(file);
|
||||
removeFile(newFile);
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Unit tests for GetUserFromPid
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <pwd.h>
|
||||
#include "getuserfrompid.h"
|
||||
|
||||
TEST(GetUserFromPid, Success)
|
||||
{
|
||||
char* expected = getpwuid(geteuid())->pw_name;
|
||||
EXPECT_STREQ(GetUserFromPid(getpid()), expected);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Unit tests for GetUserName
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <pwd.h>
|
||||
#include "getusername.h"
|
||||
|
||||
TEST(GetUserName, Success)
|
||||
{
|
||||
char* expected = getpwuid(geteuid())->pw_name;
|
||||
EXPECT_STREQ(GetUserName(), expected);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Tests IsDirectory
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "isdirectory.h"
|
||||
|
||||
TEST(IsDirectoryTest, RootIsDirectory)
|
||||
{
|
||||
EXPECT_TRUE(IsDirectory("/"));
|
||||
}
|
||||
|
||||
TEST(IsDirectoryTest, BinLsIsNotDirectory)
|
||||
{
|
||||
EXPECT_FALSE(IsDirectory("/bin/ls"));
|
||||
}
|
||||
|
||||
|
||||
TEST(IsDirectoryTest, ReturnsFalseForFakeDirectory)
|
||||
{
|
||||
EXPECT_FALSE(IsDirectory("SomeMadeUpFileNameThatDoesNotExist"));
|
||||
EXPECT_EQ(ENOENT, errno);
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements test for isexecutable()
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "isexecutable.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class IsExecutableTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
||||
static const int bufSize = 64;
|
||||
const string fileTemplate = "/tmp/isexecutabletest.fXXXXXXX";
|
||||
const mode_t mode_700 = S_IRUSR | S_IWUSR | S_IXUSR;
|
||||
const mode_t mode_070 = S_IRGRP | S_IWGRP | S_IXGRP;
|
||||
const mode_t mode_007 = S_IROTH | S_IWOTH | S_IXOTH;
|
||||
const mode_t mode_777 = mode_700 | mode_070 | mode_007;
|
||||
const mode_t mode_444 = S_IRUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
char *file;
|
||||
char fileTemplateBuf[bufSize];
|
||||
|
||||
IsExecutableTest()
|
||||
{
|
||||
// since mkstemp modifies the template string, let's give it writable buffers
|
||||
strcpy(fileTemplateBuf, fileTemplate.c_str());
|
||||
|
||||
// First create a file
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
}
|
||||
|
||||
~IsExecutableTest()
|
||||
{
|
||||
EXPECT_FALSE(unlink(file));
|
||||
}
|
||||
|
||||
void ChangeFilePermission(const char* file, mode_t mode)
|
||||
{
|
||||
EXPECT_FALSE(chmod(file, mode));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(IsExecutableTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/isexecutabletest_invalidFile";
|
||||
EXPECT_FALSE(IsExecutable(invalidFile.c_str()));
|
||||
EXPECT_EQ(ENOENT, errno);
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, NormalFileIsNotIsexecutable)
|
||||
{
|
||||
EXPECT_FALSE(IsExecutable(file));
|
||||
|
||||
ChangeFilePermission(file, mode_444);
|
||||
|
||||
EXPECT_FALSE(IsExecutable(file));
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, FilePermission_700)
|
||||
{
|
||||
ChangeFilePermission(file, mode_700);
|
||||
|
||||
EXPECT_TRUE(IsExecutable(file));
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, FilePermission_777)
|
||||
{
|
||||
ChangeFilePermission(file, mode_777);
|
||||
|
||||
EXPECT_TRUE(IsExecutable(file));
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Tests Isfile
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "isfile.h"
|
||||
|
||||
TEST(IsFileTest, RootIsFile)
|
||||
{
|
||||
EXPECT_FALSE(IsFile("/"));
|
||||
}
|
||||
|
||||
TEST(IsFileTest, BinLsIsFile)
|
||||
{
|
||||
EXPECT_TRUE(IsFile("/bin/ls"));
|
||||
}
|
||||
|
||||
TEST(IsFileTest, CannotGetOwnerOfFakeFile)
|
||||
{
|
||||
EXPECT_FALSE(IsFile("SomeMadeUpFileNameThatDoesNotExist"));
|
||||
EXPECT_EQ(errno, ENOENT);
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Implements test for isSymLink()
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "issymlink.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class isSymLinkTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
|
||||
static const int bufSize = 64;
|
||||
const string fileTemplate = "/tmp/symlinktest.fXXXXXX";
|
||||
const string dirTemplate = "/tmp/symlinktest.dXXXXXX";
|
||||
const string fileSymLink = "/tmp/symlinktest.flink";
|
||||
const string dirSymLink = "/tmp/symlinktest.dlink";
|
||||
char *file, *dir;
|
||||
char fileTemplateBuf[bufSize], dirTemplateBuf[bufSize];
|
||||
|
||||
isSymLinkTest()
|
||||
{
|
||||
// since mkstemp and mkdtemp modifies the template string, let's give them writable buffers
|
||||
strcpy(fileTemplateBuf, fileTemplate.c_str());
|
||||
strcpy(dirTemplateBuf, dirTemplate.c_str());
|
||||
|
||||
// First create a file
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
|
||||
// Create a temp directory
|
||||
dir = mkdtemp(dirTemplateBuf);
|
||||
EXPECT_TRUE(dir != NULL);
|
||||
|
||||
// Create symbolic link to file
|
||||
EXPECT_FALSE(symlink(file, fileSymLink.c_str()));
|
||||
|
||||
// Create symbolic link to directory
|
||||
EXPECT_FALSE(symlink(dir, dirSymLink.c_str()));
|
||||
}
|
||||
|
||||
~isSymLinkTest()
|
||||
{
|
||||
EXPECT_FALSE(unlink(fileSymLink.c_str()));
|
||||
|
||||
EXPECT_FALSE(unlink(dirSymLink.c_str()));
|
||||
|
||||
EXPECT_FALSE(unlink(file));
|
||||
|
||||
EXPECT_FALSE(rmdir(dir));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(isSymLinkTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/symlinktest_invalidFile";
|
||||
EXPECT_FALSE(IsSymLink(invalidFile.c_str()));
|
||||
EXPECT_EQ(ENOENT, errno);
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, NormalFileIsNotSymLink)
|
||||
{
|
||||
EXPECT_FALSE(IsSymLink(file));
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, SymLinkToFile)
|
||||
{
|
||||
EXPECT_TRUE(IsSymLink(fileSymLink.c_str()));
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, NormalDirectoryIsNotSymbLink)
|
||||
{
|
||||
EXPECT_FALSE(IsSymLink(dir));
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, SymLinkToDirectory)
|
||||
{
|
||||
EXPECT_TRUE(IsSymLink(dirSymLink.c_str()));
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
//! @brief Unit tests for linux locale
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
//! Test fixture for LocaleTest
|
||||
|
||||
class LocaleTest : public ::testing::Test
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(LocaleTest, Success)
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
ASSERT_FALSE(nl_langinfo(CODESET) == NULL);
|
||||
ASSERT_STREQ(nl_langinfo(CODESET), "UTF-8");
|
||||
}
|
17
src/powershell-native/.gitignore
vendored
17
src/powershell-native/.gitignore
vendored
|
@ -1,17 +0,0 @@
|
|||
ALL_BUILD.vcxproj
|
||||
ALL_BUILD.vcxproj.filters
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
*.sln
|
||||
Win32/
|
||||
x64/
|
||||
cmake_install.cmake
|
||||
*.dir/
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
Release/
|
||||
|
||||
# Resources
|
||||
MSG*.bin
|
||||
pwrshpluginerrorcodes.h
|
||||
pwrshpluginerrorcodes.rc
|
|
@ -1,86 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.10.0)
|
||||
|
||||
project(PowerShellNative)
|
||||
|
||||
#
|
||||
# Verify prerequisites
|
||||
#
|
||||
if (NOT $ENV{${WindowsSDKVersion}})
|
||||
message (FATAL_ERROR "WindowsSDKVersion environment variable not found")
|
||||
endif ()
|
||||
|
||||
#
|
||||
# Normalize the platform name
|
||||
SET(BUILD_ARCH_ARM 0)
|
||||
SET(BUILD_ARCH_ARM64 0)
|
||||
SET(BUILD_ARCH_X86 0)
|
||||
SET(BUILD_ARCH_AMD64 0)
|
||||
|
||||
if (BUILD_TARGET_ARCH)
|
||||
SET(WindowsSDKPlatform ${BUILD_TARGET_ARCH})
|
||||
message(STATUS "Building for " ${BUILD_TARGET_ARCH})
|
||||
else ()
|
||||
message(FATAL_ERROR "Target architecture value should be specified through BUILD_TARGET_ARCH. Supported values are x64, x86, arm, or arm64")
|
||||
endif (BUILD_TARGET_ARCH)
|
||||
|
||||
if (WindowsSDKPlatform STREQUAL "x64" OR WindowsSDKPlatform STREQUAL "X64" OR WindowsSDKPlatform STREQUAL "amd64" OR WindowsSDKPlatform STREQUAL "AMD64")
|
||||
SET(WindowsSDKPlatform "x64")
|
||||
SET(BUILD_ARCH_AMD64 1)
|
||||
elseif (WindowsSDKPlatform STREQUAL "x86" OR WindowsSDKPlatform STREQUAL "X86")
|
||||
SET(WindowsSDKPlatform "x86")
|
||||
SET(BUILD_ARCH_X86 1)
|
||||
elseif (WindowsSDKPlatform STREQUAL "arm" OR WindowsSDKPlatform STREQUAL "ARM")
|
||||
SET(WindowsSDKPlatform "arm")
|
||||
SET(BUILD_ARCH_ARM 1)
|
||||
elseif (WindowsSDKPlatform STREQUAL "arm64" OR WindowsSDKPlatform STREQUAL "ARM64")
|
||||
SET(WindowsSDKPlatform "arm64")
|
||||
SET(BUILD_ARCH_ARM64 1)
|
||||
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)
|
||||
|
||||
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
|
||||
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 )
|
||||
|
||||
#
|
||||
# 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(coreclr_defs.cmake)
|
||||
|
||||
# Default of BUILD_ONECORE should be ON once it is supported
|
||||
option(BUILD_ONECORE "Compile the OneCore version of the binaries" ON)
|
||||
|
||||
# Build the common library that powershell.exe and pwrshplugin.dll depend on
|
||||
add_subdirectory(nativemsh/pwrshcommon)
|
||||
|
||||
# Build pwrshplugin.dll
|
||||
add_subdirectory(nativemsh/pwrshplugin)
|
||||
|
||||
# Build powershell.exe
|
||||
add_subdirectory(nativemsh/pwrshexe)
|
|
@ -1,174 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.10.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "") # do not link against standard win32 libs i.e. kernel32, uuid, user32, etc.
|
||||
|
||||
if(NOT BUILD_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 BUILD_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")
|
||||
|
||||
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}")
|
||||
|
||||
# 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 (BUILD_ARCH_AMD64)
|
||||
add_definitions(-D_AMD64_)
|
||||
add_definitions(-D_WIN64)
|
||||
add_definitions(-DAMD64)
|
||||
add_definitions(-DBIT64=1)
|
||||
add_definitions(-D_M_AMD64)
|
||||
elseif (BUILD_ARCH_X86)
|
||||
add_definitions(-D_X86_)
|
||||
elseif (BUILD_ARCH_ARM)
|
||||
add_definitions(-D_ARM_)
|
||||
add_definitions(-D_WIN32)
|
||||
add_definitions(-D_M_ARM)
|
||||
add_definitions(-DARM)
|
||||
elseif (BUILD_ARCH_ARM64)
|
||||
add_definitions(-D_ARM64_)
|
||||
add_definitions(-DARM64)
|
||||
add_definitions(-D_WIN64)
|
||||
add_definitions(-DBIT64=1)
|
||||
add_definitions(-D_M_ARM64)
|
||||
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
|
||||
if (BUILD_CORECLR)
|
||||
# This option is not supported for "FullClr" because it triggers: error C2813: #import is not supported with /MP
|
||||
add_compile_options(/MP) # Build with Multiple Processes (number of processes equal to the number of processors)
|
||||
endif (BUILD_CORECLR)
|
||||
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 (BUILD_ARCH_X86)
|
||||
add_compile_options(/Gz)
|
||||
endif (BUILD_ARCH_X86)
|
||||
|
||||
add_compile_options($<$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>:/GL>)
|
||||
add_compile_options($<$<OR:$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>,$<CONFIG:Checked>>:/O1>)
|
||||
|
||||
if (BUILD_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 (BUILD_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 (BUILD_ARCH_AMD64)
|
||||
add_definitions(-D_TARGET_AMD64_=1)
|
||||
elseif (BUILD_ARCH_ARM)
|
||||
add_definitions(-D_TARGET_ARM_=1)
|
||||
elseif (BUILD_ARCH_ARM64)
|
||||
add_definitions(-D_TARGET_ARM64_=1)
|
||||
elseif (BUILD_ARCH_X86)
|
||||
add_definitions(-D_TARGET_X86_=1)
|
||||
endif (BUILD_ARCH_AMD64)
|
||||
|
||||
add_definitions(-DWIN32)
|
||||
add_definitions(-D_WIN32)
|
||||
add_definitions(-DWINVER=${WIN_VERSION_WIN8})
|
||||
add_definitions(-D_WIN32_WINNT=${WIN_VERSION_WIN8})
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN=1)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
|
||||
if(BUILD_ARCH_AMD64 OR BUILD_ARCH_X86)
|
||||
# Only enable edit and continue on windows x86 and x64.
|
||||
# Exclude arm & arm64
|
||||
add_definitions(-DEnC_SUPPORTED)
|
||||
endif(BUILD_ARCH_AMD64 OR BUILD_ARCH_X86)
|
||||
|
||||
add_definitions(-DUNICODE)
|
||||
add_definitions(-D_UNICODE)
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
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")
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#
|
||||
# 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})
|
||||
|
||||
#
|
||||
# VS 2017 corrupts the INCLUDE environment variable when processing the csproj
|
||||
# file generated for this template. The netfxsdk path is shortened from
|
||||
# C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\Include\um
|
||||
# to
|
||||
# Include\um
|
||||
# This prevents msbuild from locating corerror.h and throws a resolution error
|
||||
# during compilation. We work around the problem by force-including the
|
||||
# contents of the environment variable before it gets corrupted.
|
||||
#
|
||||
target_include_directories(pwrshcommon PUBLIC $ENV{INCLUDE})
|
||||
|
||||
if (BUILD_ONECORE)
|
||||
# Libraries to use when creating this binary for Windows on OneCore-based SKUs
|
||||
set(PWRSHCOMMON_WINDOWS_LIBS
|
||||
)
|
||||
set_target_properties(pwrshcommon PROPERTIES COMPILE_DEFINITIONS "CORECLR")
|
||||
else () # NOT BUILD_ONECORE
|
||||
# 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
|
||||
)
|
||||
endif (BUILD_ONECORE)
|
||||
|
||||
target_link_libraries(pwrshcommon
|
||||
${PWRSHCOMMON_WINDOWS_LIBS})
|
||||
|
|
@ -1,443 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// File: ClrHostWrapper.h
|
||||
//
|
||||
// Contents: Wrapper for the CLR runtime host
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "NativeMshConstants.h"
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
//
|
||||
// Abstract class to abstract CLR runtime host operations so that they can be
|
||||
// replaced with test code during test case execution.
|
||||
//
|
||||
class ClrHostWrapper
|
||||
{
|
||||
private:
|
||||
DWORD m_appDomainId;
|
||||
|
||||
public:
|
||||
ClrHostWrapper() : m_appDomainId(INVALID_APPDOMAIN_ID) {}
|
||||
virtual ~ClrHostWrapper() {}
|
||||
|
||||
virtual bool IsInitialized() { return false; }
|
||||
|
||||
// Graceful clean up of the object to prevent leaks
|
||||
virtual unsigned int CleanUpHostWrapper() = 0;
|
||||
|
||||
//
|
||||
// The following methods are direct thin wrappers for the host calls.
|
||||
//
|
||||
virtual unsigned int SetupWrapper(LPCSTR coreClrPathPtr) = 0;
|
||||
|
||||
virtual int InitializeClr(
|
||||
const char* exePath,
|
||||
const char* appDomainFriendlyName,
|
||||
int propertyCount,
|
||||
const char** propertyKeys,
|
||||
const char** propertyValues) = 0;
|
||||
|
||||
virtual int CreateDelegate(
|
||||
const char* entryPointAssemblyName,
|
||||
const char* entryPointTypeName,
|
||||
const char* entryPointMethodName,
|
||||
void** delegate) = 0;
|
||||
|
||||
// TODO: This probably isn't needed
|
||||
virtual int ShutdownClr() = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// Concrete implementation of the wrapper for CoreClr.dll's
|
||||
// Platform-Agnostic hosting interface.
|
||||
//
|
||||
class CoreClrHostingApiWrapper : public ClrHostWrapper
|
||||
{
|
||||
private:
|
||||
// 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:
|
||||
CoreClrHostingApiWrapper()
|
||||
: coreClrHandle(NULL),
|
||||
pinnedModuleHandle(NULL),
|
||||
hostHandle(NULL),
|
||||
domainId(0),
|
||||
initPtr(NULL),
|
||||
shutdownPtr(NULL),
|
||||
createDelegatePtr(NULL)
|
||||
{}
|
||||
|
||||
virtual ~CoreClrHostingApiWrapper()
|
||||
{
|
||||
this->CleanUpHostWrapper();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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())
|
||||
{
|
||||
HRESULT status = this->ShutdownClr();
|
||||
if (FAILED(status))
|
||||
{
|
||||
return g_STOP_CLR_HOST_FAILED;
|
||||
}
|
||||
|
||||
if (this->coreClrHandle)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
virtual int InitializeClr(
|
||||
const char* exePath,
|
||||
const char* appDomainFriendlyName,
|
||||
int propertyCount,
|
||||
const char** propertyKeys,
|
||||
const char** propertyValues)
|
||||
{
|
||||
if (initPtr)
|
||||
{
|
||||
return initPtr(
|
||||
exePath,
|
||||
appDomainFriendlyName,
|
||||
propertyCount,
|
||||
propertyKeys,
|
||||
propertyValues,
|
||||
&(this->hostHandle),
|
||||
&(this->domainId));
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual int CreateDelegate(
|
||||
const char* entryPointAssemblyName,
|
||||
const char* entryPointTypeName,
|
||||
const char* entryPointMethodName,
|
||||
void** delegate)
|
||||
{
|
||||
if (createDelegatePtr)
|
||||
{
|
||||
return createDelegatePtr(
|
||||
this->hostHandle,
|
||||
this->domainId,
|
||||
entryPointAssemblyName,
|
||||
entryPointTypeName,
|
||||
entryPointMethodName,
|
||||
delegate);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
virtual int ShutdownClr()
|
||||
{
|
||||
if (shutdownPtr)
|
||||
{
|
||||
return shutdownPtr(
|
||||
this->hostHandle,
|
||||
this->domainId);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
};
|
||||
|
||||
// Encapsulates the environment that CoreCLR will run in, including the TPALIST
|
||||
class HostEnvironment
|
||||
{
|
||||
private:
|
||||
// The path to this module
|
||||
char m_hostPath[MAX_PATH];
|
||||
wchar_t m_hostPathW[MAX_PATH];
|
||||
|
||||
// The path to the directory containing this module
|
||||
char m_hostDirectoryPath[MAX_PATH];
|
||||
wchar_t m_hostDirectoryPathW[MAX_PATH];
|
||||
|
||||
// The name of this module, without the path
|
||||
std::string m_hostBinaryName;
|
||||
std::wstring m_hostBinaryNameW;
|
||||
|
||||
// The path to the directory that CoreCLR is in
|
||||
char m_coreCLRDirectoryPath[MAX_PATH];
|
||||
wchar_t m_coreCLRDirectoryPathW[MAX_PATH];
|
||||
|
||||
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()
|
||||
{
|
||||
memset(m_hostPath, 0, sizeof(m_hostPath));
|
||||
memset(m_hostDirectoryPath, 0, sizeof(m_hostDirectoryPath));
|
||||
memset(m_coreCLRDirectoryPath, 0, sizeof(m_coreCLRDirectoryPath));
|
||||
}
|
||||
|
||||
~HostEnvironment() {}
|
||||
|
||||
// Safely copies in a host path
|
||||
void SetHostPath(PCSTR hostPath)
|
||||
{
|
||||
if (hostPath)
|
||||
{
|
||||
::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
|
||||
PCSTR GetHostPath()
|
||||
{
|
||||
return m_hostPath;
|
||||
}
|
||||
|
||||
PCWSTR GetHostPathW()
|
||||
{
|
||||
return m_hostPathW;
|
||||
}
|
||||
|
||||
// Safely copies in a host binary name
|
||||
void SetHostBinaryName(PCSTR hostBinaryName)
|
||||
{
|
||||
if (hostBinaryName)
|
||||
{
|
||||
m_hostBinaryName = std::string(hostBinaryName);
|
||||
}
|
||||
}
|
||||
|
||||
void SetHostBinaryNameW(PCWSTR hostBinaryName)
|
||||
{
|
||||
if (hostBinaryName)
|
||||
{
|
||||
m_hostBinaryNameW = std::wstring(hostBinaryName);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the name of the host module
|
||||
PCSTR GetHostBinaryName()
|
||||
{
|
||||
return m_hostBinaryName.c_str();
|
||||
}
|
||||
|
||||
PCWSTR GetHostBinaryNameW()
|
||||
{
|
||||
return m_hostBinaryNameW.c_str();
|
||||
}
|
||||
|
||||
// Safely copies in a host directory path
|
||||
void SetHostDirectoryPath(PCSTR hostDirPath)
|
||||
{
|
||||
if (hostDirPath)
|
||||
{
|
||||
::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
|
||||
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(PCSTR hostClrPath)
|
||||
{
|
||||
if (hostClrPath)
|
||||
{
|
||||
::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
|
||||
PCSTR GetCoreCLRDirectoryPath()
|
||||
{
|
||||
return m_coreCLRDirectoryPath;
|
||||
}
|
||||
|
||||
// Returns the directory path of the host module
|
||||
PCWSTR GetCoreCLRDirectoryPathW()
|
||||
{
|
||||
return m_coreCLRDirectoryPathW;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
} // namespace NativeMsh
|
|
@ -1,138 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#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
|
||||
break;
|
||||
}
|
||||
else if (*iter == L'p' || *iter == L'P')
|
||||
{
|
||||
std::wstring psHomeDir = this->getValueFromLine(line, psHomeDirTag);
|
||||
HANDLE dirHandle = CreateFileW(psHomeDir.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (INVALID_HANDLE_VALUE != dirHandle)
|
||||
{
|
||||
CloseHandle(dirHandle);
|
||||
this->pathToPowerShellAssemblies = psHomeDir;
|
||||
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"\\");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (*iter == L'c' || *iter == L'C')
|
||||
{
|
||||
std::wstring coreClrDir = this->getValueFromLine(line, coreClrDirTag);
|
||||
HANDLE dirHandle = CreateFileW(coreClrDir.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (INVALID_HANDLE_VALUE != dirHandle)
|
||||
{
|
||||
CloseHandle(dirHandle);
|
||||
this->coreClrDirectory = coreClrDir;
|
||||
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"\\");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// 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"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
//
|
||||
// Implement this interface to override the default no-op behaviour of the output.
|
||||
//
|
||||
class IPwrshCommonOutput
|
||||
{
|
||||
public:
|
||||
// Virtual destructor to ensure that derived destructors are called
|
||||
// during base class destruction.
|
||||
virtual ~IPwrshCommonOutput() {}
|
||||
|
||||
virtual VOID DisplayMessage(
|
||||
bool bUseStdOut,
|
||||
DWORD dwMessageId,
|
||||
...) = 0;
|
||||
|
||||
virtual void DisplayErrorWithSystemError(
|
||||
LONG lSystemErrorCode,
|
||||
int messageId,
|
||||
LPCWSTR insertionParam) = 0;
|
||||
};
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// File: NativeMsh.h
|
||||
//
|
||||
// Contents: common code required to start powershell (exe and plugin)
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strsafe.h>
|
||||
#include <assert.h>
|
||||
#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:
|
||||
// Provides default implementations of all dependencies
|
||||
PwrshCommon();
|
||||
|
||||
// Allows users to override the default dependency objects with a specific implementations.
|
||||
//
|
||||
// Note: This object deletes the pointers that are provided, so clients should
|
||||
// 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();
|
||||
|
||||
//
|
||||
// The following functions are used by the components that link to this lib
|
||||
//
|
||||
bool StringIsNullOrEmpty(
|
||||
LPCWSTR wsz);
|
||||
|
||||
// TODO: This is static because it is needed by the EXE's output object. Design wise, it is a little awkward to do this, but it resolve the circular reference and circular initialization issue
|
||||
static DWORD GetSystemErrorMessage(
|
||||
IN LONG lErrorCode,
|
||||
__deref_out_opt PWSTR * pwszErrorMessage);
|
||||
|
||||
bool VerifyMonadVersionFormat(
|
||||
LPCWSTR wszMonadVersion,
|
||||
int * lpMajorVersion,
|
||||
int * lpMinorVersion,
|
||||
bool bAllowMinorVersion,
|
||||
bool bReportError);
|
||||
|
||||
unsigned int OpenEngineRegKey(
|
||||
__deref_out_ecount(1) PHKEY phEngineKey,
|
||||
__deref_out_opt PWSTR * pwszMshEngineRegKey,
|
||||
__deref_out_opt PWSTR * pwszMonadVersion,
|
||||
__inout_ecount(1) int* lpMonadMajorVersion);
|
||||
|
||||
// API used to read a particular registry key value from the PowerShellEngine
|
||||
// regkey path. For example to read "ApplicationBase" or "ConsoleHostAssemblyName"
|
||||
//
|
||||
// Note: During successful calls the following values must be freed by the caller:
|
||||
// pwszMonadVersion
|
||||
// pwszRuntimeVersion
|
||||
// pwszRegKeyValue
|
||||
//
|
||||
// The caller must take care to check to see if they must be freed during error scenarios
|
||||
// because the function may fail after allocating one or more strings.
|
||||
//
|
||||
_Success_(return == 0)
|
||||
unsigned int GetRegistryInfo(
|
||||
__out PWSTR * pwszMonadVersion,
|
||||
__inout_ecount(1) int * lpMonadMajorVersion,
|
||||
int monadMinorVersion,
|
||||
__out PWSTR * pwszRuntimeVersion,
|
||||
LPCWSTR lpszRegKeyNameToRead,
|
||||
__out PWSTR * pwszRegKeyValue);
|
||||
|
||||
_Success_(return == 0)
|
||||
unsigned int GetRegistryInfo(
|
||||
__out PWSTR * pwszMonadVersion,
|
||||
__inout_ecount(1) int * lpMonadMajorVersion,
|
||||
int monadMinorVersion,
|
||||
__out PWSTR * pwszRuntimeVersion,
|
||||
__out PWSTR * pwszConsoleHostAssemblyName);
|
||||
|
||||
unsigned int LaunchCoreCLR(
|
||||
ClrHostWrapper* hostWrapper,
|
||||
HostEnvironment& hostEnvironment,
|
||||
PCSTR friendlyName);
|
||||
|
||||
#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.
|
||||
//
|
||||
// This code may be removed from #if protection once ICorRuntimeHost is
|
||||
// upgraded to ICLRRuntimeHost.
|
||||
//
|
||||
unsigned int LaunchCLR(
|
||||
LPCWSTR wszMonadVersion,
|
||||
LPCWSTR wszRuntimeVersion,
|
||||
__in_ecount(1) ICorRuntimeHost** pCLR);
|
||||
#endif // !CORECLR
|
||||
|
||||
protected:
|
||||
// These methods are exposed as protected here to make them unit testable.
|
||||
// Note: I tried hiding them within PwrshCommonFriend in pwrshcommon.cpp, but it made the unit testing difficult.
|
||||
// Virtual methods may be overridden in the test code.
|
||||
bool ParseInt(
|
||||
const WCHAR * pwchStart,
|
||||
const WCHAR * pwchEnd,
|
||||
int * pInt);
|
||||
|
||||
_Success_(return) bool ExtractFirstVersionComponent(
|
||||
LPCWSTR wszVersionString,
|
||||
int* lpFirstVersionComponent,
|
||||
__deref_out_opt WCHAR** wszRemainingVersionString);
|
||||
|
||||
bool RegOpenKeyWithErrorReport(
|
||||
LPCWSTR wszRegPath,
|
||||
LPCWSTR wszMonadVersion,
|
||||
__out_ecount(1) PHKEY phResult);
|
||||
|
||||
bool FormatStringWithErrorReporting(
|
||||
LPCWSTR wszFormat,
|
||||
__deref_out_opt PWSTR * pwszResult,
|
||||
__out_ecount(1) LPDWORD lpdwLength,
|
||||
int errorMessageId,
|
||||
...);
|
||||
|
||||
bool OpenLatestMSHEngineRegistry(
|
||||
__out_ecount(1) PHKEY phResult,
|
||||
__deref_out_opt PWSTR * pwszMshEngineRegKeyPath,
|
||||
__deref_out_opt PWSTR * pwszMonadVersion,
|
||||
__out_ecount(1) int * lpMonadMajorVersion);
|
||||
|
||||
bool RegQueryREG_SZValue(
|
||||
_In_ HKEY hEngineKey,
|
||||
_In_ LPCWSTR wszValueName,
|
||||
_In_ LPCWSTR wszMshEngineRegKey,
|
||||
__deref_out_opt PWSTR * pwszRegData);
|
||||
|
||||
unsigned int IsEngineRegKeyWithVersionExisting(
|
||||
LPCWSTR wszMonadVersion,
|
||||
LPCWSTR wszMonadMajorVersion);
|
||||
|
||||
unsigned int OpenEngineRegKeyWithVersion(
|
||||
__deref_out_ecount(1) PHKEY phEngineKey,
|
||||
__deref_out_opt PWSTR * pwszMshEngineRegKey,
|
||||
LPCWSTR wszMonadVersion,
|
||||
int monadMajorVersion);
|
||||
|
||||
bool VerifyDOTNetVersionFormat(
|
||||
LPCWSTR wszFullVersion,
|
||||
__out_ecount(1) int * lpMajorVersion,
|
||||
__out_ecount(1) int * lpMinorVersion);
|
||||
|
||||
virtual bool DoesAssemblyExist(
|
||||
std::string& fileToTest);
|
||||
|
||||
virtual void ProbeAssembly(
|
||||
_In_z_ PCSTR directoryPath,
|
||||
_In_z_ PCSTR assemblyName,
|
||||
std::string& result);
|
||||
|
||||
virtual void GetTrustedAssemblyList(
|
||||
PCSTR coreCLRDirectoryPath,
|
||||
std::stringstream& assemblyList,
|
||||
bool& listEmpty);
|
||||
|
||||
virtual unsigned int IdentifyHostDirectory(
|
||||
HostEnvironment& hostEnvironment);
|
||||
|
||||
private:
|
||||
// Explicitly disallow copy construction and assignment
|
||||
PwrshCommon(const PwrshCommon&);
|
||||
PwrshCommon& operator=(const PwrshCommon&);
|
||||
};
|
||||
} // namespace NativeMsh
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
//
|
||||
// Begin nativemsh.mc codes
|
||||
//
|
||||
const int g_MISSING_COMMAND_LINE_ARGUMENT = 1;
|
||||
const int g_INVALID_CONSOLE_FILE_PATH = 2;
|
||||
const int g_CLR_VERSION_NOT_INSTALLED = 3;
|
||||
const int g_CORBINDTORUNTIME_FAILED = 4;
|
||||
const int g_STARTING_CLR_FAILED = 5;
|
||||
const int g_GETTING_DEFAULT_DOMAIN_FAILED = 6;
|
||||
const int g_CREATING_MSH_ENTRANCE_FAILED = 7;
|
||||
const int g_GETTING_DISPATCH_ID_FAILED = 8;
|
||||
const int g_INOVKING_MSH_ENTRANCE_FAILED = 9;
|
||||
const int g_MANAGED_MSH_EXCEPTION = 10;
|
||||
const int g_READ_XML_COM_INIT_FAILED = 11;
|
||||
const int g_READ_XML_CREATE_DOMDOCUMENT_FAILED = 12;
|
||||
const int g_READ_XML_LOAD_FILE_FAILED = 13;
|
||||
const int g_EMPTY_REG_SZ_VALUE = 14;
|
||||
const int g_READ_XML_GET_CONSOLE_SCHEMA_VERSION_FAILED = 15;
|
||||
const int g_READ_XML_INVALID_CONSOLE_SCHEMA_VERSION = 16;
|
||||
const int g_INVALID_MONAD_VERSION = 17;
|
||||
const int g_READ_XML_GET_MONAD_VERSION_TEXT_FAILED = 18;
|
||||
const int g_SEARCH_LATEST_REG_KEY_FAILED_WITH = 19;
|
||||
const int g_OPEN_REG_KEY_FAILED_WITH = 20;
|
||||
const int g_CLOSE_REG_KEY_FAILED_WITH = 21;
|
||||
const int g_READ_REG_VALUE_FAILED_WITH = 22;
|
||||
const int g_CREATE_MSHENGINE_REG_KEY_PATH_FAILED_WITH = 23;
|
||||
const int g_EXPECT_REG_SZ_VALUE = 24;
|
||||
const int g_MSH_VERSION_NOT_INSTALLED = 25;
|
||||
const int g_INCORRECT_CONSOLE_FILE_EXTENSION = 26;
|
||||
const int g_INVALID_REG_MSHVERSION_VALUE = 27;
|
||||
const int g_INCOMPATIBLE_MINOR_VERSION = 28;
|
||||
const int g_NO_COMPLETELY_INSTALLED_FOUND_VERSION = 29;
|
||||
const int g_MISSING_REG_KEY = 30;
|
||||
const int g_READ_XML_LOAD_FILE_FAILED_WITH_SPECIFIC_ERROR = 31;
|
||||
const int g_READ_XML_LOAD_FILE_FAILED_WITH_SPECIFIC_POSITION_ERROR = 32;
|
||||
const int g_READ_XML_GET_EMPTY_MONAD_VERSION_TEXT = 33;
|
||||
const int g_READ_XML_GET_PSCONSOLEFILE_FAILED = 34;
|
||||
const int g_NOTSUPPORTED_MONAD_VERSION = 35;
|
||||
const int g_NONSTANDARD_CLR_VERSION = 36;
|
||||
const int g_SHELLBANNER1 = 37;
|
||||
const int g_SHELLBANNER2 = 38;
|
||||
// Win8: 622653 Creating a copy of g_MISSING_REG_KEY to address scenarios where pwszMonadVersion is NULL.
|
||||
const int g_MISSING_REG_KEY1 = 39;
|
||||
//
|
||||
// End nativemsh.mc codes
|
||||
//
|
||||
const int g_UNLOAD_APPDOMAIN_FAILED = 40;
|
||||
const int g_STOP_CLR_HOST_FAILED = 41;
|
||||
const int g_RELEASE_CLR_HOST_FAILED = 42;
|
||||
|
||||
const int g_MAX_REG_KEY_LENGTH = 255 + 1;
|
||||
|
||||
const int g_MAX_VERSION_FIELD_LENGTH = 10;
|
||||
|
||||
const unsigned int EXIT_CODE_SUCCESS = 0x00000000;
|
||||
const unsigned int EXIT_CODE_INIT_FAILURE = 0xFFFF0000;
|
||||
const unsigned int EXIT_CODE_BAD_COMMAND_LINE_PARAMETER = 0xFFFD0000;
|
||||
const unsigned int EXIT_CODE_READ_CONSOLE_FILE_FAILURE = 0xFFFC0000;
|
||||
const unsigned int EXIT_CODE_READ_REGISTRY_FAILURE = 0xFFFB0000;
|
||||
const unsigned int EXIT_CODE_INCOMPATIBLE_MSH_VERSION = 0xFFFA0000;
|
||||
|
||||
const DWORD INVALID_APPDOMAIN_ID = (DWORD)-1; // TODO: valid uninitialized value?
|
||||
} // namespace NativeMsh
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// File: SystemCallFacade.h
|
||||
//
|
||||
// Contents: Facade for Windows API system calls
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
//
|
||||
// Abstract class to abstract system call operations so that they can be
|
||||
// replaced with test code during test case execution.
|
||||
//
|
||||
class SystemCallFacade
|
||||
{
|
||||
public:
|
||||
SystemCallFacade() {}
|
||||
virtual ~SystemCallFacade() {}
|
||||
|
||||
// Module Manipulation Wrappers
|
||||
virtual HMODULE WINAPI LoadLibraryExW(
|
||||
_In_ PCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags) = 0;
|
||||
|
||||
virtual DWORD WINAPI GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ LPSTR lpFilename,
|
||||
_In_ DWORD nSize) = 0;
|
||||
|
||||
virtual HMODULE WINAPI GetModuleHandleA(
|
||||
_In_opt_ PCSTR lpModuleName) = 0;
|
||||
|
||||
virtual FARPROC WINAPI GetProcAddress(
|
||||
_In_ HMODULE hModule,
|
||||
_In_ LPCSTR lpProcName) = 0;
|
||||
|
||||
virtual BOOL WINAPI FreeLibrary(
|
||||
_In_ HMODULE hModule) = 0;
|
||||
|
||||
// File Manipulation Wrappers
|
||||
virtual errno_t fopen_s(
|
||||
FILE** file,
|
||||
const char *filename,
|
||||
const char *mode) = 0;
|
||||
|
||||
virtual int fclose(
|
||||
FILE *stream) = 0;
|
||||
};
|
||||
|
||||
} // namespace NativeMsh
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// File: WinSystemCallFacade.h
|
||||
//
|
||||
// Contents: Wraps the actual API calls for production scenarios.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#include "WinSystemCallFacade.h"
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
HMODULE WINAPI WinSystemCallFacade::LoadLibraryExW(
|
||||
_In_ LPCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags)
|
||||
{
|
||||
return ::LoadLibraryExW(lpFileName, hFile, dwFlags);
|
||||
}
|
||||
|
||||
#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::GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ LPSTR lpFilename, // _Out_writes_to_(nSize, return +1) OR __out_ecount_part(nSize, return + 1)? __out_ecount(nSize)
|
||||
_In_ DWORD nSize)
|
||||
{
|
||||
return ::GetModuleFileNameA(hModule, lpFilename, nSize);
|
||||
}
|
||||
|
||||
#pragma prefast(pop)
|
||||
|
||||
HMODULE WINAPI WinSystemCallFacade::GetModuleHandleA(
|
||||
_In_opt_ LPCSTR lpModuleName)
|
||||
{
|
||||
return ::GetModuleHandleA(lpModuleName);
|
||||
}
|
||||
|
||||
FARPROC WINAPI WinSystemCallFacade::GetProcAddress(
|
||||
_In_ HMODULE hModule,
|
||||
_In_ LPCSTR lpProcName)
|
||||
{
|
||||
return ::GetProcAddress(hModule, lpProcName);
|
||||
}
|
||||
|
||||
BOOL WINAPI WinSystemCallFacade::FreeLibrary(
|
||||
_In_ HMODULE hModule)
|
||||
{
|
||||
return ::FreeLibrary(hModule);
|
||||
}
|
||||
|
||||
errno_t WinSystemCallFacade::fopen_s(
|
||||
FILE** file,
|
||||
const char *filename,
|
||||
const char *mode)
|
||||
{
|
||||
return ::fopen_s(file, filename, mode);
|
||||
}
|
||||
|
||||
int WinSystemCallFacade::fclose(
|
||||
FILE *stream)
|
||||
{
|
||||
return ::fclose(stream);
|
||||
}
|
||||
|
||||
} // namespace NativeMsh
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// File: WinSystemCallFacade.h
|
||||
//
|
||||
// Contents: Wraps the actual API calls for production scenarios.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SystemCallFacade.h"
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
//
|
||||
// Actual implementation of the system calls for use during production.
|
||||
//
|
||||
class WinSystemCallFacade : public SystemCallFacade
|
||||
{
|
||||
public:
|
||||
WinSystemCallFacade() {}
|
||||
virtual ~WinSystemCallFacade() {}
|
||||
|
||||
// Module Manipulation Wrappers
|
||||
virtual HMODULE WINAPI LoadLibraryExW(
|
||||
_In_ PCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags);
|
||||
|
||||
virtual DWORD WINAPI GetModuleFileNameA(
|
||||
_In_opt_ HMODULE hModule,
|
||||
_Out_ LPSTR lpFilename,
|
||||
_In_ DWORD nSize);
|
||||
|
||||
virtual HMODULE WINAPI GetModuleHandleA(
|
||||
_In_opt_ LPCSTR lpModuleName);
|
||||
|
||||
virtual FARPROC WINAPI GetProcAddress(
|
||||
_In_ HMODULE hModule,
|
||||
_In_ LPCSTR lpProcName);
|
||||
|
||||
virtual BOOL WINAPI FreeLibrary(
|
||||
_In_ HMODULE hModule);
|
||||
|
||||
// File Manipulation Wrappers
|
||||
virtual errno_t fopen_s(
|
||||
FILE** file,
|
||||
const char *filename,
|
||||
const char *mode);
|
||||
|
||||
virtual int fclose(
|
||||
FILE *stream);
|
||||
};
|
||||
|
||||
} // namespace NativeMsh
|
File diff suppressed because it is too large
Load diff
|
@ -1,62 +0,0 @@
|
|||
#
|
||||
# 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
|
||||
onecore.lib
|
||||
${STATIC_MT_CRT_LIB}
|
||||
${STATIC_MT_VCRT_LIB}
|
||||
)
|
||||
set(powershell_definitions
|
||||
_CONSOLE
|
||||
CORECLR
|
||||
)
|
||||
|
||||
#
|
||||
# Configure lib directories so that CI picks up onecore.lib
|
||||
#
|
||||
if (BUILD_ARCH_AMD64)
|
||||
SET (WindowsSdkDir $ENV{WindowsSdkDir})
|
||||
SET (WindowsSDKVersion $ENV{WindowsSDKVersion})
|
||||
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}" )
|
||||
link_directories(${LibraryPath})
|
||||
endif ()
|
||||
|
||||
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}
|
||||
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)
|
|
@ -1,239 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// File: CoreCLRHost.cpp
|
||||
//
|
||||
// Contents: Unmanaged startup point for powershell.exe console app.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#if !CORECLR
|
||||
#include "mscoree.h"
|
||||
#endif
|
||||
#include "NativeMsh.h"
|
||||
#include "ClrHostWrapper.h"
|
||||
#include "OutputWriter.h"
|
||||
#include "ConfigFileReader.h"
|
||||
#include "WinSystemCallFacade.h"
|
||||
|
||||
namespace NativeMsh
|
||||
{
|
||||
// Define the function pointer for the powershell entry point.
|
||||
typedef int (STDMETHODCALLTYPE *MonadRunHelperFp)(LPCWSTR consoleFilePath, LPCWSTR * args, int argc); // int UnmanagedPSEntry.Start(string consoleFilePath, string[] args, int argc)
|
||||
|
||||
bool TryRun(const int argc, const wchar_t* argv[], HostEnvironment &hostEnvironment, int &exitCode, bool verbose)
|
||||
{
|
||||
// Assume failure
|
||||
exitCode = -1;
|
||||
|
||||
// All these objects will be destroyed when commonFuncs goes out of scope.
|
||||
PwrshExeOutput* output = new PwrshExeOutput();
|
||||
PwrshCommon commonFuncs(output, new ConfigFileReader(), new WinSystemCallFacade());
|
||||
CoreClrHostingApiWrapper hostWrapper;
|
||||
|
||||
exitCode = commonFuncs.LaunchCoreCLR(&hostWrapper, hostEnvironment, "powershell");
|
||||
if (EXIT_CODE_SUCCESS != exitCode)
|
||||
{
|
||||
if (verbose)
|
||||
::wprintf(L"Unable to launch CoreCLR\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hostWrapper.IsInitialized()) // TODO: redundant?
|
||||
{
|
||||
if (verbose)
|
||||
::wprintf(L"Unable to initialize CoreCLR\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Start the assembly
|
||||
MonadRunHelperFp pfnDelegate = NULL;
|
||||
HRESULT hr = hostWrapper.CreateDelegate(
|
||||
"Microsoft.PowerShell.ConsoleHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
|
||||
"Microsoft.PowerShell.UnmanagedPSEntry",
|
||||
"Start",
|
||||
(void**)&pfnDelegate);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr);
|
||||
}
|
||||
else
|
||||
{
|
||||
exitCode = pfnDelegate(NULL, &argv[0], argc);
|
||||
}
|
||||
|
||||
// Unload the AppDomain
|
||||
if (verbose)
|
||||
::wprintf(L"Unloading the AppDomain\n");
|
||||
|
||||
int utilExitCode = hostWrapper.CleanUpHostWrapper();
|
||||
if (EXIT_CODE_SUCCESS != utilExitCode)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
if (g_UNLOAD_APPDOMAIN_FAILED == utilExitCode)
|
||||
{
|
||||
// TODO: If we want localization, these must be added to nativemsh.mc
|
||||
::wprintf(L"Failed to unload the AppDomain. ERRORCODE: %u\n", utilExitCode);
|
||||
}
|
||||
else if (g_STOP_CLR_HOST_FAILED == utilExitCode)
|
||||
{
|
||||
::wprintf(L"Failed to stop the host. ERRORCODE: %u\n", utilExitCode);
|
||||
}
|
||||
else if (g_RELEASE_CLR_HOST_FAILED == utilExitCode)
|
||||
{
|
||||
::wprintf(L"Failed to release the host.ERRORCODE: %u\n", utilExitCode);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void showHelp() {
|
||||
static PCWSTR coreCLRInstallDirectory = L"%windir%\\system32\\DotNetCore\\v1.0\\";
|
||||
::wprintf(
|
||||
L"USAGE: powershell [-Verbose] [-Debug] [-File <filePath> <args>] [-Command] <CommandLine>\r\n"
|
||||
L"\r\n"
|
||||
L" CoreCLR is searched for in the directory that powershell.exe is in,\r\n"
|
||||
L" then in %s.\r\n",
|
||||
coreCLRInstallDirectory
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace NativeMsh
|
||||
|
||||
int __cdecl wmain(const int argc, const wchar_t* argv[])
|
||||
{
|
||||
// Parse the options from the command line
|
||||
const wchar_t *verboseParameter = L"-Verbose";
|
||||
const wchar_t *debugParameter = L"-Debug";
|
||||
|
||||
const wchar_t *versionParameter = L"-Version";
|
||||
const wchar_t *psConsoleFileParameter = L"-PSConsoleFile";
|
||||
const wchar_t *runtimeVersionParameter = L"-RuntimeVersion";
|
||||
|
||||
bool verbose = false;
|
||||
bool debug = false;
|
||||
bool helpRequested = false;
|
||||
|
||||
bool versionSpecified = false;
|
||||
bool psConsoleFileSpecified = false;
|
||||
bool runtimeVersionSpecified = false;
|
||||
|
||||
|
||||
int newArgc = argc - 1;
|
||||
const wchar_t **newArgv = argv + 1;
|
||||
|
||||
auto stringsMatch = [](const wchar_t * const userInput, const wchar_t * const parameter) -> bool {
|
||||
size_t userInputLength = ::wcslen(userInput);
|
||||
size_t parameterLength = ::wcslen(parameter);
|
||||
|
||||
// If the user input is longer than the parameter, they cannot be matched.
|
||||
if (userInputLength > parameterLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if the user input is a prefix of the parameter
|
||||
return ::_wcsnicmp(userInput, parameter, userInputLength) == 0;
|
||||
};
|
||||
|
||||
auto stringsEqual = [](const wchar_t * const a, const wchar_t * const b) -> bool {
|
||||
return ::_wcsicmp(a, b) == 0;
|
||||
};
|
||||
|
||||
// These parameters are considered 'native only' - they should NOT be passed to managed layer
|
||||
auto skipParameter = [&](const wchar_t * arg) -> bool {
|
||||
if (stringsMatch(arg, verboseParameter)) {
|
||||
verbose = true;
|
||||
}
|
||||
else if (stringsEqual(arg, L"/?") || stringsEqual(arg, L"-?")) {
|
||||
helpRequested = true;
|
||||
}
|
||||
else if (stringsMatch(arg, debugParameter))
|
||||
{
|
||||
debug = true;
|
||||
}
|
||||
else if (stringsEqual(arg, versionParameter))
|
||||
{
|
||||
versionSpecified = true;
|
||||
}
|
||||
else if (stringsMatch(arg, psConsoleFileParameter))
|
||||
{
|
||||
psConsoleFileSpecified = true;
|
||||
}
|
||||
else if (stringsMatch(arg, runtimeVersionParameter)) {
|
||||
runtimeVersionSpecified = true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Find the last 'native' parameter, and chomp everything up until it.
|
||||
while (newArgc > 0 && skipParameter(newArgv[0]))
|
||||
{
|
||||
newArgc--;
|
||||
newArgv++;
|
||||
|
||||
if (versionSpecified) {
|
||||
// skip the next arg if there is one
|
||||
versionSpecified = false;
|
||||
if (newArgc > 0) {
|
||||
newArgc--;
|
||||
newArgv++;
|
||||
}
|
||||
}
|
||||
|
||||
if (psConsoleFileSpecified) {
|
||||
// skip the next arg if there is one
|
||||
psConsoleFileSpecified = false;
|
||||
if (newArgc > 0) {
|
||||
newArgc--;
|
||||
newArgv++;
|
||||
}
|
||||
}
|
||||
|
||||
if (runtimeVersionSpecified) {
|
||||
// skip the next arg if there is one
|
||||
runtimeVersionSpecified = false;
|
||||
if (newArgc > 0) {
|
||||
newArgc--;
|
||||
newArgv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
::wprintf(L" Attach the debugger to powershell.exe and press any key to continue\n");
|
||||
(void) ::getchar();
|
||||
}
|
||||
|
||||
if (helpRequested)
|
||||
{
|
||||
NativeMsh::showHelp();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int exitCode;
|
||||
NativeMsh::HostEnvironment hostEnvironment;
|
||||
|
||||
auto success = TryRun(newArgc, newArgv, hostEnvironment, exitCode, verbose);
|
||||
|
||||
if (verbose)
|
||||
::wprintf(L"Execution %s\n", (success ? L"succeeded" : L"failed"));
|
||||
return exitCode;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 54 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue