internal override void Dispose(bool isDisposing) { BaseClientTransportManager.tracer.WriteLine("Disposing command with command context: {0} Operation Context: {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); base.Dispose(isDisposing); RemoveCmdTransportManager(this.cmdContextId); if (this._sessnTm != null) { this._sessnTm.RobustConnectionsInitiated -= new EventHandler <EventArgs> (this.HandleRobustConnectionsIntiated); this._sessnTm.RobustConnectionsCompleted -= new EventHandler <EventArgs> (this.HandleRobusConnectionsCompleted); } if (this.closeCmdCompleted != null) { this.closeCmdCompleted.Dispose(); this.closeCmdCompleted = null; } if (this.reconnectCmdCompleted != null) { this.reconnectCmdCompleted.Dispose(); this.reconnectCmdCompleted = null; } this.wsManCmdOperationHandle = IntPtr.Zero; }
private void SendData(byte[] data, DataPriorityType priorityType) { BaseClientTransportManager.tracer.WriteLine("Command sending data of size : {0}", new object[] { data.Length }); byte[] buffer = data; bool flag = true; if (commandSendRedirect != null) { object[] objArray3 = new object[2]; objArray3[1] = buffer; object[] args = objArray3; flag = (bool)commandSendRedirect.DynamicInvoke(args); buffer = (byte[])args[0]; } if (flag) { using (WSManNativeApi.WSManData data2 = new WSManNativeApi.WSManData(buffer)) { PSEtwLog.LogAnalyticInformational(PSEventId.WSManSendShellInputEx, PSOpcode.Send, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString(), data2.BufferLength.ToString(CultureInfo.InvariantCulture) }); lock (base.syncObject) { if (base.isClosed) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Transport manager is closed. So returning", new object[0]); } else { this.sendToRemoteCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdSendCallback); WSManNativeApi.WSManSendShellInputEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, 0, (priorityType == DataPriorityType.Default) ? "stdin" : "pr", data2, (IntPtr)this.sendToRemoteCompleted, ref this.wsManSendOperationHandle); } } } } }
internal void ClearReceiveOrSendResources(int flags, bool shouldClearSend) { if (shouldClearSend) { if (this.sendToRemoteCompleted != null) { this.sendToRemoteCompleted.Dispose(); this.sendToRemoteCompleted = (WSManNativeApi.WSManShellAsync)null; } if (!(IntPtr.Zero != this.wsManSendOperationHandle)) { return; } WSManNativeApi.WSManCloseOperation(this.wsManSendOperationHandle, 0); this.wsManSendOperationHandle = IntPtr.Zero; } else { if (flags != 1) { return; } if (IntPtr.Zero != this.wsManRecieveOperationHandle) { WSManNativeApi.WSManCloseOperation(this.wsManRecieveOperationHandle, 0); this.wsManRecieveOperationHandle = IntPtr.Zero; } if (this.receivedFromRemote == null) { return; } this.receivedFromRemote.Dispose(); this.receivedFromRemote = (WSManNativeApi.WSManShellAsync)null; } }
private void CloseSessionAndClearResources() { BaseClientTransportManager.tracer.WriteLine("Clearing session with session context: {0} Operation Context: {1}", (object)this.sessionContextID, (object)this.wsManShellOperationHandle); IntPtr manSessionHandle = this.wsManSessionHandle; this.wsManSessionHandle = IntPtr.Zero; object obj; ThreadPool.QueueUserWorkItem((WaitCallback)(state => { obj = state; if (!(IntPtr.Zero != (IntPtr)obj)) { return; } WSManNativeApi.WSManCloseSession((IntPtr)obj, 0); }), (object)manSessionHandle); WSManClientSessionTransportManager.RemoveSessionTransportManager(this.sessionContextID); if (this.closeSessionCompleted == null) { return; } this.closeSessionCompleted.Dispose(); this.closeSessionCompleted = (WSManNativeApi.WSManShellAsync)null; }
internal override void Dispose(bool isDisposing) { BaseClientTransportManager.tracer.WriteLine("Disposing command with command context: {0} Operation Context: {1}", (object)this.cmdContextId, (object)this.wsManCmdOperationHandle); base.Dispose(isDisposing); WSManClientCommandTransportManager.RemoveCmdTransportManager(this.cmdContextId); if (this.closeCmdCompleted != null) { this.closeCmdCompleted.Dispose(); this.closeCmdCompleted = (WSManNativeApi.WSManShellAsync)null; } this.wsManCmdOperationHandle = IntPtr.Zero; }
private void StartReceivingData() { BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManReceiveShellOutputEx, PSOpcode.Receive, PSTask.None, (object)this.RunspacePoolInstanceId, (object)this.powershellInstanceId); this.shouldStartReceivingData = false; lock (this.syncObject) { if (this.isClosed) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Transport manager is closed. So returning", new object[0]); } else { this.receivedFromRemote = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), WSManClientCommandTransportManager.cmdReceiveCallback); WSManNativeApi.WSManReceiveShellOutputEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, 0, (IntPtr)WSManClientSessionTransportManager.wsManApiStaticData.OutputStreamSet, (IntPtr)this.receivedFromRemote, ref this.wsManRecieveOperationHandle); } } }
internal override void CreateAsync() { byte[] firstArgument = base.serializedPipeline.ReadOrRegisterCallback(null); if (firstArgument == null) { firstArgument = new byte[0]; } bool flag = true; if (commandCodeSendRedirect != null) { object[] objArray2 = new object[2]; objArray2[1] = firstArgument; object[] objArray = objArray2; flag = (bool)commandCodeSendRedirect.DynamicInvoke(objArray); firstArgument = (byte[])objArray[0]; } if (!flag) { return; } WSManNativeApi.WSManCommandArgSet set = new WSManNativeApi.WSManCommandArgSet(firstArgument); this.cmdContextId = GetNextCmdTMHandleId(); AddCmdTransportManager(this.cmdContextId, this); PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateCommand, PSOpcode.Connect, PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString() }); this.createCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdCreateCallback); this.createCmdCompletedGCHandle = GCHandle.Alloc(this.createCmdCompleted); this.reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdReconnectCallback); using (set) { lock (base.syncObject) { if (!base.isClosed) { WSManNativeApi.WSManRunShellCommandEx(this.wsManShellOperationHandle, 0, base.PowershellInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), ((this.cmdLine == null) || (this.cmdLine.Length == 0)) ? " " : ((this.cmdLine.Length <= 0x100) ? this.cmdLine : this.cmdLine.Substring(0, 0xff)), (IntPtr)set, IntPtr.Zero, (IntPtr)this.createCmdCompleted, ref this.wsManCmdOperationHandle); BaseClientTransportManager.tracer.WriteLine("Started cmd with command context : {0} Operation context: {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); } } } if (this.wsManCmdOperationHandle == IntPtr.Zero) { PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed); TransportErrorOccuredEventArgs eventArgs = new TransportErrorOccuredEventArgs(e, TransportMethodEnum.RunShellCommandEx); this.ProcessWSManTransportError(eventArgs); } }
internal override void ConnectAsync() { byte[] firstArgument = this.serializedPipeline.ReadOrRegisterCallback((SerializedDataStream.OnDataAvailableCallback)null); if (firstArgument != null) { bool flag = true; if ((object)WSManClientCommandTransportManager.commandCodeSendRedirect != null) { object[] objArray = new object[2] { null, (object)firstArgument }; flag = (bool)WSManClientCommandTransportManager.commandCodeSendRedirect.DynamicInvoke(objArray); firstArgument = (byte[])objArray[0]; } if (!flag) { return; } WSManNativeApi.WSManCommandArgSet manCommandArgSet = new WSManNativeApi.WSManCommandArgSet(firstArgument); this.cmdContextId = WSManClientCommandTransportManager.GetNextCmdTMHandleId(); WSManClientCommandTransportManager.AddCmdTransportManager(this.cmdContextId, this); BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManCreateCommand, PSOpcode.Connect, PSTask.CreateRunspace, (object)this.RunspacePoolInstanceId, (object)this.powershellInstanceId); this.createCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), WSManClientCommandTransportManager.cmdCreateCallback); this.createCmdCompletedGCHandle = GCHandle.Alloc((object)this.createCmdCompleted); using (manCommandArgSet) { lock (this.syncObject) { if (!this.isClosed) { WSManNativeApi.WSManRunShellCommandEx(this.wsManShellOperationHandle, 0, " ", (IntPtr)manCommandArgSet, IntPtr.Zero, (IntPtr)this.createCmdCompleted, ref this.wsManCmdOperationHandle); BaseClientTransportManager.tracer.WriteLine("Started cmd with command context : {0} Operation context: {1}", (object)this.cmdContextId, (object)this.wsManCmdOperationHandle); } } } } if (!(this.wsManCmdOperationHandle == IntPtr.Zero)) { return; } this.RaiseErrorHandler(new TransportErrorOccuredEventArgs(new PSRemotingTransportException(PSRemotingErrorId.RunShellCommandExFailed, new object[0]), TransportMethodEnum.RunShellCommandEx)); }
internal override void SendStopSignal() { lock (base.syncObject) { if (!base.isClosed) { if (!this.isCreateCallbackReceived) { this.isStopSignalPending = true; } else { this.isStopSignalPending = false; BaseClientTransportManager.tracer.WriteLine("Sending stop signal with command context: {0} Operation Context {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); PSEtwLog.LogAnalyticInformational(PSEventId.WSManSignal, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString(), StopSignal }); this.signalCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdSignalCallback); WSManNativeApi.WSManSignalShellEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, 0, StopSignal, (IntPtr)this.signalCmdCompleted, ref this.cmdSignalOperationHandle); } } } }
internal override void CloseAsync() { bool flag = false; lock (this.syncObject) { if (this.isClosed) { return; } if (!this.isCreateCallbackReceived) { this.isClosePending = true; return; } this.isClosed = true; if (IntPtr.Zero == this.wsManShellOperationHandle) { flag = true; } } base.CloseAsync(); if (flag) { try { this.RaiseCloseCompleted(); } finally { WSManClientSessionTransportManager.RemoveSessionTransportManager(this.sessionContextID); } } else { BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManCloseShell, PSOpcode.Disconnect, PSTask.None, (object)this.RunspacePoolInstanceId); this.closeSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), WSManClientSessionTransportManager.sessionCloseCallback); WSManNativeApi.WSManCloseShell(this.wsManShellOperationHandle, 0, (IntPtr)this.closeSessionCompleted); } }
internal override void SendStopSignal() { lock (this.syncObject) { if (this.isClosed) { return; } if (!this.isCreateCallbackReceived) { this.isStopSignalPending = true; } else { this.isStopSignalPending = false; BaseClientTransportManager.tracer.WriteLine("Sending stop signal with command context: {0} Operation Context {1}", (object)this.cmdContextId, (object)this.wsManCmdOperationHandle); BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManSignal, PSOpcode.Disconnect, PSTask.None, (object)this.RunspacePoolInstanceId, (object)this.powershellInstanceId, (object)"powershell/signal/crtl_c"); this.signalCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), WSManClientCommandTransportManager.cmdSignalCallback); WSManNativeApi.WSManSignalShellEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, 0, "powershell/signal/crtl_c", (IntPtr)this.signalCmdCompleted, ref this.cmdSignalOperationHandle); } } }
internal override void StartReceivingData() { PSEtwLog.LogAnalyticInformational(PSEventId.WSManReceiveShellOutputEx, PSOpcode.Receive, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString() }); this.shouldStartReceivingData = false; lock (base.syncObject) { if (base.isClosed) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Transport manager is closed. So returning", new object[0]); } else if (base.receiveDataInitiated) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Command ReceiveData has already been called.", new object[0]); } else { base.receiveDataInitiated = true; this.receivedFromRemote = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdReceiveCallback); WSManNativeApi.WSManReceiveShellOutputEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, base.startInDisconnectedMode ? 0x10 : 0, (IntPtr)WSManClientSessionTransportManager.wsManApiStaticData.OutputStreamSet, (IntPtr)this.receivedFromRemote, ref this.wsManRecieveOperationHandle); } } }
internal override void ConnectAsync() { base.ReceivedDataCollection.PrepareForStreamConnect(); base.serializedPipeline.Read(); this.cmdContextId = GetNextCmdTMHandleId(); AddCmdTransportManager(this.cmdContextId, this); this.connectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdConnectCallback); this.reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdReconnectCallback); lock (base.syncObject) { if (base.isClosed) { return; } WSManNativeApi.WSManConnectShellCommandEx(this.wsManShellOperationHandle, 0, base.PowershellInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), IntPtr.Zero, IntPtr.Zero, (IntPtr)this.connectCmdCompleted, ref this.wsManCmdOperationHandle); } if (this.wsManCmdOperationHandle == IntPtr.Zero) { PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed); TransportErrorOccuredEventArgs eventArgs = new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ConnectShellCommandEx); this.ProcessWSManTransportError(eventArgs); } }
private void SendData(byte[] data, DataPriorityType priorityType) { BaseClientTransportManager.tracer.WriteLine("Session sending data of size : {0}", (object)data.Length); byte[] data1 = data; bool flag = true; if ((object)WSManClientSessionTransportManager.sessionSendRedirect != null) { object[] objArray = new object[2] { null, (object)data1 }; flag = (bool)WSManClientSessionTransportManager.sessionSendRedirect.DynamicInvoke(objArray); data1 = (byte[])objArray[0]; } if (!flag) { return; } using (WSManNativeApi.WSManData streamData = new WSManNativeApi.WSManData(data1)) { BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManSendShellInputEx, PSOpcode.Send, PSTask.None, (object)this.RunspacePoolInstanceId, (object)Guid.Empty, (object)streamData.BufferLength.ToString((IFormatProvider)CultureInfo.InvariantCulture)); lock (this.syncObject) { if (this.isClosed) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Transport manager is closed. So returning", new object[0]); } else { this.sendToRemoteCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), WSManClientSessionTransportManager.sessionSendCallback); WSManNativeApi.WSManSendShellInputEx(this.wsManShellOperationHandle, IntPtr.Zero, 0, priorityType == DataPriorityType.Default ? "stdin" : "pr", streamData, (IntPtr)this.sendToRemoteCompleted, ref this.wsManSendOperationHandle); } } } }
internal override void CloseAsync() { BaseClientTransportManager.tracer.WriteLine("Closing command with command context: {0} Operation Context {1}", (object)this.cmdContextId, (object)this.wsManCmdOperationHandle); bool flag = false; lock (this.syncObject) { if (this.isClosed) { return; } this.isClosed = true; if (IntPtr.Zero == this.wsManCmdOperationHandle) { flag = true; } } base.CloseAsync(); if (flag) { try { this.RaiseCloseCompleted(); } finally { WSManClientCommandTransportManager.RemoveCmdTransportManager(this.cmdContextId); } } else { BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManCloseCommand, PSOpcode.Disconnect, PSTask.None, (object)this.RunspacePoolInstanceId, (object)this.powershellInstanceId); this.closeCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), WSManClientCommandTransportManager.cmdCloseCallback); WSManNativeApi.WSManCloseCommand(this.wsManCmdOperationHandle, 0, (IntPtr)this.closeCmdCompleted); } }
internal override void CloseAsync() { BaseClientTransportManager.tracer.WriteLine("Closing command with command context: {0} Operation Context {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); bool flag = false; lock (base.syncObject) { if (base.isClosed) { return; } base.isClosed = true; if (IntPtr.Zero == this.wsManCmdOperationHandle) { flag = true; } } base.CloseAsync(); if (!flag) { PSEtwLog.LogAnalyticInformational(PSEventId.WSManCloseCommand, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString() }); this.closeCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdCloseCallback); WSManNativeApi.WSManCloseCommand(this.wsManCmdOperationHandle, 0, (IntPtr)this.closeCmdCompleted); } else { try { base.RaiseCloseCompleted(); } finally { RemoveCmdTransportManager(this.cmdContextId); } } }
internal override void StartReceivingData() { PSEtwLog.LogAnalyticInformational(PSEventId.WSManReceiveShellOutputEx, PSOpcode.Receive, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString(), powershellInstanceId.ToString()); // We should call Receive only once.. WSMan will call the callback multiple times. _shouldStartReceivingData = false; lock (syncObject) { // make sure the transport is not closed. if (isClosed) { tracer.WriteLine("Client Session TM: Transport manager is closed. So returning"); return; } if (receiveDataInitiated) { tracer.WriteLine("Client Session TM: ReceiveData has already been called."); return; } receiveDataInitiated = true; // receive callback _receivedFromRemote = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdReceiveCallback); WSManNativeApi.WSManReceiveShellOutputEx(_wsManShellOperationHandle, _wsManCmdOperationHandle, startInDisconnectedMode ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_RECEIVE_DELAY_OUTPUT_STREAM : 0, _sessnTm.WSManAPIData.OutputStreamSet, _receivedFromRemote, ref _wsManRecieveOperationHandle); } }
/// <summary> /// receive/send operation handles and callback handles should be released/disposed from /// receive/send callback only. Releasing them after CloseOperation() may not cover all /// the scenarios, as WSMan does not guarantee that a rcv/send callback is not called after /// Close completed callback. /// </summary> /// <param name="flags"></param> /// <param name="shouldClearSend"></param> internal void ClearReceiveOrSendResources(int flags, bool shouldClearSend) { if (shouldClearSend) { if (null != _sendToRemoteCompleted) { _sendToRemoteCompleted.Dispose(); _sendToRemoteCompleted = null; } // For send..clear always if (IntPtr.Zero != _wsManSendOperationHandle) { WSManNativeApi.WSManCloseOperation(_wsManSendOperationHandle, 0); _wsManSendOperationHandle = IntPtr.Zero; } } else { // clearing for receive..Clear only when the end of operation is reached. if (flags == (int)WSManNativeApi.WSManCallbackFlags.WSMAN_FLAG_CALLBACK_END_OF_OPERATION) { if (IntPtr.Zero != _wsManRecieveOperationHandle) { WSManNativeApi.WSManCloseOperation(_wsManRecieveOperationHandle, 0); _wsManRecieveOperationHandle = IntPtr.Zero; } if (null != _receivedFromRemote) { _receivedFromRemote.Dispose(); _receivedFromRemote = null; } } } }
/// <summary> /// Used by powershell/pipeline to send a stop message to the server command /// </summary> internal override void SendStopSignal() { lock (syncObject) { if (isClosed == true) { return; } // WSMan API do not allow a signal/input/receive be sent until RunShellCommand is // successful (ie., callback is received)..so note that a signal is to be sent // here and return. if (!_isCreateCallbackReceived) { _isStopSignalPending = true; return; } // we are about to send a signal..so clear pending bit. _isStopSignalPending = false; tracer.WriteLine("Sending stop signal with command context: {0} Operation Context {1}", _cmdContextId, _wsManCmdOperationHandle); PSEtwLog.LogAnalyticInformational(PSEventId.WSManSignal, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString(), powershellInstanceId.ToString(), StopSignal); _signalCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdSignalCallback); WSManNativeApi.WSManSignalShellEx(_wsManShellOperationHandle, _wsManCmdOperationHandle, 0, StopSignal, _signalCmdCompleted, ref _cmdSignalOperationHandle); } }
/// <summary> /// </summary> /// <exception cref="PSRemotingTransportException"> /// WSManConnectShellCommandEx failed. /// </exception> internal override void ConnectAsync() { Dbg.Assert(!isClosed, "object already disposed"); ReceivedDataCollection.PrepareForStreamConnect(); // Empty the serializedPipeline data that contains PowerShell command information created in the // constructor. We are connecting to an existing command on the server and don't want to send // information on a new command. serializedPipeline.Read(); // create cmdContextId _cmdContextId = GetNextCmdTMHandleId(); AddCmdTransportManager(_cmdContextId, this); // Create Callback _connectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdConnectCallback); _reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdReconnectCallback); lock (syncObject) { if (isClosed) { // the transport is already closed..so no need to create a connection // anymore. return; } WSManNativeApi.WSManConnectShellCommandEx(_wsManShellOperationHandle, 0, PowershellInstanceId.ToString().ToUpperInvariant(), IntPtr.Zero, IntPtr.Zero, _connectCmdCompleted, ref _wsManCmdOperationHandle); } if (_wsManCmdOperationHandle == IntPtr.Zero) { PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed); TransportErrorOccuredEventArgs eventargs = new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ConnectShellCommandEx); ProcessWSManTransportError(eventargs); return; } }
/// <summary> /// Used by callers to prepare the session transportmanager for a URI redirection. /// This must be called only after Create callback (or Error form create) is received. /// This will close the internal WSMan Session handle. Callers must catch the close /// completed event and call Redirect to perform the redirection. /// </summary> internal override void PrepareForRedirection() { Dbg.Assert(!isClosed, "Transport manager must not be closed while preparing for redirection."); _closeSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionCloseCallback); WSManNativeApi.WSManCloseShell(_wsManShellOperationHandle, 0, _closeSessionCompleted); }
/// <summary> /// Starts connecting to remote end asynchronously. This will result in a WSManCreateShellEx WSMan /// async call. By the time this call returns, we will have a valid handle, if the operation /// succeeds. Make sure other methods are called only after this method returns. Thread /// synchronization is left to the caller. /// </summary> /// <exception cref="PSRemotingTransportException"> /// WSManCreateShellEx failed. /// </exception> internal override void CreateAsync() { Dbg.Assert(!isClosed, "object already disposed"); Dbg.Assert(!String.IsNullOrEmpty(ConnectionInfo.ShellUri), "shell uri cannot be null or empty."); Dbg.Assert(WSManAPIData != null, "WSManApiData should always be created before session creation."); List<WSManNativeApi.WSManOption> shellOptions = new List<WSManNativeApi.WSManOption>(WSManAPIData.CommonOptionSet); #region SHIM: Redirection code for protocol version if (s_protocolVersionRedirect != null) { string newProtocolVersion = (string)s_protocolVersionRedirect.DynamicInvoke(); shellOptions.Clear(); WSManNativeApi.WSManOption newPrtVOption = new WSManNativeApi.WSManOption(); newPrtVOption.name = RemoteDataNameStrings.PS_STARTUP_PROTOCOL_VERSION_NAME; newPrtVOption.value = newProtocolVersion; newPrtVOption.mustComply = true; shellOptions.Add(newPrtVOption); } #endregion // Pass the WSManConnectionInfo object IdleTimeout value if it is // valid. Otherwise pass the default value that instructs the server // to use its default IdleTimeout value. uint uIdleTimeout = (ConnectionInfo.IdleTimeout > 0) ? (uint)ConnectionInfo.IdleTimeout : UseServerDefaultIdleTimeoutUInt; // startup info WSManNativeApi.WSManShellStartupInfo_ManToUn startupInfo = new WSManNativeApi.WSManShellStartupInfo_ManToUn(WSManAPIData.InputStreamSet, WSManAPIData.OutputStreamSet, uIdleTimeout, _sessionName); // additional content with create shell call. Piggy back first fragment from // the dataToBeSent buffer. if (null == _openContent) { DataPriorityType additionalDataType; byte[] additionalData = dataToBeSent.ReadOrRegisterCallback(null, out additionalDataType); #region SHIM: Redirection code for session data send. bool sendContinue = true; if (s_sessionSendRedirect != null) { object[] arguments = new object[2] { null, additionalData }; sendContinue = (bool)s_sessionSendRedirect.DynamicInvoke(arguments); additionalData = (byte[])arguments[0]; } if (!sendContinue) return; #endregion if (null != additionalData) { // WSMan expects the data to be in XML format (which is text + xml tags) // so convert byte[] into base64 encoded format string base64EncodedDataInXml = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", WSManNativeApi.PS_CREATION_XML_TAG, WSManNativeApi.PS_XML_NAMESPACE, Convert.ToBase64String(additionalData)); _openContent = new WSManNativeApi.WSManData_ManToUn(base64EncodedDataInXml); } } // Create the session context information only once. CreateAsync() can be called multiple // times by RetrySessionCreation for flaky networks. if (_sessionContextID == 0) { // Create and store context for this shell operation. This context is used from various callbacks _sessionContextID = GetNextSessionTMHandleId(); AddSessionTransportManager(_sessionContextID, this); // Create Callback _createSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionCreateCallback); _createSessionCallbackGCHandle = GCHandle.Alloc(_createSessionCallback); } PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateShell, PSOpcode.Connect, PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString()); try { lock (syncObject) { if (isClosed) { // the transport is already closed..so no need to create a connection // anymore. return; } Dbg.Assert(_startMode == WSManTransportManagerUtils.tmStartModes.None, "startMode is not in expected state"); _startMode = WSManTransportManagerUtils.tmStartModes.Create; if (_noMachineProfile) { WSManNativeApi.WSManOption noProfile = new WSManNativeApi.WSManOption(); noProfile.name = WSManNativeApi.NoProfile; noProfile.mustComply = true; noProfile.value = "1"; shellOptions.Add(noProfile); } int flags = _noCompression ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_NO_COMPRESSION : 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Block) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK : 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Drop) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP : 0; using (WSManNativeApi.WSManOptionSet optionSet = new WSManNativeApi.WSManOptionSet(shellOptions.ToArray())) { WSManNativeApi.WSManCreateShellEx(_wsManSessionHandle, flags, ConnectionInfo.ShellUri, RunspacePoolInstanceId.ToString().ToUpperInvariant(), startupInfo, optionSet, _openContent, _createSessionCallback, ref _wsManShellOperationHandle); } } if (_wsManShellOperationHandle == IntPtr.Zero) { TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(WSManAPIData.WSManAPIHandle, this, new WSManNativeApi.WSManError(), TransportMethodEnum.CreateShellEx, RemotingErrorIdStrings.ConnectExFailed, this.ConnectionInfo.ComputerName); ProcessWSManTransportError(eventargs); return; } } finally { startupInfo.Dispose(); } }
internal override void DisconnectAsync() { Dbg.Assert(!isClosed, "object already disposed"); // Pass the WSManConnectionInfo object IdleTimeout value if it is // valid. Otherwise pass the default value that instructs the server // to use its default IdleTimeout value. uint uIdleTimeout = (ConnectionInfo.IdleTimeout > 0) ? (uint)ConnectionInfo.IdleTimeout : UseServerDefaultIdleTimeoutUInt; // startup info WSManNativeApi.WSManShellDisconnectInfo disconnectInfo = new WSManNativeApi.WSManShellDisconnectInfo(uIdleTimeout); //Add ETW traces // disconnect Callback _disconnectSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionDisconnectCallback); try { lock (syncObject) { if (isClosed) { // the transport is already closed // anymore. return; } int flags = 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Block) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK : 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Drop) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP : 0; WSManNativeApi.WSManDisconnectShellEx(_wsManShellOperationHandle, flags, disconnectInfo, _disconnectSessionCompleted); } } finally { disconnectInfo.Dispose(); } }
internal override void ConnectAsync() { base.ReceivedDataCollection.PrepareForStreamConnect(); if (this.openContent == null) { DataPriorityType type; byte[] inArray = base.dataToBeSent.ReadOrRegisterCallback(null, out type); if (inArray != null) { string data = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", new object[] { "connectXml", "http://schemas.microsoft.com/powershell", Convert.ToBase64String(inArray, Base64FormattingOptions.None) }); this.openContent = new WSManNativeApi.WSManData(data); } if (base.dataToBeSent.ReadOrRegisterCallback(null, out type) != null) { return; } } this.sessionContextID = GetNextSessionTMHandleId(); AddSessionTransportManager(this.sessionContextID, this); this.supportsDisconnect = true; this.connectSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionConnectCallback); lock (base.syncObject) { if (base.isClosed) { return; } this.startMode = WSManTransportManagerUtils.tmStartModes.Connect; int flags = 0; flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Block) ? 8 : 0; flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Drop) ? 4 : 0; WSManNativeApi.WSManConnectShellEx(this.wsManSessionHandle, flags, this._connectionInfo.ShellUri, base.RunspacePoolInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), IntPtr.Zero, (IntPtr) this.openContent, (IntPtr) this.connectSessionCallback, ref this.wsManShellOperationHandle); } if (this.wsManShellOperationHandle == IntPtr.Zero) { TransportErrorOccuredEventArgs eventArgs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(wsManApiStaticData.WSManAPIHandle, this, new WSManNativeApi.WSManError(), TransportMethodEnum.ConnectShellEx, RemotingErrorIdStrings.ConnectExFailed, new object[] { this.ConnectionInfo.ComputerName }); this.ProcessWSManTransportError(eventArgs); } }
internal override void PrepareForRedirection() { this.closeSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), WSManClientSessionTransportManager.sessionCloseCallback); WSManNativeApi.WSManCloseShell(this.wsManShellOperationHandle, 0, (IntPtr)this.closeSessionCompleted); }
internal override void CreateAsync() { List<WSManNativeApi.WSManOption> list = new List<WSManNativeApi.WSManOption>(wsManApiStaticData.CommonOptionSet); if (protocolVersionRedirect != null) { string str = (string) protocolVersionRedirect.DynamicInvoke(new object[0]); list.Clear(); WSManNativeApi.WSManOption item = new WSManNativeApi.WSManOption { name = "protocolversion", value = str, mustComply = true }; list.Add(item); } int serverIdleTimeOut = (this._connectionInfo.IdleTimeout > 0) ? ((int) this._connectionInfo.IdleTimeout) : int.MaxValue; WSManNativeApi.WSManShellStartupInfo startupInfo = new WSManNativeApi.WSManShellStartupInfo(wsManApiStaticData.InputStreamSet, wsManApiStaticData.OutputStreamSet, serverIdleTimeOut, this.sessionName); if (this.openContent == null) { DataPriorityType type; byte[] inArray = base.dataToBeSent.ReadOrRegisterCallback(null, out type); bool flag = true; if (sessionSendRedirect != null) { object[] objArray2 = new object[2]; objArray2[1] = inArray; object[] objArray = objArray2; flag = (bool) sessionSendRedirect.DynamicInvoke(objArray); inArray = (byte[]) objArray[0]; } if (!flag) { return; } if (inArray != null) { string data = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", new object[] { "creationXml", "http://schemas.microsoft.com/powershell", Convert.ToBase64String(inArray, Base64FormattingOptions.None) }); this.openContent = new WSManNativeApi.WSManData(data); } } this.sessionContextID = GetNextSessionTMHandleId(); AddSessionTransportManager(this.sessionContextID, this); PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateShell, PSOpcode.Connect, PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString() }); this.createSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionCreateCallback); this.createSessionCallbackGCHandle = GCHandle.Alloc(this.createSessionCallback); try { lock (base.syncObject) { if (base.isClosed) { return; } this.startMode = WSManTransportManagerUtils.tmStartModes.Create; if (this.noMachineProfile) { WSManNativeApi.WSManOption option2 = new WSManNativeApi.WSManOption { name = "WINRS_NOPROFILE", mustComply = true, value = "1" }; list.Add(option2); } int flags = this.noCompression ? 1 : 0; flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Block) ? 8 : 0; flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Drop) ? 4 : 0; using (WSManNativeApi.WSManOptionSet set = new WSManNativeApi.WSManOptionSet(list.ToArray())) { WSManNativeApi.WSManCreateShellEx(this.wsManSessionHandle, flags, this._connectionInfo.ShellUri, base.RunspacePoolInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), startupInfo, set, this.openContent, (IntPtr) this.createSessionCallback, ref this.wsManShellOperationHandle); } } if (this.wsManShellOperationHandle == IntPtr.Zero) { TransportErrorOccuredEventArgs eventArgs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(wsManApiStaticData.WSManAPIHandle, this, new WSManNativeApi.WSManError(), TransportMethodEnum.CreateShellEx, RemotingErrorIdStrings.ConnectExFailed, new object[] { this.ConnectionInfo.ComputerName }); this.ProcessWSManTransportError(eventArgs); } } finally { startupInfo.Dispose(); } }
internal override void ConnectAsync() { List <WSManNativeApi.WSManOption> wsManOptionList = new List <WSManNativeApi.WSManOption>((IEnumerable <WSManNativeApi.WSManOption>)WSManClientSessionTransportManager.wsManApiStaticData.CommonOptionSet); if ((object)WSManClientSessionTransportManager.protocolVersionRedirect != null) { string str = (string)WSManClientSessionTransportManager.protocolVersionRedirect.DynamicInvoke(); wsManOptionList.Clear(); wsManOptionList.Add(new WSManNativeApi.WSManOption() { name = "protocolversion", value = str, mustComply = true }); } WSManNativeApi.WSManShellStartupInfo startupInfo = new WSManNativeApi.WSManShellStartupInfo(WSManClientSessionTransportManager.wsManApiStaticData.InputStreamSet, WSManClientSessionTransportManager.wsManApiStaticData.OutputStreamSet, 0L > this.idleTimeout || this.idleTimeout >= (long)uint.MaxValue ? uint.MaxValue : (uint)this.idleTimeout); if (this.openContent == null) { byte[] inArray = this.dataToBeSent.ReadOrRegisterCallback((PrioritySendDataCollection.OnDataAvailableCallback)null, out DataPriorityType _); bool flag = true; if ((object)WSManClientSessionTransportManager.sessionSendRedirect != null) { object[] objArray = new object[2] { null, (object)inArray }; flag = (bool)WSManClientSessionTransportManager.sessionSendRedirect.DynamicInvoke(objArray); inArray = (byte[])objArray[0]; } if (!flag) { return; } if (inArray != null) { this.openContent = new WSManNativeApi.WSManData(string.Format((IFormatProvider)CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", (object)"creationXml", (object)"http://schemas.microsoft.com/powershell", (object)Convert.ToBase64String(inArray, Base64FormattingOptions.None))); } } this.sessionContextID = WSManClientSessionTransportManager.GetNextSessionTMHandleId(); WSManClientSessionTransportManager.AddSessionTransportManager(this.sessionContextID, this); BaseTransportManager.ETWTracer.AnalyticChannel.WriteInformation(PSEventId.WSManCreateShell, PSOpcode.Connect, PSTask.CreateRunspace, (object)this.RunspacePoolInstanceId); this.createSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), WSManClientSessionTransportManager.sessionCreateCallback); this.createSessionCompletedGCHandle = GCHandle.Alloc((object)this.createSessionCompleted); try { lock (this.syncObject) { if (this.isClosed) { return; } if (this.noMachineProfile) { wsManOptionList.Add(new WSManNativeApi.WSManOption() { name = "WINRS_NOPROFILE", mustComply = true, value = "1" }); } using (WSManNativeApi.WSManOptionSet optionSet = new WSManNativeApi.WSManOptionSet(wsManOptionList.ToArray())) WSManNativeApi.WSManCreateShellEx(this.wsManSessionHandle, this.noCompression ? 1 : 0, this.resourceUri, startupInfo, optionSet, this.openContent, (IntPtr)this.createSessionCompleted, ref this.wsManShellOperationHandle); } if (!(this.wsManShellOperationHandle == IntPtr.Zero)) { return; } this.RaiseErrorHandler(WSManTransportManagerUtils.ConstructTransportErrorEventArgs(WSManClientSessionTransportManager.wsManApiStaticData.WSManAPIHandle, IntPtr.Zero, new WSManNativeApi.WSManError(), TransportMethodEnum.CreateShellEx, PSRemotingErrorId.ConnectExFailed)); } finally { startupInfo.Dispose(); } }
internal override void DisconnectAsync() { int serverIdleTimeOut = (this._connectionInfo.IdleTimeout > 0) ? ((int) this._connectionInfo.IdleTimeout) : int.MaxValue; WSManNativeApi.WSManShellDisconnectInfo info = new WSManNativeApi.WSManShellDisconnectInfo(serverIdleTimeOut); this.disconnectSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionDisconnectCallback); try { lock (base.syncObject) { if (!base.isClosed) { int flags = 0; flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Block) ? 8 : 0; flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Drop) ? 4 : 0; WSManNativeApi.WSManDisconnectShellEx(this.wsManShellOperationHandle, flags, (IntPtr) info, (IntPtr) this.disconnectSessionCompleted); } } } finally { info.Dispose(); } }
internal override void PrepareForRedirection() { this.closeSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionCloseCallback); WSManNativeApi.WSManCloseShell(this.wsManShellOperationHandle, 0, (IntPtr) this.closeSessionCompleted); }
internal override void StartReceivingData() { PSEtwLog.LogAnalyticInformational(PSEventId.WSManReceiveShellOutputEx, PSOpcode.Receive, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString() }); this.shouldStartReceivingData = false; lock (base.syncObject) { if (base.isClosed) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Transport manager is closed. So returning", new object[0]); } else if (base.receiveDataInitiated) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Command ReceiveData has already been called.", new object[0]); } else { base.receiveDataInitiated = true; this.receivedFromRemote = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdReceiveCallback); WSManNativeApi.WSManReceiveShellOutputEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, base.startInDisconnectedMode ? 0x10 : 0, (IntPtr) WSManClientSessionTransportManager.wsManApiStaticData.OutputStreamSet, (IntPtr) this.receivedFromRemote, ref this.wsManRecieveOperationHandle); } } }
internal void ClearReceiveOrSendResources(int flags, bool shouldClearSend) { if (shouldClearSend) { if (this.sendToRemoteCompleted != null) { this.sendToRemoteCompleted.Dispose(); this.sendToRemoteCompleted = null; } if (IntPtr.Zero != this.wsManSendOperationHandle) { WSManNativeApi.WSManCloseOperation(this.wsManSendOperationHandle, 0); this.wsManSendOperationHandle = IntPtr.Zero; } } else if (flags == 1) { if (IntPtr.Zero != this.wsManRecieveOperationHandle) { WSManNativeApi.WSManCloseOperation(this.wsManRecieveOperationHandle, 0); this.wsManRecieveOperationHandle = IntPtr.Zero; } if (this.receivedFromRemote != null) { this.receivedFromRemote.Dispose(); this.receivedFromRemote = null; } } }
/// <summary> /// Starts connecting to an existing remote session. This will result in a WSManConnectShellEx WSMan /// async call. Piggy backs available data in input stream as openXml in connect SOAP. /// DSHandler will push negotiation related messages through the open content /// </summary> /// <exception cref="PSRemotingTransportException"> /// WSManConnectShellEx failed. /// </exception> internal override void ConnectAsync() { Dbg.Assert(!isClosed, "object already disposed"); Dbg.Assert(!String.IsNullOrEmpty(ConnectionInfo.ShellUri), "shell uri cannot be null or empty."); ReceivedDataCollection.PrepareForStreamConnect(); // additional content with connect shell call. Negotiation and connect related messages // should be included in payload if (null == _openContent) { DataPriorityType additionalDataType; byte[] additionalData = dataToBeSent.ReadOrRegisterCallback(null, out additionalDataType); if (null != additionalData) { // WSMan expects the data to be in XML format (which is text + xml tags) // so convert byte[] into base64 encoded format string base64EncodedDataInXml = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", WSManNativeApi.PS_CONNECT_XML_TAG, WSManNativeApi.PS_XML_NAMESPACE, Convert.ToBase64String(additionalData)); _openContent = new WSManNativeApi.WSManData_ManToUn(base64EncodedDataInXml); } //THERE SHOULD BE NO ADDITIONAL DATA. If there is, it means we are not able to push all initial negotiation related data // as part of Connect SOAP. The connect algorithm is based on this assumption. So bail out. additionalData = dataToBeSent.ReadOrRegisterCallback(null, out additionalDataType); if (additionalData != null) { //Negotiation payload does not fit in ConnectShell. bail out. //Assert for now. should be replaced with raising an exception so upper layers can catch. Dbg.Assert(false, "Negotiation payload does not fit in ConnectShell"); return; } } // Create and store context for this shell operation. This context is used from various callbacks _sessionContextID = GetNextSessionTMHandleId(); AddSessionTransportManager(_sessionContextID, this); //session is implicitly assumed to support disconnect SupportsDisconnect = true; // Create Callback _connectSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionConnectCallback); lock (syncObject) { if (isClosed) { // the transport is already closed..so no need to connect // anymore. return; } Dbg.Assert(_startMode == WSManTransportManagerUtils.tmStartModes.None, "startMode is not in expected state"); _startMode = WSManTransportManagerUtils.tmStartModes.Connect; int flags = 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Block) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK : 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Drop) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP : 0; WSManNativeApi.WSManConnectShellEx(_wsManSessionHandle, flags, ConnectionInfo.ShellUri, RunspacePoolInstanceId.ToString().ToUpperInvariant(), //wsman is case sensitive wrt shellId. so consistently using upper case IntPtr.Zero, _openContent, _connectSessionCallback, ref _wsManShellOperationHandle); } if (_wsManShellOperationHandle == IntPtr.Zero) { TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(WSManAPIData.WSManAPIHandle, this, new WSManNativeApi.WSManError(), TransportMethodEnum.ConnectShellEx, RemotingErrorIdStrings.ConnectExFailed, this.ConnectionInfo.ComputerName); ProcessWSManTransportError(eventargs); return; } }
/// <summary> /// Closes the pending Create,Send,Receive operations and then closes the shell and release all the resources. /// The caller should make sure this method is called only after calling ConnectAsync. /// </summary> internal override void CloseAsync() { bool shouldRaiseCloseCompleted = false; // let other threads release the lock before we clean up the resources. lock (syncObject) { if (isClosed == true) { return; } if (_startMode == WSManTransportManagerUtils.tmStartModes.None) { shouldRaiseCloseCompleted = true; } else if (_startMode == WSManTransportManagerUtils.tmStartModes.Create || _startMode == WSManTransportManagerUtils.tmStartModes.Connect) { if (IntPtr.Zero == _wsManShellOperationHandle) { shouldRaiseCloseCompleted = true; } } else { Dbg.Assert(false, "startMode is in unexpected state"); } // Set boolean indicating that this session is closing. isClosed = true; } base.CloseAsync(); if (shouldRaiseCloseCompleted) { try { RaiseCloseCompleted(); } finally { RemoveSessionTransportManager(_sessionContextID); } return; } //TODO - On unexpected failures on a reconstructed session... we dont want to close server session PSEtwLog.LogAnalyticInformational(PSEventId.WSManCloseShell, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString()); _closeSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionCloseCallback); WSManNativeApi.WSManCloseShell(_wsManShellOperationHandle, 0, _closeSessionCompleted); }
private void CloseSessionAndClearResources() { BaseClientTransportManager.tracer.WriteLine("Clearing session with session context: {0} Operation Context: {1}", new object[] { this.sessionContextID, this.wsManShellOperationHandle }); IntPtr state = this.wsManSessionHandle; this.wsManSessionHandle = IntPtr.Zero; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate (object s) { IntPtr wsManSessionHandle = (IntPtr) s; if (IntPtr.Zero != wsManSessionHandle) { WSManNativeApi.WSManCloseSession(wsManSessionHandle, 0); } }), state); RemoveSessionTransportManager(this.sessionContextID); if (this.closeSessionCompleted != null) { this.closeSessionCompleted.Dispose(); this.closeSessionCompleted = null; } if (this.createSessionCallback != null) { this.createSessionCallbackGCHandle.Free(); this.createSessionCallback.Dispose(); this.createSessionCallback = null; } if (this.connectSessionCallback != null) { this.connectSessionCallback.Dispose(); this.connectSessionCallback = null; } }
/// <summary> /// Closes current session handle by calling WSManCloseSession and clears /// session related resources. /// </summary> private void CloseSessionAndClearResources() { tracer.WriteLine("Clearing session with session context: {0} Operation Context: {1}", _sessionContextID, _wsManShellOperationHandle); // Taking a copy of session handle as we should call WSManCloseSession only once and // clear the original value. This will protect us if Dispose() is called twice. IntPtr tempWSManSessionHandle = _wsManSessionHandle; _wsManSessionHandle = IntPtr.Zero; // Call WSManCloseSession on a different thread as Dispose can be called from one of // the WSMan callback threads. WSMan does not support closing a session in the callbacks. ThreadPool.QueueUserWorkItem(new WaitCallback( // wsManSessionHandle is passed as parameter to allow the thread to be independent // of the rest of the parent object. delegate (object state) { IntPtr sessionHandle = (IntPtr)state; if (sessionHandle != IntPtr.Zero) { WSManNativeApi.WSManCloseSession(sessionHandle, 0); } }), tempWSManSessionHandle); // remove session context from session handles dictionary RemoveSessionTransportManager(_sessionContextID); if (null != _closeSessionCompleted) { _closeSessionCompleted.Dispose(); _closeSessionCompleted = null; } // Dispose the create session completed callback here, since it is // used for periodic robust connection retry/auto-disconnect // notifications while the shell is active. if (null != _createSessionCallback) { _createSessionCallbackGCHandle.Free(); _createSessionCallback.Dispose(); _createSessionCallback = null; } // Dispose the OnConnect callback if one present if (null != _connectSessionCallback) { _connectSessionCallback.Dispose(); _connectSessionCallback = null; } // Reset the session context Id to zero so that a new one will be generated for // any following redirected session. _sessionContextID = 0; }
internal override void ConnectAsync() { base.ReceivedDataCollection.PrepareForStreamConnect(); base.serializedPipeline.Read(); this.cmdContextId = GetNextCmdTMHandleId(); AddCmdTransportManager(this.cmdContextId, this); this.connectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdConnectCallback); this.reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdReconnectCallback); lock (base.syncObject) { if (base.isClosed) { return; } WSManNativeApi.WSManConnectShellCommandEx(this.wsManShellOperationHandle, 0, base.PowershellInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), IntPtr.Zero, IntPtr.Zero, (IntPtr) this.connectCmdCompleted, ref this.wsManCmdOperationHandle); } if (this.wsManCmdOperationHandle == IntPtr.Zero) { PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed); TransportErrorOccuredEventArgs eventArgs = new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ConnectShellCommandEx); this.ProcessWSManTransportError(eventArgs); } }
/// <summary> /// /// </summary> /// <exception cref="PSRemotingTransportException"> /// WSManRunShellCommandEx failed. /// </exception> internal override void CreateAsync() { byte[] cmdPart1 = serializedPipeline.ReadOrRegisterCallback(null); if (null != cmdPart1) { #region SHIM: Redirection code for command code send. bool sendContinue = true; if (s_commandCodeSendRedirect != null) { object[] arguments = new object[2] { null, cmdPart1 }; sendContinue = (bool)s_commandCodeSendRedirect.DynamicInvoke(arguments); cmdPart1 = (byte[])arguments[0]; } if (!sendContinue) return; #endregion WSManNativeApi.WSManCommandArgSet argSet = new WSManNativeApi.WSManCommandArgSet(cmdPart1); // create cmdContextId _cmdContextId = GetNextCmdTMHandleId(); AddCmdTransportManager(_cmdContextId, this); PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateCommand, PSOpcode.Connect, PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString(), powershellInstanceId.ToString()); _createCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdCreateCallback); _createCmdCompletedGCHandle = GCHandle.Alloc(_createCmdCompleted); _reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdReconnectCallback); using (argSet) { lock (syncObject) { if (!isClosed) { WSManNativeApi.WSManRunShellCommandEx(_wsManShellOperationHandle, 0, PowershellInstanceId.ToString().ToUpperInvariant(), // WSManRunsShellCommand doesn't accept empty string "". (_cmdLine == null || _cmdLine.Length == 0) ? " " : (_cmdLine.Length <= 256 ? _cmdLine : _cmdLine.Substring(0, 255)), argSet, IntPtr.Zero, _createCmdCompleted, ref _wsManCmdOperationHandle); tracer.WriteLine("Started cmd with command context : {0} Operation context: {1}", _cmdContextId, _wsManCmdOperationHandle); } } } } if (_wsManCmdOperationHandle == IntPtr.Zero) { PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed); TransportErrorOccuredEventArgs eventargs = new TransportErrorOccuredEventArgs(e, TransportMethodEnum.RunShellCommandEx); ProcessWSManTransportError(eventargs); return; } }
internal override void CreateAsync() { byte[] firstArgument = base.serializedPipeline.ReadOrRegisterCallback(null); if (firstArgument == null) firstArgument = new byte[0]; bool flag = true; if (commandCodeSendRedirect != null) { object[] objArray2 = new object[2]; objArray2[1] = firstArgument; object[] objArray = objArray2; flag = (bool) commandCodeSendRedirect.DynamicInvoke(objArray); firstArgument = (byte[]) objArray[0]; } if (!flag) { return; } WSManNativeApi.WSManCommandArgSet set = new WSManNativeApi.WSManCommandArgSet(firstArgument); this.cmdContextId = GetNextCmdTMHandleId(); AddCmdTransportManager(this.cmdContextId, this); PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateCommand, PSOpcode.Connect, PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString() }); this.createCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdCreateCallback); this.createCmdCompletedGCHandle = GCHandle.Alloc(this.createCmdCompleted); this.reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdReconnectCallback); using (set) { lock (base.syncObject) { if (!base.isClosed) { WSManNativeApi.WSManRunShellCommandEx(this.wsManShellOperationHandle, 0, base.PowershellInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), ((this.cmdLine == null) || (this.cmdLine.Length == 0)) ? " " : ((this.cmdLine.Length <= 0x100) ? this.cmdLine : this.cmdLine.Substring(0, 0xff)), (IntPtr) set, IntPtr.Zero, (IntPtr) this.createCmdCompleted, ref this.wsManCmdOperationHandle); BaseClientTransportManager.tracer.WriteLine("Started cmd with command context : {0} Operation context: {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); } } } if (this.wsManCmdOperationHandle == IntPtr.Zero) { PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed); TransportErrorOccuredEventArgs eventArgs = new TransportErrorOccuredEventArgs(e, TransportMethodEnum.RunShellCommandEx); this.ProcessWSManTransportError(eventArgs); } }
/// <summary> /// Closes the pending Create,Send,Receive operations and then closes the shell and release all the resources. /// </summary> internal override void CloseAsync() { tracer.WriteLine("Closing command with command context: {0} Operation Context {1}", _cmdContextId, _wsManCmdOperationHandle); bool shouldRaiseCloseCompleted = false; // then let other threads release the lock before we cleaning up the resources. lock (syncObject) { if (isClosed == true) { return; } // first change the state..so other threads // will know that we are closing. isClosed = true; // There is no valid cmd operation handle..so just // raise close completed. if (IntPtr.Zero == _wsManCmdOperationHandle) { shouldRaiseCloseCompleted = true; } } base.CloseAsync(); if (shouldRaiseCloseCompleted) { try { RaiseCloseCompleted(); } finally { RemoveCmdTransportManager(_cmdContextId); } return; } PSEtwLog.LogAnalyticInformational(PSEventId.WSManCloseCommand, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString(), powershellInstanceId.ToString()); _closeCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdCloseCallback); Dbg.Assert((IntPtr)_closeCmdCompleted != IntPtr.Zero, "closeCmdCompleted callback is null in cmdTM.CloseAsync()"); WSManNativeApi.WSManCloseCommand(_wsManCmdOperationHandle, 0, _closeCmdCompleted); }
internal override void Dispose (bool isDisposing) { BaseClientTransportManager.tracer.WriteLine ("Disposing command with command context: {0} Operation Context: {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); base.Dispose (isDisposing); RemoveCmdTransportManager (this.cmdContextId); if (this._sessnTm != null) { this._sessnTm.RobustConnectionsInitiated -= new EventHandler<EventArgs> (this.HandleRobustConnectionsIntiated); this._sessnTm.RobustConnectionsCompleted -= new EventHandler<EventArgs> (this.HandleRobusConnectionsCompleted); } if (this.closeCmdCompleted != null) { this.closeCmdCompleted.Dispose(); this.closeCmdCompleted = null; } if (this.reconnectCmdCompleted != null) { this.reconnectCmdCompleted.Dispose(); this.reconnectCmdCompleted = null; } this.wsManCmdOperationHandle = IntPtr.Zero; }
private void SendData(byte[] data, DataPriorityType priorityType) { tracer.WriteLine("Command sending data of size : {0}", data.Length); byte[] package = data; #region SHIM: Redirection code for command data send. bool sendContinue = true; if (s_commandSendRedirect != null) { object[] arguments = new object[2] { null, package }; sendContinue = (bool)s_commandSendRedirect.DynamicInvoke(arguments); package = (byte[])arguments[0]; } if (!sendContinue) return; #endregion using (WSManNativeApi.WSManData_ManToUn serializedContent = new WSManNativeApi.WSManData_ManToUn(package)) { PSEtwLog.LogAnalyticInformational( PSEventId.WSManSendShellInputEx, PSOpcode.Send, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString(), powershellInstanceId.ToString(), serializedContent.BufferLength.ToString(CultureInfo.InvariantCulture)); lock (syncObject) { // make sure the transport is not closed. if (isClosed) { tracer.WriteLine("Client Session TM: Transport manager is closed. So returning"); return; } // send callback _sendToRemoteCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdSendCallback); WSManNativeApi.WSManSendShellInputEx(_wsManShellOperationHandle, _wsManCmdOperationHandle, 0, priorityType == DataPriorityType.Default ? WSManNativeApi.WSMAN_STREAM_ID_STDIN : WSManNativeApi.WSMAN_STREAM_ID_PROMPTRESPONSE, serializedContent, _sendToRemoteCompleted, ref _wsManSendOperationHandle); } } }
private void SendData(byte[] data, DataPriorityType priorityType) { BaseClientTransportManager.tracer.WriteLine("Command sending data of size : {0}", new object[] { data.Length }); byte[] buffer = data; bool flag = true; if (commandSendRedirect != null) { object[] objArray3 = new object[2]; objArray3[1] = buffer; object[] args = objArray3; flag = (bool) commandSendRedirect.DynamicInvoke(args); buffer = (byte[]) args[0]; } if (flag) { using (WSManNativeApi.WSManData data2 = new WSManNativeApi.WSManData(buffer)) { PSEtwLog.LogAnalyticInformational(PSEventId.WSManSendShellInputEx, PSOpcode.Send, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString(), data2.BufferLength.ToString(CultureInfo.InvariantCulture) }); lock (base.syncObject) { if (base.isClosed) { BaseClientTransportManager.tracer.WriteLine("Client Session TM: Transport manager is closed. So returning", new object[0]); } else { this.sendToRemoteCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdSendCallback); WSManNativeApi.WSManSendShellInputEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, 0, (priorityType == DataPriorityType.Default) ? "stdin" : "pr", data2, (IntPtr) this.sendToRemoteCompleted, ref this.wsManSendOperationHandle); } } } } }
internal override void Dispose(bool isDisposing) { tracer.WriteLine("Disposing command with command context: {0} Operation Context: {1}", _cmdContextId, _wsManCmdOperationHandle); base.Dispose(isDisposing); // remove command context from cmd handles dictionary RemoveCmdTransportManager(_cmdContextId); // unregister event handlers if (null != _sessnTm) { _sessnTm.RobustConnectionsInitiated -= HandleRobustConnectionsIntiated; _sessnTm.RobustConnectionsCompleted -= HandleRobusConnectionsCompleted; } if (null != _closeCmdCompleted) { _closeCmdCompleted.Dispose(); _closeCmdCompleted = null; } if (null != _reconnectCmdCompleted) { _reconnectCmdCompleted.Dispose(); _reconnectCmdCompleted = null; } _wsManCmdOperationHandle = IntPtr.Zero; }
internal override void SendStopSignal() { lock (base.syncObject) { if (!base.isClosed) { if (!this.isCreateCallbackReceived) { this.isStopSignalPending = true; } else { this.isStopSignalPending = false; BaseClientTransportManager.tracer.WriteLine("Sending stop signal with command context: {0} Operation Context {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); PSEtwLog.LogAnalyticInformational(PSEventId.WSManSignal, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString(), StopSignal }); this.signalCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdSignalCallback); WSManNativeApi.WSManSignalShellEx(this.wsManShellOperationHandle, this.wsManCmdOperationHandle, 0, StopSignal, (IntPtr) this.signalCmdCompleted, ref this.cmdSignalOperationHandle); } } } }
internal override void ReconnectAsync() { Dbg.Assert(!isClosed, "object already disposed"); ReceivedDataCollection.PrepareForStreamConnect(); //Add ETW traces // reconnect Callback _reconnectSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionReconnectCallback); lock (syncObject) { if (isClosed) { // the transport is already closed // anymore. return; } int flags = 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Block) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK : 0; flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Drop) ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP : 0; WSManNativeApi.WSManReconnectShellEx(_wsManShellOperationHandle, flags, _reconnectSessionCompleted); } }
internal override void CloseAsync() { BaseClientTransportManager.tracer.WriteLine("Closing command with command context: {0} Operation Context {1}", new object[] { this.cmdContextId, this.wsManCmdOperationHandle }); bool flag = false; lock (base.syncObject) { if (base.isClosed) { return; } base.isClosed = true; if (IntPtr.Zero == this.wsManCmdOperationHandle) { flag = true; } } base.CloseAsync(); if (!flag) { PSEtwLog.LogAnalyticInformational(PSEventId.WSManCloseCommand, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString(), this.powershellInstanceId.ToString() }); this.closeCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.cmdContextId), cmdCloseCallback); WSManNativeApi.WSManCloseCommand(this.wsManCmdOperationHandle, 0, (IntPtr) this.closeCmdCompleted); } else { try { base.RaiseCloseCompleted(); } finally { RemoveCmdTransportManager(this.cmdContextId); } } }
internal override void StartReceivingData() { lock (syncObject) { // make sure the transport is not closed. if (isClosed) { tracer.WriteLine("Client Session TM: Transport manager is closed. So returning"); return; } if (receiveDataInitiated) { tracer.WriteLine("Client Session TM: ReceiveData has already been called."); return; } receiveDataInitiated = true; tracer.WriteLine("Client Session TM: Placing Receive request using WSManReceiveShellOutputEx"); PSEtwLog.LogAnalyticInformational(PSEventId.WSManReceiveShellOutputEx, PSOpcode.Receive, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, RunspacePoolInstanceId.ToString(), Guid.Empty.ToString()); _receivedFromRemote = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionReceiveCallback); WSManNativeApi.WSManReceiveShellOutputEx(_wsManShellOperationHandle, IntPtr.Zero, 0, WSManAPIData.OutputStreamSet, _receivedFromRemote, ref _wsManRecieveOperationHandle); } }
internal override void CloseAsync() { bool flag = false; lock (base.syncObject) { if (base.isClosed) { return; } if (this.startMode == WSManTransportManagerUtils.tmStartModes.None) { flag = true; } else if (((this.startMode == WSManTransportManagerUtils.tmStartModes.Create) || (this.startMode == WSManTransportManagerUtils.tmStartModes.Connect)) && (IntPtr.Zero == this.wsManShellOperationHandle)) { flag = true; } base.isClosed = true; } base.CloseAsync(); if (!flag) { PSEtwLog.LogAnalyticInformational(PSEventId.WSManCloseShell, PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString() }); this.closeSessionCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionCloseCallback); WSManNativeApi.WSManCloseShell(this.wsManShellOperationHandle, 0, (IntPtr) this.closeSessionCompleted); } else { try { base.RaiseCloseCompleted(); } finally { RemoveSessionTransportManager(this.sessionContextID); } } }