コード例 #1
0
        /// <summary>
        /// Main Routine for Connect on a Shell.
        /// Calls in server remotesessions ExecuteConnect to run the Connect algorithm
        /// This call is synchronous. i.e WSManOperationComplete will be called before the routine completes.
        /// </summary>
        /// <param name="requestDetails"></param>
        /// <param name="flags"></param>
        /// <param name="inboundConnectInformation"></param>
        internal override void ExecuteConnect(
            WSManNativeApi.WSManPluginRequest requestDetails,           // in
            int flags,                                                  // in
            WSManNativeApi.WSManData_UnToMan inboundConnectInformation) // in optional
        {
            if (inboundConnectInformation == null)
            {
                WSManPluginInstance.ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.NullInvalidInput,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginNullInvalidInput,
                        "inboundConnectInformation",
                        "WSManPluginShellConnect"));
                return;
            }

            // not registering shutdown event as this is a synchronous operation.

            IntPtr responseXml = IntPtr.Zero;

            try
            {
                byte[] inputData;
                byte[] outputData;

                // Retrieve the string (Base64 encoded)
                inputData = ServerOperationHelpers.ExtractEncodedXmlElement(
                    inboundConnectInformation.Text,
                    WSManNativeApi.PS_CONNECT_XML_TAG);

                // this will raise exceptions on failure
                try
                {
                    _remoteSession.ExecuteConnect(inputData, out outputData);

                    // construct Xml to send back
                    string responseData = string.Format(System.Globalization.CultureInfo.InvariantCulture,
                                                        "<{0} xmlns=\"{1}\">{2}</{0}>",
                                                        WSManNativeApi.PS_CONNECTRESPONSE_XML_TAG,
                                                        WSManNativeApi.PS_XML_NAMESPACE,
                                                        Convert.ToBase64String(outputData));

                    // TODO: currently using OperationComplete to report back the responseXml. This will need to change to use WSManReportObject
                    // that is currently internal.
                    WSManPluginInstance.ReportOperationComplete(requestDetails, WSManPluginErrorCodes.NoError, responseData);
                }
                catch (PSRemotingDataStructureException ex)
                {
                    WSManPluginInstance.ReportOperationComplete(requestDetails, WSManPluginErrorCodes.PluginConnectOperationFailed, ex.Message);
                }
            }
            catch (OutOfMemoryException)
            {
                WSManPluginInstance.ReportOperationComplete(requestDetails, WSManPluginErrorCodes.OutOfMemory);
            }
            finally
            {
                if (responseXml != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(responseXml);
                }
            }

            return;
        }
コード例 #2
0
        internal bool EnableTransportManagerSendDataToClient(
            WSManNativeApi.WSManPluginRequest requestDetails,
            WSManPluginOperationShutdownContext ctxtToReport)
        {
            _shutDownContext = ctxtToReport;
            bool isRegisterWaitForSingleObjectSucceeded = true;

            lock (_syncObject)
            {
                if (_isRequestPending)
                {
                    // if a request is already pending..ignore this.
                    WSManPluginInstance.ReportWSManOperationComplete(
                        requestDetails,
                        WSManPluginErrorCodes.NoError);
                    return(false);
                }

                if (_isClosed)
                {
                    WSManPluginInstance.ReportWSManOperationComplete(requestDetails, _lastErrorReported);
                    return(false);
                }

                _isRequestPending = true;
                _requestDetails   = requestDetails;

                if (Platform.IsWindows)
                {
                    // Wrap the provided handle so it can be passed to the registration function
                    SafeWaitHandle  safeWaitHandle  = new SafeWaitHandle(requestDetails.shutdownNotificationHandle, false); // Owned by WinRM
                    EventWaitHandle eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
                    eventWaitHandle.SafeWaitHandle = safeWaitHandle;

                    _registeredShutDownWaitHandle = ThreadPool.RegisterWaitForSingleObject(
                        eventWaitHandle,
                        new WaitOrTimerCallback(WSManPluginManagedEntryWrapper.PSPluginOperationShutdownCallback),
                        _shutDownContext,
                        -1,     // INFINITE
                        true);  // TODO: Do I need to worry not being able to set missing WT_TRANSFER_IMPERSONATION?
                    if (_registeredShutDownWaitHandle == null)
                    {
                        isRegisterWaitForSingleObjectSucceeded = false;
                    }
                }
                // release thread waiting to send data to the client.
                _waitHandle.Set();
            }

            if (!isRegisterWaitForSingleObjectSucceeded)
            {
                WSManPluginInstance.PerformCloseOperation(ctxtToReport);
                WSManPluginInstance.ReportOperationComplete(
                    requestDetails,
                    WSManPluginErrorCodes.ShutdownRegistrationFailed,
                    StringUtil.Format(
                        RemotingErrorIdStrings.WSManPluginShutdownRegistrationFailed));
                return(false);
            }

            return(true);
        }