From 02ea20ae6dd0450d04215b561eae449ae1ff289e Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Mon, 10 Feb 2020 16:30:25 +0000 Subject: [PATCH] Nullable annotate System.IO.Pipes (#31918) * annotate System.IO.Pipes * update Stream override method signatures --- .../Kernel32/Interop.CreateNamedPipeClient.cs | 2 +- .../Windows/Kernel32/Interop.WaitNamedPipe.cs | 2 +- .../System.IO.Pipes/ref/System.IO.Pipes.cs | 7 +++-- .../ref/System.IO.Pipes.csproj | 1 + .../Win32/SafeHandles/SafePipeHandle.Unix.cs | 9 +++--- .../Win32/SafeHandles/SafePipeHandle.cs | 1 + .../src/System.IO.Pipes.csproj | 1 + .../AnonymousPipeServerStream.Windows.cs | 2 +- .../IO/Pipes/AnonymousPipeServerStream.cs | 2 +- .../IO/Pipes/ConnectionCompletionSource.cs | 2 +- .../IO/Pipes/NamedPipeClientStream.Unix.cs | 2 +- .../IO/Pipes/NamedPipeClientStream.Windows.cs | 6 ++-- .../System/IO/Pipes/NamedPipeClientStream.cs | 2 +- .../IO/Pipes/NamedPipeServerStream.Unix.cs | 14 +++++----- .../IO/Pipes/NamedPipeServerStream.Win32.cs | 2 +- .../IO/Pipes/NamedPipeServerStream.Windows.cs | 28 +++++++++---------- .../System/IO/Pipes/PipeCompletionSource.cs | 4 +-- .../src/System/IO/Pipes/PipeSecurity.cs | 4 +-- .../src/System/IO/Pipes/PipeStream.Unix.cs | 14 ++++++---- .../src/System/IO/Pipes/PipeStream.Windows.cs | 24 ++++++++-------- .../src/System/IO/Pipes/PipeStream.cs | 10 +++---- .../IO/Pipes/ReadWriteCompletionSource.cs | 2 +- 22 files changed, 74 insertions(+), 67 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateNamedPipeClient.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateNamedPipeClient.cs index afdb1036e81..05042ec870a 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateNamedPipeClient.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateNamedPipeClient.cs @@ -13,7 +13,7 @@ internal partial class Interop { [DllImport(Libraries.Kernel32, EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)] internal static extern SafePipeHandle CreateNamedPipeClient( - string lpFileName, + string? lpFileName, int dwDesiredAccess, System.IO.FileShare dwShareMode, ref SECURITY_ATTRIBUTES secAttrs, diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.WaitNamedPipe.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.WaitNamedPipe.cs index bb65acdc82f..a4c7b0b2a3b 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.WaitNamedPipe.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.WaitNamedPipe.cs @@ -10,6 +10,6 @@ internal partial class Interop { [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, EntryPoint = "WaitNamedPipeW")] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool WaitNamedPipe(string name, int timeout); + internal static extern bool WaitNamedPipe(string? name, int timeout); } } diff --git a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs index e0d7ef00220..a6e021631af 100644 --- a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs +++ b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs @@ -111,8 +111,8 @@ namespace System.IO.Pipes public virtual System.IO.Pipes.PipeTransmissionMode ReadMode { get { throw null; } set { } } public Microsoft.Win32.SafeHandles.SafePipeHandle SafePipeHandle { get { throw null; } } public virtual System.IO.Pipes.PipeTransmissionMode TransmissionMode { get { throw null; } } - public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; } - public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; } + public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; } + public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; } protected internal virtual void CheckPipePropertyOperations() { } protected internal void CheckReadOperations() { } protected internal void CheckWriteOperations() { } @@ -120,7 +120,8 @@ namespace System.IO.Pipes public override int EndRead(System.IAsyncResult asyncResult) { throw null; } public override void EndWrite(System.IAsyncResult asyncResult) { } public override void Flush() { } - protected void InitializeHandle(Microsoft.Win32.SafeHandles.SafePipeHandle handle, bool isExposed, bool isAsync) { } + public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } + protected void InitializeHandle(Microsoft.Win32.SafeHandles.SafePipeHandle? handle, bool isExposed, bool isAsync) { } public override int Read(byte[] buffer, int offset, int count) { throw null; } public override int Read(System.Span buffer) { throw null; } public override System.Threading.Tasks.Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } diff --git a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.csproj b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.csproj index 37fc7182451..4ddc4f2a783 100644 --- a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.csproj +++ b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent) + enable diff --git a/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.Unix.cs b/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.Unix.cs index a9810794373..406e1599a89 100644 --- a/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Net.Sockets; @@ -22,8 +23,8 @@ namespace Microsoft.Win32.SafeHandles // and operations that should go through the Socket to be done via _namedPipeSocket. We keep the // Socket's SafeHandle alive as long as this SafeHandle is alive. - private Socket _namedPipeSocket; - private SafeHandle _namedPipeSocketHandle; + private Socket? _namedPipeSocket; + private SafeHandle? _namedPipeSocketHandle; internal SafePipeHandle(Socket namedPipeSocket) : base(ownsHandle: true) { @@ -37,8 +38,8 @@ namespace Microsoft.Win32.SafeHandles SetHandle(_namedPipeSocketHandle.DangerousGetHandle()); } - internal Socket NamedPipeSocket => _namedPipeSocket; - internal SafeHandle NamedPipeSocketHandle => _namedPipeSocketHandle; + internal Socket? NamedPipeSocket => _namedPipeSocket; + internal SafeHandle? NamedPipeSocketHandle => _namedPipeSocketHandle; protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.cs b/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.cs index d6b88e5d956..aecdadcab5e 100644 --- a/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.cs +++ b/src/libraries/System.IO.Pipes/src/Microsoft/Win32/SafeHandles/SafePipeHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; using System.Security; diff --git a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj index 31ed0b5f84d..8599e10012e 100644 --- a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj +++ b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj @@ -4,6 +4,7 @@ true true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix + enable diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.Windows.cs index fc57fdf5972..033a16bc424 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.Windows.cs @@ -34,7 +34,7 @@ namespace System.IO.Pipes Create(direction, inheritability, bufferSize, null); } - private void Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity) + 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"); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.cs index 1834f98363d..249aa1e5d94 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/AnonymousPipeServerStream.cs @@ -12,7 +12,7 @@ namespace System.IO.Pipes /// public sealed partial class AnonymousPipeServerStream : PipeStream { - private SafePipeHandle _clientHandle; + private SafePipeHandle _clientHandle = null!; private bool _clientHandleExposed; public AnonymousPipeServerStream() diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ConnectionCompletionSource.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ConnectionCompletionSource.cs index f5a34ba8bf0..f0e4f1d5533 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ConnectionCompletionSource.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ConnectionCompletionSource.cs @@ -13,7 +13,7 @@ namespace System.IO.Pipes // Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations) internal ConnectionCompletionSource(NamedPipeServerStream server) - : base(server._threadPoolBinding, ReadOnlyMemory.Empty) + : base(server._threadPoolBinding!, ReadOnlyMemory.Empty) { _serverStream = server; } diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs index cfee043d439..3025ee6868f 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Unix.cs @@ -25,7 +25,7 @@ namespace System.IO.Pipes // immediately if it isn't. The only delay will be between the time the server // has called Bind and Listen, with the latter immediately following the former. var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); - SafePipeHandle clientHandle = null; + SafePipeHandle? clientHandle = null; try { socket.Connect(new UnixDomainSocketEndPoint(_normalizedPipePath)); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs index b6689f746ac..2fa4c1575e7 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.Windows.cs @@ -120,7 +120,7 @@ namespace System.IO.Pipes // access request before calling NTCreateFile, so all NamedPipeClientStreams can read // this if they are created (on WinXP SP2 at least)] uint numInstances; - if (!Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle, null, &numInstances, null, null, null, 0)) + if (!Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle!, null, &numInstances, null, null, null, 0)) { throw WinIOError(Marshal.GetLastWin32Error()); } @@ -135,10 +135,10 @@ namespace System.IO.Pipes return; PipeSecurity accessControl = this.GetAccessControl(); - IdentityReference remoteOwnerSid = accessControl.GetOwner(typeof(SecurityIdentifier)); + IdentityReference? remoteOwnerSid = accessControl.GetOwner(typeof(SecurityIdentifier)); using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent()) { - SecurityIdentifier currentUserSid = currentIdentity.Owner; + SecurityIdentifier? currentUserSid = currentIdentity.Owner; if (remoteOwnerSid != currentUserSid) { State = PipeState.Closed; diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs index 796c3f95866..73bc1332da4 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs @@ -20,7 +20,7 @@ namespace System.IO.Pipes // Maximum interval in milliseconds between which cancellation is checked. // Used by ConnectInternal. 50ms is fairly responsive time but really long time for processor. private const int CancellationCheckInterval = 50; - private readonly string _normalizedPipePath; + private readonly string? _normalizedPipePath; private readonly TokenImpersonationLevel _impersonationLevel; private readonly PipeOptions _pipeOptions; private readonly HandleInheritability _inheritability; diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Unix.cs index a47efd6d9c6..5b0cbe776bc 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Unix.cs @@ -15,7 +15,7 @@ namespace System.IO.Pipes { public sealed partial class NamedPipeServerStream : PipeStream { - private SharedServer _instance; + private SharedServer? _instance; private PipeDirection _direction; private PipeOptions _options; private int _inBufferSize; @@ -62,7 +62,7 @@ namespace System.IO.Pipes // Use and block on AcceptAsync() rather than using Accept() in order to provide // behavior more akin to Windows if the Stream is closed while a connection is pending. - Socket accepted = _instance.ListeningSocket.AcceptAsync().GetAwaiter().GetResult(); + Socket accepted = _instance!.ListeningSocket.AcceptAsync().GetAwaiter().GetResult(); HandleAcceptedSocket(accepted); } @@ -79,7 +79,7 @@ namespace System.IO.Pipes WaitForConnectionAsyncCore(); async Task WaitForConnectionAsyncCore() => - HandleAcceptedSocket(await _instance.ListeningSocket.AcceptAsync().ConfigureAwait(false)); + HandleAcceptedSocket(await _instance!.ListeningSocket.AcceptAsync().ConfigureAwait(false)); } private void HandleAcceptedSocket(Socket acceptedSocket) @@ -124,7 +124,7 @@ namespace System.IO.Pipes { CheckDisconnectOperations(); State = PipeState.Disconnected; - InternalHandle.Dispose(); + InternalHandle!.Dispose(); InitializeHandle(null, false, false); } @@ -135,7 +135,7 @@ namespace System.IO.Pipes { CheckWriteOperations(); - SafeHandle handle = InternalHandle?.NamedPipeSocketHandle; + SafeHandle? handle = InternalHandle?.NamedPipeSocketHandle; if (handle == null) { throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet); @@ -178,7 +178,7 @@ namespace System.IO.Pipes public void RunAsClient(PipeStreamImpersonationWorker impersonationWorker) { CheckWriteOperations(); - SafeHandle handle = InternalHandle?.NamedPipeSocketHandle; + SafeHandle? handle = InternalHandle?.NamedPipeSocketHandle; if (handle == null) { throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet); @@ -233,7 +233,7 @@ namespace System.IO.Pipes lock (s_servers) { - SharedServer server; + SharedServer? server; if (s_servers.TryGetValue(path, out server)) { // On Windows, if a subsequent server stream is created for the same pipe and with a different diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Win32.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Win32.cs index ea30ea28fad..410e969a4b4 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Win32.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Win32.cs @@ -23,7 +23,7 @@ namespace System.IO.Pipes { Interop.Kernel32.LoadLibraryEx("sspicli.dll", IntPtr.Zero, Interop.Kernel32.LOAD_LIBRARY_SEARCH_SYSTEM32); - if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle, null, null, null, null, userName, userNameMaxLength)) + if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle!, null, null, null, null, userName, userNameMaxLength)) { return new string(userName); } diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs index 994296f42f3..acf2576ab5c 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs @@ -53,7 +53,7 @@ namespace System.IO.Pipes // 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) + 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"); @@ -76,7 +76,7 @@ namespace System.IO.Pipes using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent()) { - SecurityIdentifier identifier = currentIdentity.Owner; + 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. @@ -145,7 +145,7 @@ namespace System.IO.Pipes } else { - if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle, IntPtr.Zero)) + if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, IntPtr.Zero)) { int errorCode = Marshal.GetLastWin32Error(); @@ -177,7 +177,7 @@ namespace System.IO.Pipes if (!IsAsync) { - return Task.Factory.StartNew(s => ((NamedPipeServerStream)s).WaitForConnection(), + return Task.Factory.StartNew(s => ((NamedPipeServerStream)s!).WaitForConnection(), this, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } @@ -189,7 +189,7 @@ namespace System.IO.Pipes CheckDisconnectOperations(); // Disconnect the pipe. - if (!Interop.Kernel32.DisconnectNamedPipe(InternalHandle)) + if (!Interop.Kernel32.DisconnectNamedPipe(InternalHandle!)) { throw Win32Marshal.GetExceptionForLastWin32Error(); } @@ -207,7 +207,7 @@ namespace System.IO.Pipes const uint UserNameMaxLength = Interop.Kernel32.CREDUI_MAX_USERNAME_LENGTH + 1; char* userName = stackalloc char[(int)UserNameMaxLength]; // ~1K - if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle, null, null, null, null, userName, UserNameMaxLength)) + if (Interop.Kernel32.GetNamedPipeHandleStateW(InternalHandle!, null, null, null, null, userName, UserNameMaxLength)) { return new string(userName); } @@ -244,11 +244,11 @@ namespace System.IO.Pipes private static readonly RuntimeHelpers.TryCode tryCode = new RuntimeHelpers.TryCode(ImpersonateAndTryCode); private static readonly RuntimeHelpers.CleanupCode cleanupCode = new RuntimeHelpers.CleanupCode(RevertImpersonationOnBackout); - private static void ImpersonateAndTryCode(object helper) + private static void ImpersonateAndTryCode(object? helper) { - ExecuteHelper execHelper = (ExecuteHelper)helper; + ExecuteHelper execHelper = (ExecuteHelper)helper!; - if (Interop.Advapi32.ImpersonateNamedPipeClient(execHelper._handle)) + if (Interop.Advapi32.ImpersonateNamedPipeClient(execHelper._handle!)) { execHelper._mustRevert = true; } @@ -264,9 +264,9 @@ namespace System.IO.Pipes } } - private static void RevertImpersonationOnBackout(object helper, bool exceptionThrown) + private static void RevertImpersonationOnBackout(object? helper, bool exceptionThrown) { - ExecuteHelper execHelper = (ExecuteHelper)helper; + ExecuteHelper execHelper = (ExecuteHelper)helper!; if (execHelper._mustRevert) { @@ -280,12 +280,12 @@ namespace System.IO.Pipes internal class ExecuteHelper { internal PipeStreamImpersonationWorker _userCode; - internal SafePipeHandle _handle; + internal SafePipeHandle? _handle; internal bool _mustRevert; internal int _impersonateErrorCode; internal int _revertImpersonateErrorCode; - internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle handle) + internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle? handle) { _userCode = userCode; _handle = handle; @@ -304,7 +304,7 @@ namespace System.IO.Pipes var completionSource = new ConnectionCompletionSource(this); - if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle, completionSource.Overlapped)) + if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, completionSource.Overlapped)) { int errorCode = Marshal.GetLastWin32Error(); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeCompletionSource.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeCompletionSource.cs index 31189655eaa..484e138d47f 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeCompletionSource.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeCompletionSource.cs @@ -43,7 +43,7 @@ namespace System.IO.Pipes _pinnedMemory = bufferToPin.Pin(); _overlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) => { - var completionSource = (PipeCompletionSource)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped); + var completionSource = (PipeCompletionSource)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped)!; Debug.Assert(completionSource.Overlapped == pOverlapped); completionSource.AsyncCallback(errorCode, numBytes); @@ -70,7 +70,7 @@ namespace System.IO.Pipes if (state == NoResult) { // Register the cancellation - _cancellationRegistration = cancellationToken.UnsafeRegister(thisRef => ((PipeCompletionSource)thisRef).Cancel(), this); + _cancellationRegistration = cancellationToken.UnsafeRegister(thisRef => ((PipeCompletionSource)thisRef!).Cancel(), this); // Grab the state for case if IO completed while we were setting the registration. state = Interlocked.Exchange(ref _state, NoResult); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeSecurity.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeSecurity.cs index eb26265e05d..7a826e20139 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeSecurity.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeSecurity.cs @@ -55,7 +55,7 @@ namespace System.IO.Pipes for (int i = 0; i < rules.Count; i++) { - PipeAccessRule fsrule = rules[i] as PipeAccessRule; + PipeAccessRule? fsrule = rules[i] as PipeAccessRule; if ((fsrule != null) && (fsrule.PipeAccessRights == rule.PipeAccessRights) && (fsrule.IdentityReference == rule.IdentityReference) @@ -97,7 +97,7 @@ namespace System.IO.Pipes for (int i = 0; i < rules.Count; i++) { - PipeAccessRule fsrule = rules[i] as PipeAccessRule; + PipeAccessRule? fsrule = rules[i] as PipeAccessRule; if ((fsrule != null) && (fsrule.PipeAccessRights == rule.PipeAccessRights) && (fsrule.IdentityReference == rule.IdentityReference) diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs index 96994ab706e..fdd1d920647 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs @@ -109,10 +109,11 @@ namespace System.IO.Pipes private unsafe int ReadCore(Span buffer) { + Debug.Assert(_handle != null); DebugAssertHandleValid(_handle); // For named pipes, receive on the socket. - Socket socket = _handle.NamedPipeSocket; + Socket? socket = _handle.NamedPipeSocket; if (socket != null) { // For a blocking socket, we could simply use the same Read syscall as is done @@ -140,10 +141,11 @@ namespace System.IO.Pipes private unsafe void WriteCore(ReadOnlySpan buffer) { + Debug.Assert(_handle != null); DebugAssertHandleValid(_handle); // For named pipes, send to the socket. - Socket socket = _handle.NamedPipeSocket; + Socket? socket = _handle.NamedPipeSocket; if (socket != null) { // For a blocking socket, we could simply use the same Write syscall as is done @@ -181,7 +183,7 @@ namespace System.IO.Pipes try { - return await InternalHandle.NamedPipeSocket.ReceiveAsync(destination, SocketFlags.None, cancellationToken).ConfigureAwait(false); + return await InternalHandle!.NamedPipeSocket.ReceiveAsync(destination, SocketFlags.None, cancellationToken).ConfigureAwait(false); } catch (SocketException e) { @@ -197,7 +199,7 @@ namespace System.IO.Pipes { while (source.Length > 0) { - int bytesWritten = await _handle.NamedPipeSocket.SendAsync(source, SocketFlags.None, cancellationToken).ConfigureAwait(false); + int bytesWritten = await _handle!.NamedPipeSocket.SendAsync(source, SocketFlags.None, cancellationToken).ConfigureAwait(false); Debug.Assert(bytesWritten > 0 && bytesWritten <= source.Length); source = source.Slice(bytesWritten); } @@ -310,7 +312,7 @@ namespace System.IO.Pipes /// semaphore. Since we don't delegate to the base stream for Read/WriteAsync due /// to having specialized support for cancellation, we do the same serialization here. /// - private SemaphoreSlim _asyncActiveSemaphore; + private SemaphoreSlim? _asyncActiveSemaphore; private SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized() { @@ -416,7 +418,7 @@ namespace System.IO.Pipes } } - internal static Exception CreateExceptionForLastError(string pipeName = null) + internal static Exception CreateExceptionForLastError(string? pipeName = null) { Interop.ErrorInfo error = Interop.Sys.GetLastErrorInfo(); return error.Error == Interop.Error.ENOTSUP ? diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs index 8a9a34eb2dc..8feb3b60eb6 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs @@ -14,7 +14,7 @@ namespace System.IO.Pipes public abstract partial class PipeStream : Stream { internal const bool CheckOperationsRequiresSetHandle = true; - internal ThreadPoolBoundHandle _threadPoolBinding; + internal ThreadPoolBoundHandle? _threadPoolBinding; internal static string GetPipePath(string serverName, string pipeName) { @@ -57,7 +57,7 @@ namespace System.IO.Pipes private unsafe int ReadCore(Span buffer) { int errorCode = 0; - int r = ReadFileNative(_handle, buffer, null, out errorCode); + int r = ReadFileNative(_handle!, buffer, null, out errorCode); if (r == -1) { @@ -89,7 +89,7 @@ namespace System.IO.Pipes int r; unsafe { - r = ReadFileNative(_handle, buffer.Span, completionSource.Overlapped, out errorCode); + r = ReadFileNative(_handle!, buffer.Span, completionSource.Overlapped, out errorCode); } // ReadFile, the OS version, will return 0 on failure, but this ReadFileNative wrapper @@ -137,7 +137,7 @@ namespace System.IO.Pipes private unsafe void WriteCore(ReadOnlySpan buffer) { int errorCode = 0; - int r = WriteFileNative(_handle, buffer, null, out errorCode); + int r = WriteFileNative(_handle!, buffer, null, out errorCode); if (r == -1) { @@ -155,7 +155,7 @@ namespace System.IO.Pipes int r; unsafe { - r = WriteFileNative(_handle, buffer.Span, completionSource.Overlapped, out errorCode); + r = WriteFileNative(_handle!, buffer.Span, completionSource.Overlapped, out errorCode); } // WriteFile, the OS version, will return 0 on failure, but this WriteFileNative @@ -188,7 +188,7 @@ namespace System.IO.Pipes } // Block until other end of the pipe has read everything. - if (!Interop.Kernel32.FlushFileBuffers(_handle)) + if (!Interop.Kernel32.FlushFileBuffers(_handle!)) { throw WinIOError(Marshal.GetLastWin32Error()); } @@ -205,7 +205,7 @@ namespace System.IO.Pipes if (_isFromExistingHandle) { uint pipeFlags; - if (!Interop.Kernel32.GetNamedPipeInfo(_handle, &pipeFlags, null, null, null)) + if (!Interop.Kernel32.GetNamedPipeInfo(_handle!, &pipeFlags, null, null, null)) { throw WinIOError(Marshal.GetLastWin32Error()); } @@ -238,7 +238,7 @@ namespace System.IO.Pipes } uint inBufferSize; - if (!Interop.Kernel32.GetNamedPipeInfo(_handle, null, null, &inBufferSize, null)) + if (!Interop.Kernel32.GetNamedPipeInfo(_handle!, null, null, &inBufferSize, null)) { throw WinIOError(Marshal.GetLastWin32Error()); } @@ -268,7 +268,7 @@ namespace System.IO.Pipes { outBufferSize = _outBufferSize; } - else if (!Interop.Kernel32.GetNamedPipeInfo(_handle, null, &outBufferSize, null, null)) + else if (!Interop.Kernel32.GetNamedPipeInfo(_handle!, null, &outBufferSize, null, null)) { throw WinIOError(Marshal.GetLastWin32Error()); } @@ -304,7 +304,7 @@ namespace System.IO.Pipes unsafe { int pipeReadType = (int)value << 1; - if (!Interop.Kernel32.SetNamedPipeHandleState(_handle, &pipeReadType, IntPtr.Zero, IntPtr.Zero)) + if (!Interop.Kernel32.SetNamedPipeHandleState(_handle!, &pipeReadType, IntPtr.Zero, IntPtr.Zero)) { throw WinIOError(Marshal.GetLastWin32Error()); } @@ -404,7 +404,7 @@ namespace System.IO.Pipes return secAttrs; } - internal static unsafe Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability, PipeSecurity pipeSecurity, ref GCHandle pinningHandle) + internal static unsafe Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability, PipeSecurity? pipeSecurity, ref GCHandle pinningHandle) { Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability); @@ -466,7 +466,7 @@ namespace System.IO.Pipes // For invalid handles, detect the error and mark our handle // as invalid to give slightly better error messages. Also // help ensure we avoid handle recycling bugs. - _handle.SetHandleAsInvalid(); + _handle!.SetHandleAsInvalid(); _state = PipeState.Broken; break; } diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.cs index b2d786b38fe..142f514ca35 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.cs @@ -16,7 +16,7 @@ namespace System.IO.Pipes internal const string AnonymousPipeName = "anonymous"; private static readonly Task s_zeroTask = Task.FromResult(0); - private SafePipeHandle _handle; + private SafePipeHandle? _handle; private bool _canRead; private bool _canWrite; private bool _isAsync; @@ -94,7 +94,7 @@ namespace System.IO.Pipes // Once a PipeStream has a handle ready, it should call this method to set up the PipeStream. If // the pipe is in a connected state already, it should also set the IsConnected (protected) property. // This method may also be called to uninitialize a handle, setting it to null. - protected void InitializeHandle(SafePipeHandle handle, bool isExposed, bool isAsync) + protected void InitializeHandle(SafePipeHandle? handle, bool isExposed, bool isAsync) { if (isAsync && handle != null) { @@ -199,7 +199,7 @@ namespace System.IO.Pipes return ReadAsyncCore(buffer, cancellationToken); } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { if (_isAsync) return TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state); @@ -305,7 +305,7 @@ namespace System.IO.Pipes return new ValueTask(WriteAsyncCore(buffer, cancellationToken)); } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { if (_isAsync) return TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state); @@ -480,7 +480,7 @@ namespace System.IO.Pipes } } - internal SafePipeHandle InternalHandle + internal SafePipeHandle? InternalHandle { get { diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ReadWriteCompletionSource.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ReadWriteCompletionSource.cs index b75b8728189..979fcc19f46 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ReadWriteCompletionSource.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/ReadWriteCompletionSource.cs @@ -16,7 +16,7 @@ namespace System.IO.Pipes private int _numBytes; // number of buffer read OR written internal ReadWriteCompletionSource(PipeStream stream, ReadOnlyMemory bufferToPin, bool isWrite) - : base(stream._threadPoolBinding, bufferToPin) + : base(stream._threadPoolBinding!, bufferToPin) { _pipeStream = stream; _isWrite = isWrite; -- 2.34.1