Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
NamedPipeServerStream.cs
Go to the documentation of this file.
8
9namespace System.IO.Pipes;
10
11public sealed class NamedPipeServerStream : PipeStream
12{
13 internal sealed class ExecuteHelper
14 {
15 internal PipeStreamImpersonationWorker _userCode;
16
18
19 internal bool _mustRevert;
20
22
24
25 internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle handle)
26 {
27 _userCode = userCode;
29 }
30 }
31
32 public const int MaxAllowedServerInstances = -1;
33
35
36 public NamedPipeServerStream(string pipeName)
38 {
39 }
40
41 public NamedPipeServerStream(string pipeName, PipeDirection direction)
42 : this(pipeName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.None, 0, 0, HandleInheritability.None)
43 {
44 }
45
46 public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances)
47 : this(pipeName, direction, maxNumberOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.None, 0, 0, HandleInheritability.None)
48 {
49 }
50
51 public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode)
52 : this(pipeName, direction, maxNumberOfServerInstances, transmissionMode, PipeOptions.None, 0, 0, HandleInheritability.None)
53 {
54 }
55
56 public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options)
57 : this(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, 0, 0, HandleInheritability.None)
58 {
59 }
60
61 public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize)
62 : this(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, HandleInheritability.None)
63 {
64 }
65
66 private NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
67 : base(direction, transmissionMode, outBufferSize)
68 {
69 ValidateParameters(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability);
70 Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability);
71 }
72
73 private void ValidateParameters(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
74 {
75 if (pipeName == null)
76 {
77 throw new ArgumentNullException("pipeName");
78 }
79 if (pipeName.Length == 0)
80 {
82 }
83 if (direction < PipeDirection.In || direction > PipeDirection.InOut)
84 {
86 }
87 if (transmissionMode < PipeTransmissionMode.Byte || transmissionMode > PipeTransmissionMode.Message)
88 {
90 }
91 if ((options & (PipeOptions)536870911) != 0)
92 {
94 }
95 if (inBufferSize < 0)
96 {
98 }
99 if (outBufferSize < 0)
100 {
102 }
103 if ((maxNumberOfServerInstances < 1 || maxNumberOfServerInstances > 254) && maxNumberOfServerInstances != -1)
104 {
105 throw new ArgumentOutOfRangeException("maxNumberOfServerInstances", System.SR.ArgumentOutOfRange_MaxNumServerInstances);
106 }
107 if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable)
108 {
110 }
111 if ((options & PipeOptions.CurrentUserOnly) != 0)
112 {
113 base.IsCurrentUserOnly = true;
114 }
115 }
116
117 public NamedPipeServerStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
118 : base(direction, PipeTransmissionMode.Byte, 0)
119 {
120 if (safePipeHandle == null)
121 {
122 throw new ArgumentNullException("safePipeHandle");
123 }
124 if (safePipeHandle.IsInvalid)
125 {
126 throw new ArgumentException(System.SR.Argument_InvalidHandle, "safePipeHandle");
127 }
128 ValidateHandleIsPipe(safePipeHandle);
129 InitializeHandle(safePipeHandle, isExposed: true, isAsync);
130 if (isConnected)
131 {
132 base.State = PipeState.Connected;
133 }
134 }
135
137 {
138 Dispose(disposing: false);
139 }
140
145
146 public IAsyncResult BeginWaitForConnection(AsyncCallback? callback, object? state)
147 {
149 }
150
155
157 {
158 if (base.State == PipeState.Closed)
159 {
160 throw Error.GetPipeNotOpen();
161 }
162 if (base.InternalHandle != null && base.InternalHandle.IsClosed)
163 {
164 throw Error.GetPipeNotOpen();
165 }
166 if (base.State == PipeState.Broken)
167 {
169 }
170 }
171
173 {
174 if (base.State == PipeState.WaitingToConnect)
175 {
177 }
178 if (base.State == PipeState.Disconnected)
179 {
181 }
182 if (base.InternalHandle == null)
183 {
185 }
186 if (base.State == PipeState.Closed || (base.InternalHandle != null && base.InternalHandle.IsClosed))
187 {
188 throw Error.GetPipeNotOpen();
189 }
190 }
191
192 internal NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability = HandleInheritability.None, PipeAccessRights additionalAccessRights = (PipeAccessRights)0)
193 : base(direction, transmissionMode, outBufferSize)
194 {
195 ValidateParameters(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability);
196 if (pipeSecurity != null && base.IsCurrentUserOnly)
197 {
199 }
200 Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, inheritability, additionalAccessRights);
201 }
202
203 protected override void Dispose(bool disposing)
204 {
205 try
206 {
208 }
209 finally
210 {
211 base.Dispose(disposing);
212 }
213 }
214
215 internal override void TryToReuse(PipeValueTaskSource source)
216 {
217 base.TryToReuse(source);
219 {
220 source._preallocatedOverlapped.Dispose();
221 }
222 }
223
224 private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
225 {
226 Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, null, inheritability, (PipeAccessRights)0);
227 }
228
229 private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
230 {
231 string fullPath = Path.GetFullPath("\\\\.\\pipe\\" + pipeName);
232 if (string.Equals(fullPath, "\\\\.\\pipe\\anonymous", StringComparison.OrdinalIgnoreCase))
233 {
235 }
236 if (base.IsCurrentUserOnly)
237 {
238 using (WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent())
239 {
240 SecurityIdentifier owner = windowsIdentity.Owner;
241 PipeAccessRule rule = new PipeAccessRule(owner, PipeAccessRights.FullControl, AccessControlType.Allow);
242 pipeSecurity = new PipeSecurity();
243 pipeSecurity.AddAccessRule(rule);
244 pipeSecurity.SetOwner(owner);
245 }
246 options &= ~PipeOptions.CurrentUserOnly;
247 }
248 int openMode = (int)direction | ((maxNumberOfServerInstances == 1) ? 524288 : 0) | (int)options | (int)additionalAccessRights;
249 int pipeMode = ((int)transmissionMode << 2) | ((int)transmissionMode << 1);
250 if (maxNumberOfServerInstances == -1)
251 {
252 maxNumberOfServerInstances = 255;
253 }
254 GCHandle pinningHandle = default(GCHandle);
255 try
256 {
257 global::Interop.Kernel32.SECURITY_ATTRIBUTES securityAttributes = PipeStream.GetSecAttrs(inheritability, pipeSecurity, ref pinningHandle);
258 SafePipeHandle safePipeHandle = global::Interop.Kernel32.CreateNamedPipe(fullPath, openMode, pipeMode, maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref securityAttributes);
259 if (safePipeHandle.IsInvalid)
260 {
262 }
263 InitializeHandle(safePipeHandle, isExposed: false, (options & PipeOptions.Asynchronous) != 0);
264 }
265 finally
266 {
267 if (pinningHandle.IsAllocated)
268 {
269 pinningHandle.Free();
270 }
271 }
272 }
273
274 public void WaitForConnection()
275 {
277 if (base.IsAsync)
278 {
280 return;
281 }
282 if (!global::Interop.Kernel32.ConnectNamedPipe(base.InternalHandle, IntPtr.Zero))
283 {
284 int lastPInvokeError = Marshal.GetLastPInvokeError();
285 if (lastPInvokeError != 535)
286 {
287 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
288 }
289 if (lastPInvokeError == 535 && base.State == PipeState.Connected)
290 {
292 }
293 }
294 base.State = PipeState.Connected;
295 }
296
298 {
299 if (cancellationToken.IsCancellationRequested)
300 {
302 }
303 if (!base.IsAsync)
304 {
305 return Task.Factory.StartNew(delegate(object s)
306 {
307 ((NamedPipeServerStream)s).WaitForConnection();
309 }
311 }
312
313 public void Disconnect()
314 {
316 if (!global::Interop.Kernel32.DisconnectNamedPipe(base.InternalHandle))
317 {
319 }
320 base.State = PipeState.Disconnected;
321 }
322
323 public unsafe string GetImpersonationUserName()
324 {
326 char* ptr = stackalloc char[514];
327 if (global::Interop.Kernel32.GetNamedPipeHandleStateW(base.InternalHandle, null, null, null, null, ptr, 514u))
328 {
329 return new string(ptr);
330 }
332 }
333
334 public void RunAsClient(PipeStreamImpersonationWorker impersonationWorker)
335 {
337 ExecuteHelper executeHelper = new ExecuteHelper(impersonationWorker, base.InternalHandle);
338 bool exceptionThrown = true;
339 try
340 {
341 ImpersonateAndTryCode(executeHelper);
342 exceptionThrown = false;
343 }
344 finally
345 {
346 RevertImpersonationOnBackout(executeHelper, exceptionThrown);
347 }
348 if (executeHelper._impersonateErrorCode != 0)
349 {
350 throw WinIOError(executeHelper._impersonateErrorCode);
351 }
352 if (executeHelper._revertImpersonateErrorCode != 0)
353 {
354 throw WinIOError(executeHelper._revertImpersonateErrorCode);
355 }
356 }
357
358 private static void ImpersonateAndTryCode(object helper)
359 {
360 ExecuteHelper executeHelper = (ExecuteHelper)helper;
361 if (global::Interop.Advapi32.ImpersonateNamedPipeClient(executeHelper._handle))
362 {
363 executeHelper._mustRevert = true;
364 }
365 else
366 {
367 executeHelper._impersonateErrorCode = Marshal.GetLastPInvokeError();
368 }
369 if (executeHelper._mustRevert)
370 {
371 executeHelper._userCode();
372 }
373 }
374
375 private static void RevertImpersonationOnBackout(object helper, bool exceptionThrown)
376 {
377 ExecuteHelper executeHelper = (ExecuteHelper)helper;
378 if (executeHelper._mustRevert && !global::Interop.Advapi32.RevertToSelf())
379 {
380 executeHelper._revertImpersonateErrorCode = Marshal.GetLastPInvokeError();
381 }
382 }
383
385 {
388 try
389 {
390 connectionValueTaskSource.PrepareForOperation();
391 if (!global::Interop.Kernel32.ConnectNamedPipe(base.InternalHandle, connectionValueTaskSource._overlapped))
392 {
393 int lastPInvokeError = Marshal.GetLastPInvokeError();
394 switch (lastPInvokeError)
395 {
396 case 997:
397 connectionValueTaskSource.RegisterForCancellation(cancellationToken);
398 break;
399 case 535:
400 connectionValueTaskSource.Dispose();
401 if (base.State == PipeState.Connected)
402 {
404 }
405 base.State = PipeState.Connected;
407 default:
408 connectionValueTaskSource.Dispose();
410 }
411 }
412 }
413 catch
414 {
415 connectionValueTaskSource.Dispose();
416 throw;
417 }
418 connectionValueTaskSource.FinishedScheduling();
419 return new ValueTask(connectionValueTaskSource, connectionValueTaskSource.Version);
420 }
421
423 {
424 if (base.InternalHandle == null)
425 {
427 }
429 }
430
431 private unsafe string HandleGetImpersonationUserNameError(int error, uint userNameMaxLength, char* userName)
432 {
433 if ((error == 0 || error == 1368) && Environment.Is64BitProcess)
434 {
435 global::Interop.Kernel32.LoadLibraryEx("sspicli.dll", IntPtr.Zero, 2048);
436 if (global::Interop.Kernel32.GetNamedPipeHandleStateW(base.InternalHandle, null, null, null, null, userName, userNameMaxLength))
437 {
438 return new string(userName);
439 }
441 }
442 throw WinIOError(error);
443 }
444}
static bool Is64BitProcess
static Exception GetPipeNotOpen()
Definition Error.cs:10
static string GetFullPath(string path)
Definition Path.cs:881
ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle handle)
void EndWaitForConnection(IAsyncResult asyncResult)
void ValidateParameters(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
static void ImpersonateAndTryCode(object helper)
void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
IAsyncResult BeginWaitForConnection(AsyncCallback? callback, object? state)
NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability)
NamedPipeServerStream(string pipeName, PipeDirection direction)
unsafe ValueTask WaitForConnectionCoreAsync(CancellationToken cancellationToken)
Task WaitForConnectionAsync(CancellationToken cancellationToken)
NamedPipeServerStream(PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability=HandleInheritability.None, PipeAccessRights additionalAccessRights=(PipeAccessRights) 0)
unsafe string HandleGetImpersonationUserNameError(int error, uint userNameMaxLength, char *userName)
NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances)
static void RevertImpersonationOnBackout(object helper, bool exceptionThrown)
override void TryToReuse(PipeValueTaskSource source)
NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options)
ConnectionValueTaskSource _reusableConnectionValueTaskSource
void RunAsClient(PipeStreamImpersonationWorker impersonationWorker)
NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize)
NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode)
void AddAccessRule(PipeAccessRule rule)
unsafe void PrepareForOperation(ReadOnlyMemory< byte > memory=default(ReadOnlyMemory< byte >))
Definition PipeStream.cs:48
unsafe void RegisterForCancellation(CancellationToken cancellationToken)
Definition PipeStream.cs:82
void ValidateHandleIsPipe(SafePipeHandle safePipeHandle)
Exception WinIOError(int errorCode)
void InitializeHandle(SafePipeHandle? handle, bool isExposed, bool isAsync)
static unsafe global::Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability)
void Dispose()
Definition Stream.cs:639
static Exception GetExceptionForLastWin32Error(string path="")
static Exception GetExceptionForWin32Error(int errorCode, string path="")
static string ArgumentOutOfRange_OptionsInvalid
Definition SR.cs:36
static string ArgumentOutOfRange_MaxNumServerInstances
Definition SR.cs:42
static string NotSupported_PipeSecurityIsCurrentUserOnly
Definition SR.cs:104
static string ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable
Definition SR.cs:38
static string InvalidOperation_PipeAlreadyDisconnected
Definition SR.cs:54
static string InvalidOperation_PipeAlreadyConnected
Definition SR.cs:52
static string InvalidOperation_PipeHandleNotSet
Definition SR.cs:48
static string ArgumentOutOfRange_TransmissionModeByteOrMsg
Definition SR.cs:30
static string Argument_InvalidHandle
Definition SR.cs:24
static string Argument_NeedNonemptyPipeName
Definition SR.cs:18
static string InvalidOperation_PipeNotYetConnected
Definition SR.cs:44
static string ArgumentOutOfRange_AnonymousReserved
Definition SR.cs:28
static string IO_PipeBroken
Definition SR.cs:74
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
static string ArgumentOutOfRange_DirectionModeInOutOrInOut
Definition SR.cs:32
Definition SR.cs:7
void SetOwner(IdentityReference identity)
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
static IAsyncResult Begin(Task task, AsyncCallback callback, object state)
Definition TaskToApm.cs:43
static void End(IAsyncResult asyncResult)
Definition TaskToApm.cs:48
static new TaskFactory< TResult > Factory
Definition Task.cs:56
static Task FromCanceled(CancellationToken cancellationToken)
Definition Task.cs:3363
new TaskAwaiter< TResult > GetAwaiter()
Definition Task.cs:221
static readonly IntPtr Zero
Definition IntPtr.cs:18
static ValueTask CompletedTask
Definition ValueTask.cs:71
static ValueTask FromException(Exception exception)
Definition ValueTask.cs:190