Exemple #1
0
        public Echo(Options options)
        {
            log.Info("creating echo host");

            log.DebugFormat("create interprocess input pipe (handle={0})", options.pipeIn);
            pipeIn = new AnonymousPipeClientStream(PipeDirection.In, options.pipeIn);
            pipeReader = new StreamReader(pipeIn);

            log.DebugFormat("create interprocess output pipe (handle={0})", options.pipeOut);
            pipeOut = new AnonymousPipeClientStream(PipeDirection.Out, options.pipeOut);
            pipeWriter = new StreamWriter(pipeOut);

            log.Debug("create native messaging port");
            port = new Port(pipeIn, pipeOut);

            log.Debug("create stop event");
            stop = new ManualResetEvent(false);

            log.Debug("synchronize processes");
            string sync = pipeReader.ReadLine();
            log.DebugFormat("sent {0}", sync);
            pipeWriter.WriteLine(sync);
            pipeWriter.Flush();
            log.DebugFormat("received {0}", sync);
            pipeOut.WaitForPipeDrain();

            log.Info("created echo host");
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NamedPipeCommunicationChannel" /> class.
        /// </summary>
        /// <param name="endPoint">The end point.</param>
        /// <param name="pipeStream">An existing pipe stream or <c>null</c> to create client.</param>
        public NamedPipeCommunicationChannel(NamedPipeEndPoint endPoint, PipeStream pipeStream = null)
        {
            _endPoint = endPoint;

            if (pipeStream != null) _pipeStream = pipeStream;
            else
            {
                var client = new NamedPipeClientStream(".", endPoint.Name, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough);

                // connect overload with timeout is extremely processor intensive
                int elapsed = 0, connectionTimeout = endPoint.ConnectionTimeout * 1000;

            CONNECT:
                try
                {
                    client.Connect(0);
                }
                catch (TimeoutException)
                {
                    Thread.Sleep(CONNECT_ATTEMPT_INTERVAL_MS);

                    if (endPoint.ConnectionTimeout != Timeout.Infinite && (elapsed += CONNECT_ATTEMPT_INTERVAL_MS) > connectionTimeout)
                        throw new TimeoutException("The host failed to connect. Timeout occurred.");

                    goto CONNECT;
                }

                _pipeStream = client;
            }

            _buffer = new byte[ReceiveBufferSize];
            _syncLock = new object();
        }
Exemple #3
0
        public Scan(Program.Options options)
        {
            log.Debug("creating scan host");

            log.DebugFormat("create interprocess input pipe (handle={0})", options.pipeIn);
            pipeIn = new AnonymousPipeClientStream(PipeDirection.In, options.pipeIn);

            log.DebugFormat("create interprocess output pipe (handle={0})", options.pipeOut);
            pipeOut = new AnonymousPipeClientStream(PipeDirection.Out, options.pipeOut);

            log.Debug("create sync event");
            sync = new ManualResetEvent(false);

            log.Debug("create native messaging port");
            port = new Port(pipeIn, pipeOut);

            log.Debug("create stop event");
            stop = new ManualResetEvent(false);

            log.Debug("create form");
            form = new Form();
            form.TopMost = true;
            form.BringToFront();

            log.Debug("create hook");
            hook = new WinFormsWindowMessageHook(form);

            log.Debug("create image acquired and image transferred events");
            imageAcquired = new ManualResetEvent(false);
            imageTransferred = new ManualResetEvent(false);

            log.Debug("scan host created");
        }
        public override void Bind(Uri uri)
        {
            EnsureDisconnected();

            var serverPipeStream = new NamedPipeServerStream(uri.PathAndQuery, PipeDirection.InOut); //TODO: Issue #20 - Properly parse URI for Endpoint specification.

            PipeStream = serverPipeStream;
        }
        public override void Disconnect()
        {
            EnsureConnected();

            PipeStream.WaitForPipeDrain();
            PipeStream.Dispose();
            PipeStream = null;
        }
    static void WriteBytesAsync(PipeStream pipeStream, byte[] buffer)
    {
        Assert.True(pipeStream.IsConnected);
        Assert.True(buffer.Length > 0);

        Task writeTask = pipeStream.WriteAsync(buffer, 0, buffer.Length);
        writeTask.Wait();
    }
        public Process Execute(string fileName, string arguments, string currentDirectory, bool interactive, Dictionary<string, string> extraEnvironmentVariables, PipeStream stdinPipeName, PipeStream stdoutPipeName, PipeStream stderrPipeName)
        {
            // C with Win32 API example to start a process under a different user: http://msdn.microsoft.com/en-us/library/aa379608%28VS.85%29.aspx

            if (!this.prison.IsLocked)
            {
                throw new PrisonException("The prison has to be locked before you can use it.");
            }

            this.prison.User.Profile.LoadUserProfileIfNotLoaded();

            var envs = this.prison.User.RetrieveDefaultEnvironmentVariables();

            // environmentVariables from the method parameters have precedence over the default envs
            if (extraEnvironmentVariables != null)
            {
                foreach (var env in extraEnvironmentVariables)
                {
                    envs[env.Key] = env.Value;
                }
            }

            string envBlock = BuildEnvironmentVariable(envs);

            Logger.Debug("Starting process '{0}' with arguments '{1}' as user '{2}' in working directory '{3}'", fileName, arguments, this.prison.User.UserName, this.prison.PrisonHomePath);

            if (string.IsNullOrWhiteSpace(fileName))
            {
                fileName = null;
            }

            if (this.prison.RuleEnabled(RuleTypes.WindowStation))
            {
                var winStationCell = this.prison.prisonCells.First((a) => { return a.RuleType == RuleTypes.WindowStation; });
                winStationCell.Apply(this.prison);
            }

            NativeMethods.PROCESS_INFORMATION processInfo = this.NativeCreateProcessAsUser(interactive, fileName, arguments, currentDirectory, envBlock, stdinPipeName, stdoutPipeName, stderrPipeName);

            NativeMethods.CloseHandle(processInfo.hProcess);
            NativeMethods.CloseHandle(processInfo.hThread);

            var workerProcessPid = processInfo.dwProcessId;
            var workerProcess = Process.GetProcessById(workerProcessPid);

            // Tag the process with the Job Object before resuming the process.
            this.prison.jobObject.AddProcess(workerProcess);

            // Add process in the second job object 
            this.prison.PrisonGuard.AddProcessToGuardJobObject(workerProcess);

            // This would allow the process to query the ExitCode. ref: http://msdn.microsoft.com/en-us/magazine/cc163900.aspx
            workerProcess.EnableRaisingEvents = true;

            ResumeProcess(workerProcess);

            return workerProcess;
        }
 private static byte[] ReadMsg(PipeStream s)
 {
     var ms = new MemoryStream();
     var buffer = new byte[0x1000];
     do
     {
         ms.Write(buffer, 0, s.Read(buffer, 0, buffer.Length));
     } while (!s.IsMessageComplete);
     return ms.ToArray();
 }
Exemple #9
0
 protected static byte[] ReadAllBytes(PipeStream stream)
 {
     var memoryStream = new MemoryStream();
     do
     {
         var buffer = new byte[65536];
         int count = stream.Read(buffer, 0, buffer.Length);
         memoryStream.Write(buffer, 0, count);
     } while (!stream.IsMessageComplete);
     return memoryStream.ToArray();
 }
    static void WriteBytes(PipeStream pipeStream, byte[] buffer)
    {
        Assert.True(pipeStream.IsConnected);
        Assert.True(buffer.Length > 0);

        pipeStream.WriteByte(buffer[0]);
        if (buffer.Length > 1)
        {
            pipeStream.Write(buffer, 1, buffer.Length - 1);
        }
    }
        public override void Connect(Uri uri)
        {
            EnsureDisconnected();

            var clientPipeStream = new NamedPipeClientStream(".", uri.PathAndQuery, PipeDirection.InOut); //TODO: Issue #20 - Properly parse URI for Endpoint specification.

            clientPipeStream.Connect();

            PipeStream = clientPipeStream;

            InitializeFraming(PipeStream);
        }
Exemple #12
0
        public PipeConnection(PipeStream stream)
        {
            trace.Header = "pipe";

            trace.TraceInformation("New Connection");

            m_pipeStream = stream;
            m_stream = new BufferedStream(m_pipeStream);

            m_deserializerThread = new Thread(DeserializerMain);
            m_deserializerThread.Start();
        }
Exemple #13
0
    public void OnAsyncMessage(PipeStream pipe, Byte [] data, Int32 bytes, Object state)
    {
        Console.WriteLine("Message: " + (Int32) state + " bytes: " + bytes);
        data = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(data, 0, bytes).ToUpper().ToCharArray());

        // Write results
        try {
            pipe.BeginWrite(data, 0, bytes, OnAsyncWriteComplete, pipe);
        }
        catch (Exception) {
            pipe.Close();
        }
    }
    static byte[] ReadBytes(PipeStream pipeStream, int length)
    {
        Assert.True(pipeStream.IsConnected);

        byte[] buffer = new byte[length];
        Assert.True(length > 0);

        buffer[0] = (byte)pipeStream.ReadByte();
        if (length > 1)
        {
            int len = pipeStream.Read(buffer, 1, length - 1);
            Assert.Equal(length - 1, len);
        }

        return buffer;
    }
        //public WaitHandle wHandle = new ManualResetEvent (false);
        //public WaitHandle wHandle = new AutoResetEvent (false);
        public void Open(NamedPipeClientStream pipe)
        {
            //if (!pipe.IsConnected)
                pipe.Connect ();

            pipe.ReadMode = PipeTransmissionMode.Byte;
            this.pipe = pipe;
            //socket.Blocking = true;
            //SocketHandle = (long)pipe.SafePipeHandle.DangerousGetHandle ();
            //SocketHandle = (long)pipe.BeginRead()
            //this.ffd = pipe.SafePipeHandle.DangerousGetHandle ();
            //SocketHandle = (long)wHandle.SafeWaitHandle.DangerousGetHandle ();
            //var ovr = new System.Threading.Overlapped ();
            //ovr.AsyncResult = asr;
            Stream = pipe;
            //WaitHandle.WaitAny
        }
    static async Task<byte[]> ReadBytesAsync(PipeStream pipeStream, int length)
    {
        Assert.True(pipeStream.IsConnected);

        byte[] buffer = new byte[length];
        Assert.True(length > 0);

        int readSoFar = 0;

        while (readSoFar < length)
        {
            int len = await pipeStream.ReadAsync(buffer, readSoFar, length - readSoFar);
            if (len == 0) break;
            readSoFar += len;
        }

        return buffer;
    }
    static byte[] ReadBytesAsync(PipeStream pipeStream, int length)
    {
        Assert.True(pipeStream.IsConnected);

        byte[] buffer = new byte[length];
        Assert.True(length > 0);

        int readSoFar = 0;

        while (readSoFar < length)
        {
            Task<int> readTask = pipeStream.ReadAsync(buffer, readSoFar, length - readSoFar);
            readTask.Wait();
            int len = readTask.Result;
            readSoFar += len;
        }

        return buffer;
    }
 public static void DoStreamOperations(PipeStream stream)
 {
     if (stream.CanWrite)
     {
         stream.Write(new byte[] { 123, 124 }, 0, 2);
     }
     if (stream.CanRead)
     {
         if (stream.ReadByte() != 123)
         {
             Console.WriteLine("First byte read != 123");
         }
         if (stream.ReadByte() != 124)
         {
             Console.WriteLine("Second byte read != 124");
         }
     }
     Console.WriteLine("*** Operations finished. ***");
 }
