コード例 #1
0
 /// <summary>
 /// Creates a new instance of the <see cref="NamedPipeServerStream" /> class with the specified pipe name, pipe direction, maximum number of server instances, transmission mode, pipe options, recommended in and out buffer sizes, pipe security, inheritability mode, and pipe access rights.
 /// </summary>
 /// <param name="pipeName">The name of the pipe.</param>
 /// <param name="direction">One of the enumeration values that determines the direction of the pipe.</param>
 /// <param name="maxNumberOfServerInstances">The maximum number of server instances that share the same name. You can pass <see cref="NamedPipeServerStream.MaxAllowedServerInstances" /> for this value.</param>
 /// <param name="transmissionMode">One of the enumeration values that determines the transmission mode of the pipe.</param>
 /// <param name="options">One of the enumeration values that determines how to open or create the pipe.</param>
 /// <param name="inBufferSize">The input buffer size.</param>
 /// <param name="outBufferSize">The output buffer size.</param>
 /// <param name="pipeSecurity">An object that determines the access control and audit security for the pipe.</param>
 /// <param name="inheritability">One of the enumeration values that determines whether the underlying handle can be inherited by child processes.</param>
 /// <param name="additionalAccessRights">One of the enumeration values that specifies the access rights of the pipe.</param>
 /// <returns>A new named pipe server stream instance.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="pipeName" /> is <see langword="null" />.</exception>
 /// <exception cref="ArgumentException"><paramref name="pipeName" /> is empty.</exception>
 /// <exception cref="IOException"><paramref name="options" /> is <see cref="PipeOptions.None" />.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="options" /> contains an invalid flag.
 /// -or-
 /// <paramref name="inBufferSize" /> is a negative number.
 /// -or
 /// <paramref name="maxNumberOfServerInstances" /> is not a valid number: it should be greater or equal than 1 and less or equal than 254, or should be set to the value of <see cref="NamedPipeServerStream.MaxAllowedServerInstances" />.
 /// -or-
 /// <paramref name="inheritability" /> contains an invalid enum value.
 /// -or
 /// <paramref name="pipeName" /> is 'anonymous', which is reserved.</exception>
 /// <remarks>If `options` contains &lt;xref:System.IO.Pipes.PipeOptions.CurrentUserOnly&gt;, the passed `pipeSecurity` is ignored and the returned &lt;xref:System.IO.Pipes.NamedPipeServerStream&gt; object is created using a custom &lt;xref:System.IO.Pipes.PipeSecurity&gt; instance assigned to the current Windows user as its only owner with full control of the pipe.</remarks>
 public static NamedPipeServerStream Create(
     string pipeName,
     PipeDirection direction,
     int maxNumberOfServerInstances,
     PipeTransmissionMode transmissionMode,
     PipeOptions options,
     int inBufferSize,
     int outBufferSize,
     PipeSecurity?pipeSecurity,
     HandleInheritability inheritability     = HandleInheritability.None,
     PipeAccessRights additionalAccessRights = default)
 {
     return(new NamedPipeServerStream(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, inheritability, additionalAccessRights));
 }
コード例 #2
0
        internal NamedPipeServerStream(
            string pipeName,
            PipeDirection direction,
            int maxNumberOfServerInstances,
            PipeTransmissionMode transmissionMode,
            PipeOptions options,
            int inBufferSize,
            int outBufferSize,
            PipeSecurity?pipeSecurity,
            HandleInheritability inheritability     = HandleInheritability.None,
            PipeAccessRights additionalAccessRights = default)
            : base(direction, transmissionMode, outBufferSize)
        {
            ValidateParameters(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability);

            if (pipeSecurity != null && IsCurrentUserOnly)
            {
                throw new ArgumentException(SR.NotSupported_PipeSecurityIsCurrentUserOnly, nameof(pipeSecurity));
            }

            Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, inheritability, additionalAccessRights);
        }
コード例 #3
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;
            }

            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();
                }
            }
        }
コード例 #4
0
 /// <summary>
 /// Creates a new instance of the <see cref="AnonymousPipeServerStream" /> class with the specified pipe direction, inheritability mode, buffer size, and pipe security.
 /// </summary>
 /// <param name="direction">One of the enumeration values that determines the direction of the pipe. Anonymous pipes can only be in one direction, so direction cannot be set to <see cref="PipeDirection.InOut" />.</param>
 /// <param name="inheritability">One of the enumeration values that determines whether the underlying handle can be inherited by child processes.</param>
 /// <param name="bufferSize">The size of the buffer. This value must be greater than or equal to 0.</param>
 /// <param name="pipeSecurity">An object that determines the access control and audit security for the pipe.</param>
 /// <returns>A new anonymous pipe server stream instance.</returns>
 /// <remarks>Setting <paramref name="pipeSecurity" /> to <see langword="null" /> is equivalent to calling the `System.IO.Pipes.AnonymousPipeServerStream(System.IO.Pipes.PipeDirection direction, System.IO.HandleInheritability inheritability, int bufferSize)` constructor directly.</remarks>
 /// <exception cref="NotSupportedException"><paramref name="direction" /> is <see cref="PipeDirection.InOut" />.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="inheritability" /> is not set to a valid <see cref="HandleInheritability" /> enum value.</exception>
 public static AnonymousPipeServerStream Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity?pipeSecurity)
 {
     return(new AnonymousPipeServerStream(direction, inheritability, bufferSize, pipeSecurity));
 }
コード例 #5
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;
            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)
            {
                throw Win32Marshal.GetExceptionForLastWin32Error();
            }

            // 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)
            {
                throw Win32Marshal.GetExceptionForLastWin32Error();
            }

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

            InitializeHandle(newServerHandle, false, false);

            State = PipeState.Connected;
        }
コード例 #6
0
        internal AnonymousPipeServerStream(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity?pipeSecurity)
            : base(direction, bufferSize)
        {
            if (direction == PipeDirection.InOut)
            {
                throw new NotSupportedException(SR.NotSupported_AnonymousPipeUnidirectional);
            }

            if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable)
            {
                throw new ArgumentOutOfRangeException(nameof(inheritability), SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable);
            }

            Create(direction, inheritability, bufferSize, pipeSecurity);
        }