Copy pwrshplugin native code from [SD:715912]

commit 77eda78
This commit is contained in:
PowerShell Team
2016-06-17 14:10:17 -07:00
committed by Sergei Vorobev
parent d24bf35c22
commit 71835813aa
11 changed files with 2806 additions and 0 deletions
@@ -0,0 +1,746 @@
// ----------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2007.
//
// Contents: Entry points for PowerShell plugin used to host powershell
// in a WSMan service.
// ----------------------------------------------------------------------
#include "pwrshplugin.h"
#include <winsqm.h>
#include "common/WindowsSqmDataID.h"
#include "common/winrmsqm.h"
#if !CORECLR
#include <muiload.h>
#endif
HINSTANCE g_hResourceInstance = 0; // TODO: Where is this freed? FreeMUILibrary for nonCoreClr and FreeLibrary for CoreCLR
LPCWSTR g_MAIN_BINARY_NAME = L"pwrshplugin.dll";
typedef VOID (NTAPI *PFN_WinSqmSetDWORD)(
__in_opt HSESSION hSession,
__in DWORD dwDatapointId,
__in DWORD dwDatapointValue
);
// gets the error message from the resources section of the current module.
// the caller should free pwszErrorMessage using LocalFree().
// returns: If the function succeeds the return value is the number of CHARs stored int the output
// buffer, excluding the terminating null character. If the function failes the return value is zero.
#pragma prefast(push)
#pragma prefast (disable: 28196)
DWORD GetFormattedErrorMessage(__deref_out PWSTR * pwszErrorMessage, DWORD dwMessageId, va_list* arguments)
#pragma prefast(pop)
{
DWORD dwLength = 0;
do
{
*pwszErrorMessage = NULL;
if (NULL == g_hResourceInstance)
{
#ifdef CORECLR
g_hResourceInstance = LoadLibraryEx(g_MAIN_BINARY_NAME, 0, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
#else
g_hResourceInstance = LoadMUILibraryW(g_MAIN_BINARY_NAME, MUI_LANGUAGE_NAME, 0);
#endif
}
LPWSTR wszSystemErrorMessage = NULL;
//string function
dwLength = FormatMessageW(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
g_hResourceInstance,
dwMessageId,
0,
(LPWSTR)&wszSystemErrorMessage,
0,
arguments);
if (dwLength > 0)
{
*pwszErrorMessage = new WCHAR[dwLength + 1];
if (NULL != *pwszErrorMessage)
{
//string function
if (FAILED(StringCchCopyW(*pwszErrorMessage, dwLength + 1, wszSystemErrorMessage)))
{
dwLength = 0;
delete [] (*pwszErrorMessage);
*pwszErrorMessage = NULL;
}
}
LocalFree(wszSystemErrorMessage);
}
}while(false);
return dwLength;
}
DWORD GetFormattedErrorMessage(__deref_out PZPWSTR pwszErrorMessage, DWORD dwMessageId, ...)
{
DWORD result = 0;
va_list args;
va_start(args, dwMessageId);
result = GetFormattedErrorMessage(pwszErrorMessage, dwMessageId, &args);
va_end(args);
return result;
}
#pragma prefast(push)
#pragma prefast (disable: 6101)
#pragma prefast (disable: 6054)
unsigned int ConstructPowerShellVersion(int iPSMajorVersion,
int iPSMinorVersion,
__deref_out_opt PWSTR *pwszMonadVersion)
{
unsigned int exitCode = EXIT_CODE_SUCCESS;
wchar_t* wszMajorVersion = new wchar_t[10];
wchar_t* wszMinorVersion = new wchar_t[10];
do
{
if ((NULL == pwszMonadVersion) || ( 0 > iPSMajorVersion) || (0 > iPSMinorVersion))
{
exitCode = EXIT_CODE_BAD_INPUT;
break;
}
if (0 != _itow_s(iPSMajorVersion, wszMajorVersion, 10, 10))
{
exitCode = EXIT_CODE_BAD_INPUT;
break;
}
if (0 != _itow_s(iPSMinorVersion, wszMinorVersion, 10, 10))
{
exitCode = EXIT_CODE_BAD_INPUT;
break;
}
size_t iMajorLength;
size_t iMinorLength;
if (SUCCEEDED(StringCchLength(wszMajorVersion, 10, &iMajorLength)) &&
SUCCEEDED(StringCchLength(wszMinorVersion, 10, &iMinorLength)))
{
size_t totalLength = iMajorLength + iMinorLength + 2;
*pwszMonadVersion = new wchar_t[totalLength];
if (NULL == *pwszMonadVersion)
{
exitCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
*pwszMonadVersion[0] = L'\0';
if (SUCCEEDED(StringCchCopyW(*pwszMonadVersion, totalLength, wszMajorVersion)) &&
SUCCEEDED(StringCchCatW(*pwszMonadVersion, totalLength, L".")) &&
SUCCEEDED(StringCchCatW(*pwszMonadVersion, totalLength, wszMinorVersion)))
{
break;
}
else
{
exitCode = EXIT_CODE_BAD_INPUT;
break;
}
}
else
{
exitCode = EXIT_CODE_BAD_INPUT;
break;
}
}while(false);
if (NULL != wszMajorVersion)
{
delete[] wszMajorVersion;
}
if (NULL != wszMinorVersion)
{
delete[] wszMinorVersion;
}
return exitCode;
}
#pragma prefast(pop)
static PwrshCommon sPwrshCommon;
// Gets the CLR Version for a given PowerShell Version. PowerShell Version is
// supplied with 2 paramaters iPSMajorVersion (PowerShell major version) and
// iPSMinorVersion (PowerShell minor version). The CLR version is returned through
// pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion.
// returns: 0 on success, non-zero on failure.
_Success_(return == 0) //EXIT_CODE_SUCCESS
unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
int iPSMinorVersion,
size_t runtimeVersionLength,
__inout_ecount_part(runtimeVersionLength, *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion,
__out_ecount(1) size_t* pRuntimeVersionLength)
{
unsigned int exitCode = EXIT_CODE_SUCCESS;
wchar_t * wszMonadVersion = NULL;
wchar_t* wszConsoleHostAssemblyName = NULL;
wchar_t* wszTempVersion = NULL;
size_t tempVersionLength = 0;
if (NULL != pRuntimeVersionLength)
{
// Initialize the output size to zero prior to attempting the copy
*pRuntimeVersionLength = 0;
}
do
{
int requestedMonadMajorVersion = iPSMajorVersion;
int requestedMonadMinorVersion = iPSMinorVersion;
// For GetRegistryInfo call, monadMajorVersion is used to calculate the version key in registry.
// For PowerShell V2, version key in registry is 1.
if (2 == requestedMonadMajorVersion)
{
requestedMonadMajorVersion = 1;
}
// For PowerShell 3, 4 and 5, the registry is 3.
if ((requestedMonadMajorVersion == 4) || (requestedMonadMajorVersion == 5))
{
requestedMonadMajorVersion = 3;
}
exitCode = ConstructPowerShellVersion(iPSMajorVersion, iPSMinorVersion, &wszMonadVersion);
if (EXIT_CODE_SUCCESS != exitCode)
{
break;
}
exitCode = sPwrshCommon.GetRegistryInfo(
&wszMonadVersion,
&requestedMonadMajorVersion,
requestedMonadMinorVersion,
&wszTempVersion,
&wszConsoleHostAssemblyName);
if (EXIT_CODE_SUCCESS != exitCode)
{
break;
}
HRESULT hResult = StringCchLength(wszTempVersion, STRSAFE_MAX_CCH, &tempVersionLength);
if (FAILED(hResult))
{
exitCode = EXIT_CODE_READ_REGISTRY_FAILURE;
break;
}
if (NULL != pwszRuntimeVersion)
{
// +1 for the '\0'
if (runtimeVersionLength < (tempVersionLength + 1))
{
exitCode = EXIT_CODE_BAD_INPUT;
break;
}
hResult = StringCchCopy(pwszRuntimeVersion, tempVersionLength + 1, wszTempVersion);
if (FAILED(hResult))
{
exitCode = EXIT_CODE_READ_REGISTRY_FAILURE;
break;
}
if (NULL != pRuntimeVersionLength)
{
// OACR warning 26030: Postcondition violation that could result in overflow
// pRuntimeVersionLength should only be populated if the copy operation succeeded
// +1 for the '\0'
*pRuntimeVersionLength = tempVersionLength + 1;
}
}
}while(false);
if (NULL != wszMonadVersion)
{
delete [] wszMonadVersion;
wszMonadVersion = NULL;
}
if (NULL != wszTempVersion)
{
delete [] wszTempVersion;
wszTempVersion = NULL;
}
if (NULL != wszConsoleHostAssemblyName)
{
delete [] wszConsoleHostAssemblyName;
wszConsoleHostAssemblyName = NULL;
}
return exitCode;
}
DWORD ReportOperationComplete(WSMAN_PLUGIN_REQUEST *requestDetails, DWORD errorCode)
{
if (NULL == requestDetails)
{
// cannot report if requestDetails is NULL.
return EXIT_CODE_SUCCESS;
}
DWORD result = EXIT_CODE_SUCCESS;
PWSTR pwszErrorMessage = NULL;
GetFormattedErrorMessage(&pwszErrorMessage, errorCode);
result = WSManPluginOperationComplete(requestDetails, 0, errorCode, pwszErrorMessage);
if (NULL != pwszErrorMessage)
{
delete[] pwszErrorMessage;
}
return result;
}
// -----------------------------------------------------------------------------
// Each plug-in needs to support the Startup callback. A plug-in may be
// initialized more than once within the same process, but only once per
// applicationIdentification.
// -----------------------------------------------------------------------------
DWORD WINAPI WSManPluginStartup(
__in DWORD flags,
__in PCWSTR applicationIdentification,
__in_opt PCWSTR extraInfo,
__out PVOID *pluginContext
)
{
//
#ifdef REMOTINGDEBUG
// This loop is added to assist debugging server.
// Attach a debugger to the server and set this variable to true
// from the debugger.
bool isDebuggerAttached = false;
do
{
Sleep(1);
}while(!isDebuggerAttached);
#endif
PwrshPlugIn* result = NULL;
try
{
*pluginContext = NULL;
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(extraInfo);
PwrshPlugIn* result = pluginMediator->CreatePwrshPlugIn(applicationIdentification, extraInfo);
*pluginContext = (PVOID)result;
// Using global SQM session
// WinSQMSetDWORD is not available on Vista
HMODULE hModule;
PFN_WinSqmSetDWORD pfnWinSqmSetDWORD;
hModule = GetModuleHandleW(L"ntdll");
if (hModule)
{
pfnWinSqmSetDWORD = (PFN_WinSqmSetDWORD) GetProcAddress(hModule, "WinSqmSetDWORD");
if (pfnWinSqmSetDWORD)
{
pfnWinSqmSetDWORD(
NULL,
DATAID_WINRMREMOTEENABLED,
WINRM_SQM_DATA_REMOTEENABLED
);
}
}
return NO_ERROR;
}
catch(PlugInException* e)
{
DWORD errorId = g_CREATION_FAILED;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
if (NULL != result)
{
delete result;
}
return errorId;
}
}
// ------------------------------------------------------------------------------------
//The WSManPluginShutdown method is called after all operations have been cancelled and
//right before the DLL is unloaded. The DLL entry point name must be WSManPluginShutdown.
//This method has an important purpose of making sure all plug-in threads are shut down
//before this method returns. If the plug-in only handles synchronous operations and all
//threads report a cancellation result before they return then this method does not have to
//do anything too complex other than plug-in cleanup. However for an asynchronous plug-in,
//any threads that are used to process the plug-in threads, including the ones that just reported
//the cancellation for all operations need to completely shutdown. Not doing this will cause
//potential crashes in the DLL because code may be executed after the DLL is unloaded.
// ------------------------------------------------------------------------------------
// reason: If this is a system shutdown this will be WSMAN_PLUGIN_SHUTDOWN_SYSTEM.
// For WSMan service shutdown this will be WSMAN_PLUGIN_SHUTDOWN_SERVICE. For an IIS host
//shutdown this will be WSMAN_PLUGIN_SHUTDOWN_IISHOST.
DWORD WINAPI WSManPluginShutdown(
__in PVOID pluginContext,
__in DWORD flags,
__in DWORD reason
)
{
if (NULL == pluginContext)
{
return g_NULL_PLUGIN_CONTEXT;
}
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->Shutdown(flags, reason);
}
catch(PlugInException* e)
{
// ignore plugin exceptions during shutdown.
if (NULL != e)
{
delete e;
}
}
// free resources occupied by this plugin..
// WSMan frees shell/command resources before calling
// plugin shutdown.
PwrshPlugIn* plugIn = reinterpret_cast<PwrshPlugIn*>(pluginContext);
delete plugIn;
return NO_ERROR;
}
#ifndef WIN32_FROM_HRESULT
#define WIN32_FROM_HRESULT(hr) (HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : hr)
#endif
// -----------------------------------------------------------------------------
// A plug-in that supports the Shell operations needs to implement this callback
// to allow commands to be created and to allow data to be streamed into either
// a shell or command. The plug-in must call WSManPluginReportContext to
// report the shell context. Once the shell is completed or when it is closed
// via the operationClosed boolean value or operationClosedHandle in the
// requestDetails the plug-in needs to call WSManPluginOperationComplete.
// The shell is active until this time.
// -----------------------------------------------------------------------------
VOID WINAPI WSManPluginShell(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in_opt WSMAN_SHELL_STARTUP_INFO *startupInfo,
__in_opt WSMAN_DATA *inboundShellInformation
)
{
PwrshPlugIn* plugIn = (NULL != pluginContext) ? (PwrshPlugIn*)pluginContext : NULL;
bool comInitialized = false;
if (NULL == plugIn)
{
ReportOperationComplete(requestDetails, g_INVALID_PLUGIN_CONTEXT);
return;
}
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
HRESULT hr = CoInitializeEx(0,COINIT_MULTITHREADED);
if (hr == S_OK)
{
comInitialized = true;
}
else if (hr == S_FALSE)
{
CoUninitialize();
comInitialized = false;
}
else if (hr == RPC_E_CHANGED_MODE)
{
comInitialized = false; //ignore
}
else
{
ReportOperationComplete(requestDetails, WIN32_FROM_HRESULT(hr));
return;
}
pluginMediator->CreateShell(plugIn, requestDetails, flags, startupInfo, inboundShellInformation);
if (comInitialized)
{
CoUninitialize();
comInitialized = false;
}
}
catch(PlugInException* e)
{
DWORD errorId = g_CREATION_FAILED;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
if (comInitialized)
{
CoUninitialize();
comInitialized = false;
}
ReportOperationComplete(requestDetails, errorId);
}
}
// -----------------------------------------------------------------------------
// WS-Man calls the WSMAN_PLUGIN_RELEASE_SHELL_CONTEXT entry point during shell
// shutdown when it is safe to delete the plug-in shell context. Any context
// reported through WSManPluginReportContext may not be deleted until the
// corresponding release function has been called. Failure to follow the contract
// will result in errors being generated.
// -----------------------------------------------------------------------------
VOID WINAPI WSManPluginReleaseShellContext(__in PVOID shellContext)
{
if ((NULL == shellContext))
{
return;
}
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->ReleaseShell(shellContext);
}
catch(PlugInException* e)
{
// ignore plugin exceptions.
if (NULL != e)
{
delete e;
}
}
}
//
// -----------------------------------------------------------------------------
// A plug-in that supports the Shell operations and needs to create commands
// that are associated with the shell needs to implement this callback.
// The plug-in must call WSManPluginReportContext to
// report the command context. Once the command is completed or when it is closed
// via the operationClosed boolean value or operationClosedHandle in the
// requestDetails the plug-in needs to call WSManPluginOperationComplete.
// The command is active until this time.
// -----------------------------------------------------------------------------
VOID WINAPI WSManPluginCommand(
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in PCWSTR commandLine,
__in_opt WSMAN_COMMAND_ARG_SET *arguments
)
{
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->CreateCommand(requestDetails, flags, shellContext, commandLine, arguments);
}
catch(PlugInException* e)
{
DWORD errorId = g_CREATION_FAILED;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
ReportOperationComplete(requestDetails, errorId);
}
}
// ---------------------------------------------------------------------------------
// WS-Man calls the WSMAN_PLUGIN_RELEASE_COMMAND_CONTEXT entry point during command
// shutdown when it is safe to delete the plug-in shell context. Any context
// reported through WSManPluginReportContext may not be deleted until the
// corresponding release function has been called. Failure to follow the contract
// will result in errors being generated.
// ---------------------------------------------------------------------------------
VOID WINAPI WSManPluginReleaseCommandContext(
__in PVOID shellContext,
__in PVOID commandContext
)
{
if ((NULL == shellContext) || (NULL == commandContext))
{
return;
}
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->ReleaseCommand(shellContext, commandContext);
}
catch(PlugInException* e)
{
// ignore plugin exceptions.
if (NULL != e)
{
delete e;
}
}
}
// -----------------------------------------------------------------------------
// A plug-in receives an inbound data stream to either the shell or command
// via this callback. Each piece of data causes the callback to be called once.
// For each piece of data the plug-in calls WSManPluginResultComplete to
// acknowledge receipt and to allow the next piece of data to be delivered.
// -----------------------------------------------------------------------------
VOID WINAPI WSManPluginSend(
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in PCWSTR stream,
__in WSMAN_DATA *inboundData
)
{
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->SendOneItemToShellOrCommand(requestDetails, flags, shellContext, commandContext, stream, inboundData);
}
catch(PlugInException* e)
{
DWORD errorId = g_INVALID_PLUGIN_CONTEXT;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
ReportOperationComplete(requestDetails, errorId);
}
}
// -----------------------------------------------------------------------------
// A plug-in sends an outbound data stream from either the shell or command
// via this callback. This API is called when an inbound request from a client
// is received. This callback may be called against the shell and/or command
// based on the client request. Each piece of data that needs to be sent back
// to the client is done so through the WSManPluginReceiveResult API. Once
// all data has been send, when the stream is terminated via some internal means,
// or if the receive call is cancelled through the operationClosed boolean
// value or operationClosedHandle, the plug-in needs to call
// WSManPluginResultComplete. The operation is marked as active until this
// time.
// -----------------------------------------------------------------------------
VOID WINAPI WSManPluginReceive(
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in_opt WSMAN_STREAM_ID_SET *streamSet
)
{
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->EnableShellOrCommandToSendDataToClient(requestDetails, flags, shellContext, commandContext, streamSet);
}
catch(PlugInException* e)
{
DWORD errorId = g_INVALID_PLUGIN_CONTEXT;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
ReportOperationComplete(requestDetails, errorId);
}
}
// -----------------------------------------------------------------------------
// A plug-in receives an inbound signal to either the shell or command
// via this callback. Each signal causes the callback to be called once.
// For each callthe plug-in calls WSManPluginResultComplete to
// acknowledge receipt and to allow the next signal to be received.
// A signal can cause the shell or command to be terminated, so the result
// of this callback may be many completion calls for the Signal, Receive, Command
// and Shell operations.
// -----------------------------------------------------------------------------
VOID WINAPI WSManPluginSignal(
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in PCWSTR code)
{
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->SignalShellOrCmd(requestDetails, flags, shellContext, commandContext, code);
}
catch(PlugInException* e)
{
DWORD errorId = g_INVALID_PLUGIN_CONTEXT;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
ReportOperationComplete(requestDetails, errorId);
}
}
VOID WINAPI WSManPluginConnect(
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in_opt WSMAN_DATA *inboundConnectInformation)
{
try
{
PwrshPlugInMediator* pluginMediator = PwrshPlugInMediator::GetPwrshPlugInMediator(NULL);
pluginMediator->ExecuteConnectToShellOrCommand(requestDetails, flags, shellContext, commandContext, inboundConnectInformation);
}
catch(PlugInException* e)
{
DWORD errorId = g_INVALID_PLUGIN_CONTEXT;
if (NULL != e)
{
errorId = e->dwMessageId;
delete e;
}
ReportOperationComplete(requestDetails, errorId);
}
}
@@ -0,0 +1,18 @@
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2007.
//
// Contents: Headers used by pwrshplugin.
// pwrshplugin is totally unmanaged.
// ----------------------------------------------------------------------
#pragma once
#include <windows.h>
#include <wchar.h>
#include "pwrshpluginerrorcodes.h"
const int EXIT_CODE_BAD_INPUT = 100;
extern DWORD GetFormattedErrorMessage(__deref_out PWSTR * pwszErrorMessage, DWORD dwMessageId, ...);
extern unsigned int ConstructPowerShellVersion(int iPSMajorVersion, int iPSMinorVersion, __deref_out_opt PWSTR *pwszMonadVersion);
@@ -0,0 +1,472 @@
// ----------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2014.
//
// Contents: Source code for abstraction of CLR and worker differences between PowerShell versions.
// pwrshplugin is totally unmanaged.
// ----------------------------------------------------------------------
#pragma once
#include "pwrshclrhost.h"
#include "NativeMsh.h"
#include "entrypoints.h"
#include "WinSystemCallFacade.h"
#if !CORECLR
// include the tlb for mscorlib for access to the default AppDomain through COM Interop
#import <mscorlib.tlb> raw_interfaces_only high_property_prefixes("_get","_put","_putref")\
rename("ReportEvent", "CLRReportEvent")
using namespace mscorlib;
#endif
using namespace NativeMsh;
// Init function calls are handled internally here within the context of the mediator singleton
typedef void (WINAPI *InitPluginFuncPtr)(); // Original PS init
typedef DWORD (WINAPI *InitPluginWkrPtrsFuncPtr)(__out PwrshPluginWkr_Ptrs* wkrPtrs); // Updated PS init
#ifdef CORECLR
// Define the function pointer for the powershell entry point.
typedef int (STDMETHODCALLTYPE *MonadRunHelperFp)(int length, LPCWSTR* commands);
// Define the function pointer for AssemblyLoadContext initializer.
typedef void (STDMETHODCALLTYPE *LoaderRunHelperFp)(LPCWSTR appPath);
unsigned int PowerShellCoreClrWorker::LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion)
{
return commonLib->LaunchCoreCLR(hostWrapper, hostEnvironment);
}
unsigned int PowerShellCoreClrWorker::LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ wchar_t* wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException)
{
unsigned int exitCode = EXIT_CODE_SUCCESS;
*pPluginException = NULL;
exitCode = commonLib->CreateAppDomain(hostWrapper, L"PwrshPlugin", hostEnvironment);
if (EXIT_CODE_SUCCESS != exitCode)
{
return exitCode;
}
// Set the powershell custom assembly loader to be the default
LoaderRunHelperFp initDelegate = NULL;
HRESULT hr = hostWrapper->CreateDelegate(
hostWrapper->GetAppDomainId(),
L"Microsoft.PowerShell.CoreCLR.AssemblyLoadContext, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
L"System.Management.Automation.PowerShellAssemblyLoadContextInitializer",
L"SetPowerShellAssemblyLoadContext",
(INT_PTR*)&initDelegate);
if (FAILED(hr))
{
output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr);
}
else
{
initDelegate(hostEnvironment.GetHostDirectoryPath());
}
// Call into powershell entry point
InitPluginWkrPtrsFuncPtr entryPointDelegate = NULL;
// Create the function pointer for the managed entry point
// It must be targeted at a static method in the managed code.
hr = hostWrapper->CreateDelegate(
hostWrapper->GetAppDomainId(),
L"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
L"System.Management.Automation.Remoting.WSManPluginManagedEntryWrapper",
L"InitPlugin",
(INT_PTR*)&entryPointDelegate);
if (FAILED(hr))
{
//LONG systemErrorCode = GetLastError();
output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr);
return EXIT_CODE_INIT_FAILURE;
}
// Passes empty pointer structure to the function, expects a filled struct if successful
return entryPointDelegate(workerCallbackPtrs);
}
PowerShellCoreClrWorker::PowerShellCoreClrWorker()
: systemCalls(new WinSystemCallFacade()),
hostWrapper(new ICLRRuntimeHost2Wrapper()),
output(new PwrshPluginOutputDefault()),
commonLib(new PwrshCommon())
{
}
//
// sysCalls is expected to be new'd by the caller.
// It will be freed in PowerShellCoreClrWorker's destructor.
//
PowerShellCoreClrWorker::PowerShellCoreClrWorker(
SystemCallFacade* sysCalls,
ClrHostWrapper* hstWrp,
PwrshCommon* cmnLib)
: systemCalls(sysCalls),
hostWrapper(hstWrp),
output(new PwrshPluginOutputDefault()),
commonLib(cmnLib)
{
if (NULL == systemCalls)
{
// Instantiate it even if one is not provided to guarantee that it will
// always be non-NULL during execution.
systemCalls = new WinSystemCallFacade();
}
if (NULL == hostWrapper)
{
// Instantiate it even if one is not provided to guarantee that it will
// always be non-NULL during execution.
hostWrapper = new ICLRRuntimeHost2Wrapper();
}
if (NULL == commonLib)
{
commonLib = new PwrshCommon(new PwrshPluginOutputDefault(), new WinSystemCallFacade());
}
}
PowerShellCoreClrWorker::~PowerShellCoreClrWorker()
{
unsigned int exitCode = hostWrapper->CleanUpHostWrapper();
if (EXIT_CODE_SUCCESS != exitCode)
{
output->DisplayMessage(false, exitCode);
}
if (systemCalls)
{
delete systemCalls;
systemCalls = NULL;
}
if (hostWrapper)
{
delete hostWrapper;
hostWrapper = NULL;
}
if (output)
{
delete output;
output = NULL;
}
if (commonLib)
{
delete commonLib;
commonLib = NULL;
}
}
#else // !CORECLR
PowerShellClrWorker::PowerShellClrWorker() :
pHost(NULL),
hManagedPluginModule(NULL),
systemCalls(new WinSystemCallFacade()),
g_INIT_PLUGIN("InitPlugin"),
g_SHUTDOWN_PLUGIN("ShutdownPlugin"),
g_MANAGED_PLUGIN_CREATE_SHELL("WSManPluginShell"),
g_MANAGED_PLUGIN_RELEASE_SHELL("WSManPluginReleaseShellContext"),
g_MANAGED_PLUGIN_CREATE_COMMAND("WSManPluginCommand"),
g_MANAGED_PLUGIN_RELEASE_COMMAND("WSManPluginReleaseCommandContext"),
g_MANAGED_PLUGIN_SEND("WSManPluginSend"),
g_MANAGED_PLUGIN_RECEIVE("WSManPluginReceive"),
g_MANAGED_PLUGIN_SIGNAL("WSManPluginSignal"),
g_MANAGED_PLUGIN_CONNECT("WSManPluginConnect"),
output(new PwrshPluginOutputDefault())
{}
PowerShellClrWorker::PowerShellClrWorker(
SystemCallFacade* sysCalls)
: pHost(NULL),
hManagedPluginModule(NULL),
systemCalls(sysCalls),
g_INIT_PLUGIN("InitPlugin"),
g_SHUTDOWN_PLUGIN("ShutdownPlugin"),
g_MANAGED_PLUGIN_CREATE_SHELL("WSManPluginShell"),
g_MANAGED_PLUGIN_RELEASE_SHELL("WSManPluginReleaseShellContext"),
g_MANAGED_PLUGIN_CREATE_COMMAND("WSManPluginCommand"),
g_MANAGED_PLUGIN_RELEASE_COMMAND("WSManPluginReleaseCommandContext"),
g_MANAGED_PLUGIN_SEND("WSManPluginSend"),
g_MANAGED_PLUGIN_RECEIVE("WSManPluginReceive"),
g_MANAGED_PLUGIN_SIGNAL("WSManPluginSignal"),
g_MANAGED_PLUGIN_CONNECT("WSManPluginConnect"),
output(new PwrshPluginOutputDefault())
{
if (NULL == systemCalls)
{
systemCalls = new WinSystemCallFacade();
}
}
PowerShellClrWorker::~PowerShellClrWorker()
{
if (NULL != hManagedPluginModule)
{
FreeLibrary(hManagedPluginModule);
hManagedPluginModule = NULL;
}
if (output)
{
delete output;
output = NULL;
}
if (systemCalls)
{
delete systemCalls;
systemCalls = NULL;
}
}
unsigned int PowerShellClrWorker::LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion)
{
return commonLib.LaunchCLR(wszMonadVersion, wszRuntimeVersion, &pHost);
}
unsigned int PowerShellClrWorker::LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ wchar_t* wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException)
{
*pPluginException = NULL;
#pragma prefast(push)
#pragma prefast (disable: 28752)
if (wszMgdPlugInFileName)
{
hManagedPluginModule = systemCalls->LoadLibraryExW(wszMgdPlugInFileName, NULL, 0);
}
#pragma prefast(pop)
unsigned int exitCode = EXIT_CODE_SUCCESS;
if (NULL == hManagedPluginModule)
{
// Get Extended error information.. to know why load failed.
PWSTR msg = NULL;
exitCode = g_MANAGED_PLUGIN_LOAD_FAILED;
commonLib.GetSystemErrorMessage(GetLastError(), &msg);
*pPluginException = new PlugInException(exitCode, msg);
return exitCode;
}
// Now get the proc address for all the plugin API.
// Init is handled differently because it is not used in the updated
// worker module.
InitPluginFuncPtr hInitPluginMethodAddress = (InitPluginFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_INIT_PLUGIN);
// This is not strictly necessary (they can be directly assigned), but I am doing this
// to keep all the code paths common
workerCallbackPtrs->shutdownPluginFuncPtr = (ShutdownPluginFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_SHUTDOWN_PLUGIN);
workerCallbackPtrs->wsManPluginShellFuncPtr = (WSManPluginShellFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_CREATE_SHELL);
workerCallbackPtrs->wsManPluginReleaseShellContextFuncPtr = (WSManPluginReleaseShellContextFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_RELEASE_SHELL);
workerCallbackPtrs->wsManPluginCommandFuncPtr = (WSManPluginCommandFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_CREATE_COMMAND);
workerCallbackPtrs->wsManPluginReleaseCommandContextFuncPtr = (WSManPluginReleaseCommandContextFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_RELEASE_COMMAND);
workerCallbackPtrs->wsManPluginSendFuncPtr = (WSManPluginSendFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_SEND);
workerCallbackPtrs->wsManPluginReceiveFuncPtr = (WSManPluginReceiveFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_RECEIVE);
workerCallbackPtrs->wsManPluginSignalFuncPtr = (WSManPluginSignalFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_SIGNAL);
workerCallbackPtrs->wsManPluginConnectFuncPtr = (WSManPluginConnectFuncPtr)systemCalls->GetProcAddress(hManagedPluginModule, g_MANAGED_PLUGIN_CONNECT);
// Initialize the loaded module (pspluginwkr.dll)
if (hInitPluginMethodAddress)
{
// Only the "old" version of the worker requires a stand-alone init call.
// This object is a member of the PwrshPlugInMediator singleton, so this
// call is made from that context.
(hInitPluginMethodAddress)();
}
else
{
PWSTR msg = NULL;
exitCode = g_MANAGED_METHOD_RESOLUTION_FAILED;
GetFormattedErrorMessage(&msg, exitCode);
*pPluginException = new PlugInException(exitCode, msg);
return exitCode;
}
return exitCode;
}
unsigned int PowerShellClrManagedWorker::LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion)
{
return commonLib.LaunchCLR(wszMonadVersion, wszRuntimeVersion, &pHost);
}
unsigned int PowerShellClrManagedWorker::LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ wchar_t* wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException)
{
unsigned int exitCode = EXIT_CODE_SUCCESS;
HRESULT hr = S_OK;
*pPluginException = NULL;
do
{
// Get a pointer to the default AppDomain
CComPtr<_AppDomain> spDefaultDomain = NULL;
CComPtr<IUnknown> spAppDomainPunk = NULL;
hr = pHost->GetDefaultDomain(&spAppDomainPunk);
if (FAILED(hr) || spAppDomainPunk == NULL)
{
output->DisplayMessage(false, g_GETTING_DEFAULT_DOMAIN_FAILED, hr);
exitCode = EXIT_CODE_INIT_FAILURE;
break;
}
hr = spAppDomainPunk->QueryInterface(__uuidof(_AppDomain), (PVOID*)&spDefaultDomain);
if (FAILED(hr) || spDefaultDomain == NULL)
{
output->DisplayMessage(false, g_GETTING_DEFAULT_DOMAIN_FAILED, hr);
exitCode = EXIT_CODE_INIT_FAILURE;
break;
}
CComPtr<_ObjectHandle> spObjectHandle;
// use CreateInstance because we use the assembly strong name (as opposed to CreateInstanceFrom)
//
// wszMgdPlugInFileName is %systemdir%\Windows\System32\WindowsPowerShell\v1.0\system.management.automation.dll.
_bstr_t bstrConsoleHostAssemblyName = _bstr_t(L"System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
_bstr_t bstrUnmanagedMshEntryClass = _bstr_t(L"System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper");
hr = spDefaultDomain->CreateInstance(
bstrConsoleHostAssemblyName,
bstrUnmanagedMshEntryClass,
&spObjectHandle);
if (FAILED(hr) || spObjectHandle == NULL)
{
output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr);
exitCode = EXIT_CODE_INIT_FAILURE;
break;
}
CComVariant VntUnwrapped;
hr = spObjectHandle->Unwrap(&VntUnwrapped);
if (FAILED(hr))
{
output->DisplayMessage(false, g_CREATING_MSH_ENTRANCE_FAILED, hr);
exitCode = EXIT_CODE_INIT_FAILURE;
break;
}
CComPtr<IDispatch> pDisp;
pDisp = VntUnwrapped.pdispVal;
OLECHAR FAR * wszMember = L"GetEntryDelegate";
DISPID dispid;
//Retrieve the DISPID
hr = pDisp->GetIDsOfNames(
IID_NULL,
&wszMember,
1,
LOCALE_SYSTEM_DEFAULT,
&dispid);
if (FAILED(hr))
{
output->DisplayMessage(false, g_GETTING_DISPATCH_ID_FAILED, hr);
exitCode = EXIT_CODE_INIT_FAILURE;
break;
}
DISPPARAMS dispparamsOneArg = { NULL, NULL, 0 };
VARIANT varResult;
VariantInit(&varResult);
EXCEPINFO exception;
unsigned int uArgErr = 0;
//Invoke the method on the Dispatch Interface
hr = pDisp->Invoke(
dispid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dispparamsOneArg,
&varResult,
&exception,
&uArgErr);
InitPluginWkrPtrsFuncPtr entryPointDelegate = (InitPluginWkrPtrsFuncPtr)varResult.byref;
if (FAILED(hr) ||
NULL == entryPointDelegate)
{
if (DISP_E_EXCEPTION == hr)
{
output->DisplayMessage(false, g_MANAGED_MSH_EXCEPTION, exception.bstrDescription);
}
else
{
output->DisplayMessage(false, g_INOVKING_MSH_ENTRANCE_FAILED, hr);
}
exitCode = EXIT_CODE_INIT_FAILURE;
break;
}
// Passes empty pointer structure to the function, expects a filled struct if successful
exitCode = entryPointDelegate(workerCallbackPtrs);
}
while (false);
return exitCode;
}
PowerShellClrManagedWorker::~PowerShellClrManagedWorker()
{
// No need to call pHost->Stop() because,
// as the common language runtime is automatically unloaded when the process exits.
if (output)
{
delete output;
output = NULL;
}
}
#endif
//
// This factory method analyzes the wszMgdPlugInFileName and determines the
// appropriate IPowerShellClrHost to instantiate. It is the caller's responsibility
// to free the IPowerShellClrHost once finished using it.
//
IPowerShellClrHost* PowerShellClrWorkerFactory(
_In_ PWSTR wszMgdPlugInFileName)
{
#ifdef CORECLR
return new PowerShellCoreClrWorker(); // Calls into System.Management.Automation.dll
#else // !CORECLR
std::wstring pluginFileName(wszMgdPlugInFileName);
// This is a case-sensitive search. It checks to see if the file name portion of the path matches the v3 module name.
if (std::wstring::npos != pluginFileName.rfind(g_MANAGED_PLUGIN_FILENAME_V3_STRING))
{
return new PowerShellClrManagedWorker(); // Calls into System.Management.Automation.dll
}
return new PowerShellClrWorker(); // Calls into pspluginwkr.dll (previous generation of plugin worker)
#endif // !CORECLR
}
@@ -0,0 +1,165 @@
// ----------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2007.
//
// Contents: Headers used by pwrshplugin.
// pwrshplugin is totally unmanaged.
// ----------------------------------------------------------------------
#pragma once
#include "pwrshplugindefs.h" // PwrshPluginWkr_Ptrs and PlugInException
#include <mscoree.h>
#include <atlbase.h>
#include <string>
#include "SystemCallFacade.h"
#include "ClrHostWrapper.h"
#include "NativeMsh.h"
class PwrshPluginOutputDefault : public NativeMsh::IPwrshCommonOutput
{
public:
virtual VOID DisplayMessage(
bool bUseStdOut,
DWORD dwMessageId,
...)
{
return;
}
virtual void DisplayErrorWithSystemError(
LONG lSystemErrorCode,
int messageId,
LPCWSTR insertionParam)
{
return;
}
};
class IPowerShellClrHost
{
public:
// Virtual destructor to ensure that derived destructors are called
// during base class destruction.
virtual ~IPowerShellClrHost() {}
virtual unsigned int LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion) = 0;
virtual unsigned int LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ PWSTR wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException) = 0;
};
#if !CORECLR // See note for LaunchCLR for an explanation.
class PowerShellClrWorker : public IPowerShellClrHost
{
private:
CComPtr<ICorRuntimeHost> pHost;
HMODULE hManagedPluginModule;
NativeMsh::IPwrshCommonOutput* output;
NativeMsh::PwrshCommon commonLib;
const LPCSTR g_INIT_PLUGIN;
const LPCSTR g_SHUTDOWN_PLUGIN;
const LPCSTR g_MANAGED_PLUGIN_CREATE_SHELL;
const LPCSTR g_MANAGED_PLUGIN_RELEASE_SHELL;
const LPCSTR g_MANAGED_PLUGIN_CREATE_COMMAND;
const LPCSTR g_MANAGED_PLUGIN_RELEASE_COMMAND;
const LPCSTR g_MANAGED_PLUGIN_SEND;
const LPCSTR g_MANAGED_PLUGIN_RECEIVE;
const LPCSTR g_MANAGED_PLUGIN_SIGNAL;
const LPCSTR g_MANAGED_PLUGIN_CONNECT;
NativeMsh::SystemCallFacade* systemCalls;
public:
PowerShellClrWorker();
PowerShellClrWorker(NativeMsh::SystemCallFacade* sysCalls);
virtual ~PowerShellClrWorker();
//
// IPowerShellClrHost Methods
//
virtual unsigned int LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion);
virtual unsigned int LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ wchar_t* wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException);
};
class PowerShellClrManagedWorker : public IPowerShellClrHost
{
private:
CComPtr<ICorRuntimeHost> pHost;
NativeMsh::IPwrshCommonOutput* output;
NativeMsh::PwrshCommon commonLib;
public:
PowerShellClrManagedWorker() : pHost(NULL), output(new PwrshPluginOutputDefault())
{}
virtual ~PowerShellClrManagedWorker();
//
// IPowerShellClrHost Methods
//
virtual unsigned int LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion);
virtual unsigned int LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ wchar_t* wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException);
};
#else // CORECLR
class PowerShellCoreClrWorker : public IPowerShellClrHost
{
private:
NativeMsh::ClrHostWrapper* hostWrapper;
NativeMsh::SystemCallFacade* systemCalls;
NativeMsh::PwrshCommon* commonLib;
NativeMsh::IPwrshCommonOutput* output;
NativeMsh::HostEnvironment hostEnvironment;
public:
PowerShellCoreClrWorker();
PowerShellCoreClrWorker(
NativeMsh::SystemCallFacade* sysCalls,
NativeMsh::ClrHostWrapper* hstWrp,
NativeMsh::PwrshCommon* cmnLib);
virtual ~PowerShellCoreClrWorker();
std::wstring GetHostDirectory() { return std::wstring(hostEnvironment.GetHostDirectoryPath()); }
std::wstring GetClrDirectory() { return std::wstring(hostEnvironment.GetCoreCLRDirectoryPath()); }
//
// IPowerShellClrHost Methods
//
virtual unsigned int LaunchClr(
_In_ LPCWSTR wszMonadVersion,
_In_ LPCWSTR wszRuntimeVersion);
virtual unsigned int LoadWorkerCallbackPtrs(
_In_ PwrshPluginWkr_Ptrs* workerCallbackPtrs,
_In_z_ PWSTR wszMgdPlugInFileName,
_Outptr_result_maybenull_ PlugInException** pPluginException);
};
#endif // CORECLR
IPowerShellClrHost* PowerShellClrWorkerFactory(
_In_ PWSTR wszMgdPlugInFileName);
@@ -0,0 +1,22 @@
// ----------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2008.
//
// Contents: Headers used by internal windows teams to access certain
// Powershell functionality
// ----------------------------------------------------------------------
#pragma once
// Gets the CLR Version for a given PowerShell Version. PowerShell Version is
// supplied with 2 paramaters iPSMajorVersion (PowerShell major version) and
// iPSMinorVersion (PowerShell minor version). The CLR version is returned through
// pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion.
// returns: 0 on success, non-zero on failure.
_Success_(return == 0) // EXIT_CODE_SUCCESS
extern unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion,
int iPSMinorVersion,
size_t runtimeVersionLength,
__inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion,
__out_ecount(1) size_t* pRuntimeVersionLength);
@@ -0,0 +1,17 @@
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0"
>
<description>PowerShell Plugin</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,13 @@
// Copyright (C) 2005 Microsoft Corporation
//
// resource script for msh.exe
//
#include <windows.h>
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST "pwrshplugin.dll.manifest"
#include "pwrshpluginerrorcodes.rc"
#include "version.rc"
@@ -0,0 +1,159 @@
// ----------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 2007.
//
// Contents: Headers used by pwrshplugin.
// pwrshplugin is totally unmanaged.
// ----------------------------------------------------------------------
#pragma once
#include <windows.h>
#include <ntverp.h>
// include wsman.h header file..it is required to declare the version
// number of the wsman API to use
#define WSMAN_API_VERSION_1_0
#include <wsman.h>
// plugin errors start from 1000
const int g_NULL_PLUGIN_CONTEXT = 1100;
const int g_CREATION_FAILED = 1101;
const int g_MANAGED_PLUGIN_ALREADY_LOADED = 1102;
const int g_MANAGED_PLUGIN_PATH_CONSTRUCTION_ERROR = 1103;
const int g_MANAGED_PLUGIN_LOAD_FAILED = 1104;
const int g_SHELL_CREATION_FAILED = 1201;
const int g_OPTION_SET_MAJOR_VERSION_NOT_MATCH = 1202;
const int g_OPTION_SET_CLR_VERSION_NOT_MATCH = 1203;
const int g_OPTION_SET_APP_BASE_NOT_MATCH = 1204;
const PCWSTR g_VERSION_OPTION_STRING = L"version";
const PCWSTR g_PSPLUGINWKRV3_REGISTRY_KEY = L"PSPluginWkrModuleName";
const PCWSTR g_MANAGED_PLUGIN_FILENAME_STRING = L"pspluginwkr.dll";
const PCWSTR g_MANAGED_PLUGIN_FILENAME_V3_STRING = L"system.management.automation.dll";
const PCWSTR g_PSVERSION_CONFIG = L"PSVersion";
const PCWSTR g_INITIALIZATIONPARAM_CONFIG = L"InitializationParameters";
// The following VER_ macros are defined in ntverp.h
const PCWSTR g_BUILD_VERSION = LVER_PRODUCTVERSION_STR;
// Managed and mixed-mode plugin worker method entrypoints
//
// The v3 version of the worker is a mixed-mode managed C++ DLL, so it can
// be accessed directly using GetProcAddress.
// The CoreCLR-compliant worker is included in System.Management.Automation.dll,
// so we have to use alternate means to acquire the function pointers.
// Once we have the pointers, they may be used in the same way regardless of the
// method used to obtain them.
typedef void (WINAPI *ShutdownPluginFuncPtr)(__in PVOID pluginContext);
typedef void (WINAPI *WSManPluginShellFuncPtr)(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PCWSTR extraInfo,
__in_opt WSMAN_SHELL_STARTUP_INFO *startupInfo,
__in_opt WSMAN_DATA *inboundShellInformation
);
typedef void (WINAPI *WSManPluginConnectFuncPtr)(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in_opt WSMAN_DATA *inboundConnectInformation
);
typedef void (WINAPI *WSManPluginReleaseShellContextFuncPtr)(
__in PVOID pluginContext,
__in PVOID shellContext
);
typedef void (WINAPI *WSManPluginCommandFuncPtr)(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in PCWSTR commandLine,
__in_opt WSMAN_COMMAND_ARG_SET *arguments
);
typedef void (WINAPI *WSManPluginReleaseCommandContextFuncPtr)(
__in PVOID pluginContext,
__in PVOID shellContext,
__in PVOID commandContext
);
typedef void (WINAPI *WSManPluginSendFuncPtr)(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in PCWSTR stream,
__in WSMAN_DATA *inboundData
);
typedef void (WINAPI *WSManPluginReceiveFuncPtr)(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in_opt WSMAN_STREAM_ID_SET* streamSet
);
typedef void (WINAPI *WSManPluginSignalFuncPtr)(
__in PVOID pluginContext,
__in WSMAN_PLUGIN_REQUEST *requestDetails,
__in DWORD flags,
__in PVOID shellContext,
__in_opt PVOID commandContext,
__in PCWSTR code);
typedef struct _PwrshPluginWkr_Ptrs
{
ShutdownPluginFuncPtr shutdownPluginFuncPtr;
WSManPluginShellFuncPtr wsManPluginShellFuncPtr;
WSManPluginReleaseShellContextFuncPtr wsManPluginReleaseShellContextFuncPtr;
WSManPluginCommandFuncPtr wsManPluginCommandFuncPtr;
WSManPluginReleaseCommandContextFuncPtr wsManPluginReleaseCommandContextFuncPtr;
WSManPluginSendFuncPtr wsManPluginSendFuncPtr;
WSManPluginReceiveFuncPtr wsManPluginReceiveFuncPtr;
WSManPluginSignalFuncPtr wsManPluginSignalFuncPtr;
WSManPluginConnectFuncPtr wsManPluginConnectFuncPtr;
} PwrshPluginWkr_Ptrs;
class PlugInException
{
public:
DWORD dwMessageId;
// This message is allocated outside the exception, but the exception frees
// the memory.
PWSTR extendedErrorInformation;
PlugInException(DWORD msgId, __in PWSTR msg)
{
dwMessageId = msgId;
extendedErrorInformation = msg;
}
~PlugInException()
{
if (NULL != extendedErrorInformation)
{
delete[] extendedErrorInformation;
extendedErrorInformation = NULL;
}
}
private:
// Provided without implementation to prevent automatic instantiation and copying
// since copying will lead to double frees given the existing code.
PlugInException();
PlugInException(const PlugInException&);
PlugInException& operator=(const PlugInException&);
};
@@ -0,0 +1,80 @@
;// Copyright (C) Microsoft Corporation, 2000 - 2007
;#undef FACILITY_POWERSHELL
FacilityNames=(PowerShell=84:FACILITY_POWERSHELL)
SeverityNames=(Success=0x0
CoError=0x2
)
MessageId=1001
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_INVALID_PLUGIN_CONTEXT
Language=English
The supplied plugin context is invalid.
.
MessageId=1002
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_INVALID_INPUT
Language=English
Invalid parameter to plugin method %1!ls!.
.
MessageId=1003
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_MANAGED_METHOD_RESOLUTION_FAILED
Language=English
Unable to find plugin methods WSManPluginShell, WSManPluginCommand, WSManPluginSend, WSManPluginRecieve in the Managed plugin module.
.
MessageId=1004
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_OPTION_SET_NOT_COMPLY
Language=English
Powershell plugin does not support the options requested. Make sure client is compatible with build %1!ls! of PowerShell.
.
MessageId=1005
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_PSVERSION_NOT_FOUND_IN_CONFIG
Language=English
A "%1!ls!" name-value pair is expected in the "%2!ls!" element of the configuration xml. Contact your administrator.
.
MessageId=1006
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_BAD_INITPARAMETERS
Language=English
The "%1!ls!" element in the configuration xml is badly formatted. Contact your administrator.
.
MessageId=1007
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_INIT_CRITICALSECTION_FAILED
Language=English
An error occurred while initializing the plugin. Contact your administrator.
.
MessageId=1008
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_CLR_LOAD_FAILED
Language=English
An error occurred while loading version %1!ls! of CLR. Contact your administrator.
.
MessageId=1009
Facility=POWERSHELL
Severity=CoError
SymbolicName=g_MANAGED_CONNECT_METHOD_RESOLUTION_FAILED
Language=English
An error occured while processing the connect operation. A relevant entry point is not found in the managed plugin module
Make sure that the configured plugin supports connect operation.
.
@@ -0,0 +1,13 @@
//
// 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 "pwrshplugin.dll"
#define VER_INTERNALNAME_STR "pwrshplugin.dll"
#define VER_ORIGINALFILENAME_STR "pwrshplugin.dll"
#include <common.ver>