Skip to content

Commit

Permalink
Nullable annotate System.IO.Pipes (#31918)
Browse files Browse the repository at this point in the history
* annotate System.IO.Pipes

* update Stream override method signatures
  • Loading branch information
eiriktsarpalis authored Feb 10, 2020
1 parent 1dca86f commit 02ea20a
Show file tree
Hide file tree
Showing 22 changed files with 74 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal partial class Kernel32
{
[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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ internal partial class Kernel32
{
[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);
}
}
7 changes: 4 additions & 3 deletions src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,17 @@ protected PipeStream(System.IO.Pipes.PipeDirection direction, System.IO.Pipes.Pi
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() { }
protected override void Dispose(bool disposing) { }
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<byte> buffer) { throw null; }
public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.IO.Pipes/ref/System.IO.Pipes.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.IO.Pipes.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,8 +23,8 @@ public sealed partial class SafePipeHandle : SafeHandleZeroOrMinusOneIsInvalid
// 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)
{
Expand All @@ -37,8 +38,8 @@ internal SafePipeHandle(Socket namedPipeSocket) : base(ownsHandle: true)
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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OmitTransitiveCompileReferences>true</OmitTransitiveCompileReferences>
<TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Compiled Source Files -->
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private void Create(PipeDirection direction, HandleInheritability inheritability
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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace System.IO.Pipes
/// </summary>
public sealed partial class AnonymousPipeServerStream : PipeStream
{
private SafePipeHandle _clientHandle;
private SafePipeHandle _clientHandle = null!;
private bool _clientHandleExposed;

public AnonymousPipeServerStream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal sealed class ConnectionCompletionSource : PipeCompletionSource<VoidResu

// Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations)
internal ConnectionCompletionSource(NamedPipeServerStream server)
: base(server._threadPoolBinding, ReadOnlyMemory<byte>.Empty)
: base(server._threadPoolBinding!, ReadOnlyMemory<byte>.Empty)
{
_serverStream = server;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ private bool TryConnect(int timeout, CancellationToken cancellationToken)
// 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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public unsafe int NumberOfServerInstances
// 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());
}
Expand All @@ -135,10 +135,10 @@ private void ValidateRemotePipeUser()
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public sealed partial class NamedPipeClientStream : PipeStream
// 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -62,7 +62,7 @@ public void WaitForConnection()

// 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);
}

Expand All @@ -79,7 +79,7 @@ public Task WaitForConnectionAsync(CancellationToken cancellationToken)
WaitForConnectionAsyncCore();

async Task WaitForConnectionAsyncCore() =>
HandleAcceptedSocket(await _instance.ListeningSocket.AcceptAsync().ConfigureAwait(false));
HandleAcceptedSocket(await _instance!.ListeningSocket.AcceptAsync().ConfigureAwait(false));
}

private void HandleAcceptedSocket(Socket acceptedSocket)
Expand Down Expand Up @@ -124,7 +124,7 @@ public void Disconnect()
{
CheckDisconnectOperations();
State = PipeState.Disconnected;
InternalHandle.Dispose();
InternalHandle!.Dispose();
InitializeHandle(null, false, false);
}

Expand All @@ -135,7 +135,7 @@ public string GetImpersonationUserName()
{
CheckWriteOperations();

SafeHandle handle = InternalHandle?.NamedPipeSocketHandle;
SafeHandle? handle = InternalHandle?.NamedPipeSocketHandle;
if (handle == null)
{
throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet);
Expand Down Expand Up @@ -178,7 +178,7 @@ public override int OutBufferSize
public void RunAsClient(PipeStreamImpersonationWorker impersonationWorker)
{
CheckWriteOperations();
SafeHandle handle = InternalHandle?.NamedPipeSocketHandle;
SafeHandle? handle = InternalHandle?.NamedPipeSocketHandle;
if (handle == null)
{
throw new InvalidOperationException(SR.InvalidOperation_PipeHandleNotSet);
Expand Down Expand Up @@ -233,7 +233,7 @@ internal static SharedServer Get(string path, int maxCount)

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private unsafe string HandleGetImpersonationUserNameError(int error, uint userNa
{
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private void Create(string pipeName, PipeDirection direction, int maxNumberOfSer
// 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");
Expand All @@ -76,7 +76,7 @@ private void Create(string pipeName, PipeDirection direction, int maxNumberOfSer

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.
Expand Down Expand Up @@ -145,7 +145,7 @@ public void WaitForConnection()
}
else
{
if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle, IntPtr.Zero))
if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, IntPtr.Zero))
{
int errorCode = Marshal.GetLastWin32Error();

Expand Down Expand Up @@ -177,7 +177,7 @@ public Task WaitForConnectionAsync(CancellationToken cancellationToken)

if (!IsAsync)
{
return Task.Factory.StartNew(s => ((NamedPipeServerStream)s).WaitForConnection(),
return Task.Factory.StartNew(s => ((NamedPipeServerStream)s!).WaitForConnection(),
this, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}

Expand All @@ -189,7 +189,7 @@ public void Disconnect()
CheckDisconnectOperations();

// Disconnect the pipe.
if (!Interop.Kernel32.DisconnectNamedPipe(InternalHandle))
if (!Interop.Kernel32.DisconnectNamedPipe(InternalHandle!))
{
throw Win32Marshal.GetExceptionForLastWin32Error();
}
Expand All @@ -207,7 +207,7 @@ public unsafe string GetImpersonationUserName()
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);
}
Expand Down Expand Up @@ -244,11 +244,11 @@ public void RunAsClient(PipeStreamImpersonationWorker impersonationWorker)
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;
}
Expand All @@ -264,9 +264,9 @@ private static void ImpersonateAndTryCode(object helper)
}
}

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)
{
Expand All @@ -280,12 +280,12 @@ private static void RevertImpersonationOnBackout(object helper, bool exceptionTh
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;
Expand All @@ -304,7 +304,7 @@ private unsafe Task WaitForConnectionCoreAsync(CancellationToken cancellationTok

var completionSource = new ConnectionCompletionSource(this);

if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle, completionSource.Overlapped))
if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, completionSource.Overlapped))
{
int errorCode = Marshal.GetLastWin32Error();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected PipeCompletionSource(ThreadPoolBoundHandle handle, ReadOnlyMemory<byte
_pinnedMemory = bufferToPin.Pin();
_overlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
{
var completionSource = (PipeCompletionSource<TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
var completionSource = (PipeCompletionSource<TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped)!;
Debug.Assert(completionSource.Overlapped == pOverlapped);

completionSource.AsyncCallback(errorCode, numBytes);
Expand All @@ -70,7 +70,7 @@ internal void RegisterForCancellation(CancellationToken cancellationToken)
if (state == NoResult)
{
// Register the cancellation
_cancellationRegistration = cancellationToken.UnsafeRegister(thisRef => ((PipeCompletionSource<TResult>)thisRef).Cancel(), this);
_cancellationRegistration = cancellationToken.UnsafeRegister(thisRef => ((PipeCompletionSource<TResult>)thisRef!).Cancel(), this);

// Grab the state for case if IO completed while we were setting the registration.
state = Interlocked.Exchange(ref _state, NoResult);
Expand Down
Loading

0 comments on commit 02ea20a

Please sign in to comment.