Exemple #1
0
 private void InitializeAsyncHandle(SafePipeHandle handle)
 {
     // nop
 }
Exemple #2
0
        /// <summary>
        /// Helper method to create a PowerShell transport named pipe via native API, along
        /// with a returned .Net NamedPipeServerStream object wrapping the named pipe.
        /// </summary>
        /// <param name="serverName">Named pipe server name.</param>
        /// <param name="namespaceName">Named pipe namespace name.</param>
        /// <param name="coreName">Named pipe core name.</param>
        /// <param name="securityDesc"></param>
        /// <returns>NamedPipeServerStream.</returns>
        private static NamedPipeServerStream CreateNamedPipe(
            string serverName,
            string namespaceName,
            string coreName,
            CommonSecurityDescriptor securityDesc)
        {
            if (serverName == null)
            {
                throw new PSArgumentNullException(nameof(serverName));
            }

            if (namespaceName == null)
            {
                throw new PSArgumentNullException(nameof(namespaceName));
            }

            if (coreName == null)
            {
                throw new PSArgumentNullException(nameof(coreName));
            }

#if !UNIX
            string fullPipeName = @"\\" + serverName + @"\" + namespaceName + @"\" + coreName;

            // Create optional security attributes based on provided PipeSecurity.
            NamedPipeNative.SECURITY_ATTRIBUTES securityAttributes = null;
            GCHandle?securityDescHandle = null;
            if (securityDesc != null)
            {
                byte[] securityDescBuffer = new byte[securityDesc.BinaryLength];
                securityDesc.GetBinaryForm(securityDescBuffer, 0);
                securityDescHandle = GCHandle.Alloc(securityDescBuffer, GCHandleType.Pinned);
                securityAttributes = NamedPipeNative.GetSecurityAttributes(securityDescHandle.Value);
            }

            // Create named pipe.
            SafePipeHandle pipeHandle = NamedPipeNative.CreateNamedPipe(
                fullPipeName,
                NamedPipeNative.PIPE_ACCESS_DUPLEX | NamedPipeNative.FILE_FLAG_FIRST_PIPE_INSTANCE | NamedPipeNative.FILE_FLAG_OVERLAPPED,
                NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
                1,
                _namedPipeBufferSizeForRemoting,
                _namedPipeBufferSizeForRemoting,
                0,
                securityAttributes);

            int lastError = Marshal.GetLastWin32Error();
            if (securityDescHandle != null)
            {
                securityDescHandle.Value.Free();
            }

            if (pipeHandle.IsInvalid)
            {
                throw new PSInvalidOperationException(
                          StringUtil.Format(RemotingErrorIdStrings.CannotCreateNamedPipe, lastError));
            }

            // Create the .Net NamedPipeServerStream wrapper.
            try
            {
                return(new NamedPipeServerStream(
                           PipeDirection.InOut,
                           true,                // IsAsync
                           false,               // IsConnected
                           pipeHandle));
            }
            catch (Exception)
            {
                pipeHandle.Dispose();
                throw;
            }
#else
            return(new NamedPipeServerStream(
                       pipeName: coreName,
                       direction: PipeDirection.InOut,
                       maxNumberOfServerInstances: 1,
                       transmissionMode: PipeTransmissionMode.Byte,
                       options: PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly,
                       inBufferSize: _namedPipeBufferSizeForRemoting,
                       outBufferSize: _namedPipeBufferSizeForRemoting));
#endif
        }
        // Create an AnonymousPipeServerStream from two existing pipe handles.
        public AnonymousPipeServerStream(PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle)
            : base(direction, 0)
        {
            if (direction == PipeDirection.InOut)
            {
                throw new NotSupportedException(SR.NotSupported_AnonymousPipeUnidirectional);
            }
            if (serverSafePipeHandle == null)
            {
                throw new ArgumentNullException(nameof(serverSafePipeHandle));
            }
            if (clientSafePipeHandle == null)
            {
                throw new ArgumentNullException(nameof(clientSafePipeHandle));
            }
            if (serverSafePipeHandle.IsInvalid)
            {
                throw new ArgumentException(SR.Argument_InvalidHandle, nameof(serverSafePipeHandle));
            }
            if (clientSafePipeHandle.IsInvalid)
            {
                throw new ArgumentException(SR.Argument_InvalidHandle, nameof(clientSafePipeHandle));
            }
            ValidateHandleIsPipe(serverSafePipeHandle);
            ValidateHandleIsPipe(clientSafePipeHandle);

            InitializeHandle(serverSafePipeHandle, true, false);

            _clientHandle        = clientSafePipeHandle;
            _clientHandleExposed = true;
            State = PipeState.Connected;
        }
        // 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;
            }

            GCHandle pinningHandle = default;

            try
            {
                Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = 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();
                }
            }
        }
 public static extern bool DisconnectNamedPipe(SafePipeHandle hNamedPipe);
