internal ServerRemoteSessionDSHandlerlImpl(ServerRemoteSession session, AbstractServerSessionTransportManager transportManager) { this._session = session; this._stateMachine = new ServerRemoteSessionDSHandlerStateMachine(session); this._transportManager = transportManager; this._transportManager.DataReceived += new EventHandler<RemoteDataEventArgs>(session.DispatchInputQueueData); }
/// <summary> /// Constructs a ServerRemoteSession handler using the supplied transport manager. The /// supplied transport manager will be used to send and receive data from the remote /// client. /// </summary> /// <param name="session"></param> /// <param name="transportManager"></param> internal ServerRemoteSessionDSHandlerImpl(ServerRemoteSession session, AbstractServerSessionTransportManager transportManager) { Dbg.Assert(null != session, "session cannot be null."); Dbg.Assert(null != transportManager, "transportManager cannot be null."); _session = session; _stateMachine = new ServerRemoteSessionDSHandlerStateMachine(session); _transportManager = transportManager; _transportManager.DataReceived += session.DispatchInputQueueData; }
internal static ServerRemoteSession CreateServerRemoteSession(PSSenderInfo senderInfo, string configurationProviderId, string initializationParameters, AbstractServerSessionTransportManager transportManager) { _trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Finding InitialSessionState provider for id : {0}", new object[] { configurationProviderId }), new object[0]); if (string.IsNullOrEmpty(configurationProviderId)) { throw PSTraceSource.NewInvalidOperationException("remotingerroridstrings", "NonExistentInitialSessionStateProvider", new object[] { configurationProviderId }); } ServerRemoteSession session = new ServerRemoteSession(senderInfo, configurationProviderId, initializationParameters, transportManager); RemoteSessionStateMachineEventArgs fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.CreateSession); session._sessionDSHandler.StateMachine.RaiseEvent(fsmEventArg); return session; }
internal ServerPowerShellDataStructureHandler CreatePowerShellDataStructureHandler(Guid instanceId, Guid runspacePoolId, RemoteStreamOptions remoteStreamOptions, PowerShell localPowerShell) { AbstractServerTransportManager transportManager = this.transportManager; if (instanceId != Guid.Empty) { transportManager = this.transportManager.GetCommandTransportManager(instanceId); } ServerPowerShellDataStructureHandler handler = new ServerPowerShellDataStructureHandler(instanceId, runspacePoolId, remoteStreamOptions, transportManager, localPowerShell); lock (this.associationSyncObject) { this.associatedShells.Add(handler.PowerShellId, handler); } handler.RemoveAssociation += new EventHandler(this.HandleRemoveAssociation); return handler; }
internal ServerRunspacePoolDriver(Guid clientRunspacePoolId, int minRunspaces, int maxRunspaces, PSThreadOptions threadOptions, ApartmentState apartmentState, HostInfo hostInfo, InitialSessionState initialSessionState, PSPrimitiveDictionary applicationPrivateData, ConfigurationDataFromXML configData, AbstractServerSessionTransportManager transportManager, bool isAdministrator, RemoteSessionCapability serverCapability, Hashtable configHash) { this.serverCapability = serverCapability; System.Management.Automation.Remoting.ServerRemoteHost host = new System.Management.Automation.Remoting.ServerRemoteHost(clientRunspacePoolId, Guid.Empty, hostInfo, transportManager); this.remoteHost = host; this.configData = configData; this.configHash = configHash; this.applicationPrivateData = applicationPrivateData; this.localRunspacePool = RunspaceFactory.CreateRunspacePool(minRunspaces, maxRunspaces, initialSessionState, host); PSThreadOptions options = configData.ShellThreadOptions.HasValue ? configData.ShellThreadOptions.Value : PSThreadOptions.UseCurrentThread; if ((threadOptions == PSThreadOptions.Default) || (threadOptions == options)) { this.localRunspacePool.ThreadOptions = options; } else { if (!isAdministrator) { throw new InvalidOperationException(PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.MustBeAdminToOverrideThreadOptions, new object[0])); } this.localRunspacePool.ThreadOptions = threadOptions; } ApartmentState state = configData.ShellThreadApartmentState.HasValue ? configData.ShellThreadApartmentState.Value : ApartmentState.Unknown; if ((apartmentState == ApartmentState.Unknown) || (apartmentState == state)) { this.localRunspacePool.ApartmentState = state; } else { this.localRunspacePool.ApartmentState = apartmentState; } this.clientRunspacePoolId = clientRunspacePoolId; this.dsHandler = new ServerRunspacePoolDataStructureHandler(this, transportManager); this.localRunspacePool.StateChanged += new EventHandler<RunspacePoolStateChangedEventArgs>(this.HandleRunspacePoolStateChanged); this.localRunspacePool.ForwardEvent += new EventHandler<PSEventArgs>(this.HandleRunspacePoolForwardEvent); this.localRunspacePool.RunspaceCreated += new EventHandler<RunspaceCreatedEventArgs>(this.HandleRunspaceCreated); this.localRunspacePool.RunspaceCreated += new EventHandler<RunspaceCreatedEventArgs>(this.HandleRunspaceCreatedForTypeTable); this.dsHandler.CreateAndInvokePowerShell += new EventHandler<RemoteDataEventArgs<RemoteDataObject<PSObject>>>(this.HandleCreateAndInvokePowerShell); this.dsHandler.GetCommandMetadata += new EventHandler<RemoteDataEventArgs<RemoteDataObject<PSObject>>>(this.HandleGetCommandMetadata); this.dsHandler.HostResponseReceived += new EventHandler<RemoteDataEventArgs<RemoteHostResponse>>(this.HandleHostResponseReceived); this.dsHandler.SetMaxRunspacesReceived += new EventHandler<RemoteDataEventArgs<PSObject>>(this.HandleSetMaxRunspacesReceived); this.dsHandler.SetMinRunspacesReceived += new EventHandler<RemoteDataEventArgs<PSObject>>(this.HandleSetMinRunspacesReceived); this.dsHandler.GetAvailableRunspacesReceived += new EventHandler<RemoteDataEventArgs<PSObject>>(this.HandleGetAvailalbeRunspacesReceived); }
internal ServerRemoteSession(PSSenderInfo senderInfo, string configurationProviderId, string initializationParameters, AbstractServerSessionTransportManager transportManager) { NativeCommandProcessor.IsServerSide = true; this._senderInfo = senderInfo; this._configProviderId = configurationProviderId; this._initParameters = initializationParameters; this._cryptoHelper = (PSRemotingCryptoHelperServer) transportManager.CryptoHelper; this._cryptoHelper.Session = this; this._context = new ServerRemoteSessionContext(); this._sessionDSHandler = new ServerRemoteSessionDSHandlerlImpl(this, transportManager); base.BaseSessionDataStructureHandler = this._sessionDSHandler; this._sessionDSHandler.CreateRunspacePoolReceived += new EventHandler<RemoteDataEventArgs>(this.HandleCreateRunspacePool); this._sessionDSHandler.NegotiationReceived += new EventHandler<RemoteSessionNegotiationEventArgs>(this.HandleNegotiationReceived); this._sessionDSHandler.SessionClosing += new EventHandler<EventArgs>(this.HandleSessionDSHandlerClosing); this._sessionDSHandler.PublicKeyReceived += new EventHandler<RemoteDataEventArgs<string>>(this.HandlePublicKeyReceived); transportManager.Closing += new EventHandler(this.HandleResourceClosing); transportManager.ReceivedDataCollection.MaximumReceivedObjectSize = 0xa00000; transportManager.ReceivedDataCollection.MaximumReceivedDataSize = null; }
internal ServerRunspacePoolDataStructureHandler(ServerRunspacePoolDriver driver, AbstractServerSessionTransportManager transportManager) { this.clientRunspacePoolId = driver.InstanceId; this.transportManager = transportManager; }
/// <summary> /// Creates the runspace pool driver /// </summary> /// <param name="clientRunspacePoolId">client runspace pool id to associate</param> /// <param name="transportManager">transport manager associated with this /// runspace pool driver</param> /// <param name="maxRunspaces">maximum runspaces to open</param> /// <param name="minRunspaces">minimum runspaces to open</param> /// <param name="threadOptions">threading options for the runspaces in the pool</param> /// <param name="apartmentState">apartment state for the runspaces in the pool</param> /// <param name="hostInfo">host information about client side host</param> /// <param name="configData"> /// Contains: /// 1. Script to run after a RunspacePool/Runspace is created in this session. /// For RunspacePool case, every newly created Runspace (in the pool) will run /// this script. /// 2. ThreadOptions for RunspacePool/Runspace /// 3. ThreadApartment for RunspacePool/Runspace /// </param> /// <param name="initialSessionState">configuration of the runspace</param> /// <param name="applicationPrivateData">application private data</param> /// <param name="isAdministrator">True if the driver is being created by an administrator</param> /// <param name="serverCapability">server capability reported to the client during negotiation (not the actual capability)</param> /// <param name="psClientVersion">Client PowerShell version.</param> /// <param name="configurationName">Optional endpoint configuration name to create a pushed configured runspace.</param> internal ServerRunspacePoolDriver( Guid clientRunspacePoolId, int minRunspaces, int maxRunspaces, PSThreadOptions threadOptions, ApartmentState apartmentState, HostInfo hostInfo, InitialSessionState initialSessionState, PSPrimitiveDictionary applicationPrivateData, ConfigurationDataFromXML configData, AbstractServerSessionTransportManager transportManager, bool isAdministrator, RemoteSessionCapability serverCapability, Version psClientVersion, string configurationName) #endif { Dbg.Assert(null != configData, "ConfigurationData cannot be null"); _serverCapability = serverCapability; _clientPSVersion = psClientVersion; _configurationName = configurationName; // Create a new server host and associate for host call // integration _remoteHost = new ServerDriverRemoteHost(clientRunspacePoolId, Guid.Empty, hostInfo, transportManager, null); _configData = configData; _applicationPrivateData = applicationPrivateData; RunspacePool = RunspaceFactory.CreateRunspacePool( minRunspaces, maxRunspaces, initialSessionState, _remoteHost); // Set ThreadOptions for this RunspacePool // The default server settings is to make new commands execute in the calling thread...this saves // thread switching time and thread pool pressure on the service. // Users can override the server settings only if they are administrators PSThreadOptions serverThreadOptions = configData.ShellThreadOptions.HasValue ? configData.ShellThreadOptions.Value : PSThreadOptions.UseCurrentThread; if (threadOptions == PSThreadOptions.Default || threadOptions == serverThreadOptions) { RunspacePool.ThreadOptions = serverThreadOptions; } else { if (!isAdministrator) { throw new InvalidOperationException(PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.MustBeAdminToOverrideThreadOptions)); } RunspacePool.ThreadOptions = threadOptions; } #if !CORECLR // No ApartmentState In CoreCLR // Set Thread ApartmentState for this RunspacePool ApartmentState serverApartmentState = configData.ShellThreadApartmentState.HasValue ? configData.ShellThreadApartmentState.Value : Runspace.DefaultApartmentState; if (apartmentState == ApartmentState.Unknown || apartmentState == serverApartmentState) { RunspacePool.ApartmentState = serverApartmentState; } else { RunspacePool.ApartmentState = apartmentState; } #endif // If we have a runspace pool with a single runspace then we can run nested pipelines on // on it in a single pipeline invoke thread. if (maxRunspaces == 1 && (RunspacePool.ThreadOptions == PSThreadOptions.Default || RunspacePool.ThreadOptions == PSThreadOptions.UseCurrentThread)) { _driverNestedInvoker = new PowerShellDriverInvoker(); } InstanceId = clientRunspacePoolId; DataStructureHandler = new ServerRunspacePoolDataStructureHandler(this, transportManager); // handle the StateChanged event of the runspace pool RunspacePool.StateChanged += new EventHandler<RunspacePoolStateChangedEventArgs>(HandleRunspacePoolStateChanged); // listen for events on the runspace pool RunspacePool.ForwardEvent += new EventHandler<PSEventArgs>(HandleRunspacePoolForwardEvent); RunspacePool.RunspaceCreated += HandleRunspaceCreated; // register for all the events from the data structure handler DataStructureHandler.CreateAndInvokePowerShell += new EventHandler<RemoteDataEventArgs<RemoteDataObject<PSObject>>>(HandleCreateAndInvokePowerShell); DataStructureHandler.GetCommandMetadata += new EventHandler<RemoteDataEventArgs<RemoteDataObject<PSObject>>>(HandleGetCommandMetadata); DataStructureHandler.HostResponseReceived += new EventHandler<RemoteDataEventArgs<RemoteHostResponse>>(HandleHostResponseReceived); DataStructureHandler.SetMaxRunspacesReceived += new EventHandler<RemoteDataEventArgs<PSObject>>(HandleSetMaxRunspacesReceived); DataStructureHandler.SetMinRunspacesReceived += new EventHandler<RemoteDataEventArgs<PSObject>>(HandleSetMinRunspacesReceived); DataStructureHandler.GetAvailableRunspacesReceived += new EventHandler<RemoteDataEventArgs<PSObject>>(HandleGetAvailableRunspacesReceived); DataStructureHandler.ResetRunspaceState += new EventHandler<RemoteDataEventArgs<PSObject>>(HandleResetRunspaceState); }
/// <summary> /// Creates the runspace pool driver /// </summary> /// <param name="clientRunspacePoolId">client runspace pool id to associate</param> /// <param name="transportManager">transport manager associated with this /// runspace pool driver</param> /// <param name="maxRunspaces">maximum runspaces to open</param> /// <param name="minRunspaces">minimum runspaces to open</param> /// <param name="threadOptions">threading options for the runspaces in the pool</param> /// <param name="hostInfo">host information about client side host</param> /// <param name="configData"> /// Contains: /// 1. Script to run after a RunspacePool/Runspace is created in this session. /// For RunspacePool case, every newly created Runspace (in the pool) will run /// this script. /// 2. ThreadOptions for RunspacePool/Runspace /// 3. ThreadApartment for RunspacePool/Runspace /// </param> /// <param name="initialSessionState">configuration of the runspace</param> /// <param name="applicationPrivateData">application private data</param> /// <param name="isAdministrator">True if the driver is being created by an administrator</param> /// <param name="serverCapability">server capability reported to the client during negotiation (not the actual capability)</param> /// <param name="psClientVersion">Client PowerShell version.</param> /// <param name="configurationName">Optional endpoint configuration name to create a pushed configured runspace.</param> internal ServerRunspacePoolDriver( Guid clientRunspacePoolId, int minRunspaces, int maxRunspaces, PSThreadOptions threadOptions, HostInfo hostInfo, InitialSessionState initialSessionState, PSPrimitiveDictionary applicationPrivateData, ConfigurationDataFromXML configData, AbstractServerSessionTransportManager transportManager, bool isAdministrator, RemoteSessionCapability serverCapability, Version psClientVersion, string configurationName)
/// <summary> /// Used by OutOfProcessServerMediator to create a remote session. /// </summary> /// <param name="senderInfo"></param> /// <param name="initializationScriptForOutOfProcessRunspace"></param> /// <param name="transportManager"></param> /// <param name="configurationName"></param> /// <returns></returns> internal static ServerRemoteSession CreateServerRemoteSession(PSSenderInfo senderInfo, string initializationScriptForOutOfProcessRunspace, AbstractServerSessionTransportManager transportManager, string configurationName) { ServerRemoteSession result = CreateServerRemoteSession(senderInfo, "Microsoft.PowerShell", "", transportManager, configurationName); result._initScriptForOutOfProcRS = initializationScriptForOutOfProcessRunspace; return result; }
/// <summary> /// Creates a server remote session for the supplied <paramref name="configurationProviderId"/> /// and <paramref name="transportManager"/>. /// </summary> /// <param name="senderInfo"></param> /// <param name="configurationProviderId"></param> /// <param name="initializationParameters"> /// Initialization Parameters xml passed by WSMan API. This data is read from the config /// xml. /// </param> /// <param name="transportManager"></param> /// <param name="configurationName">Optional configuration endpoint name for OutOfProc sessions</param> /// <returns></returns> /// <exception cref="InvalidOperationException"> /// InitialSessionState provider with <paramref name="configurationProviderId"/> does /// not exist on the remote server. /// </exception> /* <InitializationParameters> <Param Name="PSVersion" Value="2.0" /> <Param Name="ApplicationBase" Value="<folder path>" /> ... </InitializationParameters> */ internal static ServerRemoteSession CreateServerRemoteSession(PSSenderInfo senderInfo, string configurationProviderId, string initializationParameters, AbstractServerSessionTransportManager transportManager, string configurationName = null) { Dbg.Assert((senderInfo != null) & (senderInfo.UserInfo != null), "senderInfo and userInfo cannot be null."); s_trace.WriteLine("Finding InitialSessionState provider for id : {0}", configurationProviderId); if (string.IsNullOrEmpty(configurationProviderId)) { throw PSTraceSource.NewInvalidOperationException("RemotingErrorIdStrings.NonExistentInitialSessionStateProvider", configurationProviderId); } ServerRemoteSession result = new ServerRemoteSession(senderInfo, configurationProviderId, initializationParameters, transportManager) { _configurationName = configurationName }; // start state machine. RemoteSessionStateMachineEventArgs startEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.CreateSession); result.SessionDataStructureHandler.StateMachine.RaiseEvent(startEventArg); return result; }
/// <summary> /// This constructor instantiates a ServerRemoteSession object and /// a ServerRemoteSessionDataStructureHandler object. /// </summary> /// <param name="senderInfo"> /// Details about the user creating this session. /// </param> /// <param name="configurationProviderId"> /// The resource URI for which this session is being created /// </param> /// <param name="initializationParameters"> /// Initialization Parameters xml passed by WSMan API. This data is read from the config /// xml. /// </param> /// <param name="transportManager"> /// The transport manager this session should use to send/receive data /// </param> /// <returns></returns> internal ServerRemoteSession(PSSenderInfo senderInfo, string configurationProviderId, string initializationParameters, AbstractServerSessionTransportManager transportManager) { Dbg.Assert(null != transportManager, "transportManager cannot be null."); // let input,output and error from native commands redirect as we have // to send (or receive) them back to client for action. NativeCommandProcessor.IsServerSide = true; _senderInfo = senderInfo; _configProviderId = configurationProviderId; _initParameters = initializationParameters; #if !UNIX _cryptoHelper = (PSRemotingCryptoHelperServer)transportManager.CryptoHelper; _cryptoHelper.Session = this; #else _cryptoHelper = null; #endif Context = new ServerRemoteSessionContext(); SessionDataStructureHandler = new ServerRemoteSessionDSHandlerlImpl(this, transportManager); BaseSessionDataStructureHandler = SessionDataStructureHandler; SessionDataStructureHandler.CreateRunspacePoolReceived += HandleCreateRunspacePool; SessionDataStructureHandler.NegotiationReceived += HandleNegotiationReceived; SessionDataStructureHandler.SessionClosing += HandleSessionDSHandlerClosing; SessionDataStructureHandler.PublicKeyReceived += new EventHandler<RemoteDataEventArgs<string>>(HandlePublicKeyReceived); transportManager.Closing += HandleResourceClosing; // update the quotas from sessionState..start with default size..and // when Custom Session Configuration is loaded (during runspace creation) update this. transportManager.ReceivedDataCollection.MaximumReceivedObjectSize = BaseTransportManager.MaximumReceivedObjectSize; // session transport manager can receive unlimited data..however each object is limited // by maxRecvdObjectSize. this is to allow clients to use a session for an unlimited time.. // also the messages that can be sent to a session are limited and very controlled. // However a command transport manager can be restricted to receive only a fixed amount of data // controlled by maxRecvdDataSizeCommand..This is because commands can accept any number of input // objects transportManager.ReceivedDataCollection.MaximumReceivedDataSize = null; }
internal ServerDriverRemoteHost( Guid clientRunspacePoolId, Guid clientPowerShellId, HostInfo hostInfo, AbstractServerSessionTransportManager transportManager, ServerRemoteDebugger debugger) : base(clientRunspacePoolId, clientPowerShellId, hostInfo, transportManager, null, null) { _debugger = debugger; }
internal static ServerRemoteSession CreateServerRemoteSession(PSSenderInfo senderInfo, string initializationScriptForOutOfProcessRunspace, AbstractServerSessionTransportManager transportManager) { ServerRemoteSession session = CreateServerRemoteSession(senderInfo, "Microsoft.PowerShell", "", transportManager); session._initScriptForOutOfProcRS = initializationScriptForOutOfProcessRunspace; return session; }