Exemple #19
0
        /// <summary>
        /// The main loop. Arguments are used to setup Inter-Process Communication, so follow the instructions!
        /// </summary>
        /// <param name="arg0">The first command line argument to the program.</param>
        /// <param name="arg1">The second command line argument to the program</param>
        public static void Loop(String arg0, String arg1)
        {
            pipeIn = new AnonymousPipeClientStream(PipeDirection.In, arg0);
            pipeOut = new AnonymousPipeClientStream(PipeDirection.Out, arg1);
            messageReceiver = new MessageReceiver(pipeIn);
            messageSender = new MessageSender(pipeOut);

            while (thinking)
            {
                Message m = messageReceiver.WaitForMessage();
                if (m is InitMessage)
                    RunInitMessage((InitMessage)m);
                else if (m is ExitMessage)
                    RunExitMessage((ExitMessage)m);
                else if (m is MethodCallMessage)
                    RunMethodCallMessage((MethodCallMessage)m);
                else
                    throw new Exception("Shouldn't have received that kind of message!");
            }
        }
Exemple #20
0
        /// <summary>
        /// Read a Request from the given stream.
        /// 
        /// The total request size must be less than 1MB.
        /// </summary>
        /// <returns>null if the Request was too large, the Request otherwise.</returns>
        public static async Task<BuildRequest> ReadAsync(PipeStream inStream, CancellationToken cancellationToken)
        {
            // Read the length of the request
            var lengthBuffer = new byte[4];
            CompilerServerLogger.Log("Reading length of request");
            await BuildProtocolConstants.ReadAllAsync(inStream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
            var length = BitConverter.ToInt32(lengthBuffer, 0);

            // Back out if the request is > 1MB
            if (length > 0x100000)
            {
                CompilerServerLogger.Log("Request is over 1MB in length, cancelling read.");
                return null;
            }

            cancellationToken.ThrowIfCancellationRequested();

            // Read the full request
            var responseBuffer = new byte[length];
            await BuildProtocolConstants.ReadAllAsync(inStream, responseBuffer, length, cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();

            CompilerServerLogger.Log("Parsing request");
            // Parse the request into the Request data structure.
            using (var reader = new BinaryReader(new MemoryStream(responseBuffer), Encoding.Unicode))
            {
                uint requestId = reader.ReadUInt32();
                uint argumentCount = reader.ReadUInt32();

                var argumentsBuilder = ImmutableArray.CreateBuilder<Argument>((int)argumentCount);

                for (int i = 0; i < argumentCount; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    argumentsBuilder.Add(BuildRequest.Argument.ReadFromBinaryReader(reader));
                }

                return new BuildRequest(requestId, argumentsBuilder.ToImmutable());
            }
        }
		public static int Read(PipeStream stream, byte[] buffer, int offset, int count, bool isAsync, TimeoutHelper timeoutHelper)
		{
			// 异步时,使用异步方式读取数据
			if (isAsync)
			{
				IAsyncResult asyncResult = stream.BeginRead(buffer, offset, count, null, null);

				// 等待 timeoutHelper 计算后的剩余时间,如果在这段时间内没有读到数据,那么将直接返回,这时,由于没有读到数据,返回的数据长度为 0
				asyncResult.AsyncWaitHandle.WaitOne(timeoutHelper == null ? 60000 : (int)timeoutHelper.RemainingTime().TotalMilliseconds);

				if (asyncResult.GetType() == pipeStreamAsyncResultType)
				{
				    pipeStreamAsyncResult_waitHandle.SetValue(asyncResult, null);
				}

				return stream.EndRead(asyncResult);
			}

			// 使用系统内置的方式进行同步阻塞式读取,该方法直到读取到数据才返回
			return stream.Read(buffer, offset, count);
		}
Exemple #22
0
        private void WaitForConnection(IAsyncResult ar)
        {
            NamedPipeServerStream server = ar.AsyncState as NamedPipeServerStream;
            server.EndWaitForConnection(ar);

            pipe = server;
            isReady = true;
        }
Exemple #23
0
        protected void HandlePipeConnection(PipeStream pipeStream, IDictionary<string, object> initialMessage)
        {
            // You think we'd scope these with using() right? They are IDisposable
            //  after all... but nope, the implementation of these is such that
            //  disposing of them also disposes the underlying stream.  Leaving us
            //  with a double (or triple if we close the pipeServer stream ourselves)
            //  close.  Yay.  Instead we abandoned these to the GC knowing that they
            //  are only wrappers anyway and have/use little/no resources of their own.
            BinaryReader reader = new BinaryReader(pipeStream, Encoding.Unicode);
            BinaryWriter writer = new BinaryWriter(pipeStream, Encoding.Unicode);

            try
            {
                // If we should announce with a specific message, do so
                if (initialMessage != null)
                {
                    WriteMessage(writer, initialMessage);
                }

                // So long as our Func<> returns true, we keep going.  When it returns false,
                //  it is done and its time to closeup and look for another client.
                while (StreamAction(reader, writer)) { }
            }
            catch(Exception e)
            {
                LibraryLogging.Error("Error while using pipe connection: {0}", e);
            }

            try
            {
                pipeStream.Flush();
                pipeStream.WaitForPipeDrain();
                pipeStream.Close();
            }
            catch(Exception e)
            {
                LibraryLogging.Error("Error while flushing/closing pipe connection: {0}", e);
            }
        }
Exemple #24
0
        private bool TryConnect(int timeout, CancellationToken cancellationToken)
        {
            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(_inheritability);

            int _pipeFlags = (int)_pipeOptions;

            if (_impersonationLevel != TokenImpersonationLevel.None)
            {
                _pipeFlags |= Interop.mincore.SecurityOptions.SECURITY_SQOS_PRESENT;
                _pipeFlags |= (((int)_impersonationLevel - 1) << 16);
            }

            if (!Interop.mincore.WaitNamedPipe(_normalizedPipePath, timeout))
            {
                int errorCode = Marshal.GetLastWin32Error();

                // Server is not yet created
                if (errorCode == Interop.mincore.Errors.ERROR_FILE_NOT_FOUND)
                {
                    return(false);
                }

                // The timeout has expired.
                if (errorCode == Interop.mincore.Errors.ERROR_SUCCESS)
                {
                    if (cancellationToken.CanBeCanceled)
                    {
                        // It may not be real timeout.
                        return(false);
                    }
                    throw new TimeoutException();
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            // Pipe server should be free.  Let's try to connect to it.
            int access = 0;

            if ((PipeDirection.In & _direction) != 0)
            {
                access |= Interop.mincore.GenericOperations.GENERIC_READ;
            }
            if ((PipeDirection.Out & _direction) != 0)
            {
                access |= Interop.mincore.GenericOperations.GENERIC_WRITE;
            }
            SafePipeHandle handle = Interop.mincore.CreateNamedPipeClient(_normalizedPipePath,
                                                                          access,        // read and write access
                                                                          0,             // sharing: none
                                                                          ref secAttrs,  // security attributes
                                                                          FileMode.Open, // open existing
                                                                          _pipeFlags,    // impersonation flags
                                                                          IntPtr.Zero);  // template file: null

            if (handle.IsInvalid)
            {
                int errorCode = Marshal.GetLastWin32Error();

                // Handle the possible race condition of someone else connecting to the server
                // between our calls to WaitNamedPipe & CreateFile.
                if (errorCode == Interop.mincore.Errors.ERROR_PIPE_BUSY)
                {
                    return(false);
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }

            // Success!
            InitializeHandle(handle, false, (_pipeOptions & PipeOptions.Asynchronous) != 0);
            State = PipeState.Connected;

            return(true);
        }
Exemple #25
0
        public void Start(Boolean isClient)
        {
            if (isClient) {
                NamedPipeClientStream client = new NamedPipeClientStream(".", _pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
                client.Connect(10000); // 10 second timeout.

                pipe = client;
                isReady = true;
            } else {
                // Grant read/write access to everyone, so the pipe can be written to from impersonated processes
                PipeSecurity pipeSecurity = new PipeSecurity();
                pipeSecurity.SetAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow));
                NamedPipeServerStream server = new NamedPipeServerStream(_pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 4096, 4096, pipeSecurity);
                server.BeginWaitForConnection(new AsyncCallback(WaitForConnection), server);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="OverlappingPipeStream"/> class.
 /// </summary>
 /// <param name="stream">The stream.</param>
 /// <param name="bufferSize">Size of the buffer.</param>
 public OverlappingPipeStream([NotNull] PipeStream stream, int bufferSize = 0)
 {
     if (stream == null) throw new ArgumentNullException("stream");
     Stream = stream;
     if (bufferSize < 1) bufferSize = 1024;
     _buffer = new byte[bufferSize];
 }
        protected override int Read(byte[] buffer, int offset, int count)
        {
            pipe = (PipeStream)Stream;
            AsyncCallback cb = delegate (IAsyncResult ar)
            {
                //wHandle = ar.AsyncWaitHandle;

                pipe.EndRead (ar);
                ((ManualResetEvent)wHandle).Set ();

            };

            //((AutoResetEvent)wHandle).
            IAsyncResult iar = pipe.BeginRead (buffer, offset, count, cb, wHandle);

            Thread.Sleep (100);
            wHandle.WaitOne ();
            ((ManualResetEvent)wHandle).Reset ();

            return count;
        }
        private int _numBytes; // number of buffer read OR written

        internal ReadWriteCompletionSource(PipeStream stream, ReadOnlyMemory <byte> bufferToPin, bool isWrite)
            : base(stream._threadPoolBinding !, bufferToPin)
Exemple #29
0
        /// <summary>
        /// Überträgt ein Objekt in eine Kommunikationseinheit.
        /// </summary>
        /// <param name="pipe">Die Kommunikationseinheit.</param>
        /// <param name="serializer">Die Serialisierungsinstanz.</param>
        /// <param name="instance">Das betroffene Objekt.</param>
        internal static void SendToPipe( PipeStream pipe, XmlSerializer serializer, object instance )
        {
            // Create helper
            using (var temp = new MemoryStream())
            {
                // Create writer configuration
                var settings = new XmlWriterSettings { CheckCharacters = false };

                // Create
                using (var writer = XmlWriter.Create( temp, settings ))
                    serializer.Serialize( writer, instance );

                // Read data and create buffer for length
                var len = new byte[sizeof( long )];
                var data = temp.ToArray();

                // Lock briefly
                var lenLock = GCHandle.Alloc( len, GCHandleType.Pinned );
                try
                {
                    // Fill
                    Marshal.WriteInt64( lenLock.AddrOfPinnedObject(), data.LongLength );
                }
                finally
                {
                    // Release
                    lenLock.Free();
                }

                // Send all
                pipe.Write( len, 0, len.Length );

                // Write in blocks
                for (int n = 0; n < data.Length; )
                {
                    // Block size
                    int block = Math.Min( BlockSize, data.Length - n );

                    // Send chunck
                    pipe.Write( data, n, block );
                    pipe.Flush();

                    // Advance
                    n += block;
                }

                // Flush
                pipe.Flush();
                pipe.WaitForPipeDrain();
            }
        }
 public NamedPipeConnection(System.IO.Pipes.PipeStream stream)
 {
     this.stream = stream;
 }
        // Waits for a pipe instance to become available. This method may return before WaitForConnection is called
        // on the server end, but WaitForConnection will not return until we have returned.  Any data written to the
        // pipe by us after we have connected but before the server has called WaitForConnection will be available
        // to the server after it calls WaitForConnection.
        private bool TryConnect(int timeout, CancellationToken cancellationToken)
        {
            Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(_inheritability);

            // PipeOptions.CurrentUserOnly is special since it doesn't match directly to a corresponding Win32 valid flag.
            // Remove it, while keeping others untouched since historically this has been used as a way to pass flags to
            // CreateNamedPipeClient that were not defined in the enumeration.
            int _pipeFlags = (int)(_pipeOptions & ~PipeOptions.CurrentUserOnly);

            if (_impersonationLevel != TokenImpersonationLevel.None)
            {
                _pipeFlags |= Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT;
                _pipeFlags |= (((int)_impersonationLevel - 1) << 16);
            }

            int access = 0;

            if ((PipeDirection.In & _direction) != 0)
            {
                access |= Interop.Kernel32.GenericOperations.GENERIC_READ;
            }
            if ((PipeDirection.Out & _direction) != 0)
            {
                access |= Interop.Kernel32.GenericOperations.GENERIC_WRITE;
            }

            // Let's try to connect first
            SafePipeHandle handle = Interop.Kernel32.CreateNamedPipeClient(_normalizedPipePath,
                                                                           access,        // read and write access
                                                                           0,             // sharing: none
                                                                           ref secAttrs,  // security attributes
                                                                           FileMode.Open, // open existing
                                                                           _pipeFlags,    // impersonation flags
                                                                           IntPtr.Zero);  // template file: null

            if (handle.IsInvalid)
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode != Interop.Errors.ERROR_PIPE_BUSY &&
                    errorCode != Interop.Errors.ERROR_FILE_NOT_FOUND)
                {
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }

                if (!Interop.Kernel32.WaitNamedPipe(_normalizedPipePath, timeout))
                {
                    errorCode = Marshal.GetLastWin32Error();

                    // Server is not yet created or a timeout occurred before a pipe instance was available.
                    if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND ||
                        errorCode == Interop.Errors.ERROR_SEM_TIMEOUT)
                    {
                        return(false);
                    }

                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }

                // Pipe server should be free.  Let's try to connect to it.
                handle = Interop.Kernel32.CreateNamedPipeClient(_normalizedPipePath,
                                                                access,        // read and write access
                                                                0,             // sharing: none
                                                                ref secAttrs,  // security attributes
                                                                FileMode.Open, // open existing
                                                                _pipeFlags,    // impersonation flags
                                                                IntPtr.Zero);  // template file: null

                if (handle.IsInvalid)
                {
                    errorCode = Marshal.GetLastWin32Error();

                    // Handle the possible race condition of someone else connecting to the server
                    // between our calls to WaitNamedPipe & CreateFile.
                    if (errorCode == Interop.Errors.ERROR_PIPE_BUSY)
                    {
                        return(false);
                    }

                    throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                }
            }

            // Success!
            InitializeHandle(handle, false, (_pipeOptions & PipeOptions.Asynchronous) != 0);
            State = PipeState.Connected;
            ValidateRemotePipeUser();
            return(true);
        }
 protected PipeValueTaskSource(PipeStream pipeStream)
 {
     _pipeStream = pipeStream;
     _source.RunContinuationsAsynchronously = true;
     _preallocatedOverlapped = new PreAllocatedOverlapped(s_ioCallback, this, null);
 }
Exemple #33
0
 public static System.IO.Pipes.PipeSecurity GetAccessControl(System.IO.Pipes.PipeStream stream)
 {
     throw null;
 }
Exemple #34
0
 public static void SetAccessControl(System.IO.Pipes.PipeStream stream, System.IO.Pipes.PipeSecurity pipeSecurity)
 {
 }
Exemple #35
0
        // The IsConnected property on named pipes does not detect when the client has disconnected
        // if we don't attempt any new I/O after the client disconnects. We start an async I/O here
        // which serves to check the pipe for disconnection. 
        private async Task MonitorPipeForDisconnectionAsync(PipeStream pipeStream, CancellationToken cancellationToken)
        {
            byte[] buffer = new byte[0];

            while (!cancellationToken.IsCancellationRequested && pipeStream.IsConnected)
            {
                CompilerServerLogger.Log("Before poking pipe.");
                try
                {
                    await pipeStream.ReadAsync(buffer, 0, 0).ConfigureAwait(continueOnCapturedContext: false);
                }
                catch (ObjectDisposedException)
                {
                    // Another thread may have closed the stream already.  Not a problem.
                    CompilerServerLogger.Log("Pipe has already been closed.");
                    return;
                }
                CompilerServerLogger.Log("After poking pipe.");
                // Wait a hundredth of a second before trying again
                await Task.Delay(10).ConfigureAwait(false);
            }
                
            if (!cancellationToken.IsCancellationRequested)
            {
                throw new PipeBrokenException();
            }
        }
Exemple #36
0
        // This overload is used in Mono to implement public constructors.
        private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances,
                            PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize,
                            PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
        {
            Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty");
            Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction");
            Debug.Assert(inBufferSize >= 0, "inBufferSize is negative");
            Debug.Assert(outBufferSize >= 0, "outBufferSize is negative");
            Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid");
            Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range");

            string fullPipeName = Path.GetFullPath(@"\\.\pipe\" + pipeName);

            // Make sure the pipe name isn't one of our reserved names for anonymous pipes.
            if (String.Equals(fullPipeName, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentOutOfRangeException(nameof(pipeName), SR.ArgumentOutOfRange_AnonymousReserved);
            }

            if (IsCurrentUserOnly)
            {
                Debug.Assert(pipeSecurity == null);

                using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent())
                {
                    SecurityIdentifier identifier = currentIdentity.Owner;

                    // Grant full control to the owner so multiple servers can be opened.
                    // Full control is the default per MSDN docs for CreateNamedPipe.
                    PipeAccessRule rule = new PipeAccessRule(identifier, PipeAccessRights.FullControl, AccessControlType.Allow);
                    pipeSecurity = new PipeSecurity();

                    pipeSecurity.AddAccessRule(rule);
                    pipeSecurity.SetOwner(identifier);
                }

                // PipeOptions.CurrentUserOnly is special since it doesn't match directly to a corresponding Win32 valid flag.
                // Remove it, while keeping others untouched since historically this has been used as a way to pass flags to CreateNamedPipe
                // that were not defined in the enumeration.
                options &= ~PipeOptions.CurrentUserOnly;
            }

            int openMode = ((int)direction) |
                           (maxNumberOfServerInstances == 1 ? Interop.Kernel32.FileOperations.FILE_FLAG_FIRST_PIPE_INSTANCE : 0) |
                           (int)options |
                           (int)additionalAccessRights;

            // We automatically set the ReadMode to match the TransmissionMode.
            int pipeModes = (int)transmissionMode << 2 | (int)transmissionMode << 1;

            // Convert -1 to 255 to match win32 (we asserted that it is between -1 and 254).
            if (maxNumberOfServerInstances == MaxAllowedServerInstances)
            {
                maxNumberOfServerInstances = 255;
            }

            var pinningHandle = new GCHandle();

            try
            {
                Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(inheritability, pipeSecurity, ref pinningHandle);
                SafePipeHandle handle = Interop.Kernel32.CreateNamedPipe(fullPipeName, openMode, pipeModes,
                                                                         maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref secAttrs);

                if (handle.IsInvalid)
                {
                    throw Win32Marshal.GetExceptionForLastWin32Error();
                }

                InitializeHandle(handle, false, (options & PipeOptions.Asynchronous) != 0);
            }
            finally
            {
                if (pinningHandle.IsAllocated)
                {
                    pinningHandle.Free();
                }
            }
        }
Exemple #37
0
 /// <summary>
 /// Überträgt ein Objekt in eine Kommunikationseinheit.
 /// </summary>
 /// <param name="pipe">Die Kommunikationseinheit.</param>
 /// <param name="serializer">Die Serialisierungsinstanz.</param>
 /// <param name="response">Das betroffene Objekt.</param>
 internal static void SendToPipe( PipeStream pipe, XmlSerializer serializer, Response response )
 {
     // Forward
     SendToPipe( pipe, serializer, (object) response );
 }
 public PipeStreamFacade(PipeStream pipeStream)
 {
     PipeStream = pipeStream;
 }
Exemple #39
0
        /// <summary>
        /// Rekonstruiert ein Objekt aus dem angegebenen Kommunikationskanal.
        /// </summary>
        /// <param name="pipe">Der gewünschte Kanal.</param>
        /// <param name="serializer">Die Instanz zur Rekonstruktion des Objektes.</param>
        /// <returns>Das rekonstruierte Objekt.</returns>
        private static object ReadFromPipe( PipeStream pipe, XmlSerializer serializer )
        {
            // Allocate length field
            byte[] len = new byte[sizeof( long )], data;

            // Load it
            if (len.Length != pipe.Read( len, 0, len.Length ))
                return null;

            // Lock briefly
            var lenLock = GCHandle.Alloc( len, GCHandleType.Pinned );
            try
            {
                // Fill
                data = new byte[Marshal.ReadInt64( lenLock.AddrOfPinnedObject() )];
            }
            finally
            {
                // Release
                lenLock.Free();
            }

            // Read in blocks
            for (int n = 0; n < data.Length; )
            {
                // Block size
                int block = Math.Min( BlockSize, data.Length - n );

                // Load chunk
                if (pipe.Read( data, n, block ) != block)
                    return null;

                // Advance
                n += block;
            }

            // Create settings
            var settings = new XmlReaderSettings { CheckCharacters = false };

            // Reconstruct
            using (var temp = new MemoryStream( data, false ))
            using (var reader = XmlReader.Create( temp, settings ))
                return serializer.Deserialize( reader );
        }
Exemple #40
0
        private void Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity?pipeSecurity)
        {
            Debug.Assert(direction != PipeDirection.InOut, "Anonymous pipe direction shouldn't be InOut");
            Debug.Assert(bufferSize >= 0, "bufferSize is negative");

            bool           bSuccess;
            SafePipeHandle serverHandle, clientHandle;
            SafePipeHandle newServerHandle;

            // Create the two pipe handles that make up the anonymous pipe.
            GCHandle pinningHandle = default;

            try
            {
                Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(inheritability, pipeSecurity, ref pinningHandle);

                if (direction == PipeDirection.In)
                {
                    bSuccess = Interop.Kernel32.CreatePipe(out serverHandle, out clientHandle, ref secAttrs, bufferSize);
                }
                else
                {
                    bSuccess = Interop.Kernel32.CreatePipe(out clientHandle, out serverHandle, ref secAttrs, bufferSize);
                }
            }
            finally
            {
                if (pinningHandle.IsAllocated)
                {
                    pinningHandle.Free();
                }
            }

            if (!bSuccess)
            {
                Exception e = Win32Marshal.GetExceptionForLastWin32Error();

                serverHandle.Dispose();
                clientHandle.Dispose();

                throw e;
            }

            // Duplicate the server handle to make it not inheritable.  Note: We need to do this so that the child
            // process doesn't end up getting another copy of the server handle.  If it were to get a copy, the
            // OS wouldn't be able to inform the child that the server has closed its handle because it will see
            // that there is still one server handle that is open.
            bSuccess = Interop.Kernel32.DuplicateHandle(Interop.Kernel32.GetCurrentProcess(), serverHandle, Interop.Kernel32.GetCurrentProcess(),
                                                        out newServerHandle, 0, false, Interop.Kernel32.HandleOptions.DUPLICATE_SAME_ACCESS);

            if (!bSuccess)
            {
                Exception e = Win32Marshal.GetExceptionForLastWin32Error();

                serverHandle.Dispose();
                newServerHandle.Dispose();
                clientHandle.Dispose();

                throw e;
            }

            // Close the inheritable server handle.
            serverHandle.Dispose();

            _clientHandle = clientHandle;
            InitializeHandle(newServerHandle, false, false);

            State = PipeState.Connected;
        }