Exemple #6
0
 internal static extern unsafe bool ConnectNamedPipe(SafePipeHandle handle, NativeOverlapped *overlapped);
 private void ValidateRemotePipeUser(SafePipeHandle handle)
 {
     throw new PlatformNotSupportedException();
 }
 public static extern bool WriteFile(SafePipeHandle handle, byte[] bytes,
                                     int numBytesToWrite, out int numBytesWritten, IntPtr overlapped);
        public static void ClientInvalidHandleThrows()
        {
            SafePipeHandle pipeHandle = new SafePipeHandle(new IntPtr(-1), true);

            Assert.Throws <ArgumentException>("safePipeHandle", () => new NamedPipeClientStream(PipeDirection.InOut, false, true, pipeHandle));
        }
Exemple #10
0
 private static void DebugAssertHandleValid(SafePipeHandle handle)
 {
     Debug.Assert(handle != null, "handle is null");
     Debug.Assert(!handle.IsClosed, "handle is closed");
 }
Exemple #11
0
 internal static unsafe extern int Write(SafePipeHandle fd, byte *buffer, int bufferSize);
        public NamedPipeServerStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
            : base(direction, PipeTransmissionMode.Byte, 0)
        {
            if (safePipeHandle == null)
            {
                throw new ArgumentNullException("safePipeHandle");
            }
            if (safePipeHandle.IsInvalid)
            {
                throw new ArgumentException(SR.Argument_InvalidHandle, "safePipeHandle");
            }
            ValidateHandleIsPipe(safePipeHandle);

            InitializeHandle(safePipeHandle, true, isAsync);

            if (isConnected)
            {
                State = PipeState.Connected;
            }
        }
 public AnonymousPipeClientStream(PipeDirection direction, SafePipeHandle safePipeHandle);
Exemple #14
0
 /// <summary>Initializes the handle to be used asynchronously.</summary>
 /// <param name="handle">The handle.</param>
 private void InitializeAsyncHandle(SafePipeHandle handle)
 {
     // If the handle is of async type, bind the handle to the ThreadPool so that we can use
     // the async operations (it's needed so that our native callbacks get called).
     _threadPoolBinding = ThreadPoolBoundHandle.BindHandle(handle);
 }
Exemple #15
0
 private static void DebugAssertReadWriteArgs(byte[] buffer, int offset, int count, SafePipeHandle handle)
 {
     Debug.Assert(buffer != null, "buffer is null");
     Debug.Assert(offset >= 0, "offset is negative");
     Debug.Assert(count >= 0, "count is negative");
     Debug.Assert(offset <= buffer.Length - count, "offset + count is too big");
     Debug.Assert(handle != null, "handle is null");
     Debug.Assert(!handle.IsClosed, "handle is closed");
 }
 public NamedPipeServerStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle);
 internal static extern int FStat(SafePipeHandle fd, out FileStatus output);
 public static extern bool FlushFileBuffers(SafePipeHandle handle);
        public static void ClientBadPipeHandleAsInvalidThrows()
        {
            SafePipeHandle pipeHandle = new SafePipeHandle(new IntPtr(-1), true);

            Assert.Throws <ArgumentException>(() => new AnonymousPipeClientStream(PipeDirection.In, pipeHandle));
        }
