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:
Aditya Patwardhan 2018-10-02 12:48:42 -07:00 committed by Travis Plunk
parent 2ea815756d
commit b42c001700
120 changed files with 6 additions and 11549 deletions

4
.gitmodules vendored
View file

@ -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

View file

@ -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

View file

@ -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})

View file

@ -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>

View 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.

View file

@ -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"

View file

@ -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

View file

@ -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 ()

View file

@ -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.

View file

@ -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)

View file

@ -1 +0,0 @@
pal_config.h

View file

@ -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})

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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());
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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());
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -1,3 +0,0 @@
#pragma once
#cmakedefine01 HAVE_SYS_SYSCTL_H

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}

View 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);
}

View file

@ -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()));
}

View file

@ -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");
}

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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")

View file

@ -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

View file

@ -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})

View file

@ -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

View file

@ -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"");
}
}
}

View file

@ -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

View file

@ -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;
};
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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