Beispiel #1
0
 internal static void WSManCreateShellEx(
     IntPtr wsManSessionHandle,
     int flags,
     string resourceUri,
     WSManNativeApi.WSManShellStartupInfo startupInfo,
     WSManNativeApi.WSManOptionSet optionSet,
     WSManNativeApi.WSManData openContent,
     IntPtr asyncCallback,
     ref IntPtr shellOperationHandle)
 {
     WSManNativeApi.WSManCreateShellExInternal(wsManSessionHandle, flags, resourceUri, (IntPtr)startupInfo, (IntPtr)optionSet, (IntPtr)openContent, asyncCallback, ref shellOperationHandle);
 }
        /// <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 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 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();
     }
 }