Exemple #20
0
 public NamedPipeClientStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
     : base(direction, DefaultBufferSize)
 {
     if (IsWindows)
     {
         impl = new Win32NamedPipeClient(this, safePipeHandle);
     }
     else
     {
         impl = new UnixNamedPipeClient(this, safePipeHandle);
     }
     IsConnected = isConnected;
     InitializeHandle(safePipeHandle, true, isAsync);
 }
Exemple #21
0
 internal static bool TryGetImpersonationUserName(SafePipeHandle handle, out string impersonationUserName)
 {
     throw new Exception("Should not call on Unix.");
 }
Exemple #22
0
 internal static extern bool ConnectNamedPipe(SafePipeHandle handle, IntPtr overlapped);
Exemple #23
0
 internal static bool TryGetNumberOfServerInstances(SafePipeHandle handle, out uint numberOfServerInstances)
 {
     throw new Exception("Should not call on Unix.");
 }
 internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle handle)
 {
     _userCode = userCode;
     _handle   = handle;
 }
 public static extern bool ConnectNamedPipe(SafePipeHandle hNamedPipe,
                                            IntPtr overlapped);
 internal static partial bool DisconnectNamedPipe(SafePipeHandle hNamedPipe);
        /// <summary>
        /// P/Invoke the native APIs related to named pipe operations to connect
        /// to the named pipe.
        /// </summary>
        public static void Run(string argPipeServerName, byte[] argSendData, out string outResponseMessage)
        {
            SafePipeHandle hNamedPipe = null;

            outResponseMessage = "Server No Response";
            try
            {
                // Try to open the named pipe identified by the pipe name.
                while (true)
                {
                    hNamedPipe = NativeMethod.CreateFile(
                        argPipeServerName,                     // Pipe name
                        FileDesiredAccess.GENERIC_READ |       // Read access
                        FileDesiredAccess.GENERIC_WRITE,       // Write access
                        FileShareMode.Zero,                    // No sharing
                        null,                                  // Default security attributes
                        FileCreationDisposition.OPEN_EXISTING, // Opens existing pipe
                        0,                                     // Default attributes
                        IntPtr.Zero                            // No template file
                        );

                    // If the pipe handle is opened successfully ...
                    if (!hNamedPipe.IsInvalid)
                    {
                        //Console.WriteLine("The named pipe ({0}) is connected.",argPipeServerName);
                        break;
                    }

                    // Exit if an error other than ERROR_PIPE_BUSY occurs.
                    if (Marshal.GetLastWin32Error() != ERROR_PIPE_BUSY)
                    {
                        throw new Win32Exception();
                    }

                    // All pipe instances are busy, so wait for 5 seconds.
                    if (!NativeMethod.WaitNamedPipe(argPipeServerName, 5000))
                    {
                        throw new Win32Exception();
                    }
                }

                // Set the read mode and the blocking mode of the named pipe. In
                // this sample, we set data to be read from the pipe as a stream
                // of messages.
                PipeMode mode = PipeMode.PIPE_READMODE_MESSAGE;
                if (!NativeMethod.SetNamedPipeHandleState(hNamedPipe, ref mode,
                                                          IntPtr.Zero, IntPtr.Zero))
                {
                    throw new Win32Exception();
                }

                //
                // Send a request from client to server.
                //



                int cbRequest = argSendData.Length, cbWritten;

                if (!NativeMethod.WriteFile(
                        hNamedPipe,             // Handle of the pipe
                        argSendData,            // Message to be written
                        cbRequest,              // Number of bytes to write
                        out cbWritten,          // Number of bytes written
                        IntPtr.Zero             // Not overlapped
                        ))
                {
                    throw new Win32Exception();
                }

                //Console.WriteLine("Send {0} bytes to server: ",cbWritten);
                outResponseMessage = cbWritten.ToString();
                //
                // Receive a response from server.
                //

                //bool finishRead = false;
                //do
                //{
                //    byte[] bResponse = new byte[1024];
                //    int cbResponse = bResponse.Length, cbRead;

                //    finishRead = NativeMethod.ReadFile(
                //        hNamedPipe,             // Handle of the pipe
                //        bResponse,              // Buffer to receive data
                //        cbResponse,             // Size of buffer in bytes
                //        out cbRead,             // Number of bytes read
                //        IntPtr.Zero             // Not overlapped
                //        );

                //    if (!finishRead &&
                //        Marshal.GetLastWin32Error() != ERROR_MORE_DATA)
                //    {
                //        throw new Win32Exception();
                //    }

                //    // Unicode-encode the received byte array and trim all the
                //    // '\0' characters at the end.
                //    outResponseMessage = Encoding.Unicode.GetString(bResponse).TrimEnd('\0');
                //    Console.WriteLine("Receive {0} bytes from server: ",  cbRead);
                //}
                //while (!finishRead);  // Repeat loop if ERROR_MORE_DATA
            }
            catch (Exception ex)
            {
                Console.WriteLine("The client throws the error: {0}", ex.Message);
            }
            finally
            {
                if (hNamedPipe != null)
                {
                    hNamedPipe.Close();
                    hNamedPipe = null;
                }
            }
        }
