From 8948aa7efb9e3e54a38907dbb9dd1d6346484b90 Mon Sep 17 00:00:00 2001 From: Mike Richmond Date: Fri, 1 Jul 2016 14:10:32 -0700 Subject: [PATCH] Initial changes to split the CMake project into a hierarchical set of CMakeLists.txt files --- build.psm1 | 4 +- src/powershell-native/CMakeLists.txt | 57 +- .../nativemsh/pwrshcommon/CMakeLists.txt | 37 ++ .../nativemsh/pwrshcommon/ClrHostWrapper.h | 382 +++++++------ .../nativemsh/pwrshcommon/NativeMsh.h | 35 +- .../nativemsh/pwrshcommon/SystemCallFacade.h | 21 +- .../pwrshcommon/WinSystemCallFacade.cpp | 32 +- .../pwrshcommon/WinSystemCallFacade.h | 21 +- .../nativemsh/pwrshcommon/pwrshcommon.cpp | 524 +++++++----------- .../nativemsh/pwrshexe/CMakeLists.txt | 48 ++ .../nativemsh/pwrshplugin/CMakeLists.txt | 37 ++ .../nativemsh/pwrshplugin/pwrshclrhost.cpp | 39 +- .../nativemsh/pwrshplugin/pwrshclrhost.h | 9 +- .../nativemsh/pwrshplugin/pwrshplugin.h | 4 +- 14 files changed, 596 insertions(+), 654 deletions(-) create mode 100644 src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt create mode 100644 src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt create mode 100644 src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt diff --git a/build.psm1 b/build.psm1 index 95ee565a8..8d9998cf4 100644 --- a/build.psm1 +++ b/build.psm1 @@ -221,7 +221,7 @@ function Start-PSBuild { @("nativemsh/pwrshplugin") | % { $nativeResourcesFolder = $_ Get-ChildItem $nativeResourcesFolder -Filter "*.mc" | % { - # & $mcexe -c -U $_.FullName -h $nativeResourcesFolder -r $nativeResourcesFolder + & $mcexe -o -d -c -U $_.FullName -h $nativeResourcesFolder -r $nativeResourcesFolder } } @@ -231,7 +231,7 @@ function Start-PSBuild { Start-NativeExecution { cmake . } } - Start-NativeExecution { msbuild powershell.vcxproj /p:Configuration=$msbuildConfiguration } + Start-NativeExecution { msbuild ALL_BUILD.vcxproj /p:Configuration=$msbuildConfiguration } } finally { Pop-Location diff --git a/src/powershell-native/CMakeLists.txt b/src/powershell-native/CMakeLists.txt index 0388e2644..171ed8fe7 100644 --- a/src/powershell-native/CMakeLists.txt +++ b/src/powershell-native/CMakeLists.txt @@ -10,54 +10,29 @@ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) +# +# TODO: Will this interfere with OneCore compilations? +# # set these flags, so build does static linking for msvcr120.dll # otherwise this dll need to be present on the system set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -include_directories( - nativemsh/pwrshcommon - nativemsh/pwrshplugin) +# Compiler flags that are universal to all powershell native binaries +SET(common_pwrsh_definitions + UNICODE + _UNICODE) -link_directories( - nativemsh/pwrshcommon) +# Default of BUILD_ONECORE should be ON once it is supported +option(BUILD_ONECORE "Compile the OneCore version of the binaries" OFF) +option(BUILD_DOWNLEVEL "Compile the downlevel version of the binaries" OFF) -add_executable(powershell WIN32 - nativemsh/pwrshcommon/pwrshcommon.cpp - nativemsh/pwrshcommon/WinSystemCallFacade.cpp - nativemsh/pwrshexe/MainEntry.cpp) +# Build the common library that powershell.exe and pwrshplugin.dll depend on +add_subdirectory(nativemsh/pwrshcommon) -add_library(pwrshplugin - nativemsh/pwrshplugin/entrypoints.cpp - nativemsh/pwrshplugin/pwrshclrhost.cpp - #nativemsh/pwrshplugin/pwrshpluginerrorcodes.mc - #nativemsh/pwrshplugin/pwrshpluginerrorcodes.rc - nativemsh/pwrshplugin/pwrshplugin.def) +# Build pwrshplugin.dll +add_subdirectory(nativemsh/pwrshplugin) - -SET(powershell_definitions - _CONSOLE - UNICODE - _UNICODE) - -set_target_properties(powershell PROPERTIES COMPILE_DEFINITIONS "${powershell_definitions}") -set_target_properties(powershell PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE") -set_target_properties(powershell PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE") -set_target_properties(powershell PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE") -set_target_properties(powershell PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE") - -SET(pwrshplugin_definitions - UNICODE - _UNICODE) - -set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "${pwrshplugin_definitions}") - -target_link_libraries(powershell - mscoree.lib - MUILoad.lib - kernel32.lib - msxml6.lib - legacy_stdio_definitions.lib) - -target_link_libraries(pwrshplugin) +# Build powershell.exe +add_subdirectory(nativemsh/pwrshexe) diff --git a/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt b/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt new file mode 100644 index 000000000..947ab92c5 --- /dev/null +++ b/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# 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) + +target_include_directories(pwrshcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +if (BUILD_ONECORE) + # Libraries to use when creating this binary for Windows on OneCore-based SKUs + set(PWRSHCOMMON_WINDOWS_LIBS + onecore.lib) + set(pwrshcommon_definitions ${common_pwrsh_definitions} CORECLR) +else () # !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 + # ole32.lib + # oleaut32.lib + # uuid.lib + # user32.lib + # MUILoad.lib + # msxml6.lib + # mscoree.lib) + ) + set(pwrshcommon_definitions ${common_pwrsh_definitions}) + # target_include_directories(pwrshcommon PUBLIC + # "%ProgramFiles(x86)%/Windows Kits/NETFXSDK/4.6/Include/um") +endif (BUILD_ONECORE) + +set_target_properties(pwrshcommon PROPERTIES COMPILE_DEFINITIONS "${pwrshcommon_definitions}") + +target_link_libraries(pwrshcommon + ${PWRSHCOMMON_WINDOWS_LIBS}) + diff --git a/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h b/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h index b1c3b7cfb..861581cc5 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h +++ b/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h @@ -12,7 +12,6 @@ #pragma once #include -#include #include "NativeMshConstants.h" namespace NativeMsh @@ -32,322 +31,315 @@ namespace NativeMsh virtual bool IsInitialized() { return false; } - // For setting a host ptr since it is not known at container creation time. - // TODO: Can I make it immutable? - virtual void SetClrHost( - void* hostPtr) = 0; - // Graceful clean up of the object to prevent leaks virtual unsigned int CleanUpHostWrapper() = 0; - void SetAppDomainId(DWORD id) - { - m_appDomainId = id; - } - - DWORD GetAppDomainId() - { - return m_appDomainId; - } - // // The following methods are direct thin wrappers for the host calls. // - virtual HRESULT STDMETHODCALLTYPE CreateAppDomainWithManager( - /* [in] */ LPCWSTR wszFriendlyName, - /* [in] */ DWORD dwFlags, - /* [in] */ LPCWSTR wszAppDomainManagerAssemblyName, - /* [in] */ LPCWSTR wszAppDomainManagerTypeName, - /* [in] */ int nProperties, - /* [in] */ LPCWSTR *pPropertyNames, - /* [in] */ LPCWSTR *pPropertyValues, - /* [out] */ DWORD *pAppDomainID) = 0; + virtual HMODULE SetupWrapper(LPCSTR coreClrPathPtr) = 0; - virtual HRESULT STDMETHODCALLTYPE UnloadAppDomain( - /* [in] */ DWORD dwAppDomainId, - /* [in] */ BOOL fWaitUntilDone) = 0; + virtual int InitializeClr( + const char* exePath, + const char* appDomainFriendlyName, + int propertyCount, + const char** propertyKeys, + const char** propertyValues) = 0; - virtual HRESULT STDMETHODCALLTYPE CreateDelegate( - /* [in] */ DWORD appDomainID, - /* [in] */ LPCWSTR wszAssemblyName, - /* [in] */ LPCWSTR wszClassName, - /* [in] */ LPCWSTR wszMethodName, - /* [out] */ INT_PTR *fnPtr) = 0; + virtual int CreateDelegate( + const char* entryPointAssemblyName, + const char* entryPointTypeName, + const char* entryPointMethodName, + void** delegate) = 0; - virtual HRESULT STDMETHODCALLTYPE Authenticate( - /* [in] */ ULONGLONG authKey) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetStartupFlags( - /* [in] */ STARTUP_FLAGS dwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE Start() = 0; - - virtual HRESULT STDMETHODCALLTYPE Stop() = 0; - - virtual HRESULT STDMETHODCALLTYPE Release() = 0; + // TODO: This probably isn't needed + virtual int ShutdownClr() = 0; }; -#if CORECLR // - // Concrete implementation of the wrapper for the ICLRRuntimeHost2 interface. + // Concrete implementation of the wrapper for CoreClr.dll's + // Platform-Agnostic hosting interface. // - class ICLRRuntimeHost2Wrapper : public ClrHostWrapper + class CoreClrHostingApiWrapper : public ClrHostWrapper { private: - ICLRRuntimeHost2* pHost; + // Handle of CoreClr.dll + HMODULE coreClrHandle; + HMODULE pinnedModuleHandle; + + // CoreCLR.dll API values that are hidden from the user and kept internal. + void* hostHandle; + unsigned int domainId; + + // The name of the CoreCLR native runtime DLL. + PCSTR coreClrDllName = "CoreCLR.dll"; + + // + // Function Pointer Definitions for the function pointers to load from CoreCLR.dll + // + typedef int (*coreclr_initialize_ptr)( + const char* exePath, + const char* appDomainFriendlyName, + int propertyCount, + const char** propertyKeys, + const char** propertyValues, + void** hostHandle, + unsigned int* domainId); + + typedef int (*coreclr_shutdown_ptr)( + void* hostHandle, + unsigned int domainId); + + typedef int (*coreclr_create_delegate_ptr)( + void* hostHandle, + unsigned int domainId, + const char* entryPointAssemblyName, + const char* entryPointTypeName, + const char* entryPointMethodName, + void** delegate); + + // Pointers to exported functions of CoreClr.dll + coreclr_initialize_ptr initPtr; + coreclr_shutdown_ptr shutdownPtr; + coreclr_create_delegate_ptr createDelegatePtr; public: - ICLRRuntimeHost2Wrapper() : pHost(NULL) {} - virtual ~ICLRRuntimeHost2Wrapper() + CoreClrHostingApiWrapper() + : coreClrHandle(NULL), + pinnedModuleHandle(NULL), + hostHandle(NULL), + domainId(0), + initPtr(NULL), + shutdownPtr(NULL), + createDelegatePtr(NULL) + {} + + virtual ~CoreClrHostingApiWrapper() { - CleanUpHostWrapper(); + this->CleanUpHostWrapper(); } - virtual bool IsInitialized() { return (pHost != NULL); } - - // For setting a host ptr since it is not known at container creation time. - virtual void SetClrHost(void* hostPtr) + virtual bool IsInitialized() + { + return (NULL != coreClrHandle); + } + + // + // TODO: This shouldn't return HMODULE because that breaks encapsulation. I need a better way to + // have the caller extract the value. Either Pass as a reference or provide an accessor. + // + // 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 HMODULE SetupWrapper(LPCSTR coreClrPathPtr) { - pHost = (ICLRRuntimeHost2*)hostPtr; + std::string coreClrPath(coreClrPathPtr); + coreClrPath += coreClrDllName; + + HMODULE result = LoadLibraryExA(coreClrPath.c_str(), NULL, 0); + if (!result) + { + return NULL; + } + + // Pin the module - CoreCLR.dll does not support being unloaded. + if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, coreClrPath.c_str(), &pinnedModuleHandle)) + { + return NULL; + } + + // Initialization succeeded. Save the handle and return success; + coreClrHandle = result; + return result; } virtual unsigned int CleanUpHostWrapper() { if (this->IsInitialized()) { - if (FAILED(this->UnloadAppDomain(this->GetAppDomainId(), true))) - { - return g_UNLOAD_APPDOMAIN_FAILED; - } - - if (FAILED(this->Stop())) + HRESULT status = this->ShutdownClr(); + if (FAILED(status)) { return g_STOP_CLR_HOST_FAILED; } - - // Release the reference to the host - if (FAILED(this->Release())) + + if (this->coreClrHandle) { - return g_RELEASE_CLR_HOST_FAILED; + // TODO: Is this comment still relevant with the new hosting API? + // + // Free the module. This is done for completeness, but in fact CoreCLR.dll + // was pinned earlier so this call won't actually free it. The pinning is + // done because CoreCLR does not support unloading. + ::FreeLibrary(this->coreClrHandle); + this->coreClrHandle = NULL; } - this->SetClrHost(NULL); } return EXIT_CODE_SUCCESS; } - virtual HRESULT STDMETHODCALLTYPE CreateAppDomainWithManager( - /* [in] */ LPCWSTR wszFriendlyName, - /* [in] */ DWORD dwFlags, - /* [in] */ LPCWSTR wszAppDomainManagerAssemblyName, - /* [in] */ LPCWSTR wszAppDomainManagerTypeName, - /* [in] */ int nProperties, - /* [in] */ LPCWSTR *pPropertyNames, - /* [in] */ LPCWSTR *pPropertyValues, - /* [out] */ DWORD *pAppDomainID) + virtual int InitializeClr( + const char* exePath, + const char* appDomainFriendlyName, + int propertyCount, + const char** propertyKeys, + const char** propertyValues) { - if (pHost) + if (initPtr) { - return pHost->CreateAppDomainWithManager( - wszFriendlyName, - dwFlags, - wszAppDomainManagerAssemblyName, - wszAppDomainManagerTypeName, - nProperties, - pPropertyNames, - pPropertyValues, - pAppDomainID); + return initPtr( + exePath, + appDomainFriendlyName, + propertyCount, + propertyKeys, + propertyValues, + &(this->hostHandle), + &(this->domainId)); } return E_FAIL; } - virtual HRESULT STDMETHODCALLTYPE UnloadAppDomain( - /* [in] */ DWORD dwAppDomainId, - /* [in] */ BOOL fWaitUntilDone) + virtual int CreateDelegate( + const char* entryPointAssemblyName, + const char* entryPointTypeName, + const char* entryPointMethodName, + void** delegate) { - if (pHost) + if (createDelegatePtr) { - return pHost->UnloadAppDomain( - dwAppDomainId, - fWaitUntilDone); + return createDelegatePtr( + this->hostHandle, + this->domainId, + entryPointAssemblyName, + entryPointTypeName, + entryPointMethodName, + delegate); } return E_FAIL; } - virtual HRESULT STDMETHODCALLTYPE CreateDelegate( - /* [in] */ DWORD appDomainID, - /* [in] */ LPCWSTR wszAssemblyName, - /* [in] */ LPCWSTR wszClassName, - /* [in] */ LPCWSTR wszMethodName, - /* [out] */ INT_PTR *fnPtr) + virtual int ShutdownClr() { - if (pHost) + if (shutdownPtr) { - return pHost->CreateDelegate( - appDomainID, - wszAssemblyName, - wszClassName, - wszMethodName, - fnPtr); - } - return E_FAIL; - } - - virtual HRESULT STDMETHODCALLTYPE Authenticate( - /* [in] */ ULONGLONG authKey) - { - if (pHost) - { - return pHost->Authenticate( - authKey); - } - return E_FAIL; - } - - virtual HRESULT STDMETHODCALLTYPE SetStartupFlags( - /* [in] */ STARTUP_FLAGS dwFlags) - { - if (pHost) - { - return pHost->SetStartupFlags( - dwFlags); - } - return E_FAIL; - } - - virtual HRESULT STDMETHODCALLTYPE Start() - { - if (pHost) - { - return pHost->Start(); - } - return E_FAIL; - } - - virtual HRESULT STDMETHODCALLTYPE Stop() - { - if (pHost) - { - return pHost->Stop(); - } - return E_FAIL; - } - - virtual HRESULT STDMETHODCALLTYPE Release() - { - if (pHost) - { - return pHost->Release(); + return shutdownPtr( + this->hostHandle, + this->domainId); } return E_FAIL; } }; -#endif // Encapsulates the environment that CoreCLR will run in, including the TPALIST class HostEnvironment { private: // The path to this module - wchar_t m_hostPath[MAX_PATH]; + char m_hostPath[MAX_PATH]; // The path to the directory containing this module - wchar_t m_hostDirectoryPath[MAX_PATH]; + char m_hostDirectoryPath[MAX_PATH]; + wchar_t m_hostDirectoryPathW[MAX_PATH]; // The name of this module, without the path - std::wstring m_hostBinaryName; + std::string m_hostBinaryName; // The path to the directory that CoreCLR is in - wchar_t m_coreCLRDirectoryPath[MAX_PATH]; - - HMODULE m_coreCLRModule; + char m_coreCLRDirectoryPath[MAX_PATH]; public: HostEnvironment() - : m_coreCLRModule(0) { memset(m_hostPath, 0, sizeof(m_hostPath)); memset(m_hostDirectoryPath, 0, sizeof(m_hostDirectoryPath)); memset(m_coreCLRDirectoryPath, 0, sizeof(m_coreCLRDirectoryPath)); } - ~HostEnvironment() - { - if (m_coreCLRModule) - { - // Free the module. This is done for completeness, but in fact CoreCLR.dll - // was pinned earlier so this call won't actually free it. The pinning is - // done because CoreCLR does not support unloading. - ::FreeLibrary(m_coreCLRModule); - } - } + ~HostEnvironment() {} // Safely copies in a host path - void SetHostPath(PCWSTR hostPath) + void SetHostPath(PCSTR hostPath) { if (hostPath) { - ::ExpandEnvironmentStringsW(hostPath, m_hostPath, MAX_PATH); - //::wcsncpy_s(m_hostPath, hostPath, _TRUNCATE); + ::ExpandEnvironmentStringsA(hostPath, m_hostPath, MAX_PATH); } } // Returns the path to the host module - PCWSTR GetHostPath() + PCSTR GetHostPath() { return m_hostPath; } // Safely copies in a host binary name - void SetHostBinaryName(PCWSTR hostBinaryName) + void SetHostBinaryName(PCSTR hostBinaryName) { if (hostBinaryName) { - m_hostBinaryName = std::wstring(hostBinaryName); + m_hostBinaryName = std::string(hostBinaryName); } } // Returns the name of the host module - PCWSTR GetHostBinaryName() + PCSTR GetHostBinaryName() { return m_hostBinaryName.c_str(); } // Safely copies in a host directory path - void SetHostDirectoryPath(PCWSTR hostDirPath) + void SetHostDirectoryPath(PCSTR hostDirPath) { if (hostDirPath) { - ::ExpandEnvironmentStringsW(hostDirPath, m_hostDirectoryPath, MAX_PATH); - //::wcsncpy_s(m_hostDirectoryPath, hostDirPath, _TRUNCATE); + ::ExpandEnvironmentStringsA(hostDirPath, m_hostDirectoryPath, MAX_PATH); + + // 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, m_hostDirectoryPath, -1, NULL, 0); + if (0 < length) + { + LPWSTR result = new wchar_t[length]; + if (NULL != result) + { + length = ::MultiByteToWideChar(CP_UTF8, 0, m_hostDirectoryPath, -1, result, length); + if (0 < length) + { + wcscpy_s(m_hostDirectoryPathW, MAX_PATH, result); + } + delete[] result; // Free the allocated string to avoid a memory leak + } + } } } // Returns the directory path of the host module - PCWSTR GetHostDirectoryPath() + PCSTR GetHostDirectoryPath() { return m_hostDirectoryPath; } + // Returns the directory path of the host module as a wide char string + PCWSTR GetHostDirectoryPathW() + { + return m_hostDirectoryPathW; + } + // Safely copies in a core clr directory path - void SetCoreCLRDirectoryPath(PCWSTR hostClrPath) + void SetCoreCLRDirectoryPath(PCSTR hostClrPath) { if (hostClrPath) { - ::ExpandEnvironmentStringsW(hostClrPath, m_coreCLRDirectoryPath, MAX_PATH); - //::wcsncpy_s(m_coreCLRDirectoryPath, hostClrPath, _TRUNCATE); + ::ExpandEnvironmentStringsA(hostClrPath, m_coreCLRDirectoryPath, MAX_PATH); } } // Returns the directory path of the host module - PCWSTR GetCoreCLRDirectoryPath() + PCSTR GetCoreCLRDirectoryPath() { return m_coreCLRDirectoryPath; } - - void SetCoreCLRModule(HMODULE module) - { - m_coreCLRModule = module; - } }; -} // namespace NativeMsh \ No newline at end of file +} // namespace NativeMsh diff --git a/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h b/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h index df477f4cc..eee01a498 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h +++ b/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h @@ -19,6 +19,10 @@ #include "SystemCallFacade.h" #include "IPwrshCommonOutput.h" +#if !CORECLR +#include +#endif + namespace NativeMsh { class PwrshCommon @@ -91,17 +95,12 @@ namespace NativeMsh __deref_out_opt PWSTR * pwszRuntimeVersion, __deref_out_opt PWSTR * pwszConsoleHostAssemblyName); -#if CORECLR unsigned int LaunchCoreCLR( ClrHostWrapper* hostWrapper, - HostEnvironment& hostEnvironment); + HostEnvironment& hostEnvironment, + PCSTR friendlyName); - unsigned int CreateAppDomain( - ClrHostWrapper* hostWrapper, - PCWSTR friendlyName, - HostEnvironment& hostEnvironment); - -#else // !CORECLR +#if !CORECLR // NOTE: // This must be ifdef'd out of the CoreCLR build because it uses .NET 1.0 // types that have been deprecated and removed from mscoree.h. @@ -113,7 +112,6 @@ namespace NativeMsh LPCWSTR wszMonadVersion, LPCWSTR wszRuntimeVersion, __in_ecount(1) ICorRuntimeHost** pCLR); - #endif // !CORECLR protected: @@ -170,28 +168,21 @@ namespace NativeMsh __out_ecount(1) int * lpMinorVersion); virtual bool DoesAssemblyExist( - std::wstring& fileToTest); + std::string& fileToTest); virtual void ProbeAssembly( - _In_z_ PCWSTR directoryPath, - _In_z_ PCWSTR assemblyName, - std::wstring& result); + _In_z_ PCSTR directoryPath, + _In_z_ PCSTR assemblyName, + std::string& result); virtual void GetTrustedAssemblyList( - PCWSTR coreCLRDirectoryPath, - std::wstringstream& assemblyList, + PCSTR coreCLRDirectoryPath, + std::stringstream& assemblyList, bool& listEmpty); virtual unsigned int IdentifyHostDirectory( HostEnvironment& hostEnvironment); - virtual HMODULE TryLoadCoreCLR( - _In_ PCWSTR directoryPath); - - virtual unsigned int InitializeClr( - _In_ ClrHostWrapper* hostWrapper, - _In_ HMODULE coreClrModule); - private: // Explicitly disallow copy construction and assignment PwrshCommon(const PwrshCommon&); diff --git a/src/powershell-native/nativemsh/pwrshcommon/SystemCallFacade.h b/src/powershell-native/nativemsh/pwrshcommon/SystemCallFacade.h index 877f3d2b0..97dcfa194 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/SystemCallFacade.h +++ b/src/powershell-native/nativemsh/pwrshcommon/SystemCallFacade.h @@ -32,18 +32,13 @@ namespace NativeMsh _Reserved_ HANDLE hFile, _In_ DWORD dwFlags) = 0; - virtual DWORD WINAPI GetModuleFileNameW( + virtual DWORD WINAPI GetModuleFileNameA( _In_opt_ HMODULE hModule, - _Out_ PWSTR lpFilename, + _Out_ LPSTR lpFilename, _In_ DWORD nSize) = 0; - virtual HMODULE WINAPI GetModuleHandleW( - _In_opt_ PCWSTR lpModuleName) = 0; - - virtual BOOL WINAPI GetModuleHandleExW( - _In_ DWORD dwFlags, - _In_opt_ PCWSTR lpModuleName, - _Out_ HMODULE *phModule) = 0; + virtual HMODULE WINAPI GetModuleHandleA( + _In_opt_ PCSTR lpModuleName) = 0; virtual FARPROC WINAPI GetProcAddress( _In_ HMODULE hModule, @@ -53,12 +48,12 @@ namespace NativeMsh _In_ HMODULE hModule) = 0; // File Manipulation Wrappers - virtual FILE* _wfopen( - const wchar_t *filename, - const wchar_t *mode) = 0; + virtual FILE* fopen( + const char *filename, + const char *mode) = 0; virtual int fclose( FILE *stream) = 0; }; -} // namespace NativeMsh \ No newline at end of file +} // namespace NativeMsh diff --git a/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.cpp b/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.cpp index 8ccfb2b25..9f49a43d5 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.cpp +++ b/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.cpp @@ -14,7 +14,7 @@ namespace NativeMsh { HMODULE WINAPI WinSystemCallFacade::LoadLibraryExW( - _In_ LPCTSTR lpFileName, + _In_ LPCWSTR lpFileName, _Reserved_ HANDLE hFile, _In_ DWORD dwFlags) { @@ -24,28 +24,20 @@ namespace NativeMsh #pragma prefast(push) #pragma prefast (disable: 26006) // Possibly incorrect single element annotation on string buffer - This is a thin wrapper around a system call, so it's behavior is not controllable. - DWORD WINAPI WinSystemCallFacade::GetModuleFileNameW( + DWORD WINAPI WinSystemCallFacade::GetModuleFileNameA( _In_opt_ HMODULE hModule, - _Out_ LPTSTR lpFilename, // _Out_writes_to_(nSize, return +1) OR __out_ecount_part(nSize, return + 1)? __out_ecount(nSize) + _Out_ LPSTR lpFilename, // _Out_writes_to_(nSize, return +1) OR __out_ecount_part(nSize, return + 1)? __out_ecount(nSize) _In_ DWORD nSize) { - return ::GetModuleFileNameW(hModule, lpFilename, nSize); + return ::GetModuleFileNameA(hModule, lpFilename, nSize); } #pragma prefast(pop) - HMODULE WINAPI WinSystemCallFacade::GetModuleHandleW( - _In_opt_ LPCTSTR lpModuleName) + HMODULE WINAPI WinSystemCallFacade::GetModuleHandleA( + _In_opt_ LPCSTR lpModuleName) { - return ::GetModuleHandleW(lpModuleName); - } - - BOOL WINAPI WinSystemCallFacade::GetModuleHandleExW( - _In_ DWORD dwFlags, - _In_opt_ LPCTSTR lpModuleName, - _Out_ HMODULE *phModule) - { - return ::GetModuleHandleExW(dwFlags, lpModuleName, phModule); + return ::GetModuleHandleA(lpModuleName); } FARPROC WINAPI WinSystemCallFacade::GetProcAddress( @@ -61,11 +53,11 @@ namespace NativeMsh return ::FreeLibrary(hModule); } - FILE* WinSystemCallFacade::_wfopen( - const wchar_t *filename, - const wchar_t *mode) + FILE* WinSystemCallFacade::fopen( + const char *filename, + const char *mode) { - return ::_wfopen(filename, mode); + return ::fopen(filename, mode); } int WinSystemCallFacade::fclose( @@ -74,4 +66,4 @@ namespace NativeMsh return ::fclose(stream); } -} // namespace NativeMsh \ No newline at end of file +} // namespace NativeMsh diff --git a/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.h b/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.h index bdaa3a116..1ec4379e8 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.h +++ b/src/powershell-native/nativemsh/pwrshcommon/WinSystemCallFacade.h @@ -30,18 +30,13 @@ namespace NativeMsh _Reserved_ HANDLE hFile, _In_ DWORD dwFlags); - virtual DWORD WINAPI GetModuleFileNameW( + virtual DWORD WINAPI GetModuleFileNameA( _In_opt_ HMODULE hModule, - _Out_ PWSTR lpFilename, + _Out_ LPSTR lpFilename, _In_ DWORD nSize); - virtual HMODULE WINAPI GetModuleHandleW( - _In_opt_ PCWSTR lpModuleName); - - virtual BOOL WINAPI GetModuleHandleExW( - _In_ DWORD dwFlags, - _In_opt_ PCWSTR lpModuleName, - _Out_ HMODULE *phModule); + virtual HMODULE WINAPI GetModuleHandleA( + _In_opt_ LPCSTR lpModuleName); virtual FARPROC WINAPI GetProcAddress( _In_ HMODULE hModule, @@ -51,12 +46,12 @@ namespace NativeMsh _In_ HMODULE hModule); // File Manipulation Wrappers - virtual FILE* _wfopen( - const wchar_t *filename, - const wchar_t *mode); + virtual FILE* fopen( + const char *filename, + const char *mode); virtual int fclose( FILE *stream); }; -} // namespace NativeMsh \ No newline at end of file +} // namespace NativeMsh diff --git a/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp b/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp index 64d0a014d..5d1229e32 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp +++ b/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp @@ -667,176 +667,176 @@ namespace NativeMsh // System.Management.Automation must not be listed here. I should exist on the APP_PATH. // // NOTE: The names must not include the .dll extension because it will be added programmatically. - static PCWSTR trustedAssemblies[] = + static PCSTR trustedAssemblies[] = { - L"Microsoft.CSharp", - L"Microsoft.VisualBasic", - L"Microsoft.Win32.Primitives", - L"Microsoft.Win32.Registry.AccessControl", - L"Microsoft.Win32.Registry", - L"mscorlib", - L"System.AppContext", - L"System.Buffers", - L"System.Collections.Concurrent", - L"System.Collections", - L"System.Collections.Immutable", - L"System.Collections.NonGeneric", - L"System.Collections.Specialized", - L"System.ComponentModel.Annotations", - L"System.ComponentModel.DataAnnotations", - L"System.ComponentModel", - L"System.ComponentModel.EventBasedAsync", - L"System.ComponentModel.Primitives", - L"System.ComponentModel.TypeConverter", - L"System.Console", - L"System.Core", - L"System.Data.Common", - L"System.Diagnostics.Contracts", - L"System.Diagnostics.Debug", - L"System.Diagnostics.DiagnosticSource", - L"System.Diagnostics.FileVersionInfo", - L"System.Diagnostics.Process", - L"System.Diagnostics.StackTrace", - L"System.Diagnostics.TextWriterTraceListener", - L"System.Diagnostics.Tools", - L"System.Diagnostics.TraceSource", - L"System.Diagnostics.Tracing", - L"System", - L"System.Dynamic.Runtime", - L"System.Globalization.Calendars", - L"System.Globalization", - L"System.Globalization.Extensions", - L"System.IO.Compression", - L"System.IO.Compression.ZipFile", - L"System.IO", - L"System.IO.FileSystem.AccessControl", - L"System.IO.FileSystem", - L"System.IO.FileSystem.DriveInfo", - L"System.IO.FileSystem.Primitives", - L"System.IO.FileSystem.Watcher", - L"System.IO.MemoryMappedFiles", - L"System.IO.Packaging", - L"System.IO.Pipes", - L"System.IO.UnmanagedMemoryStream", - L"System.Linq", - L"System.Linq.Expressions", - L"System.Linq.Parallel", - L"System.Linq.Queryable", - L"System.Net", - L"System.Net.Http", - L"System.Net.Http.WinHttpHandler", - L"System.Net.NameResolution", - L"System.Net.NetworkInformation", - L"System.Net.Ping", - L"System.Net.Primitives", - L"System.Net.Requests", - L"System.Net.Security", - L"System.Net.Sockets", - L"System.Net.WebHeaderCollection", - L"System.Net.WebSockets.Client", - L"System.Net.WebSockets", - L"System.Numerics", - L"System.Numerics.Vectors", - L"System.ObjectModel", - L"System.Private.DataContractSerialization", - L"System.Private.ServiceModel", - L"System.Private.Uri", - L"System.Reflection.DispatchProxy", - L"System.Reflection", - L"System.Reflection.Emit", - L"System.Reflection.Emit.ILGeneration", - L"System.Reflection.Emit.Lightweight", - L"System.Reflection.Extensions", - L"System.Reflection.Metadata", - L"System.Reflection.Primitives", - L"System.Reflection.TypeExtensions", - L"System.Resources.ReaderWriter", - L"System.Resources.ResourceManager", - L"System.Runtime.CompilerServices.VisualC", - L"System.Runtime", - L"System.Runtime.Extensions", - L"System.Runtime.Handles", - L"System.Runtime.InteropServices", - L"System.Runtime.InteropServices.PInvoke", - L"System.Runtime.InteropServices.RuntimeInformation", - L"System.Runtime.Loader", - L"System.Runtime.Numerics", - L"System.Runtime.Serialization", - L"System.Runtime.Serialization.Json", - L"System.Runtime.Serialization.Primitives", - L"System.Runtime.Serialization.Xml", - L"System.Security.AccessControl", - L"System.Security.Claims", - L"System.Security.Cryptography.Algorithms", - L"System.Security.Cryptography.Cng", - L"System.Security.Cryptography.Csp", - L"System.Security.Cryptography.Encoding", - L"System.Security.Cryptography.OpenSsl", - L"System.Security.Cryptography.Primitives", - L"System.Security.Cryptography.X509Certificates", - L"System.Security.Principal", - L"System.Security.Principal.Windows", - L"System.Security.SecureString", - L"System.ServiceModel", - L"System.ServiceModel.Duplex", - L"System.ServiceModel.Http", - L"System.ServiceModel.NetTcp", - L"System.ServiceModel.Primitives", - L"System.ServiceModel.Security", - L"System.ServiceModel.Web", - L"System.ServiceProcess.ServiceController", - L"System.Text.Encoding.CodePages", - L"System.Text.Encoding", - L"System.Text.Encoding.Extensions", - L"System.Text.Encodings.Web", - L"System.Text.RegularExpressions", - L"System.Threading.AccessControl", - L"System.Threading", - L"System.Threading.Overlapped", - L"System.Threading.Tasks.Dataflow", - L"System.Threading.Tasks", - L"System.Threading.Tasks.Extensions", - L"System.Threading.Tasks.Parallel", - L"System.Threading.Thread", - L"System.Threading.ThreadPool", - L"System.Threading.Timer", - L"System.Windows", - L"System.Xml", - L"System.Xml.Linq", - L"System.Xml.ReaderWriter", - L"System.Xml.Serialization", - L"System.Xml.XDocument", - L"System.Xml.XmlDocument", - L"System.Xml.XmlSerializer", - L"System.Xml.XPath", - L"System.Xml.XPath.XDocument", - L"System.Xml.XPath.XmlDocument", - L"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext" + "Microsoft.CSharp", + "Microsoft.VisualBasic", + "Microsoft.Win32.Primitives", + "Microsoft.Win32.Registry.AccessControl", + "Microsoft.Win32.Registry", + "mscorlib", + "System.AppContext", + "System.Buffers", + "System.Collections.Concurrent", + "System.Collections", + "System.Collections.Immutable", + "System.Collections.NonGeneric", + "System.Collections.Specialized", + "System.ComponentModel.Annotations", + "System.ComponentModel.DataAnnotations", + "System.ComponentModel", + "System.ComponentModel.EventBasedAsync", + "System.ComponentModel.Primitives", + "System.ComponentModel.TypeConverter", + "System.Console", + "System.Core", + "System.Data.Common", + "System.Diagnostics.Contracts", + "System.Diagnostics.Debug", + "System.Diagnostics.DiagnosticSource", + "System.Diagnostics.FileVersionInfo", + "System.Diagnostics.Process", + "System.Diagnostics.StackTrace", + "System.Diagnostics.TextWriterTraceListener", + "System.Diagnostics.Tools", + "System.Diagnostics.TraceSource", + "System.Diagnostics.Tracing", + "System", + "System.Dynamic.Runtime", + "System.Globalization.Calendars", + "System.Globalization", + "System.Globalization.Extensions", + "System.IO.Compression", + "System.IO.Compression.ZipFile", + "System.IO", + "System.IO.FileSystem.AccessControl", + "System.IO.FileSystem", + "System.IO.FileSystem.DriveInfo", + "System.IO.FileSystem.Primitives", + "System.IO.FileSystem.Watcher", + "System.IO.MemoryMappedFiles", + "System.IO.Packaging", + "System.IO.Pipes", + "System.IO.UnmanagedMemoryStream", + "System.Linq", + "System.Linq.Expressions", + "System.Linq.Parallel", + "System.Linq.Queryable", + "System.Net", + "System.Net.Http", + "System.Net.Http.WinHttpHandler", + "System.Net.NameResolution", + "System.Net.NetworkInformation", + "System.Net.Ping", + "System.Net.Primitives", + "System.Net.Requests", + "System.Net.Security", + "System.Net.Sockets", + "System.Net.WebHeaderCollection", + "System.Net.WebSockets.Client", + "System.Net.WebSockets", + "System.Numerics", + "System.Numerics.Vectors", + "System.ObjectModel", + "System.Private.DataContractSerialization", + "System.Private.ServiceModel", + "System.Private.Uri", + "System.Reflection.DispatchProxy", + "System.Reflection", + "System.Reflection.Emit", + "System.Reflection.Emit.ILGeneration", + "System.Reflection.Emit.Lightweight", + "System.Reflection.Extensions", + "System.Reflection.Metadata", + "System.Reflection.Primitives", + "System.Reflection.TypeExtensions", + "System.Resources.ReaderWriter", + "System.Resources.ResourceManager", + "System.Runtime.CompilerServices.VisualC", + "System.Runtime", + "System.Runtime.Extensions", + "System.Runtime.Handles", + "System.Runtime.InteropServices", + "System.Runtime.InteropServices.PInvoke", + "System.Runtime.InteropServices.RuntimeInformation", + "System.Runtime.Loader", + "System.Runtime.Numerics", + "System.Runtime.Serialization", + "System.Runtime.Serialization.Json", + "System.Runtime.Serialization.Primitives", + "System.Runtime.Serialization.Xml", + "System.Security.AccessControl", + "System.Security.Claims", + "System.Security.Cryptography.Algorithms", + "System.Security.Cryptography.Cng", + "System.Security.Cryptography.Csp", + "System.Security.Cryptography.Encoding", + "System.Security.Cryptography.OpenSsl", + "System.Security.Cryptography.Primitives", + "System.Security.Cryptography.X509Certificates", + "System.Security.Principal", + "System.Security.Principal.Windows", + "System.Security.SecureString", + "System.ServiceModel", + "System.ServiceModel.Duplex", + "System.ServiceModel.Http", + "System.ServiceModel.NetTcp", + "System.ServiceModel.Primitives", + "System.ServiceModel.Security", + "System.ServiceModel.Web", + "System.ServiceProcess.ServiceController", + "System.Text.Encoding.CodePages", + "System.Text.Encoding", + "System.Text.Encoding.Extensions", + "System.Text.Encodings.Web", + "System.Text.RegularExpressions", + "System.Threading.AccessControl", + "System.Threading", + "System.Threading.Overlapped", + "System.Threading.Tasks.Dataflow", + "System.Threading.Tasks", + "System.Threading.Tasks.Extensions", + "System.Threading.Tasks.Parallel", + "System.Threading.Thread", + "System.Threading.ThreadPool", + "System.Threading.Timer", + "System.Windows", + "System.Xml", + "System.Xml.Linq", + "System.Xml.ReaderWriter", + "System.Xml.Serialization", + "System.Xml.XDocument", + "System.Xml.XmlDocument", + "System.Xml.XmlSerializer", + "System.Xml.XPath", + "System.Xml.XPath.XDocument", + "System.Xml.XPath.XmlDocument", + "Microsoft.PowerShell.CoreCLR.AssemblyLoadContext" }; // Define the function pointer for the CLR entry point typedef HRESULT(STDAPICALLTYPE *GetCLRRuntimeHostFp)(REFIID riid, IUnknown** pUnk); // The name of the CoreCLR native runtime DLL. - static PCWSTR coreClrDll = L"CoreCLR.dll"; + static PCSTR coreClrDll = "CoreCLR.dll"; // The location where CoreCLR is expected to be installed. If CoreCLR.dll isn't // found in the same directory as the host, it will be looked for here. - static PCWSTR coreCLRInstallDirectory = L"%windir%\\system32\\DotNetCore\\v1.0\\"; + static PCSTR coreCLRInstallDirectory = "%windir%\\system32\\DotNetCore\\v1.0\\"; // The location where CoreCLR PowerShell Ext binaries are expected to be installed. - static PCWSTR coreCLRPowerShellExtInstallDirectory = L"%windir%\\system32\\CoreClrPowerShellExt\\v1.0\\"; + static PCSTR coreCLRPowerShellExtInstallDirectory = "%windir%\\system32\\CoreClrPowerShellExt\\v1.0\\"; // The default PowerShell install directory. This location may be overridden through a config file in %windir%\System32. - static PCWSTR powerShellInstallPath = L"%windir%\\System32\\WindowsPowerShell\\v1.0\\"; + static PCSTR powerShellInstallPath = "%windir%\\System32\\WindowsPowerShell\\v1.0\\"; unsigned int PwrshCommon::IdentifyHostDirectory( HostEnvironment& hostEnvironment) { // Discover the path to the exe's module (powershell.exe or wsmprovhost.exe). // For remoting, this is expected to be %windir%\system32 since that is the location of wsmprovhost.exe. - wchar_t hostPath[MAX_PATH]; - DWORD thisModuleLength = sysCalls->GetModuleFileNameW(sysCalls->GetModuleHandleW(NULL), hostPath, MAX_PATH); + char hostPath[MAX_PATH]; + DWORD thisModuleLength = sysCalls->GetModuleFileNameA(sysCalls->GetModuleHandleA(NULL), hostPath, MAX_PATH); if (0 == thisModuleLength) { @@ -865,76 +865,10 @@ namespace NativeMsh return EXIT_CODE_SUCCESS; } - // Attempts to load CoreCLR.dll from the specified directory. - // On success pins the dll, sets coreCLRDirectoryPath and returns the HMODULE. - // On failure returns NULL. - HMODULE PwrshCommon::TryLoadCoreCLR( - _In_ PCWSTR directoryPath) - { - std::wstring coreCLRPath(directoryPath); - coreCLRPath += coreClrDll; - - HMODULE result = sysCalls->LoadLibraryExW(coreCLRPath.c_str(), NULL, 0); - if (!result) - { - return NULL; - } - - // Pin the module - CoreCLR.dll does not support being unloaded. - HMODULE dummy_coreCLRModule; - if (!sysCalls->GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, coreCLRPath.c_str(), &dummy_coreCLRModule)) - { - return NULL; - } - - return result; - } - - unsigned int PwrshCommon::InitializeClr( - _In_ ClrHostWrapper* hostWrapper, - _In_ HMODULE coreClrModule) - { -#if CORECLR - // Get the function pointer for "GetCLRRuntimeHost" - GetCLRRuntimeHostFp getCLRRuntimeHostfp = (GetCLRRuntimeHostFp)sysCalls->GetProcAddress(coreClrModule, "GetCLRRuntimeHost"); - if (getCLRRuntimeHostfp == NULL) - { - return EXIT_CODE_INIT_FAILURE; - } - - // Get the CLR runtime host - ICLRRuntimeHost2* pHost = NULL; - HRESULT hResult = getCLRRuntimeHostfp(IID_ICLRRuntimeHost2, (IUnknown**)&pHost); - if (FAILED(hResult)) - { - return EXIT_CODE_INIT_FAILURE; - } - - hostWrapper->SetClrHost(pHost); - // Authenticate with either - // CORECLR_HOST_AUTHENTICATION_KEY or - // CORECLR_HOST_AUTHENTICATION_KEY_NONGEN - hResult = hostWrapper->Authenticate(CORECLR_HOST_AUTHENTICATION_KEY); - if (FAILED(hResult)) - { - return EXIT_CODE_INIT_FAILURE; - } - - hostWrapper->SetStartupFlags((STARTUP_FLAGS)(STARTUP_SINGLE_APPDOMAIN | STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN)); - - hResult = hostWrapper->Start(); - if (FAILED(hResult)) - { - return EXIT_CODE_INIT_FAILURE; - } -#endif - return EXIT_CODE_SUCCESS; - } - bool PwrshCommon::DoesAssemblyExist( - std::wstring& fileToTest) + std::string& fileToTest) { - FILE *file = sysCalls->_wfopen(fileToTest.c_str(), L"r"); + FILE *file = sysCalls->fopen(fileToTest.c_str(), "r"); // TODO: Use fopen_s? if (file != NULL) { sysCalls->fclose(file); @@ -945,15 +879,15 @@ namespace NativeMsh // This assumes that directoryPath already includes a trailing "\\" void PwrshCommon::ProbeAssembly( - _In_z_ PCWSTR directoryPath, - _In_z_ PCWSTR assemblyName, - std::wstring& result) + _In_z_ PCSTR directoryPath, + _In_z_ PCSTR assemblyName, + std::string& result) { - PCWSTR niExtension = L".ni.dll"; - PCWSTR ilExtension = L".dll"; + PCSTR niExtension = ".ni.dll"; + PCSTR ilExtension = ".dll"; // Test NI extension first because it is preferable to IL - std::wstring fileToTest(directoryPath); + std::string fileToTest(directoryPath); fileToTest += assemblyName; fileToTest += niExtension; if (DoesAssemblyExist(fileToTest)) { @@ -973,13 +907,13 @@ namespace NativeMsh // Returns the semicolon-separated list of paths to runtime dlls that are considered trusted. // Do not put powershell assemblies in the TPA list as it will cause 'Security Transparent V.S. Security Critical' error. void PwrshCommon::GetTrustedAssemblyList( - PCWSTR coreCLRDirectoryPath, - std::wstringstream& assemblyList, + PCSTR coreCLRDirectoryPath, + std::stringstream& assemblyList, bool& listEmpty) { - for (const wchar_t * &assembly : trustedAssemblies) + for (const char* &assembly : trustedAssemblies) { - std::wstring assemblyPath; + std::string assemblyPath; ProbeAssembly(coreCLRDirectoryPath, assembly, assemblyPath); if (assemblyPath.length() > 0) @@ -987,7 +921,7 @@ namespace NativeMsh if (listEmpty) listEmpty = false; else - assemblyList << L";"; + assemblyList << ";"; assemblyList << assemblyPath; } } @@ -1351,10 +1285,10 @@ namespace NativeMsh pwszRuntimeVersion, L"ConsoleHostAssemblyName", pwszConsoleHostAssemblyName); } - #if CORECLR unsigned int PwrshCommon::LaunchCoreCLR( ClrHostWrapper* hostWrapper, - HostEnvironment& hostEnvironment) + HostEnvironment& hostEnvironment, + PCSTR friendlyName) { unsigned int exitCode = this->IdentifyHostDirectory(hostEnvironment); if (EXIT_CODE_SUCCESS != exitCode) @@ -1364,130 +1298,80 @@ namespace NativeMsh } // Try to load from the well-known location. - wchar_t coreCLRInstallPath[MAX_PATH]; - exitCode = ::ExpandEnvironmentStringsW(coreCLRInstallDirectory, coreCLRInstallPath, MAX_PATH); + char coreCLRInstallPath[MAX_PATH]; + exitCode = ::ExpandEnvironmentStringsA(coreCLRInstallDirectory, coreCLRInstallPath, MAX_PATH); if (0 == exitCode || _countof(coreCLRInstallPath) <= exitCode) { this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError()); return EXIT_CODE_INIT_FAILURE; } - HMODULE coreClrModule = this->TryLoadCoreCLR(coreCLRInstallPath); - - if (coreClrModule) + HMODULE coreClrModule = hostWrapper->SetupWrapper(coreCLRInstallPath); + if (!coreClrModule) { - // Save the directory that CoreCLR was found in - WCHAR coreCLRDirectoryPath[MAX_PATH]; - DWORD modulePathLength = sysCalls->GetModuleFileNameW(coreClrModule, coreCLRDirectoryPath, MAX_PATH); + this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError()); + return EXIT_CODE_INIT_FAILURE; + } + + // Save the directory that CoreCLR was found in + char coreCLRDirectoryPath[MAX_PATH]; + DWORD modulePathLength = sysCalls->GetModuleFileNameA(coreClrModule, coreCLRDirectoryPath, MAX_PATH); - // Search for the last backslash and terminate it there to keep just the directory path with trailing slash - for (int lastBackslashIndex = modulePathLength - 1; lastBackslashIndex >= 0; lastBackslashIndex--) + // Search for the last backslash and terminate it there to keep just the directory path with trailing slash + for (int lastBackslashIndex = modulePathLength - 1; lastBackslashIndex >= 0; lastBackslashIndex--) + { + if (coreCLRDirectoryPath[lastBackslashIndex] == L'\\') { - if (coreCLRDirectoryPath[lastBackslashIndex] == L'\\') - { - coreCLRDirectoryPath[lastBackslashIndex + 1] = L'\0'; - break; - } + coreCLRDirectoryPath[lastBackslashIndex + 1] = L'\0'; + break; } - hostEnvironment.SetCoreCLRDirectoryPath(coreCLRDirectoryPath); - } - else - { - this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError()); - return EXIT_CODE_INIT_FAILURE; } + hostEnvironment.SetCoreCLRDirectoryPath(coreCLRDirectoryPath); - exitCode = this->InitializeClr(hostWrapper, coreClrModule); - if (EXIT_CODE_SUCCESS != exitCode) - { - this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError()); - return exitCode; - } - - hostEnvironment.SetCoreCLRModule(coreClrModule); - - return exitCode; - } - - unsigned int PwrshCommon::CreateAppDomain( - ClrHostWrapper* hostWrapper, - PCWSTR friendlyName, - HostEnvironment& hostEnvironment) - { - const int nMaxProps = 8; - LPCWSTR props[nMaxProps]; - LPCWSTR vals[nMaxProps]; - - if (!hostWrapper->IsInitialized()) - { - return EXIT_CODE_INIT_FAILURE; - } - - //PAL_LeaveHolder holder; - DWORD dwDomainFlags = 0; - dwDomainFlags = APPDOMAIN_SECURITY_DEFAULT; - dwDomainFlags |= APPDOMAIN_ENABLE_ASSEMBLY_LOADFILE; - dwDomainFlags |= APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT; - - // By default CoreCLR only allows platform neutral assembly to be run. To allow - // assemblies marked as platform specific, include this flag - dwDomainFlags |= APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS; - // Enable PInvoke - dwDomainFlags |= APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP; - // This will not tear down an application if a managed exception goes unhandled - dwDomainFlags |= APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS; - + const int nMaxProps = 8; + LPCSTR props[nMaxProps]; + LPCSTR vals[nMaxProps]; int nProps = 0; - props[nProps] = L"APPBASE"; - vals[nProps] = hostEnvironment.GetHostDirectoryPath(); - nProps++; // If I do not include my managed enload point dll in this list, I get a security error. - std::wstringstream assemblyList; + std::stringstream assemblyList; bool listEmpty = true; this->GetTrustedAssemblyList(hostEnvironment.GetCoreCLRDirectoryPath(), assemblyList, listEmpty); - wchar_t coreCLRPowerShellExtInstallPath[MAX_PATH]; - ::ExpandEnvironmentStringsW(coreCLRPowerShellExtInstallDirectory, coreCLRPowerShellExtInstallPath, MAX_PATH); + char coreCLRPowerShellExtInstallPath[MAX_PATH]; + ::ExpandEnvironmentStringsA(coreCLRPowerShellExtInstallDirectory, coreCLRPowerShellExtInstallPath, MAX_PATH); this->GetTrustedAssemblyList(coreCLRPowerShellExtInstallPath, assemblyList, listEmpty); - props[nProps] = L"TRUSTED_PLATFORM_ASSEMBLIES"; - std::wstring tempStr = assemblyList.str(); + props[nProps] = "TRUSTED_PLATFORM_ASSEMBLIES"; + std::string tempStr = assemblyList.str(); vals[nProps] = tempStr.c_str(); nProps++; props[nProps] = L"APP_PATHS"; - vals[nProps] = L""; + vals[nProps] = L""; // Used to be hostEnvironment.GetHostDirectoryPath() nProps++; props[nProps] = L"APP_NI_PATHS"; - vals[nProps] = L""; + vals[nProps] = L""; // Used to be hostEnvironment.GetHostDirectoryPath() nProps++; - // Create the customized AppDomainManager out of the SandboxHelper class - DWORD appDomainId = INVALID_APPDOMAIN_ID; - HRESULT hr = hostWrapper->CreateAppDomainWithManager( - friendlyName, - dwDomainFlags, - NULL, // AppDomainManager is no longer required now that we can use AssemblyLoadContext to access arbitrary assemblies from within SMA.dll - NULL, - nProps, - props, - vals, - &appDomainId); + int hr = hostWrapper->InitializeClr( + hostEnvironment.GetHostDirectoryPath(), + friendlyName, + nProps, + props, + vals); + if (FAILED(hr)) { - //LONG systemErrorCode = GetLastError(); - this->output->DisplayMessage(false, g_GETTING_DEFAULT_DOMAIN_FAILED, hr); - + this->output->DisplayMessage(false, g_STARTING_CLR_FAILED, GetLastError()); return EXIT_CODE_INIT_FAILURE; } - hostWrapper->SetAppDomainId(appDomainId); + return EXIT_CODE_SUCCESS; } - #else // !CORECLR - +#if !CORECLR // NOTE: // This must be ifdef'd out of the CoreCLR build because it uses .NET 1.0 // types that have been deprecated and removed from mscoree.h. @@ -1550,7 +1434,7 @@ namespace NativeMsh return exitCode; } - #endif // !CORECLR +#endif // !CORECLR #pragma prefast(pop) diff --git a/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt b/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt new file mode 100644 index 000000000..dc339562e --- /dev/null +++ b/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt @@ -0,0 +1,48 @@ +# +# 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 + # TODO: Fix this once the file is migrated from SD + # CssMainEntry.cpp) + MainEntry.cpp) + set(PWRSHEXE_WINDOWS_LIBS + onecore.lib) + set(powershell_definitions + _CONSOLE + CORECLR + ${common_pwrsh_definitions}) +else (BUILD_ONECORE) + # 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 + # ole32.lib + # oleaut32.lib + # uuid.lib + # user32.lib + MUILoad.lib + msxml6.lib + mscoree.lib + ) + set(powershell_definitions + _CONSOLE + ${common_pwrsh_definitions}) +endif (BUILD_ONECORE) + +add_executable(powershell + ${PWRSHEXE_WINDOWS_SOURCES}) + +set_target_properties(powershell PROPERTIES COMPILE_DEFINITIONS "${powershell_definitions}") +set_target_properties(powershell PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE") +set_target_properties(powershell PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE") +set_target_properties(powershell PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE") +set_target_properties(powershell PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE") + +target_link_libraries(powershell + ${PWRSHEXE_WINDOWS_LIBS}) + +#target_link_libraries(powershell LINK_PUBLIC pwrshcommon) +target_link_libraries(powershell pwrshcommon) diff --git a/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt b/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt new file mode 100644 index 000000000..817dceac2 --- /dev/null +++ b/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# Builds pwrshplugin.dll, the WinRM plugin for PowerShell remote hosting. +# +add_library(pwrshplugin + entrypoints.cpp + pwrshclrhost.cpp + pwrshpluginerrorcodes.mc + pwrshpluginerrorcodes.rc + pwrshplugin.def) + +if (BUILD_ONECORE) + # Libraries to use when creating this binary for Windows on OneCore-based SKUs + set(PWRSHPLUGIN_WINDOWS_LIBS + onecore.lib) + set(pwrshplugin_definitions ${common_pwrsh_definitions} CORECLR) +else (BUILD_ONECORE) + # Libraries to use when creating this binary for Windows on full SKUs + set(PWRSHPLUGIN_WINDOWS_LIBS + ntdll.lib + kernel32.lib + advapi32.lib + ole32.lib + MUILoad.lib + mscoree.lib + oleaut32.lib + uuid.lib + wsmsvc.lib) + set(pwrshplugin_definitions ${common_pwrsh_definitions}) +endif (BUILD_ONECORE) + +set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "${pwrshplugin_definitions}") + +target_link_libraries(pwrshplugin + ${PWRSHPLUGIN_WINDOWS_LIBS}) + +#target_link_libraries(pwrshplugin LINK_PUBLIC pwrshcommon) +target_link_libraries(pwrshplugin pwrshcommon) diff --git a/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.cpp b/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.cpp index db5a72c3d..533b0efe4 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.cpp +++ b/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.cpp @@ -40,9 +40,10 @@ typedef void (STDMETHODCALLTYPE *LoaderRunHelperFp)(LPCWSTR appPath); unsigned int PowerShellCoreClrWorker::LaunchClr( _In_ LPCWSTR wszMonadVersion, - _In_ LPCWSTR wszRuntimeVersion) + _In_ LPCWSTR wszRuntimeVersion, + _In_ LPCSTR friendlyName) { - return commonLib->LaunchCoreCLR(hostWrapper, hostEnvironment); + return commonLib->LaunchCoreCLR(hostWrapper, hostEnvironment, friendlyName); } unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs( @@ -50,23 +51,15 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs( _In_z_ wchar_t* wszMgdPlugInFileName, _Outptr_result_maybenull_ PlugInException** pPluginException) { - unsigned int exitCode = EXIT_CODE_SUCCESS; *pPluginException = NULL; - exitCode = commonLib->CreateAppDomain(hostWrapper, L"PwrshPlugin", hostEnvironment); - if (EXIT_CODE_SUCCESS != exitCode) - { - return exitCode; - } - // Set the powershell custom assembly loader to be the default LoaderRunHelperFp initDelegate = NULL; HRESULT hr = hostWrapper->CreateDelegate( - hostWrapper->GetAppDomainId(), - L"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", - L"System.Management.Automation.PowerShellAssemblyLoadContextInitializer", - L"SetPowerShellAssemblyLoadContext", + "Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", + "System.Management.Automation.PowerShellAssemblyLoadContextInitializer", + "SetPowerShellAssemblyLoadContext", (INT_PTR*)&initDelegate); if (FAILED(hr)) @@ -75,7 +68,7 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs( } else { - initDelegate(hostEnvironment.GetHostDirectoryPath()); + initDelegate(hostEnvironment.GetHostDirectoryPathW()); } // Call into powershell entry point @@ -84,14 +77,12 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs( // Create the function pointer for the managed entry point // It must be targeted at a static method in the managed code. hr = hostWrapper->CreateDelegate( - hostWrapper->GetAppDomainId(), - L"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", - L"System.Management.Automation.Remoting.WSManPluginManagedEntryWrapper", - L"InitPlugin", + "System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", + "System.Management.Automation.Remoting.WSManPluginManagedEntryWrapper", + "InitPlugin", (INT_PTR*)&entryPointDelegate); if (FAILED(hr)) { - //LONG systemErrorCode = GetLastError(); output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr); return EXIT_CODE_INIT_FAILURE; @@ -103,7 +94,7 @@ unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs( PowerShellCoreClrWorker::PowerShellCoreClrWorker() : systemCalls(new WinSystemCallFacade()), - hostWrapper(new ICLRRuntimeHost2Wrapper()), + hostWrapper(new CoreClrHostingApiWrapper()), output(new PwrshPluginOutputDefault()), commonLib(new PwrshCommon()) { @@ -133,7 +124,7 @@ PowerShellCoreClrWorker::PowerShellCoreClrWorker( { // Instantiate it even if one is not provided to guarantee that it will // always be non-NULL during execution. - hostWrapper = new ICLRRuntimeHost2Wrapper(); + hostWrapper = new CoreClrHostingApiWrapper(); } if (NULL == commonLib) @@ -240,7 +231,8 @@ PowerShellClrWorker::~PowerShellClrWorker() unsigned int PowerShellClrWorker::LaunchClr( _In_ LPCWSTR wszMonadVersion, - _In_ LPCWSTR wszRuntimeVersion) + _In_ LPCWSTR wszRuntimeVersion, + _In_ LPCWSTR friendlyName) { return commonLib.LaunchCLR(wszMonadVersion, wszRuntimeVersion, &pHost); } @@ -310,7 +302,8 @@ unsigned int PowerShellClrWorker::LoadWorkerCallbackPtrs( unsigned int PowerShellClrManagedWorker::LaunchClr( _In_ LPCWSTR wszMonadVersion, - _In_ LPCWSTR wszRuntimeVersion) + _In_ LPCWSTR wszRuntimeVersion, + _In_ LPCWSTR friendlyName) { return commonLib.LaunchCLR(wszMonadVersion, wszRuntimeVersion, &pHost); } diff --git a/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.h b/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.h index 50ea8258e..82852c4e4 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.h +++ b/src/powershell-native/nativemsh/pwrshplugin/pwrshclrhost.h @@ -46,7 +46,8 @@ public: virtual unsigned int LaunchClr( _In_ LPCWSTR wszMonadVersion, - _In_ LPCWSTR wszRuntimeVersion) = 0; + _In_ LPCWSTR wszRuntimeVersion, + _In_ LPCWSTR friendlyName) = 0; virtual unsigned int LoadWorkerCallbackPtrs( _In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs, @@ -88,7 +89,8 @@ public: // virtual unsigned int LaunchClr( _In_ LPCWSTR wszMonadVersion, - _In_ LPCWSTR wszRuntimeVersion); + _In_ LPCWSTR wszRuntimeVersion, + _In_ LPCWSTR friendlyName); virtual unsigned int LoadWorkerCallbackPtrs( _In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs, @@ -114,7 +116,8 @@ public: // virtual unsigned int LaunchClr( _In_ LPCWSTR wszMonadVersion, - _In_ LPCWSTR wszRuntimeVersion); + _In_ LPCWSTR wszRuntimeVersion, + _In_ LPCWSTR friendlyName); virtual unsigned int LoadWorkerCallbackPtrs( _In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs, diff --git a/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h b/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h index ab7c6d267..6a45f248b 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h +++ b/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h @@ -714,7 +714,7 @@ private: break; } - exitCode = powerShellClrHost->LaunchClr(wszMonadVersion, wszTempCLRVersion); + exitCode = powerShellClrHost->LaunchClr(wszMonadVersion, wszTempCLRVersion, L"PwrshPlugin"); if (EXIT_CODE_SUCCESS != exitCode) { PWSTR msg = NULL; @@ -1098,4 +1098,4 @@ void WINAPI PerformWSManPluginReportCompletion() // - pluginContext MUST be the same context that plugin provided to the WSManPluginStartup method // - flags are reserved, so 0 WSManPluginReportCompletion(g_pPluginContext, 0); -} \ No newline at end of file +}