mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Copy pwrshplugin native code from [SD:715912]
commit 77eda78
This commit is contained in:
committed by
Sergei Vorobev
parent
d24bf35c22
commit
71835813aa
@@ -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>
|
||||
Reference in New Issue
Block a user