Exemple #28
0
 internal static extern unsafe int Read(SafePipeHandle fd, byte *buffer, int count);
 public static extern bool SetNamedPipeHandleState(
     SafePipeHandle hNamedPipe, ref PipeMode mode,
     IntPtr maxCollectionCount, IntPtr collectDataTimeout);
        public static void InvalidPipeHandle_Throws_ArgumentException(PipeDirection direction)
        {
            SafePipeHandle pipeHandle = new SafePipeHandle(new IntPtr(-1), true);

            AssertExtensions.Throws <ArgumentException>("safePipeHandle", () => new NamedPipeServerStream(direction, false, true, pipeHandle));
        }
 public static extern bool ReadFile(SafePipeHandle handle, byte[] bytes,
                                    int numBytesToRead, out int numBytesRead, IntPtr overlapped);
Exemple #32
0
        private void PipeServerThread()
        {
            try
            {
                s = new NamedPipeServerStream(PipeDirection.InOut, false, false, sph);
                s.WaitForConnection();

                //sph.Close();
                sph = null;
            }
            catch
            {
                return;
            }

            try
            {
                while (1 == 1)
                {
                    int command = s.ReadByte();

                    switch (command)
                    {
                    case -1:
                    case Commands.EXIT: return;     //pipe closed

                    case Commands.TEST:
                        s.WriteByte((byte)(s.ReadByte() ^ 0xce));
                        break;

                    case Commands.INITMODULELIST:
                        initModuleList();
                        break;

                    case Commands.GETMETHODENTRYPOINT:
                        getMethodEntryPoint();
                        break;

                    case Commands.GETMETHODPARAMETERS:
                        getMethodParameters();
                        break;

                    case Commands.GETFIELDTYPENAME:
                        getFieldTypeName();
                        break;

                    case Commands.GETFIELDVALUE:
                        getFieldValue();
                        break;

                    case Commands.SETFIELDVALUE:
                        setFieldValue();
                        break;

                    case Commands.LOADMODULE:
                        loadModule();
                        break;

                    case Commands.WRAPOBJECT:
                        wrapObject();
                        break;

                    case Commands.UNWRAPOBJECT:
                        unwrapObject();
                        break;

                    case Commands.INVOKEMETHOD:
                        invokeMethod();
                        break;
                    }
                }
            }
            catch
            {
            }
            finally
            {
                s.Close();
            }
        }
 public AnonymousPipeServerStream(PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle);